How to Build an AI Agent
How to Build an AI Agent
s01

El Ciclo del Agente

Herramientas y Ejecución

Bash is All You Need

84 LOC1 herramientasSingle-tool agent loop
The minimal agent kernel is a while loop + one tool

[ s01 ] s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > s10 > s11 > s12

"Una boucle et Bash, c'est tout ce qu'il vous faut" -- una herramienta + un bucle = un agente.

Problema

Un modelo de lenguaje puede razonar sobre código, pero no puede tocar el mundo real -- no puede leer archivos, ejecutar pruebas o verificar errores. Sin un bucle, cada llamada a herramienta requiere que copies y pegues manualmente los resultados. Te conviertes en el bucle.

Solución

+--------+      +-------+      +---------+
|  User  | ---> |  LLM  | ---> |  Tool   |
| prompt |      |       |      | execute |
+--------+      +---+---+      +----+----+
                    ^                |
                    |   tool_result  |
                    +----------------+
                    (loop until stop_reason != "tool_use")

Una condición de salida controla todo el flujo. El bucle se ejecuta hasta que el modelo deja de llamar a herramientas.

Cómo Funciona

  1. El prompt del usuario se convierte en el primer mensaje.
messages.append({"role": "user", "content": query})
  1. Envía mensajes + definiciones de herramientas al LLM.
response = client.messages.create(
    model=MODEL, system=SYSTEM, messages=messages,
    tools=TOOLS, max_tokens=8000,
)
  1. Añade la respuesta del asistente. Verifica stop_reason -- si el modelo no llamó a una herramienta, hemos terminado.
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
    return
  1. Ejecuta cada llamada de herramienta, recopila los resultados y los añade como mensaje de usuario. Vuelve al paso 2.
results = []
for block in response.content:
    if block.type == "tool_use":
        output = run_bash(block.input["command"])
        results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": output,
        })
messages.append({"role": "user", "content": results})

Ensamblado en una función:

def agent_loop(query):
    messages = [{"role": "user", "content": query}]
    while True:
        response = client.messages.create(
            model=MODEL, system=SYSTEM, messages=messages,
            tools=TOOLS, max_tokens=8000,
        )
        messages.append({"role": "assistant", "content": response.content})

        if response.stop_reason != "tool_use":
            return

        results = []
        for block in response.content:
            if block.type == "tool_use":
                output = run_bash(block.input["command"])
                results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": output,
                })
        messages.append({"role": "user", "content": results})

Ese es el agente completo en menos de 30 líneas. Todo lo demás en este curso se construye sobre esto -- sin cambiar el bucle.

Qué Cambió

ComponenteAntesDespués
Bucle del agente(ninguno)while True + stop_reason
Herramientas(ninguno)bash (una herramienta)
Mensajes(ninguno)Lista acumulativa
Flujo de control(ninguno)stop_reason != "tool_use"

Pruébalo

python agents/s01_agent_loop.py
  1. Crea un archivo llamado hello.py que imprima "Hello, World!"
  2. Lista todos los archivos Python en este directorio
  3. ¿Cuál es la rama actual de git?
  4. Crea un directorio llamado test_output y escribe 3 archivos en él