Todo el Track hasta acá te insistió en el contrato de entrada: parámetros tipados, enums, formato, required. Pero el tool también devuelve algo, y lo que devuelve es contrato de igual peso. La parte mala es que la mayoría de los autores de tools devuelven "lo que sale del query" o "una linda oración" y se olvidan.
El problema: el agente lee el output del tool como contexto para decidir el siguiente paso. Si ese contexto es ambiguo, el siguiente paso es ambiguo. Si es estructurado, el siguiente paso casi se programa solo.
Estructura siempre. Devolvé objeto JSON con campos nombrados. Nunca prosa cuando hay datos discretos.
Documentá la shape en la description. El modelo lee la description antes de invocar; si sabe qué va a recibir, planifica mejor el siguiente paso.
Description: "...Returns: { shift_id, status: 'scheduled'|'active'|
'completed', crewmates: [...], lead_alias }"Enums explícitos en los outputs también. Si status solo puede ser 4 valores, decilo. El agente va a confiar y razonar sobre esa lista cerrada en vez de inventar branches para "active_with_warnings".
Cuando un campo puede no estar:
null explícito, no omitas el campo. notes: null le dice al agente "consulté y no hay". Si omitís notes, el agente no sabe si no consultaste, si el tool falló parcial, o si hay vacío real.null esperados en la description. notes: string|null.Errores también son output. Ya viste en el step 8 (preview del próximo unit) que la shape de error es:
{ ok: false, error: { code: "...", message: "...", ...extra } }Esa shape es contrato igual que la de éxito. Documentala. El agente la lee y aprende a manejar cada code.
Test mental: si vos fueras el agente y solo vieras el output crudo del tool (sin contexto extra), ¿podrías decidir el siguiente paso con certeza? Si la respuesta es "depende de cómo interprete esta frase", el output está mal diseñado.