El Cinturón de Herramientas de R2-D2: Tool Use en Profundidad
El ciclo completo del Tool Use, herramientas en paralelo, manejo de errores — y por qué Claude no ejecuta nada por su cuenta.
En el primer video de este módulo viste que los tools son las manos del agente. En el segundo video viste cómo los patrones de coordinación usan esas manos en distintas formaciones. Ahora vamos a abrir el capó y entender cómo funciona el Tool Use por dentro — el ciclo completo, de principio a fin.
Esto importa por dos razones. Primero, porque el examen CCA-F te va a preguntar sobre el ciclo de vida de un tool_use block y sobre qué pasa en cada momento. Segundo, porque si no entendés el ciclo, vas a escribir agentes que fallan de formas misteriosas y no vas a saber por qué.
R2-D2 tiene un cinturón de herramientas con compartimentos para todo: soldador, interface de red, proyector holográfico, cable de datos, computadora de navegación. Cada herramienta hace una cosa específica. R2-D2 decide cuál usar según la situación — pero es Chewie o Luke quien efectivamente la conecta al sistema. R2 es el cerebro. Ellos son las manos.
Claude es R2-D2. Tu código es Luke. Claude decide qué herramienta usar y con qué parámetros — tu código la ejecuta y le devuelve el resultado. Este es el contrato fundamental del Tool Use y el examen lo evalúa constantemente.
El ciclo completo del Tool Use
Hay cinco momentos en el ciclo de vida de un tool_use. Cada uno tiene un actor específico y un output específico. Si mezclás los actores o saltás un paso, el agente falla.
Ese ciclo se repite hasta que Claude tiene toda la información que necesita para responder — en ese punto, stop_reason pasa a ser 'end_turn' y el loop agéntico termina.
💡 El ciclo puede repetirse múltiples veces en una sola conversación. Claude puede pedir herramienta A, recibir el resultado, decidir que necesita herramienta B, recibir ese resultado, y recién entonces formular la respuesta final. Tu loop tiene que estar preparado para eso.
El tool_use block por dentro
Cuando Claude decide usar una herramienta, no te manda solo texto. Te manda un objeto estructurado — el tool_use block — que tiene todo lo que necesitás para ejecutar la función correcta con los parámetros correctos.
El campo id es especialmente importante. Cuando le devolvés el resultado a Claude, tenés que incluir ese mismo id en el tool_result — es la forma en que Claude sabe a qué solicitud pertenece cada resultado. Si mandás un id incorrecto, Claude no puede correlacionar el resultado con su pedido.
Implementación completa: el ciclo de principio a fin
Acá está el ciclo completo implementado de forma clara, con comentarios en cada momento del loop:
💡 Fijate que empaquetamos TODOS los tool_results en un mismo mensaje de tipo 'user' antes de mandárselos a Claude. Si Claude pidió dos herramientas en paralelo, los dos resultados van juntos en un solo mensaje — no en dos mensajes separados.
Tool Use en paralelo: R2-D2 usando dos sistemas a la vez
Algo que mucha gente no sabe: Claude puede pedir múltiples herramientas en una sola respuesta. Si la pregunta requiere información de dos fuentes independientes, Claude no necesita hacer dos rondas — puede pedir las dos herramientas al mismo tiempo.
En la práctica, cuando le preguntás al agente '¿Quién es Luke y dónde está?', Claude puede generar en un solo response dos bloques tool_use — uno para buscar_personaje y otro para obtener_ubicacion. Tu código tiene que estar preparado para manejar eso.
Este comportamiento — múltiples tool_use en un solo response — es normal y eficiente. Claude lo hace cuando puede resolverlo en paralelo. Tu implementación del loop ya lo maneja correctamente si iterás sobre todos los bloques de response.content en vez de asumir que hay uno solo.
Manejo de errores: qué pasa cuando una herramienta falla
En el mundo real, las herramientas fallan. Una API externa puede estar caída, una base de datos puede no encontrar el registro, un parámetro puede ser inválido. ¿Qué hacés cuando eso pasa?
La respuesta correcta no es crashear el agente. Es devolver el error como tool_result — de forma estructurada — para que Claude pueda decidir qué hacer a continuación. Claude puede intentar con parámetros distintos, usar otra herramienta, o informarle al usuario que no pudo completar la tarea.
⚠️ El campo is_error en tool_result es opcional pero muy útil. Cuando está en True, Claude sabe explícitamente que el tool falló y ajusta su respuesta en consecuencia — en vez de intentar interpretar si el resultado es un error o datos válidos.
El mapa mental del Tool Use
Antes de las preguntas del examen, acá está el mapa completo del ciclo en formato visual:
Cada vez que ves 'VOS' en ese diagrama, es código que tenés que escribir. Cada vez que ves 'CLAUDE', es el modelo tomando decisiones. La línea entre los dos siempre pasa por la API.
Las preguntas trampa del examen
Trampa 1: Claude ejecuta el tool directamente
El examen te dice que 'cuando Claude usa un tool, Claude ejecuta la función y recibe el resultado'. ¿Es correcto?
No. Claude genera un tool_use block con el nombre y los parámetros. Tu código ejecuta la función. Claude recibe el resultado recién cuando vos se lo mandás como tool_result. Claude nunca tiene acceso directo a ninguna función.
Trampa 2: Un tool_result por mensaje
El examen te muestra un loop que manda cada tool_result en un mensaje separado — un mensaje de rol 'user' por cada resultado. ¿Es correcto?
No. Si Claude pidió dos tools en paralelo, los dos resultados tienen que ir en el mismo mensaje de rol 'user'. Si los mandás en mensajes separados, la conversación queda en un estado inválido porque los roles deben alternarse estrictamente (user → assistant → user → assistant...).
Trampa 3: Ignorar el id del tool_use
El examen te muestra código que construye el tool_result sin incluir tool_use_id. ¿Funciona?
No funciona. Claude no puede correlacionar el resultado con el pedido si no tiene el id. La API puede rechazar el request o Claude puede responder con confusión porque no sabe a qué tool_use corresponde ese resultado.
Trampa 4: Asumir que siempre hay un solo bloque en response.content
Código que hace response.content[0] asumiendo que siempre hay un solo bloque. ¿El problema?
Claude puede incluir texto antes del tool_use, o múltiples tool_use blocks en paralelo. Si el primer bloque es texto y el segundo es tool_use, response.content[0].type es 'text' — no 'tool_use'. Siempre iterá sobre todos los bloques y chequeá el type de cada uno.
💡 La implementación robusta siempre itera: for bloque in response.content: if bloque.type == 'tool_use': ... — nunca accede directo por índice.
R2-D2 no puede soldar cables en el espacio sin que alguien lo conecte físicamente al sistema. Por más inteligente que sea, necesita a Luke o a Chewie para que la acción suceda en el mundo real. Claude y el Tool Use funcionan exactamente igual.
En el próximo video vamos a ver los criterios de parada y la seguridad en sistemas agénticos — cómo evitar que un agente entre en loops infinitos, cómo implementar human-in-the-loop, y cuándo un agente debería detenerse por sí solo en vez de seguir ejecutando. 🌟
Código del video