Spaces:
Sleeping
Sleeping
| # Evaluación del asistente clínico | |
| Suite de evals rigurosa para un asistente de diagnóstico veterinario: mide precisión, | |
| groundedness y **seguridad**, y bloquea despliegues ante regresiones. | |
| Principio de diseño: **toda la evaluación tiene que poder correr sin una clave de pago.** | |
| Una puerta de calidad que depende de saldo se apaga el día que se acaba, y se apaga justo | |
| cuando más falta hace. Por eso los jueces LLM usan el CLI de Claude Code (la sesión que ya | |
| tienes) o un modelo local en Ollama; la ruta por SDK con `ANTHROPIC_API_KEY` queda como | |
| opción explícita. | |
| ## Capas | |
| 1. **Regresión del motor determinista** (`frontend/tests`, Vitest) — fija el comportamiento | |
| de `analisis.ts`. Es la red de seguridad de la migración. | |
| 2. **Evals clínicas** (`run_evals.py`) — comprobaciones deterministas sobre la salida del | |
| modelo: recall de diferenciales, cobertura de hallazgos, acierto de derivación, idioma | |
| y **violaciones de seguridad** (tolerancia cero). Puerta de CI. La cobertura se mide | |
| sobre el campo estructurado o, si el backend devuelve prosa, sobre las menciones en el | |
| texto (marcado `~` en la salida): una métrica que la ruta de producción no puede pasar | |
| por construcción no es una puerta. | |
| 3. **Juez clínico LLM** (`judge/clinical_judge.py`) — rúbrica de corrección, hedging, | |
| seguridad y completitud, servida por el **CLI de Claude Code** o por un modelo **local en | |
| Ollama**, sin clave de API en ninguno de los dos casos. Atrapa lo que ninguna comparación | |
| de strings ve: razonamiento incorrecto con las palabras clave correctas, sobreconfianza, | |
| consejo peligroso. | |
| 4. **Groundedness con Ragas** (`run_ragas.py`) — faithfulness y precisión/recall del | |
| contexto sobre el índice RAG real, con el mismo juez local. | |
| 5. **Eval de recuperación** (`run_retrieval_eval.py`) — aísla la recuperación de la | |
| generación para hacer A/B de configs (embeddings × idioma de consulta). | |
| 6. **promptfoo** (`promptfooconfig.yaml`) — regresión declarativa del prompt (idioma, sin | |
| tokens de control, rúbricas). | |
| ## Ejecutar | |
| ```bash | |
| # Tubería sin modelo (valida la mecánica y los umbrales) | |
| make evals # split dev, sólo casos validados | |
| make evals-test # split reservado | |
| # Con el modelo real (genera interpretaciones vía backend) | |
| cd backend && uv run python ../evals/run_evals.py --modelo medgemma | |
| # Con salidas precomputadas, eligiendo juez | |
| cd backend && uv run python ../evals/run_evals.py --predicciones preds.jsonl --juez cli | |
| cd backend && uv run python ../evals/run_evals.py --predicciones preds.jsonl --juez ollama | |
| # Groundedness (requiere índice RAG y Ollama) | |
| make ragas ARGS="--predicciones preds.jsonl" | |
| # A/B de recuperación | |
| make retrieval-eval | |
| # promptfoo | |
| cd evals && npx promptfoo@latest eval | |
| ``` | |
| ## Los jueces | |
| Tres transportes tras la misma rúbrica y el mismo esquema de salida. `--juez auto` (por | |
| defecto) prueba en este orden y usa el primero disponible: | |
| | `--juez` | Qué necesita | Coste | Notas | | |
| |---|---|---|---| | |
| | `cli` | El CLI `claude` con sesión iniciada | Límites de uso de tu suscripción | Mejor juicio. No existe en CI | | |
| | `ollama` | Ollama con el modelo descargado | Ninguno | Reproducible (temp. 0). Mantiene viva la rúbrica en CI | | |
| | `claude` | `ANTHROPIC_API_KEY` | Saldo de API | Explícito, para auditorías | | |
| ```bash | |
| claude --version # juez CLI: basta con tener sesión iniciada | |
| ollama pull qwen2.5:7b # juez local por defecto | |
| ``` | |
| | Variable | Por defecto | Para qué | | |
| |---|---|---| | |
| | `MORPHOS_JUEZ_CLI_MODELO` | `sonnet` | Modelo del juez CLI (`opus` para auditar) | | |
| | `MORPHOS_JUEZ_MODELO` | `qwen2.5:7b` | Modelo del juez local | | |
| | `MORPHOS_JUEZ_BASE_URL` | `http://localhost:11434` | Dónde está Ollama | | |
| ### El juez CLI | |
| `judge/claude_cli.py` invoca `claude -p` con la rúbrica como system prompt y | |
| `--output-format json`, sin MCP, sin sesión persistida y con un solo turno. Resuelve lo que | |
| bloqueaba esta capa: **no hace falta clave de API**, basta la sesión que ya tienes. A cambio | |
| no está en un runner de CI y no expone temperatura, así que es menos reproducible que la | |
| ruta Ollama. | |
| ### Elegir modelo de juez | |
| - **No uses el modelo bajo evaluación.** Un modelo que se juzga a sí mismo se puntúa alto | |
| por sesgo de auto-preferencia y deja de detectar sus propias regresiones. | |
| - **Los umbrales dependen del juez.** `UMBRALES_JUEZ` está calibrado contra el juez local | |
| pequeño. Sobre las mismas salidas simuladas (deliberadamente pobres), qwen2.5:7b puntuó | |
| `hedging_apropiado` en 1.0 y el juez CLI en 0.4: el pequeño aprueba lo que el grande | |
| suspende. Si cambias de juez, recalibra los umbrales en vez de asumir que la escala es la | |
| misma. | |
| Con `--simular` el juez se omite a propósito: puntuaría el simulador, no el modelo. Con | |
| `--juez-informativo` corre pero no bloquea la puerta. Los jueces remotos se paralelizan | |
| (4 casos a la vez); el local va en serie porque competiría consigo mismo por la GPU. | |
| ## Umbrales (puerta de CI) | |
| Definidos en `run_evals.py` → `UMBRALES` (deterministas) y `UMBRALES_JUEZ` (rúbrica). Salida | |
| con código ≠0 si alguna métrica cae por debajo o si hay cualquier violación de seguridad, | |
| venga de la comprobación determinista o del juez. Ver `.github/workflows/evals.yml`. | |
| ## Disciplina del dataset | |
| Dos reglas, ambas aplicadas por el runner y no sólo documentadas: | |
| - **Split reservado.** `--split dev` (por defecto) es el conjunto sobre el que se itera; | |
| `--split test` sólo se mira en agregado y antes de desplegar. Mirar los fallos caso a caso | |
| del split reservado para afinar un prompt lo convierte en otro split de desarrollo. | |
| - **Sin firma veterinaria no es oro.** Los casos con `validado: false` no cuentan para la | |
| puerta (salvo `--incluir-pendientes`): no pueden aprobar ni bloquear un despliegue. | |
| ```bash | |
| make revision # hoja de revisión | |
| python evals/revision.py --validar imha-canino --revisor "Dra. Pérez" | |
| python evals/revision.py --estado | |
| ``` | |
| Esquema de los casos y estado de validación: `dataset/README.md`. | |