04 Investigar
Transforme um sinal negativo do usuário em diagnóstico e correção revisados por uma pessoa, sem confundir feedback com verdade absoluta.
Ponto de partida
O Módulo 03 produziu um trace autoritativo do Chat para How many active customers do we have? com uma divergência intencional:
| Evidência | Valor esperado |
|---|---|
| observação raiz | chat_turn |
sql-execution-success | true |
user-thumbs | false |
metadado policyversion | policy-v1 |
Mantenha ID/URL desse trace e as duas contagens da planilha. Não use o diagnóstico curl não avaliado do Módulo 03.
Por que uma investigação humana é necessária
Um 👎 indica onde procurar, mas não o que falhou. O usuário pode ter pretendido outra coisa, a solicitação pode ser ambígua, o SQL pode ser inválido ou duas definições de negócio podem divergir. Promover todo sinal negativo diretamente ao dataset dourado transformaria palpites em verdade absoluta.
Aqui, o revisor primeiro registra o observável, testa explicações e só então registra diagnóstico e correção. Essa decisão revisada — não o 👎 — é a verdade entregue ao Módulo 05.
Objetivo
Concluir uma tarefa de anotação production-investigation-<session> para o chat_turn raiz do Módulo 03, com observação, categoria de falha, SQL corrigido exato, aprovação para o dataset dourado e proveniência de produção.
Etapa 1 — Encontrar o incidente de feedback exato
No Langfuse, abra Tracing e filtre a pontuação booleana user-thumbs = false. Abra o trace que tenha:
- nome/observação raiz
chat_turn; - pergunta
How many active customers do we have?; config_idvencedor e ID registrados no Módulo 03;- metadado
policyversion=policy-v1; e - pontuações
sql-execution-success=trueeuser-thumbs=false.
O código de serving emite policy_version, mas o adaptador OpenTelemetry remove o sublinhado; no Langfuse, a chave é policyversion.
Anote o chat_turn raiz, não sua generation filha llm_call. A raiz contém pergunta e saída estruturada ponta a ponta — SQL, colunas, linhas, erro e outcome — necessárias à investigação. A filha contém apenas a transcrição do modelo e o SQL, e não é o incidente autoritativo.
Etapa 2 — Criar as três configurações de pontuação da revisão
Esta configuração é intencionalmente uma etapa de revisão humana apenas na interface. O repositório não contém comando que crie ou conclua a tarefa.
Antes da fila, abra Settings → Scores → Create e crie:
| Nome | Tipo de dado | Valores permitidos / finalidade |
|---|---|---|
observed-issue | TEXT | Descreva somente evidências visíveis no trace e na comparação. |
failure-category | CATEGORICAL | stale-business-policy, incorrect-sql, ambiguous-request, not-actionable |
approved-for-golden | BOOLEAN | Aprove somente após verificar a correção. |
Use nomes e hifens exatamente como mostrados. Criar as configurações primeiro é mais seguro, pois o conjunto de IDs anexado à fila fica fixo na criação. Se uma for omitida, crie nova fila com sufixo novo. As próprias configurações são mutáveis: alterações compatíveis de nome, esquema ou categoria exigem atualização auditada e não reescrevem pontuações existentes.
Etapa 3 — Criar a fila e apontar para a raiz lógica
Abra Annotations → Queues → Create e:
- Dê o nome
production-investigation-<session>, substituindo<session>por um identificador curto e único. - Anexe as três configurações da Etapa 2.
- Crie a fila.
- Volte ao trace do Módulo 03, selecione a observação raiz
chat_turn, abra Annotate e escolha a fila. - Abra a tarefa e verifique que o alvo é
chat_turn, nãollm_call.
A fila não pode alterar os IDs de configurações após a criação. Recrie-a apenas se o conjunto estiver errado; para editar uma configuração já anexada, use atualização auditada.
Etapa 4 — Codificar abertamente o que é observável
O Módulo 03 revelou a preparação intencional. Nesta investigação, deixe esse conhecimento prévio de lado e pratique o fluxo para incidente desconhecido: examine pergunta, SQL, contagem, modelo/prompt e ambas as pontuações antes de nomear uma causa. Em observed-issue, insira uma nota apenas de evidências, como:
The answer returned a count and its SQL executed. The observed count differs from the
second reference count recorded in Module 03. The generated query uses a 90-day
customer signup window, and the trace metadata reports policy-v1.Isso ainda não culpa modelo, mecanismo SQL, usuário ou política. A separação impede que o diagnóstico preparado seja introduzido antes da verificação.
Etapa 5 — Inspecionar todas as evidências do trace
No chat_turn raiz, verifique:
- metadado
policyversion=policy-v1; - SQL com
v_customerse janela de 90 dias emsignup_date; - resultado estruturado com a contagem do Módulo 03;
- pontuação operacional booleana
sql-execution-success=true; e - sinal do usuário booleano
user-thumbs=false.
O SQL segue as instruções policy-v1, e a pontuação de execução está correta em seu escopo estreito. Nenhum dos fatos prova se a política implantada corresponde à definição vigente.
Etapa 6 — Testar as duas definições lado a lado
Em ClickHouse_Demos/workshops/agent_arena, execute ambas no mesmo ambiente somente leitura:
source .env
.venv/bin/python - <<'PY'
from arena.config import load_config
from agents.chclient import ROClickHouseClient
queries = {
"policy-v1": """SELECT count() FROM v_customers
WHERE signup_date >= today() - INTERVAL 90 DAY""",
"policy-v2": """SELECT uniqExact(customer_id) FROM v_orders
WHERE order_ts >= now() - INTERVAL 30 DAY
AND status NOT IN ('cancelled', 'returned')""",
}
client = ROClickHouseClient(load_config().clickhouse)
for version, sql in queries.items():
result = client.query(sql)
print(f"{version}: {result.rows[0][0]}")
PYAs contagens devem corresponder à planilha e ser diferentes. Agora há evidência para diagnosticar definição de negócio implantada desatualizada: o trace anuncia policy-v1, o SQL segue essa política e a consulta atual verificada implementa policy-v2.
Etapa 7 — Anotar, corrigir, aprovar e concluir
Na tarefa, registre:
| Campo | Valor |
|---|---|
observed-issue | Mantenha a nota baseada em evidências e acrescente a comparação verificada. |
failure-category | stale-business-policy |
| Corrected Output | O SQL exato abaixo |
approved-for-golden | true |
Mude Corrected Output para plain-text mode e insira este SQL bruto exato:
SELECT uniqExact(customer_id) FROM v_orders
WHERE order_ts >= now() - INTERVAL 30 DAY
AND status NOT IN ('cancelled', 'returned')O Langfuse registra, mas não executa a correção. O cliente da Etapa 6 deve executar o texto exato antes da aprovação; se editar, execute novamente. Escolha Complete (ou Complete + next). Uma correção malformada, inexequível ou não verificada não pode virar verdade dourada.
Etapa 8 — Registrar a proveniência para o Módulo 05
Copie para a planilha, mantendo IDs privados:
| Campo de proveniência | Valor a registrar |
|---|---|
source | production-feedback |
source_trace_id | ID do trace autoritativo do Chat no Módulo 03 |
failure_category | stale-business-policy |
source_policy_version | policy-v1 |
annotation_id | ID da tarefa concluída, quando disponível |
| correção revisada | SQL exato da política atual acima |
source_trace_id, failure_category e source_policy_version são obrigatórios para um registro derivado da produção. annotation_id é opcional no runtime, mas registre-o quando disponível para manter a decisão auditável.
Como verificar se terminou
- Você investigou o único trace do Chat do Módulo 03 com
user-thumbs=false. - O alvo é
chat_turn, nunca a filhallm_call. - A fila se chama
production-investigation-<session>e contém as três configurações corretamente tipadas. observed-issueregistra comportamento antes do diagnóstico.- Você executou os dois SQLs e confirmou contagens diferentes.
- A tarefa concluída contém
stale-business-policy, o SQL exato eapproved-for-golden=true. - A planilha preserva a proveniência sem publicar IDs ou URLs.
- Você explica por que o 👎 prioriza revisão, mas não vira verdade por si só.
Continue para o Módulo 05 — Fechar o ciclo para promover a correção, comparar políticas e impedir online a mesma classe de falha.