Skip to content
This page has been auto-translated and may contain errors.View in English

Agentes

docs.scrimba.com

Un agente es un modelo ejecutándose en un bucle, eligiendo la siguiente herramienta a llamar hasta que se complete una tarea. El resto de este capítulo explica qué significa eso, dónde rinde sus frutos, y dónde silenciosamente te cuesta.

El bucle del agente

En uso de herramientas el modelo llamaba una función y tú enviabas el resultado de vuelta. Pero algunas tareas toman varios pasos, y no conoces los pasos con anticipación. "Encuentra el vuelo más barato y resérvalo" podría significar buscar, comparar, revisar un calendario, luego reservar, y el modelo tiene que elaborar esa secuencia sobre la marcha.

Entonces en lugar de manejar una única llamada de herramienta, pones todo en un bucle. Este ciclo repetido es el bucle del agente, un turno repetido hasta que se complete la tarea:

  1. Envía la conversación y las herramientas disponibles al modelo.
  2. El modelo llamará a una herramienta o dará una respuesta final.
  3. Si llamó a una herramienta, ejecútala, añade el resultado a la conversación, y vuelve al paso 1.
  4. Si dio una respuesta final, detén.

Cada turno el modelo ve todo lo que sucedió hasta ahora, incluyendo resultados previos de herramientas, y decide el siguiente movimiento. Esa es la única diferencia del uso de herramientas: mantienes el bucle hasta que el modelo crea que ha terminado.

El cambio real es quién está dirigiendo. En cada capítulo hasta ahora, 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 entrega esa decisión al modelo. El bucle sigue preguntando "¿qué debería suceder ahora?" y la predicción del modelo es la respuesta cada vez. Cambias control por flexibilidad, y ese cambio es la fuente tanto del alcance como del riesgo.

Debajo de todo, nada nuevo está sucediendo. Es la misma predicción sobre un contexto creciente, el viaje de ida y vuelta del uso de herramientas repetido. El modelo no elabora un plan y lo sigue. Cada turno predice el único mejor siguiente paso a partir de lo que puede ver ahora mismo, luego el bucle se ejecuta de nuevo.

Cuando eso funciona, se ve como razonamiento hacia una meta. Cuando no, el agente se buclea en sí mismo o deambula por un callejón sin salida, porque ninguna parte del sistema está manteniendo el plan general.

JunoEl bucle del agente Un agente es el bucle de uso de herramientas repetido: envía la conversación y herramientas, el modelo llama a una herramienta o da una respuesta final, ejecutas cualquier herramienta y alimentas el resultado de vuelta, y lo haces de nuevo hasta que responda. Cada turno el modelo ve todos los resultados previos y elige el siguiente paso. La única idea nueva sobre el simple uso de herramientas es hacer bucles en lugar de manejar una única llamada.

En uso de herramientas manejaste una llamada y devolviste el resultado. Un agente es ese viaje de ida y vuelta envuelto en un bucle, ejecutado hasta que el modelo decide que ha terminado. Ese bucle es el bucle del agente. Aquí está el movimiento: deja de codificar la secuencia de pasos y deja que el modelo elija el siguiente en cada turno.

El ciclo tiene cuatro pasos:

  1. Envía la conversación más la lista de herramientas al modelo.
  2. El modelo responde con llamadas de herramientas o una respuesta de texto final.
  3. Si pidió herramientas, ejecútalas, añade cada resultado a la conversación, y haz bucle.
  4. Si respondió, detén y devuelve el resultado.

El mecanismo que hace esto funcionar es que el modelo ve la conversación completa creciente cada turno: tu solicitud original, cada llamada de herramienta que hizo, y cada resultado que regresó. Ese contexto acumulado es la única memoria del agente. Cada predicción está condicionada por el historial completo hasta ahora, lo que es por qué puede encadenar pasos que dependen de resultados anteriores.

Un detalle que vale la pena nombrar temprano: el paso 2 puede devolver varias llamadas de herramientas a la vez, no una. Cuando las llamadas no dependen una de la otra, como verificar el clima en tres ciudades, el modelo puede solicitar las tres en un único turno y las ejecutas juntas. Cuando una llamada necesita el resultado de una anterior, el modelo tiene que esperar ese resultado antes de poder pedir la siguiente, así que esas llegan en turnos separados. El bucle maneja ambas: ejecuta cualquier llamada que regresó en este turno, alimenta todos los resultados, y predice de nuevo.

No hay un plan global dentro de nada de esto. El modelo predice el mejor siguiente paso a partir de lo que puede ver ahora mismo, no a partir de un mapa de toda la tarea. Esa es la diferencia entre un agente y los conductos fijos que has escrito antes, y es por qué el mismo bucle que encadena pasos de investigación también puede perseguir su propia cola.

JunoEl bucle del agente Un agente es el viaje de ida y vuelta de uso de herramientas en un bucle: envía conversación más herramientas, el modelo llama a herramientas o responde, ejecutas las herramientas y alimentas los resultados de vuelta, repite hasta que responda. La conversación creciente es la única memoria del agente, así que cada paso está condicionado por cada resultado antes de él. Un turno puede devolver varias llamadas de herramientas independientes a la vez, o una por una cuando cada una depende de la última. No hay un plan global en ningún lugar: cada paso es una conjetura de siguiente paso completamente nueva.

Un agente es el viaje de ida y vuelta del uso de herramientas colocado en un bucle y con la mano en el volante, el bucle del agente: el modelo elige la siguiente herramienta en cada turno, la ejecutas, alimentas el resultado de vuelta, y lo haces de nuevo hasta que emita una respuesta final en lugar de una llamada. El bucle tiene cuatro pasos y no es la parte interesante. La parte interesante es lo que la arquitectura te da y no te da.

El ciclo:

  1. Envía la conversación en ejecución más los esquemas de herramientas.
  2. El modelo devuelve llamadas de herramientas o una respuesta final.
  3. Ejecuta cualquier llamada, añade resultados, haz bucle.
  4. En una respuesta final, devuelve.

Un único turno puede devolver múltiples llamadas de herramientas. El modelo emite llamadas paralelas cuando las juzga independientes (tres búsquedas sin dependencia de datos entre ellas), y llamadas seriales en turnos cuando una necesita la salida de otra primero. No puedes forzar esto desde afuera: si el trabajo se paraleliza es la decisión del modelo basada en la tarea que infirió, así que una tarea que piensas que es paralela puede volver serializada y más lenta, y una que piensas que es serial puede volver como un lote que debes estar listo para ejecutar junto.

Aquí está el hecho que carga, el que cada modo de fallar se remonta a. No hay un plan global. El modelo no posee un mapa de la tarea y ejecuta contra él. Cada turno predice el siguiente paso de la conversación actual, y esa conversación es todo el estado del sistema, tu indicación más cada llamada y resultado hasta ahora, acumulados.

Cada paso confía en el paso anterior, sin nada verificando el todo. Es por eso que un agente que se ve como si estuviera razonando hacia una meta está realmente haciendo una secuencia de conjeturas localmente plausibles que sucede, cuando funciona, sumar.

La consecuencia para internalizar ahora, porque la sección de guardrails lo compensa: porque el estado es solo el transcrito creciente y cada paso está condicionado por él, un resultado de herramienta incorrecto temprano no se corrige, se construye sobre. El error se propaga hacia adelante y se compone, y ninguna parte del bucle está posicionada para notarlo. El trabajo de confiabilidad en agentes es mayormente luchar contra esa única propiedad.

JunoEl bucle del agente Un agente es el viaje de ida y vuelta de uso de herramientas en un bucle con el modelo dirigiendo: elige la siguiente herramienta, la ejecutas, alimentas el resultado de vuelta, repite hasta que responda. Todo el estado es el transcrito creciente, y no hay un plan global en ningún lugar, solo una cadena de conjeturas de siguiente paso cada una condicionada por la última. Un turno puede devolver llamadas paralelas cuando el modelo las juzga independientes o llamadas seriales cuando dependen una de la otra, y no controlas cuál. Ten presente una cosa: cada paso confía en el paso anterior, así que un resultado incorrecto temprano se compone hacia adelante sin nada verificando el todo.

Un agente mínimo

Aquí está el bucle en código. Reutiliza las definiciones de herramientas e implementaciones del uso de herramientas y las envuelve en un bucle que se ejecuta hasta que el modelo deja de pedir herramientas.

python
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  # ninguna herramienta solicitada: esta es la respuesta final

        # ejecuta cada herramienta solicitada y alimenta los resultados de vuelta
        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 "Stopped: the agent reached its step limit."  # red de seguridad

Léelo de arriba a abajo: llama al modelo, empuja su mensaje a la conversación, y si pidió herramientas, ejecuta todas ellas y añade los resultados, luego haz bucle de nuevo. Cuando el modelo devuelve texto en lugar de una llamada de herramienta, ese texto es la respuesta final y lo devuelves.

El valor de max_steps establece un límite de pasos, la red de seguridad que mantiene el bucle de escaparse, sobre lo cual la siguiente sección trata. La forma aquí coincide con SDK de un proveedor; los nombres de campo difieren entre proveedores, pero el bucle es el mismo en todas partes.

JunoUn agente mínimo Un agente mínimo es un bucle alrededor de una llamada de modelo: ejecuta el modelo, ejecuta cualquier herramienta que pida, alimenta los resultados de vuelta, repite. Cuando el modelo devuelve texto en lugar de una llamada de herramienta, ese texto es la respuesta final. El límite de pasos es una red de seguridad requerida, no algo extra que añades después.

Aquí está el bucle en código, reutilizando las definiciones de herramientas e implementaciones del uso de herramientas. Se ejecuta hasta que el modelo deja de pedir herramientas o golpea el tope de pasos.

python
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  # respuesta final

        for call in calls:
            args = json.loads(call.function.arguments)
            try:
                result = tool_impls[call.function.name](args)
            except Exception as err:
                result = {"error": str(err)}  # muestra el fallo, no falles
            messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

        step += 1

    return "Stopped: the agent reached its step limit."

La forma es el SDK de un proveedor y los nombres de campo varían, pero cada bucle tiene estas partes: añade el mensaje del modelo, rama en si pidió herramientas, ejecuta las solicitadas, alimenta cada resultado de vuelta como un mensaje de tool vinculado a su id de llamada.

El único cambio que vale la pena hacer sobre la versión descubierta es el try/except alrededor de la herramienta. Cuando una herramienta falla, no dejes que la excepción mate el bucle. Captura y alimenta el error de vuelta al modelo como el resultado de la herramienta. El modelo puede entonces leer "esa búsqueda falló" en su siguiente turno y adaptarse: reintentar con argumentos diferentes, intentar otra herramienta, o decirle al usuario que no podía completar la tarea. Un fallo da al modelo ninguna oportunidad de recuperarse; este patrón error-como-resultado lo mantiene en el bucle con información para actuar.

Dos cosas para rastrear mientras esto se ejecuta. Primero, la conversación solo crece. Cada turno añade el mensaje del modelo y cada resultado de herramienta, así que en el paso cinco el modelo está leyendo todo desde los pasos uno al cuatro de nuevo. Esa es la memoria del agente y también su factura: cada paso reenvía todo el contexto acumulado, así que el costo de tokens por paso sube a medida que la tarea avanza. Un agente de diez pasos no son diez llamadas baratas, son diez llamadas sobre un transcrito cada vez más grande.

Segundo, eso es el crecimiento por qué max_steps importa más allá de detener bucles infinitos. Elige contra la tarea. Una pregunta de clima necesita dos o tres pasos; una tarea de investigación podría querer diez. Establece el tope un poco arriba de lo que una ejecución saludable toma, así una tarea legítimamente más larga puede terminar pero una atascada todavía se corta antes de que drene tu presupuesto.

JunoUn agente mínimo El bucle es: añade el mensaje del modelo, rama en si pidió herramientas, ejecútalas, alimenta cada resultado de vuelta como un mensaje de tool. Envuelve la llamada de herramienta en try/except y alimenta errores de vuelta en lugar de fallar, así el modelo puede reintentar o recuperarse. Ten en cuenta que la conversación solo crece: cada paso reenvía el transcrito completo, así el costo de tokens por paso sube a medida que la tarea corre. Establece max_steps contra la tarea, un poco arriba de una ejecución saludable.

El bucle, reutilizando la capa de herramientas del uso de herramientas. Una forma de SDK de un proveedor, los nombres de campo varían, la estructura no.

python
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

        for call in calls:
            args = json.loads(call.function.arguments)
            try:
                result = tool_impls[call.function.name](args)
            except Exception as err:
                result = {"error": str(err)}  # el modelo lee esto y puede adaptarse en el próximo turno
            messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

        step += 1

    return "Stopped: the agent reached its step limit."

El bucle descubierto es correcto e impresentable, y el espacio entre los dos es donde vive esta sección. Tres propiedades de este código muerden en producción.

Muestra errores, nunca falles. El try/except alimenta una herramienta fallida de vuelta al modelo como un resultado que puede leer. Eso es correcto, pero entiende lo que estás haciendo: estás entregando al modelo una cadena de error y confiando en que se recupere sensatamente. Podría reintentar la misma llamada mala, o inventar un enfoque diferente, o disculparse y parar.

Alimentar errores de vuelta mantiene el agente vivo; no hace que la recuperación sea confiable. Para cualquier cosa que sea crítica, limita reintentos por herramienta y trata el fallo repetido como un estado terminal que manejas, no un bucle que dejas que el modelo resuelva por intuición.

El transcrito solo crece, y eso son dos costos que se cumulan. El costo de tokens por paso sube porque cada llamada reenvía el historial completo acumulado, así una ejecución larga paga una factura creciente en cada turno, no una plana. Y cuanto más largo es el transcrito, más el modelo está leyendo salida de herramientas antiguas para decidir el siguiente movimiento, que es exactamente donde el efecto lost-in-the-middle del capítulo ventana de contexto comienza a morder, donde un modelo atiende menos a la información enterrada en el medio de un contexto largo: las instrucciones tempranas que deberían limitar el agente se hunden bajo resultados acumulados y se atiende menos. Los agentes largos no fallan ruidosamente, se desplazan.

max_steps es un presupuesto, no una guardia de error. Existe porque el modelo decide cuándo parar y puede decidir mal: bucle en un paso, ping-pong entre dos herramientas, persigue un callejón sin salida.

El número es un tope de costo real. El peor caso de gasto es aproximadamente max_steps multiplicado por el costo de una llamada de contexto completo cerca del final de la ejecución, así un tope generoso en una tarea pesada en contexto es una factura generosa. Establécelo a partir de la ejecución más larga legítima más un margen, alarma cuando las ejecuciones rutinariamente lo golpean (esa es una señal de que el agente está atascado, no que el tope es muy bajo), y resiste levantarlo para encubrir un agente que no puede terminar.

JunoUn agente mínimo El bucle descubierto es correcto e impresentable. Alimenta errores de herramientas de vuelta para que el modelo pueda adaptarse, pero limita reintentos y trata el fallo repetido como terminal, porque superficiar un error no hace que la recuperación sea confiable. El transcrito solo crece, así el costo de tokens por paso sube y tus instrucciones tempranas se entierran bajo resultados antiguos hasta que el agente se desplaza. max_steps es un tope de costo, no una guardia de error: dimensiónalo a la ejecución más larga real más margen, y cuando las ejecuciones siguen golpeándolo, el agente está atascado, así que no levantes reflexivamente el número.

Detener y guardrails

Un bucle que deja que un modelo decida cuándo parar puede fallar en parar. Podría llamar herramientas por siempre, repetirse, o perseguir un callejón sin salida. Porque cada paso es una llamada de modelo facturada por tokens, un agente desbocado quema dinero y tiempo rápidamente.

Así que guardrails, los límites que pones alrededor del bucle, son parte del diseño, no un paso de pulido que añades al final:

  • Un límite de pasos. Limita el número de bucles, la forma que max_steps hace. Cuando se golpea, detén y devuelve.
  • Valida entradas de herramientas. El modelo elige los argumentos, así verifica antes de ejecutar cualquier cosa con consecuencias reales.
  • Limita lo que las herramientas pueden hacer. Dale al agente el menos poder que necesita. Una herramienta que lee es más segura que una que elimina.
  • Observa el costo. Varias llamadas de modelo por tarea se multiplican rápidamente, así rastrea tokens y establece un presupuesto.

El hilo que ata estos: el modelo está improvisando el camino, así pones los límites en lugar de que no los haya. Asume que el agente hará lo incorrecto al menos una vez, y haz que sea survivible.

JunoDetener y guardrails Un agente decide su propio punto de parada, así puede buclear para siempre, y cada bucle cuesta tokens. Siempre establece un límite de pasos, valida los argumentos que el modelo elige, y da a las herramientas el menos poder que necesitan. Rastrea costo, porque varias llamadas de modelo por tarea suman rápidamente.

Un bucle donde el modelo decide cuándo parar puede fallar en parar, y porque cada paso es una llamada de modelo facturada por tokens, un agente atascado quema presupuesto rápidamente. Los guardrails son parte del diseño. Los cuatro para conectar:

  • Un límite de pasos. Limita los bucles con max_steps y devuelve limpiamente cuando se golpea. Este es tu parada dura contra bucles desbocados.
  • Valida entradas de herramientas. El modelo elige los argumentos, y puede elegir mal o ser dirigido mal. Verifica antes de que cualquier herramienta con consecuencias reales se ejecute: una eliminación sin id, una transferencia con un monto negativo, un camino fuera del directorio permitido.
  • Menos poder. Dale a cada herramienta la capacidad más estrecha que la tarea necesita. Solo lectura vence lectura-escritura, una consulta con alcance vence acceso crudo a base de datos, una lista fija de destinatarios vence envío arbitrario.
  • Tope de costo. Rastrea tokens en toda la ejecución, no por llamada, y detén cuando una ejecución cruza un presupuesto.

El punto que ata estos es que los argumentos a tus herramientas vienen del modelo, lo que significa que vienen, indirectamente, de cualquier texto que el modelo haya leído. Si una herramienta traía una página web y esa página contenía instrucciones, esas instrucciones están ahora en el contexto del modelo y pueden dirigir la siguiente llamada de herramienta. Esto es inyección de indicación: texto no confiado en el contexto influyendo lo que el agente hace. La defensa no está en la indicación. Está en validar cada entrada de herramienta y alcance cada poder de la herramienta para que incluso un argumento completamente secuestrado no pueda causar daño real.

JunoDetener y guardrails Cuatro guardrails, por diseño no pulido: una parada dura de max_steps, validación de entrada en cada herramienta consequencial, alcance de herramienta de menos poder, y un presupuesto de tokens en toda la ejecución. La razón por la que la validación de entrada importa: los argumentos de herramientas vienen del modelo, que significa de cualquier texto que leyó, así una página buscada que lleva instrucciones es inyección de indicación que puede dirigir la siguiente llamada. Valida entradas y alcance poder para que un argumento secuestrado aún no pueda causar daño.

Un bucle donde el modelo decide cuándo parar puede fallar en parar, y cada paso es una llamada facturada por tokens, así el modo de falla es caro por defecto. Los cuatro guardrails (límite de pasos, validación de entrada, menos poder, tope de costo) son fundamentales. La parte que merece tu atención es por qué la validación de entrada es un control de seguridad, no una verificación de cordura.

Los argumentos de herramientas son salida de modelo, y la salida de modelo está condicionada por todo en el contexto, incluyendo texto que el agente buscó desde afuera. El momento en que un agente lee una página web, un documento, un email, o un resultado de herramienta que no controlas, texto no confiado está en su contexto y puede llevar instrucciones. Eso es inyección de indicación: contenido adversarial en la entrada dirigiendo el modelo a acciones que no intentabas. En una indicación de un único disparo es una molestia. En un agente es un exploit vivo, porque el próximo movimiento del modelo es una llamada de herramienta con efecto del mundo real, y el texto inyectado logra influir esa llamada.

Diseña para esto como adversarial, porque lo es. Tres reglas se sostienen:

  • Valida cada argumento de herramienta contra una lista de permitidos, no una de bloqueados. Define qué se ve un argumento válido (este formato de id, este conjunto de destinatarios, este directorio) y rechaza todo lo demás. No puedes enumerar cada entrada mala que un atacante inventará; puedes enumerar las buenas.
  • Alcance poder de herramienta para que una llamada completamente secuestrada sea survivible. Asume el argumento es controlado por atacante y pregunta qué la herramienta podría entonces hacer. Si la respuesta real es "email a cualquiera" o "elimina cualquier fila", la herramienta es demasiado amplia sin importar cuán cuidadosa sea la indicación. Menos poder es el control que se sostiene cuando el modelo está comprometido, y la indicación no es un control en absoluto.
  • Pon un humano en el bucle en acciones irreversibles. Enviar dinero, eliminar datos, emailing a clientes: limita esto en confirmación. El agente propone, una persona o una verificación más estricta dispone.

La razón más profunda de por qué ninguno de esto vive en la indicación: instrucciones en la indicación del sistema e instrucciones inyectadas en contenido buscado llegan como el mismo tipo de cosa, texto en el contexto, y el modelo no tiene una forma confiable de rangear una sobre la otra. Así no puedes indicación-camino a seguridad. El límite que se sostiene está fuera del modelo: entradas validadas y herramientas alcanzadas. Esto se conecta al tratamiento más amplio en seguridad y límites.

JunoDetener y guardrails Los cuatro guardrails son fundamentales; el que merece pensamiento es validación de entrada, porque es un control de seguridad. Los argumentos de herramientas son salida de modelo condicionada en todo lo que leyó, así cualquier página buscada o email puede llevar instrucciones inyectadas que dirijan la próxima llamada, y en un agente esa llamada tiene efecto del mundo real. Valida contra una lista de permitidos, alcance cada herramienta para que un argumento secuestrado sea aún survivible, y limita acciones irreversibles en un humano. No puedes indicación-camino a seguridad: las instrucciones inyectadas y de sistema son el mismo tipo de texto para el modelo, así el límite tiene que vivir fuera de él.

Cuándo un flujo de trabajo vence un agente

Los agentes son emocionantes, lo que lo hace tentador alcanzar uno cuando no lo necesitas. La regla simple: si ya conoces los pasos, no uses un agente. Escríbelos como código simple, un flujo de trabajo, donde cada paso se ejecuta en un orden fijo.

Un flujo de trabajo es más confiable, más barato, y mucho más fácil de depurar, porque controlas el camino en lugar de esperar que el modelo lo encuentre. Guarda agentes para tareas abiertas donde los pasos dependen de lo que se descubre en el camino.

Muchas características que se ven como si necesitaran un agente son mejores como una llamada de salida estructurada o una búsqueda RAG conectadas a mano. Alcanza un agente solo cuando no puedas escribir los pasos con anticipación.

JunoCuándo un flujo de trabajo vence un agente Si ya conoces los pasos, codifica duros como un flujo de trabajo en lugar de usar un agente: es más barato, más confiable, y más fácil de depurar. Guarda agentes para tareas abiertas donde los pasos dependen de lo que se encuentra en el camino. Muchas características "agente" son realmente una llamada de salida estructurada o RAG conectada a mano.

Los agentes son la herramienta emocionante, que es exactamente por qué se alcanzan cuando son incorrectos. La regla de decisión es una pregunta: ¿puedes escribir los pasos con anticipación? Si sí, quieres un flujo de trabajo, los pasos como código simple en un orden fijo, no un agente.

Un flujo de trabajo gana en todo lo que un agente lucha. Es más barato, porque haces una o dos llamadas de modelo en lugar de un bucle de ellas. Es más confiable, porque el camino es fijo en lugar de re-decidido cada turno. Y es mucho más fácil de depurar, porque un fallo sucede en un paso conocido que puedes inspeccionar, no en algún lugar en una cadena de movimientos elegidos por modelo.

Aquí está la prueba en la práctica. "Resumir este ticket de soporte, clasificar su urgencia, y encaminarlo a una cola" tiene pasos conocidos en un orden conocido, así es un flujo de trabajo: una llamada de salida estructurada para obtener el resumen, categoría, y urgencia, luego código simple para encaminar en el resultado. "Investigar por qué los tres últimos pedidos de este cliente fallaron" no tiene pasos conocidos, el camino depende de lo que cada búsqueda revela, así es un agente.

La trampa es que muchas características se ven abiertas y no lo son. Extrayendo campos de un documento, respondiendo de tus docs, clasificando correo entrante: estos se ven como trabajo de agente pero resuelven a una llamada de salida estructurada o una búsqueda RAG con código alrededor. Incumple al flujo de trabajo y deja que una tarea gane el agente siendo impredecible de una forma que no puedas hacer script.

JunoCuándo un flujo de trabajo vence un agente La decisión es una pregunta: ¿puedes escribir los pasos con anticipación? Si sí, construye un flujo de trabajo, los pasos como código simple, porque es más barato, más confiable, y depurable en un punto conocido. "Resumir, clasificar, encaminar un ticket" es un flujo de trabajo: una llamada de salida estructurada más código de encaminamiento. "Investigar por qué estos pedidos fallaron" es un agente, porque el camino depende de lo que cada paso encuentra. Incumple al flujo de trabajo y haz que la tarea gane el agente.

El agente es la herramienta que la gente quiere usar, que es por qué se usa donde no pertenece. La regla de decisión es corta: si puedes escribir los pasos con anticipación, escríbelos. Eso es un flujo de trabajo, los pasos como código en un orden fijo, y vence un agente en costo, confiabilidad, y depurabilidad para cualquier tarea cuya forma conoces.

La razón traza directo a la arquitectura. Un agente no tiene plan global y compone errores hacia adelante, así su confiabilidad es el producto de cada paso yendo bien sin nada verificando el todo. Un flujo de trabajo que escribiste tiene un plan, por definición, y puedes inspeccionar, probar, y validar cada paso aisladamente. Cuando algo rompe en un flujo de trabajo, rompe en una línea. Cuando algo rompe en un agente, rompe en algún lugar en un transcrito de movimientos elegidos por modelo, y reconstruyes lo que estaba pensando desde la traza.

Ahora el caso más difícil, porque "¿sé los pasos?" es la mitad recta. Un agente puede ser la herramienta incorrecta incluso cuando la tarea es abierta, cuando el costo de un paso incorrecto es demasiado alto para dejar que un guesser de próximo paso la tome. Un agente que reserva viajes, mueve dinero, o modifica datos de producción es abierto y también en algún lugar que no quieres un bucle sin plan, inyectable, composición de error sosteniendo los controles. El diseño correcto ahí es a menudo un híbrido: el modelo planea o propone, pero un flujo de trabajo fijo y compuertas humanas ejecutan, así la parte impredecible nunca toca la parte irreversible directamente.

Así la pregunta es dos preguntas. ¿Sé los pasos, y qué cuesta un paso incorrecto?

Pasos conocidos van a un flujo de trabajo. Pasos desconocidos con acciones baratas, reversibles son donde un agente gana su lugar. Pasos desconocidos con acciones caras, irreversibles quieren un diseño limitado, no un bucle libre.

Un agente encaja trabajo abierto con pasos baratos, reversibles, y poco más. Una fracción sorprendente de características "agente" es una llamada de salida estructurada o una búsqueda RAG con código alrededor, y están mejor quedándose así.

JunoCuándo un flujo de trabajo vence un agente Dos preguntas, no una: ¿sé los pasos, y qué cuesta un paso incorrecto? Pasos conocidos van a un flujo de trabajo, que vence un agente en costo, confiabilidad, y depuración porque tiene un plan y el agente nunca lo hace. Pasos desconocidos con acciones baratas reversibles son donde un agente gana su lugar. Pasos desconocidos con acciones caras irreversibles quieren un híbrido: el modelo propone, un flujo de trabajo fijo y compuertas humanas ejecutan, así el bucle que se compone de error nunca toca la parte que no puedes deshacer.

En la práctica

La función run_agent arriba es el todo. Dale una pregunta, un conjunto de herramientas, e sus implementaciones, y hace bucle hasta que se haga o hasta que golpee el límite de pasos. Una pequeña tarea muestra el bucle ganando su lugar:

python
answer = run_agent(
    "¿Cuál es el clima en Buenos Aires y debería traer un paraguas?",
    tools,        # incluye get_weather del capítulo de uso de herramientas
    tool_impls,   # {"get_weather": ...}
)
# El agente llama get_weather, lee "nublado", luego responde en un turno final:
# "Está nublado en Buenos Aires a 18 grados, así que un paraguas es una idea sensata."

Una herramienta, un bucle, una respuesta. La misma estructura escala a varias herramientas y varios pasos sin cambiar forma. Una vez puedas construir cosas esta capaces, la siguiente pregunta es cómo sabes que realmente funcionan, que es lo que evals trata.

JunoEn la práctica El bucle run_agent es el patrón entero: dale una pregunta, herramientas, e sus implementaciones, y hace bucle hasta que el modelo deja de pedir herramientas o golpea el límite. Una herramienta y un bucle escalan a muchas sin cambiar forma. La siguiente pregunta es cómo sabes que realmente funciona, que es evals.

La función run_agent es el patrón entero. Dale una pregunta, herramientas, e implementaciones, y hace bucle hasta que el modelo deja de pedir o golpea el tope.

python
answer = run_agent(
    "¿Cuál es el clima en Buenos Aires y debería traer un paraguas?",
    tools,        # incluye get_weather del capítulo de uso de herramientas
    tool_impls,   # {"get_weather": ...}
)
# El agente llama get_weather, lee "nublado", luego responde en un turno final.

Una herramienta, un bucle, una respuesta, y la misma forma escala a varias herramientas y varios pasos. Lo que no escala gratis es tu confianza en que funciona. Un flujo de trabajo puedes probar paso a paso; un agente toma un camino diferente en entradas diferentes, así una ejecución que funcionó ayer te dice poco sobre la ejecución que falla hoy.

Eso es por qué la siguiente cosa a construir junto a un agente es una forma de medirlo: ejecútalo a través de un conjunto de tareas representativas y revisa los resultados, en lugar de confiar en una buena demo. Girar "funcionó cuando lo intenté" en un número que puedas rastrear es exactamente lo que evals cubre.

JunoEn la práctica El bucle run_agent es el patrón entero, y una herramienta y un bucle escalan a muchas sin cambiar forma. Lo que no escala gratis es confianza: un agente toma un camino diferente por entrada, así una buena demo prueba poco sobre el próximo intento. Construye una forma de medirlo a través de tareas representativas en lugar de confiar en un éxito, que es lo que evals es para.

La función run_agent es el patrón entero, y el ejemplo abajo es el mínimo descubierto: una herramienta, un bucle, una respuesta.

python
answer = run_agent(
    "¿Cuál es el clima en Buenos Aires y debería traer un paraguas?",
    tools,        # incluye get_weather del capítulo de uso de herramientas
    tool_impls,   # {"get_weather": ...}
)
# get_weather devuelve "nublado", el modelo responde en un turno final.

La forma escala a muchas herramientas y muchos pasos sin cambiar, y esa es la trampa, porque los modos de falla escalan con esto mientras el código permanece inmóvil. Un agente es dependiente de camino: entradas diferentes conducen a secuencias diferentes de pasos elegidos por modelo, así la prueba por entrada te dice casi nada sobre la entrada que no has visto. La no-determinación de muestreo significa incluso la misma entrada puede tomar un camino diferente dos veces.

Así la cosa que construyes próxima a un agente es medición, y es un tipo diferente de medición de la que un flujo de trabajo necesita. No estás aseverando una salida esperada; estás muestreando muchas tareas representativas y leyendo la distribución de resultados: cuán a menudo termina en presupuesto, cuán a menudo alcanza la respuesta correcta, dónde hace bucle, cuánto cuesta en la cola. Esa es la versión en forma de agente de evals, y es la única forma las preocupaciones de confiabilidad, costo, y seguridad de las secciones arriba se giran en números que puedes defender en lugar de una demo que tuviste suerte en.

JunoEn la prácticarun_agent es el patrón entero y escala en forma mientras los modos de falla escalan con esto. Un agente es dependiente de camino y muestreo añade no-determinación, así la prueba por entrada te dice poco y una buena demo prueba menos. Mídelo la forma agente: muestra muchas tareas representativas y lee la distribución, cuán a menudo termina en presupuesto, dónde hace bucle, cuánto cuesta la cola. Eso es para qué evals es, y es cómo las preocupaciones de confiabilidad y costo arriba se vuelven números que puedes defender.