03 Lançar e detectar
Lance o agente selecionado com uma lacuna de política conhecida e use avaliação operacional e feedback real para detectá-la.
Ponto de partida
Módulo 02 concluído. Registre o config_id vencedor da execução real da Arena e exporte-o na raiz do laboratório (ClickHouse_Demos/workshops/agent_arena):
source .env
export WINNER_CONFIG_ID="${WINNER_CONFIG_ID:-qwen3.7-flash__P2_fewshot}"A execução verificada selecionou qwen3.7-flash__P2_fewshot; mantenha o vencedor da sua turma se for diferente. Você usará o mesmo modelo e prompt medidos, não um agente especial feito para falhar.
Se o vencedor for Qwen, desative OpenRouter Settings → Privacy → Data Policies → Zero Data Retention → Non-frontier. A rota Alibaba disponível é rejeitada quando o ZDR non-frontier está ativo. Revise os requisitos de privacidade antes de alterar isso para dados reais.
Por que um evaluator aprovado ainda pode ignorar o valor para o usuário
Um evaluator online mede somente a dimensão para a qual foi criado. Aqui, sql-execution-success responde se o agente gerou SQL executável pelo ClickHouse. Ele não sabe se o SQL segue a definição atual de cliente ativo.
Isso cria uma lacuna realista de monitoramento:
| Sinal | Pergunta respondida | Valor esperado neste incidente |
|---|---|---|
sql-execution-success | O SQL gerado foi executado com sucesso? | true |
user-thumbs | A resposta atendeu à necessidade deste usuário? | false |
A avaliação operacional detecta SQL quebrado, timeouts e erros de execução. A avaliação semântica ou do usuário verifica utilidade e alinhamento com o significado de negócio. Nenhuma substitui a outra. Um 👎 prioriza uma investigação; não é a verdade absoluta. Uma pessoa investigará no Módulo 04.
Objetivo
Criar um trace real chat_turn no qual o evaluator operacional aprova, mas o usuário rejeita a resposta. Registre o trace e as duas contagens conflitantes para a investigação humana.
Etapa 1 — Comprovar que o incidente preparado é reproduzível
Execute o preflight na raiz antes de iniciar o servidor:
source .env
export WINNER_CONFIG_ID="${WINNER_CONFIG_ID:-qwen3.7-flash__P2_fewshot}"
.venv/bin/python -m schema.gen_schema_context
.venv/bin/python -m scripts.check_online_eval_scenario \
--config-id "$WINNER_CONFIG_ID"O comando executa ambas as definições e faz três paráfrases à configuração selecionada. Ele deve exibir valores diferentes para stale_count e current_count, três linhas classification_N=policy-v1 e:
Se uma paráfrase retornar ok/unknown, o preflight repete apenas a mesma paráfrase e configuração uma vez. Não repete policy-v2 nem falhas do provedor/modelo/agente; um segundo ok/unknown continua bloqueando.
OK: seeded online-evaluation incident is reproducibleSe as contagens forem iguais ou alguma classificação não for policy-v1, pare: o contraste não seria visível nesta execução.
A definição atual do negócio é este SQL exato:
SELECT uniqExact(customer_id) FROM v_orders
WHERE order_ts >= now() - INTERVAL 30 DAY
AND status NOT IN ('cancelled', 'returned')A definição antiga policy-v1 conta clientes cadastrados nos últimos 90 dias. Portanto, o SQL gerado aqui é válido diante das instruções explícitas de policy-v1. O problema não é falta de inteligência do modelo: o contexto de política implantado está desatualizado e o evaluator de execução é estreito demais para perceber.
Etapa 2 — Provisionar o evaluator operacional
O provisionamento é idempotente:
source .env
.venv/bin/python -m scripts.provision_online_evaluators --operationalA saída deve citar o evaluator sql-execution-success e a regra habilitada agent-arena-sql-execution-online.
Etapa 3 — Iniciar a versão com política desatualizada
No primeiro terminal, inicie o servidor escolhendo explicitamente a política antiga e deixe-o em execução:
source .env
AGENT_ARENA_POLICY_VERSION=policy-v1 \
.venv/bin/uvicorn serving.api:app --port 8100Não omita AGENT_ARENA_POLICY_VERSION. O serviço usa por padrão a policy-v2 atual, que exclui corretamente pedidos cancelados e devolvidos.
Etapa 4 — Perguntar e avaliar no Chat
Em outro terminal, inicie o dashboard se necessário:
scripts/arena.sh serveAbra http://localhost:5174, escolha a aba Chat e $WINNER_CONFIG_ID e pergunte:
How many active customers do we have?Leia o SQL e o resultado. Eles devem seguir a definição preparada de cadastro em 90 dias da policy-v1. Clique em 👎 e aguarde feedback sent.
Esse trace raiz do Chat é o único incidente autoritativo que será pontuado e entregue ao Módulo 04.
Etapa 5 — Encontrar e verificar o trace do Chat
No Langfuse, abra Tracing e filtre user-thumbs = false. Abra o chat_turn raiz mais recente cuja pergunta seja How many active customers do we have?, cuja configuração corresponda a $WINNER_CONFIG_ID e cujos metadados mostrem policyversion=policy-v1. Copie ID e URL do trace e defina o ID localmente:
export CHAT_TRACE_ID="<paste the Chat trace ID>"
.venv/bin/python -m scripts.verify_online_scores "$CHAT_TRACE_ID" \
sql-execution-success=true user-thumbs=falseConfirme que user-thumbs é Boolean false, não pontuação numérica ou textual. O código de serving chama o campo de policy_version; o adaptador OpenTelemetry o sanitiza para a chave emitida policyversion.
Etapa 6 — Reproduzir com curl sem avaliação
A chamada bruta à API é uma reprodução obrigatória em nível de comando. Ela cria outro trace, mas não é o incidente de feedback e não deve ser avaliada:
source .env
export WINNER_CONFIG_ID="${WINNER_CONFIG_ID:-qwen3.7-flash__P2_fewshot}"
ASK_BODY=$(.venv/bin/python -c \
'import json,sys; print(json.dumps({"question": sys.argv[1], "config_id": sys.argv[2]}))' \
"How many active customers do we have?" "$WINNER_CONFIG_ID")
CURL_RESPONSE=$(curl -fsS http://localhost:8100/ask \
-H 'content-type: application/json' -d "$ASK_BODY")
printf '%s\n' "$CURL_RESPONSE" | .venv/bin/python -m json.tool
CURL_TRACE_ID=$(printf '%s\n' "$CURL_RESPONSE" | .venv/bin/python -c \
'import json,sys; data=json.load(sys.stdin); assert data.get("policy_version") == "policy-v1"; assert data.get("outcome") == "ok"; trace_id=data.get("trace_id"); assert isinstance(trace_id, str) and trace_id; print(trace_id)')A resposta deve conter outcome: "ok", trace_id não vazio e policy_version: "policy-v1".
Aguarde o evaluator assíncrono e verifique apenas a pontuação operacional:
.venv/bin/python -m scripts.verify_online_scores "$CURL_TRACE_ID" \
sql-execution-success=trueNão chame /feedback para CURL_TRACE_ID nem o coloque na planilha. Ele é apenas um diagnóstico reproduzível; CHAT_TRACE_ID continua sendo o trace de entrega.
Etapa 7 — Comparar com a política atual
Execute o SQL atual pelo mesmo cliente ClickHouse somente leitura do agente e compare o único resultado com o resultado desatualizado em CURL_RESPONSE:
.venv/bin/python - <<'PY'
from arena.config import load_config
from agents.chclient import ROClickHouseClient
sql = """SELECT uniqExact(customer_id) FROM v_orders
WHERE order_ts >= now() - INTERVAL 30 DAY
AND status NOT IN ('cancelled', 'returned')"""
result = ROClickHouseClient(load_config().clickhouse).query(sql)
print(result.rows[0][0])
PYEsta é a consulta exata executada:
SELECT uniqExact(customer_id) FROM v_orders
WHERE order_ts >= now() - INTERVAL 30 DAY
AND status NOT IN ('cancelled', 'returned')A diferença é a falha visível. O SQL rodou, mas respondeu à definição errada. Registre a contagem junto às evidências do trace autoritativo.
Planilha de investigação
Leve isto ao Módulo 04:
| Evidência | Seu valor |
|---|---|
config_id vencedor | |
| ID do trace autoritativo do Chat | |
| URL do trace autoritativo do Chat | |
Contagem desatualizada policy-v1 | |
Contagem atual policy-v2 | |
sql-execution-success | true |
user-thumbs | false |
Como verificar se terminou
- O preflight mostrou contagens distintas e classificou as três perguntas como
policy-v1. - O serviço usou
AGENT_ARENA_POLICY_VERSION=policy-v1e/askretornououtcome: "ok". - O trace autoritativo tem
sql-execution-success=trueeuser-thumbs=falseno Langfuse. - O diagnóstico curl retornou
outcome: "ok", criou outroCURL_TRACE_IDe não foi avaliado nem entregue. - Você registrou ID/URL do trace do Chat e ambas as contagens sem compartilhar credenciais.
- Consegue explicar por que executar SQL com sucesso não prova correção semântica.
Continue para o Módulo 04 — Investigar e transforme o sinal em diagnóstico revisado por uma pessoa.