Agent ArenaClickHouse Workshops

03 Publicar y detectar

Publica el agente seleccionado con un punto ciego conocido de política y usa después la evaluación operativa y feedback real para detectarlo.

Punto de partida

El Módulo 02 está completado. Registra el config_id ganador seleccionado en la ejecución real de la Arena y expórtalo desde la raíz del laboratorio (ClickHouse_Demos/workshops/agent_arena):

source .env
export WINNER_CONFIG_ID="${WINNER_CONFIG_ID:-qwen3.7-flash__P2_fewshot}"

La ejecución verificada del taller eligió qwen3.7-flash__P2_fewshot; conserva el ganador de tu grupo si es distinto. Usarás el mismo modelo y prompt que mediste, no un agente especial diseñado para fallar.

Si tu ganador es Qwen, debes desactivar OpenRouter Settings → Privacy → Data Policies → Zero Data Retention → Non-frontier. La ruta disponible de Alibaba se rechaza cuando se impone ZDR para non-frontier. Revisa tus requisitos de privacidad antes de cambiar este ajuste para datos reales.

Por qué un evaluator que aprueba puede omitir el valor para el usuario

Un evaluator online solo mide la dimensión para la que fue diseñado. Aquí, sql-execution-success responde una pregunta operativa importante: ¿el agente produjo un SQL que ClickHouse pudo ejecutar? No sabe si el SQL sigue la definición de negocio actual de cliente activo.

Esto crea una carencia realista de monitorización:

SeñalPregunta que respondeValor esperado en este incidente
sql-execution-success¿El SQL generado se ejecutó correctamente?true
user-thumbs¿Esta respuesta satisfizo la necesidad del usuario?false

La evaluación operativa detecta SQL roto, timeouts y errores de ejecución. La evaluación semántica o de usuario pregunta si una respuesta ejecutable es útil y concuerda con el significado de negocio. Ninguna sustituye a la otra. Un pulgar hacia abajo es una señal de priorización, no verdad de referencia; una persona lo investigará en el Módulo 04.

Objetivo

Crear una traza real chat_turn en la que el evaluator operativo aprueba, pero el usuario valora negativamente la respuesta. Registra la traza y los dos recuentos discrepantes para la investigación humana.

Paso 1 — Demostrar que el incidente preparado es reproducible

Ejecuta el preflight desde la raíz del laboratorio antes de iniciar el servidor de demostración:

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"

El comando ejecuta ambas definiciones y plantea tres paráfrasis a la configuración seleccionada. Debe mostrar valores distintos para stale_count y current_count, tres líneas classification_N=policy-v1 y lo siguiente:

Si una paráfrasis devuelve ok/unknown, el preflight reintenta una sola vez esa misma paráfrasis y configuración. No reintenta policy-v2 ni fallos del proveedor, modelo o agente; un segundo ok/unknown sigue bloqueando el proceso.

OK: seeded online-evaluation incident is reproducible

Si los recuentos coinciden o alguna clasificación no es policy-v1, detente: el contraste no sería visible en esta ejecución de datos y modelo.

La definición de negocio actual es este SQL exacto:

SELECT uniqExact(customer_id) FROM v_orders
WHERE order_ts >= now() - INTERVAL 30 DAY
AND status NOT IN ('cancelled', 'returned')

La definición antigua policy-v1 cuenta, en cambio, los clientes registrados durante los últimos 90 días. Por tanto, el SQL generado en este módulo es válido respecto de las instrucciones explícitas de policy-v1. El objetivo no es demostrar que el modelo carece de inteligencia, sino que el contexto de política publicado está obsoleto y el evaluator de ejecución SQL es demasiado estrecho para detectarlo.

Paso 2 — Aprovisionar el evaluator operativo

El aprovisionamiento es idempotente, por lo que se puede repetir con seguridad:

source .env
.venv/bin/python -m scripts.provision_online_evaluators --operational

La salida debe mencionar el evaluator sql-execution-success y la regla habilitada agent-arena-sql-execution-online.

Paso 3 — Iniciar la versión preparada con la política obsoleta

En el primer terminal, desde la raíz del laboratorio, inicia el servidor seleccionando explícitamente la política antigua y déjalo activo:

source .env
AGENT_ARENA_POLICY_VERSION=policy-v1 \
  .venv/bin/uvicorn serving.api:app --port 8100

No omitas AGENT_ARENA_POLICY_VERSION. De lo contrario, el servicio usa de forma predeterminada la policy-v2 actual, que excluye correctamente pedidos cancelados y devueltos.

Paso 4 — Preguntar y valorar mediante Chat

En otro terminal, inicia el dashboard si aún no está activo:

scripts/arena.sh serve

Abre http://localhost:5174, selecciona la pestaña Chat y $WINNER_CONFIG_ID, y pregunta:

How many active customers do we have?

Lee el SQL generado y el resultado. Debe seguir la definición preparada de altas durante 90 días de policy-v1. Haz clic en 👎 y espera a que la interfaz muestre feedback sent.

Esta traza raíz de Chat es el único incidente autoritativo que puntuarás y entregarás al Módulo 04.

Paso 5 — Encontrar y verificar la traza de Chat

En Langfuse, abre Tracing y filtra por user-thumbs = false. Abre la raíz chat_turn más reciente cuya pregunta sea How many active customers do we have?, cuya configuración coincida con $WINNER_CONFIG_ID y cuyos metadatos muestren policyversion=policy-v1. Copia su ID y URL, y configura localmente el ID:

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=false

Verifica que user-thumbs sea un Boolean false, no una puntuación numérica ni de texto. El código del servicio llama al campo de metadatos policy_version; el adaptador OpenTelemetry lo sanea y emite en Langfuse como policyversion.

Paso 6 — Reproducir con un curl sin valoración

La llamada a la API sin procesar es una reproducción y un diagnóstico obligatorios desde línea de comandos. Crea una traza separada, pero no es el incidente de feedback y no debe valorarse:

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)')

La respuesta debe incluir outcome: "ok", un trace_id no vacío y policy_version: "policy-v1".

Espera al evaluator asíncrono y verifica solo su puntuación operativa:

.venv/bin/python -m scripts.verify_online_scores "$CURL_TRACE_ID" \
  sql-execution-success=true

No llames a /feedback para CURL_TRACE_ID ni lo incluyas en la hoja de trabajo. Es solo un diagnóstico reproducible de la API; CHAT_TRACE_ID sigue siendo la traza de entrega.

Paso 7 — Comparar con la política actual

Ejecuta el SQL de la política actual mediante el mismo cliente de ClickHouse de solo lectura que usa el agente y compara su único resultado con el resultado obsoleto de 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])
PY

Esta es la consulta exacta que acabas de ejecutar:

SELECT uniqExact(customer_id) FROM v_orders
WHERE order_ts >= now() - INTERVAL 30 DAY
AND status NOT IN ('cancelled', 'returned')

El recuento diferente es el fallo visible para el usuario. El SQL se ejecutó, pero respondió a una definición de negocio equivocada. Registra ese recuento junto a las pruebas de la traza autoritativa de Chat.

Hoja de trabajo de investigación

Conserva esta entrega para el Módulo 04:

PruebaTu valor
config_id ganador
ID de la traza autoritativa de Chat
URL de la traza autoritativa de Chat
Recuento obsoleto de policy-v1
Recuento actual de policy-v2
sql-execution-successtrue
user-thumbsfalse

Cómo verificar que has terminado

  • El preflight mostró recuentos obsoleto y actual distintos, y clasificó las tres preguntas preparadas como policy-v1.
  • El servicio se ejecutó con AGENT_ARENA_POLICY_VERSION=policy-v1 y /ask devolvió outcome: "ok".
  • La traza autoritativa de Chat tiene sql-execution-success=true y user-thumbs=false en Langfuse.
  • El diagnóstico curl obligatorio devolvió outcome: "ok", produjo un CURL_TRACE_ID distinto y no se valoró ni entregó.
  • Registraste el ID y la URL de la traza autoritativa de Chat y ambos recuentos sin compartir credenciales.
  • Puedes explicar por qué una ejecución SQL correcta no demostró corrección semántica.

Continúa con el Módulo 04 — Investigar para convertir esta señal en un diagnóstico revisado por una persona.

En esta página

¿Quieres seguir tu progreso?

Opcional. Enviaremos un enlace por correo para confirmar tu dirección; el progreso se registrará cuando lo abras.

Usa tu correo de trabajo, no uno personal.

Para seguir el progreso también debes aceptar los Términos del servicio actuales en la Configuración de privacidad.

ES