PTENES
Investigación · IA local · código abierto

El modelo observa, el código decide.

Un especialista pequeño que funciona en tu máquina, lee cada mensaje y responde preguntas fijas con sí, no o no se puede saber. La duda siempre se deriva a una persona.

Banner de jev-open: especialista local de clasificación — el modelo observa, el código decide. Preguntas fijas; sí, no o sin evidencia; reglas en el código; consultas para una persona; se ejecuta en CPU; código abierto
Qué es

Un clasificador local al estilo de Jev para la clasificación inicial de solicitudes de atención

Proyecto de investigación y educación. No afirma tener paridad con Jev ni estar listo para producción. Los ejemplos del repositorio usan datos sintéticos, y cada cifra está marcada como [medido], [relato] o [simulación].

🧩 Tres respuestas por pregunta

Cada pregunta de la ficha ("¿quieres agendar?", "¿hay urgencia?") se convierte en sí / no / incierto, con probabilidad calibrada. La falta de evidencia nunca se convierte en "sí".

⚙️ Reglas en el código

La agenda, los plazos, los valores, la prioridad y las colas están en código común. El modelo solo observa, y una lista de palabras clave puede escalar casos críticos.

🖥️ Funciona en CPU

Se entrena en la GPU y funciona en CPU con ONNX int8 (~570 MB), en una API sin torch y en un contenedor Docker. Ningún mensaje sale de la máquina.

Cómo funciona

Del mensaje a la cola correcta

Todos los mensajes siguen llegando a una persona. El especialista solo ordena la cola e indica qué es urgente.

Mensaje→ Modelo: 7 preguntas × 3 hipótesis→ sí / no / incierto + %→ Código: reglas + palabras clave→ Cola + motivos

Construcción (una vez)

Ficha de la tarea → ejemplos revisados → datos → baseline sin entrenamiento → entrenamiento de las 2 últimas capas → prueba final congelada + carril OOD.

Uso (siempre)

API POST /classify en CPU. El texto vacío, demasiado largo (nunca se trunca) o con un error interno pasa directamente a revisión humana.

Recibos

Cada etapa guarda un JSON con hashes, métricas y todas las predicciones. No se sobrescribe nada y la prueba final se ejecuta una sola vez.

Requisitos previos

Qué debe incluir

Para entrenar, una GPU ayuda mucho. Para servir, basta con una CPU.

Python 3.12 + uv

Gestiona las dependencias de entrenamiento (torch, transformers, onnx).

uv sync

Ollama (opcional)

Solo para generar datos sintéticos de prototipos con un LLM local, sin costo de API.

ollama pull qwen3:30b

Docker (servicio)

La imagen solo incluye onnxruntime y tokenizers. Los pesos se montan en /pacotes.

docker compose up --build
Guía de uso · paso a paso

De cero a un especialista en servicio

Los mismos comandos sirven para cualquier nicho: solo cambia la carpeta tasks/<nicho>/ cambia. La guía completa paso a paso, con las precauciones para cada nicho, está en docs/PASSO-A-PASSO.md.

1

Clonar y preparar el entorno

Verifica si torch detecta la GPU.

git clone https://github.com/inematds/jev-open && cd jev-open
uv sync
uv run python -c "import torch; print(torch.cuda.is_available())"
2

Escribir la ficha del nicho

Preguntas, tres hipótesis por pregunta, significados de cada etiqueta, acciones por cola, pregunta crítica y objetivos. Usa un nicho existente como modelo.

mkdir tasks/meu-nicho
cp tasks/advocacia-atendimento/{ficha.yaml,regras.py,rede_urgencia.py,__init__.py} tasks/meu-nicho/
# edita ficha.yaml, regras.py y la lista de palabras clave
3

5 ejemplos + prueba de humo

Una persona del nicho revisa los ejemplos (barrera 1). Solo cuentan como prueba y nunca se convierten en datos de entrenamiento.

uv run python tools/zeroshot_smoke.py meu-nicho   # recibo en tasks/meu-nicho/recibos/
4

Datos

Lo ideal son mensajes reales anonimizados. Para crear un prototipo, el generador sintético usa un LLM local y un segundo LLM como verificador, y todo queda marcado como sintético.

uv run python tools/gerar_sintetico.py meu-nicho tasks/meu-nicho/dados/sintetico.jsonl \
    --n 320 --gerador qwen3.6:35b-a3b --verificador qwen3:30b --prefixo syn
uv run python tools/pipeline.py preparar meu-nicho   # división por grupo + deduplicación + manifest
5

Baseline, entrenamiento y prueba final

El baseline decide si vale la pena entrenar. La prueba final se ejecuta una vez, con el modelo base y el entrenado, en la prueba y en la pista OOD.

uv run python tools/pipeline.py baseline meu-nicho
uv run python tools/pipeline.py treinar  meu-nicho
uv run python tools/pipeline.py testar   meu-nicho
6

Exportar y servir en CPU

ONNX int8, con una barrera de paridad (±1 pp frente a fp32) y medición de latencia. La API rechaza el paquete si la ficha cambió después del entrenamiento.

uv run python tools/exportar_onnx.py meu-nicho
mkdir -p pacotes && cp -r workshops/meu-nicho-v1/pacote pacotes/meu-nicho
JEV_PACOTES=pacotes uv run python -m serve.api --tarefas meu-nicho
uv run python tools/testar_servico.py http://127.0.0.1:8080 meu-nicho
Ejemplos

Dos nichos en el repositorio

El alcance es siempre administrativo: sin opiniones jurídicas ni diagnósticos. Profesionales deben validar las listas de palabras clave y los textos fijos antes de cualquier uso real.

⚖️ Atención jurídica

7 preguntas: agendar, servicio, estado del proceso, pago, documento, consulta jurídica y urgencia (prisión, audiencia o plazo hoy/mañana, orden judicial, desalojo). La urgencia "sí" o "incierto" se envía al abogado de inmediato; la meta es cero urgencias perdidas. El estado del caso solo se informa después de verificar la identidad (confidencialidad).

🩺 Recepción de clínica

4 preguntas: agendar, reprogramar, documento y síntoma de alarma. La alerta "sí" o "incierto" se envía a una persona de inmediato; la meta es cero alertas perdidas. Los datos de salud son sensibles según la LGPD, por eso todo se ejecuta en la máquina de la clínica.

POST /classify?tarefa=advocacia-atendimento
{"texto": "Boa noite, meu filho foi preso agora há pouco e está na delegacia do centro..."}

# formato de la respuesta (fragmento)
{"decisao": {"prioridade": "advogado_imediato",
             "motivos": ["urgencia=sim -> advogado_imediato",
                         "rede de palavras-chave: delegacia, preso -> advogado_imediato"]},
 "observacoes": {"urgencia": {"rotulo": "sim", "confianca": ..., "probs": [...]}, ...}}
Hoja de ruta

Dónde está el proyecto

Estado al 2026-09-25. Lo que depende de datos reales o de una VPS real aún no se ha medido.

Listo
Fases 0–1: entorno, fichas y prueba de humotorch con CUDA en la GB10 [medido]; dos nichos con ficha, reglas y palabras clave; prueba de humo sin perder ningún caso crítico [medido, 5 ejemplos sintéticos].
Listo
Ejecución v1 completa, con datos sintéticos [simulación]Abogacía: la precisión en la prueba pasó del 72% al 96%, con 1 urgencia perdida (meta no alcanzada). Clínica: pasó del 82% al 96%, sin alertas perdidas. ONNX int8 de 570 MB, 0,7–1,5 s por mensaje y ~1,2–1,3 GB de RAM por nicho con 2 hilos [medido en la GB10, no en una VPS]; la API y Docker superaron las 9 pruebas del servicio. Detalles y metas no alcanzadas en RESULTADOS-v1.md.
Siguiente
Datos reales anonimizados + umbral calibradoMensajes reales con autorización, anotados por dos personas; carril OOD de otro bufete o clínica; umbral de confianza por pregunta calibrado en dev; metas verificadas de verdad.
Después
VPS real y nuevas tareasLatencia y RAM en una VPS de 2 vCPU / 4 GB; clasificación de notificaciones judiciales, verificación de poderes y guías de seguro médico.