claudio.cool
CCDV-FLecciones

CCDV-F · Evaluación, pruebas y depuración

Leer la traza, ¿falla la integración o la salida del modelo?

⏱ 3 min de lecturaBorrador

Un servicio de envíos usa una herramienta create_shipment. En los pedidos grandes, el JSON de entrada falla al parsear, y el equipo ya está comparando modelos para ver cuál “arma mejor los JSON”. Nadie miró que sin streaming la entrada llega perfecta siempre. El modelo nunca fue el problema: lo era el código que juntaba los fragmentos. Antes de cambiar de modelo o de prompt, hay que leer la traza (trace).

Qué tiene que tener una traza

Por cada llamada, lo suficiente para reconstruir qué pasó sin adivinar:

  • el pedido exacto que armó tu código: system, mensajes, herramientas, parámetros;
  • la respuesta cruda: bloques de contenido, stop_reason y usage (tokens de entrada y salida);
  • el ID de la solicitud (request ID) que devuelve la API, el ID del modelo y la versión del prompt;
  • en un agente, cada tool_use con su entrada, lo que hizo tu código y el tool_result que devolvió;
  • tiempos y errores, incluidos los eventos de error dentro de un stream.

Con solo el texto final guardado, es imposible saber si el problema fue lo que pidió el modelo o lo que hizo tu código después.

Integración o modelo

La capa de integración (integration layer) es todo lo que hay entre tu aplicación y la API: armar el pedido, parsear la respuesta, ejecutar herramientas, devolver resultados. La pregunta clave es: ¿la salida cruda del modelo estaba bien?

Síntoma en la traza Dónde suele estar Qué hacer
stop_reason: max_tokens y output_tokens igual al límite Configuración Subir max_tokens y tratar el corte como incompleto
JSON roto solo con streaming; sin streaming llega bien Integración Acumular los input_json_delta y parsear al cerrar el bloque
El tool_use tiene la entrada correcta, pero el resultado está mal Integración Revisar el dispatcher: nombre mapeado, tipos, unidades
400 que nombra un tool_use sin tool_result Integración (harness) Devolver un resultado por cada bloque, juntos
Respuestas end_turn vacías después de herramientas Integración (harness) Mandar solo los tool_result, sin texto agregado detrás
El modelo elige mal la herramienta o inventa un valor que no estaba Modelo, prompt o descripciones Mejorar descripciones, prompt o ejemplos; recién después evaluar otro modelo
stop_reason: refusal Contenido del pedido Otro camino: reformular, respaldo o revisión humana

Cómo aislar el origen

  1. Reproducir el problema (reproduce the issue) con un caso concreto que falle.
  2. Tomar el pedido exacto de la traza y mandarlo directo con el SDK, sin tu aplicación en el medio. Si la respuesta cruda está bien, el error está en tu integración.
  3. Cambiar una sola cosa por vez: con y sin streaming, con y sin la herramienta, con el prompt anterior.
  4. Recién cuando la salida cruda del modelo está mal de forma consistente, trabajar sobre prompt, descripciones o modelo, y medirlo contra un set de casos.

Ese proceso convierte “anda mal a veces” en un modo de falla (failure mode) concreto: “en los pedidos con más de cuarenta ítems, la entrada se parsea antes de que termine el bloque”.

Las trampas típicas

  • Cambiar de modelo antes de leer la traza.
  • Culpar al modelo de un error que está en cómo tu código procesa su salida.
  • Guardar solo el texto final, sin stop_reason, usage ni el pedido exacto.
  • Probar varios cambios juntos y no saber cuál arregló el problema.
  • Reintentar a ciegas algo que falla siempre igual.

En el examen

Leé los datos de la traza que da el escenario: stop_reason, output_tokens, si pasa con y sin streaming, qué devolvió la herramienta. Si la salida cruda del modelo está bien, la respuesta está en la integración y descartá las opciones que cambian de modelo o agregan instrucciones. Si la traza muestra que el modelo eligió mal o inventó datos, ahí sí buscá mejoras de prompt o de descripciones.

Pregunta rápida

Una pregunta del simulacro sobre este dominio. Cuenta para tu progreso.

A procurement company has built an agent with the Claude API that checks supplier invoices against purchase orders using two client tools. The harness runs the tool-use loop itself: when stop_reason is tool_use, it executes the tool and sends the result back.

In production, about one task in six ends abruptly. The final response has stop_reason end_turn but an empty or near-empty text block, and the invoice is left unchecked. Retrying the task sometimes works.

The team captured full request traces. In the failing tasks, the model's tool calls and arguments look correct, and the tools return the right data. Each follow-up user message the harness builds contains the tool_result block followed by a text block reminding the model to 'continue with the next check'. The reminder was added last month.

The team is considering a move to a larger model.

What change is most likely to fix the failures?

Practicá este dominio en el simulacro →