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

La boucle d'agent

Outils et exécution

Bash is All You Need

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

"Une boucle et Bash, c'est tout ce qu'il vous faut" -- une outil + une boucle = un agent.

Problème

Un modèle de langage peut raisonner sur le code, mais il ne peut pas toucher le monde réel -- il ne peut pas lire des fichiers, exécuter des tests ou vérifier les erreurs. Sans boucle, chaque appel d'outil nécessite que vous copiez-colliez manuellement les résultats. Vous devenez la boucle.

Solution

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

Une condition de sortie contrôle tout le flux. La boucle s'exécute jusqu'à ce que le modèle arrête d'appeler des outils.

Comment Ça Marche

  1. Le prompt de l'utilisateur devient le premier message.
messages.append({"role": "user", "content": query})
  1. Envoyez les messages + définitions d'outils au LLM.
response = client.messages.create(
    model=MODEL, system=SYSTEM, messages=messages,
    tools=TOOLS, max_tokens=8000,
)
  1. Ajoutez la réponse de l'assistant. Vérifiez stop_reason -- si le modèle n'a pas appelé un outil, nous avons terminé.
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
    return
  1. Exécutez chaque appel d'outil, regroupez les résultats et ajoutez comme message utilisateur. Revenez à l'étape 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})

Assemblé en une fonction :

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

C'est tout l'agent en moins de 30 lignes. Tout le reste de ce cours s'ajoute par-dessus -- sans changer la boucle.

Qu'est-ce qui a Changé

ComposantAvantAprès
Boucle agent(aucune)while True + stop_reason
Outils(aucun)bash (un outil)
Messages(aucun)Liste cumulative
Flux de contrôle(aucun)stop_reason != "tool_use"

Essayer

python agents/s01_agent_loop.py
  1. Créer un fichier appelé hello.py qui affiche "Hello, World!"
  2. Lister tous les fichiers Python dans ce répertoire
  3. Quelle est la branche git actuelle ?
  4. Créer un répertoire appelé test_output et y écrire 3 fichiers