morphos / .github /workflows /evals.yml
Jose Salazar
CI: disparo manual (workflow_dispatch) en ambas puertas
b0a3b8f
Raw
History Blame Contribute Delete
3.66 kB
name: evals
# Puerta de calidad CLÍNICA: bloquea el merge si el motor determinista regresa o si la suite
# de evaluación cae bajo sus umbrales o registra violaciones de seguridad.
#
# Este sí filtra por rutas —es el workflow caro— pero el filtro anterior era demasiado
# estrecho: nombraba `backend/app/ai/**` y `backend/app/rag/**`, dejando fuera `schemas.py`
# (que define `InterpretacionClinica`, la forma misma que las evals puntúan) y `config.py`
# (umbrales y ruta de modelo por defecto). Un cambio ahí alteraba la salida evaluada sin
# disparar la puerta. Las puertas de código —ruff, pytest, tsc, eslint— viven en `ci.yml`,
# que corre en TODOS los PR sin filtro.
on:
pull_request:
paths:
- "frontend/**"
- "backend/**"
- "evals/**"
- "data/**"
push:
branches: [main]
# Disparo manual: además de para relanzar tras un fallo de infraestructura, esta puerta va
# filtrada por rutas, así que a veces interesa correrla a mano sobre un cambio que el filtro
# no coge. Ver la nota en ci.yml.
workflow_dispatch:
jobs:
motor-regresion:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- name: Instalar frontend
working-directory: frontend
run: npm ci
- name: Suite de regresión del motor (vitest)
working-directory: frontend
run: npm test
evals-clinicas:
runs-on: ubuntu-latest
needs: motor-regresion
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "22"
- uses: astral-sh/setup-uv@v5
- name: Sincronizar backend
working-directory: backend
run: uv sync
- name: Instalar deps del motor (para el puente Node)
working-directory: frontend
run: npm ci
# Antes de la puerta, la puerta misma: métricas, rúbrica, umbrales y esquema del dataset
# son código sin cobertura de nadie más. Si el medidor está roto, el resultado de la
# puerta no significa nada (visto: el simulador dejaba `fuera_de_alcance` sin declarar y
# suspendía una métrica de tolerancia cero por su cuenta).
- name: Pruebas unitarias de los scripts de evals
working-directory: backend
run: uv run pytest -q ../evals/tests
# En CI real, sustituir --simular por --modelo medgemma apuntando a un endpoint,
# o subir un archivo de predicciones generado en un job con GPU.
#
# Sobre el juez: con --simular se omite a propósito (juzgaría el simulador, no el
# modelo). Sobre salidas reales se activa solo, en este orden: CLI de Claude Code (no
# existe en el runner), Ollama local (tampoco, salvo que se instale en el job) y SDK de
# Claude si ANTHROPIC_API_KEY está en los secrets. Sin ninguno la puerta sigue siendo
# válida, sólo más ciega: las métricas deterministas se calculan igual.
- name: Ejecutar evals (puerta de CI split dev)
working-directory: backend
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: uv run python ../evals/run_evals.py --simular --split dev
# El split reservado no se usa para iterar, pero sí tiene que seguir verde antes de
# llegar a main: si sólo se mirara en el despliegue, se descubriría demasiado tarde.
- name: Ejecutar evals sobre el split reservado
working-directory: backend
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: uv run python ../evals/run_evals.py --simular --split test