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

Il Loop dell'Agente

Strumenti & Esecuzione

Bash is All You Need

84 LOC1 strumentiSingle-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

"Un loop e Bash è tutto ciò che ti serve" -- uno strumento + un loop = un agente.

Problema

Un modello linguistico può ragionare sul codice, ma non può toccare il mondo reale -- non può leggere file, eseguire test o controllare errori. Senza un loop, ogni chiamata di strumento richiede di copiare e incollare manualmente i risultati. Diventi tu il loop.

Soluzione

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

Una condizione di uscita controlla l'intero flusso. Il loop continua fino a quando il modello smette di chiamare strumenti.

Come Funziona

  1. Il prompt dell'utente diventa il primo messaggio.
messages.append({"role": "user", "content": query})
  1. Invia messaggi + definizioni degli strumenti al LLM.
response = client.messages.create(
    model=MODEL, system=SYSTEM, messages=messages,
    tools=TOOLS, max_tokens=8000,
)
  1. Aggiungi la risposta dell'assistente. Controlla stop_reason -- se il modello non ha chiamato uno strumento, abbiamo finito.
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
    return
  1. Esegui ogni chiamata di strumento, raccogli i risultati, aggiungi come messaggio utente. Torna al passo 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})

Assemblato in una funzione:

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})

Questo è l'intero agente in meno di 30 righe. Tutto il resto del corso si aggiunge sopra -- senza cambiare il loop.

Cosa è Cambiato

ComponentePrimaDopo
Loop agente(nessuno)while True + stop_reason
Strumenti(nessuno)bash (uno strumento)
Messaggi(nessuno)Lista accumulativa
Flusso controllo(nessuno)stop_reason != "tool_use"

Provalo

python agents/s01_agent_loop.py
  1. Crea un file chiamato hello.py che stampa "Hello, World!"
  2. Elenca tutti i file Python in questa directory
  3. Qual è il branch git attuale?
  4. Crea una directory chiamata test_output e scrivi 3 file al suo interno