Pular para o conteúdo

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, EscalationCorrectnessScorer e RetrievalRecallScorer.
  • Pontuadores apoiados por juiz se anexam apenas quando um cliente juiz é fornecido (uma chave de API da Anthropic está configurada): GroundednessScorer e FaithfulnessScorer (pontuadores de rubrica via LLMAsJudge diretamente) e HallucinationScorer (via HallucinationMetric do 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 Anthropic claude-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