Pipeline de avaliação
O arcabouço de avaliação lê um conjunto de dados golden JSONL fixado, executa cada caso de ponta a ponta no mesmo agente LangGraph compilado que o caminho de produção usa (ele constrói o grafo uma vez por execução, com HITL desligado), despacha cada estado final do agente para um conjunto componível de pontuadores e emite tanto um resumo em markdown quanto um artefato JSON. A barreira de CI consome o artefato JSON; uma falha determinista por caso ou uma violação de limiar de corpus apoiada por juiz produz um código de saída diferente de zero e faz falhar a verificação do PR.
A execução padrão do runner usa dois grupos de pontuadores:
- Pontuadores deterministas sempre ativos (sem LLM, sem chave necessária)
condicionam cada PR:
CitationCoverageScorer,CitationCorrectnessScorer,RefusalCorrectnessScorer,EscalationCorrectnessScorereRetrievalRecallScorer. - Pontuadores apoiados por juiz se anexam apenas quando um cliente juiz é
fornecido (uma chave de API da Anthropic está configurada):
GroundednessScorereFaithfulnessScorer(pontuadores de rubrica viaLLMAsJudgediretamente) eHallucinationScorer(viaHallucinationMetricdo DeepEval). Sem uma chave de juiz, a execução reporta o juiz como desabilitado e a barreira de limiar roda apenas contra os pontuadores deterministas. O modelo juiz é o Anthropicclaude-haiku-4-5.
Consulte ADR-0003 para a política de limiares e a escolha do modelo juiz.
Um gate de calibração à parte verifica o próprio juiz. Sobre uma fatia reservada rotulada por humanos ele mede a concordância por dimensão entre o juiz e um especialista de domínio; roda consultivo por padrão e armado em fail-closed sobre as duas dimensões de segurança (escalonamento e autolesão) no trilho de CI que exige, sem chaves e determinístico.
flowchart LR
A["Golden dataset<br/>(JSONL, pinned)"] --> B["evals/runner.py<br/>PytestEvalRunner"]
B --> C["Agent run<br/>(compiled LangGraph + LLMClient + RAG)"]
C --> D["Final AgentState per case<br/>(response, retrieved context,<br/>guardrail decisions, cost)"]
D --> E1["Deterministic scorers (always on)<br/>CitationCoverage, CitationCorrectness,<br/>RefusalCorrectness, EscalationCorrectness,<br/>RetrievalRecall"]
D --> E2["Judge-backed scorers (only when a judge key is set)<br/>Groundedness, Faithfulness (LLMAsJudge rubric),<br/>Hallucination (DeepEval)"]
E1 --> F["Report writer<br/>(write_reports)"]
E2 --> F
F --> G1["Markdown summary<br/>(evals/reports/latest.md)"]
F --> G2["JSON artifact<br/>(evals/reports/latest.json)"]
G2 --> H{"CI gate<br/>per-case deterministic gate +<br/>judge corpus thresholds"}
H -- "pass" --> I["PR check: pass"]
H -- "fail" --> J["PR check: fail"]
G2 --> K["Calibration gate (key-free)<br/>human-vs-judge agreement per dimension<br/>advisory; fail-closed on escalation + self-harm"]
K -- "agree" --> I
K -- "drift on a safety dim" --> J