Agentes


Un agente es un modelo que corre en un bucle, eligiendo la siguiente herramienta que llamar hasta que la tarea esté terminada. El resto de este capítulo trata sobre qué significa eso, dónde vale la pena usarlo y dónde te cuesta caro sin que te des cuenta.
El bucle del agente
En uso de herramientas el modelo llamaba a una sola función y tú devolvías el resultado. Pero algunas tareas requieren varios pasos, y no conoces esos pasos de antemano. "Encuentra el vuelo más barato y resérvalo" puede implicar buscar, comparar, revisar un calendario y luego reservar, y el modelo tiene que ir descubriendo esa secuencia sobre la marcha.
Entonces, en lugar de manejar una sola llamada a una herramienta, pones todo el proceso dentro de un bucle. Este ciclo que se repite es el bucle del agente, un turno que se repite hasta que la tarea está terminada:
- Envía la conversación y las herramientas disponibles al modelo.
- El modelo llama a una herramienta o da una respuesta final.
- Si llamó a una herramienta, ejecútala, agrega el resultado a la conversación y vuelve al paso 1.
- Si dio una respuesta final, detente.
En cada turno, el modelo ve todo lo que ha pasado hasta ese momento, incluyendo resultados de herramientas anteriores, y decide el siguiente movimiento. Esa es toda la diferencia con el uso de herramientas: sigues repitiendo el ciclo hasta que el modelo considera que terminó.
El cambio real está en quién tiene el control. En todos los capítulos anteriores, tu código decidía el flujo de control: tú elegías cuándo llamar al modelo, cuándo ejecutar una herramienta, qué venía después. Un agente le entrega esa decisión al modelo. El bucle sigue preguntando "¿qué debería pasar ahora?" y la predicción del modelo es la respuesta cada vez. Cambias control por flexibilidad, y ese intercambio es la fuente tanto del alcance como del riesgo.
Por debajo, no está pasando nada nuevo. Es la misma predicción sobre un contexto que crece, el mismo ida y vuelta de uso de herramientas repetido. El modelo no traza un plan y lo sigue. En cada turno predice el mejor siguiente paso a partir de lo que puede ver en ese momento, y luego el bucle vuelve a correr.
Cuando esto funciona, parece razonamiento hacia una meta. Cuando no funciona, el agente da vueltas sobre sí mismo o termina en un callejón sin salida, porque ninguna parte del sistema está sosteniendo el plan general.
Un agente mínimo
Aquí está el bucle en código. Reutiliza las definiciones e implementaciones de herramientas de uso de herramientas y las envuelve en un bucle que corre hasta que el modelo deja de pedir herramientas.
import json
def run_agent(user_text, tools, tool_impls, max_steps=6):
messages = [{"role": "user", "content": user_text}]
step = 0
while step < max_steps:
response = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
message = response.choices[0].message
messages.append(message)
calls = message.tool_calls
if not calls:
return message.content # no quiso ninguna herramienta: esta es la respuesta final
# ejecuta cada herramienta solicitada y devuelve los resultados
for call in calls:
args = json.loads(call.function.arguments)
result = tool_impls[call.function.name](args)
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
step += 1
return "Detenido: el agente alcanzó su límite de pasos." # red de seguridadLéelo de arriba a abajo: llama al modelo, agrega su mensaje a la conversación, y si pidió herramientas, ejecútalas todas y agrega los resultados, luego vuelve a repetir. Cuando el modelo devuelve texto en lugar de una llamada a herramienta, esa es la respuesta final y la devuelves.
El valor max_steps establece un límite de pasos, la red de seguridad que evita que el bucle se descontrole, de lo cual trata la siguiente sección. La forma de este código corresponde al SDK de un proveedor; los nombres de los campos varían entre proveedores, pero el bucle es el mismo en todas partes.
Detenerse y salvaguardas
Un bucle que deja que un modelo decida cuándo detenerse puede no lograr detenerse. Puede llamar herramientas para siempre, repetirse, o terminar en un callejón sin salida. Como cada paso es una llamada al modelo cobrada por tokens, un agente descontrolado gasta dinero y tiempo rápidamente.
Por eso las salvaguardas, los límites que pones alrededor del bucle, son parte del diseño, no un detalle que agregas al final:
- Un límite de pasos. Limita el número de vueltas, tal como lo hace
max_steps. Cuando se alcanza, detente y devuelve el resultado. - Valida las entradas de las herramientas. El modelo elige los argumentos, así que revísalos antes de ejecutar cualquier cosa con consecuencias reales.
- Limita lo que las herramientas pueden hacer. Dale al agente el mínimo poder que necesita. Una herramienta que solo lee es más segura que una que borra.
- Vigila el costo. Varias llamadas al modelo por tarea se multiplican rápido, así que rastrea los tokens y fija un presupuesto.
El hilo que une todo esto: el modelo está improvisando el camino, así que tú pones los límites que él no va a poner. Asume que el agente hará algo incorrecto al menos una vez, y haz que eso sea sobrevivible.
Cuándo un workflow es mejor que un agente
Los agentes son emocionantes, lo cual hace tentador recurrir a uno cuando en realidad no lo necesitas. La regla simple: si ya conoces los pasos, no uses un agente. Escríbelos como código plano, un workflow, donde cada paso corre en un orden fijo.
Un workflow es más confiable, más económico, y mucho más fácil de depurar, porque tú controlas el camino en lugar de esperar que el modelo lo encuentre. Reserva los agentes para tareas abiertas donde los pasos dependen de lo que se va descubriendo en el camino.
Muchas funciones que parecen necesitar un agente en realidad funcionan mejor como una llamada de salida estructurada o una consulta de RAG armada a mano. Recurre a un agente solo cuando no puedas escribir los pasos de antemano.
En la práctica
La función run_agent de arriba es todo el patrón. Dale una pregunta, un conjunto de herramientas y sus implementaciones, y repite el ciclo hasta terminar o hasta alcanzar el límite de pasos. Una tarea pequeña muestra al bucle demostrando su utilidad:
answer = run_agent(
"¿Cómo está el clima en Lima y debería llevar sombrilla?",
tools, # incluye get_weather del capítulo de uso de herramientas
tool_impls, # {"get_weather": ...}
)
# El agente llama a get_weather, lee "nublado", y luego responde en un turno final:
# "Está nublado en Lima a 18 grados, así que llevar sombrilla es buena idea."Una herramienta, un bucle, una respuesta. La misma estructura escala a varias herramientas y varios pasos sin cambiar de forma. Una vez que puedas construir cosas así de capaces, la siguiente pregunta es cómo sabes que en realidad funcionan, que es de lo que trata evals.
run_agent es todo el patrón: le das una pregunta, herramientas y sus implementaciones, y repite el ciclo hasta que el modelo deja de pedir herramientas o alcanza el límite de pasos. Una herramienta y un bucle escalan a muchas sin cambiar de forma. La siguiente pregunta es cómo sabes que en realidad funciona, que es evals. 
