Wird geladen

Die Agentenschleife erklärt

Lektion 47 Min.
Wird geladen

Die Agentenschleife erklärt

Du hast bereits API-Aufrufe gemacht, aber ein einzelner Aufruf liefert nur eine Antwort. Wenn du einen Workflow automatisieren möchtest, muss Claude handeln, das Ergebnis betrachten, entscheiden, was als Nächstes kommt, und weitermachen. Dieses Muster ist gemeint, wenn Leute von agentischen Workflows sprechen.

Was ein Agent tatsächlich ist

Ein Agent ist eine autonome Version von Claude, die beide Seiten der Nachrichtenschleife ausführt, ohne dass ein Mensch dazwischen steht. Ein Agent erhält eine Aufgabe, wählt ein Tool aus und führt Code in einer Schleife aus, bis Claude entscheidet, dass die Aufgabe erledigt ist.

Die einfachste Art, eine Agentenschleife zu implementieren, sieht so aus:

  1. Sende eine Nachricht an Claude mit verfügbaren Tools.
  2. Claude antwortet entweder mit einer endgültigen Antwort oder einer Anfrage, ein von dir definiertes Tool zu verwenden.
  3. Dein Code führt dieses Tool aus.
  4. Du sendest das Ergebnis zurück an Claude.
  5. Wiederhole dies, solange der Stopp-Grund tool_use ist. end_turn bedeutet, dass Claude fertig ist, und jeder andere Stopp-Grund beendet ebenfalls die Schleife.

Stell es dir wie ein Gespräch vor, bei dem sich die Runden abwechseln: Der Nutzer gibt den Anstoß, der Agent ruft ein Tool auf, das Tool liefert ein Ergebnis, und der Agent macht weiter, bis er eine Antwort hat.

Ein minimales funktionierendes Beispiel

Um diese Schleife end-to-end laufen zu sehen, ohne eine Datenbank oder eine Benutzeroberfläche einzubeziehen, richten wir ein Fake-Tool namens get_weather ein und fragen Claude, was man heute in Austin anziehen sollte. Claude hat keine Möglichkeit, das Wetter selbst zu kennen, also muss es das Tool aufrufen, das Ergebnis lesen und dir dann eine Antwort geben.

Hier ist das gesamte Skript:

python
import anthropic

client = anthropic.Anthropic()

# Das tools-Array sagt Claude, was verfügbar ist:
# ein Name, eine Beschreibung und ein JSON-Schema für die Eingaben.
tools = [
    {
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "input_schema": {
            "type": "object",
            "properties": {
                "city": {
                    "type": "string",
                    "description": "The city to get weather for",
                }
            },
            "required": ["city"],
        },
    }
]

# run_tool ist nur ein fest codiertes Lookup.
# In einer echten App würde das deine Datenbank, eine API oder ähnliches ansprechen.
def run_tool(name, tool_input):
    if name == "get_weather":
        return f"Weather in {tool_input['city']}: 95F, sunny"
    raise ValueError(f"Unknown tool: {name}")

messages = [
    {"role": "user", "content": "What should I wear in Austin today?"}
]

# Die Agent-Loop. Jede Iteration sendet Nachrichten an Claude
# und verzweigt je nach stop reason der Antwort.
while True:
    response = client.messages.create(
        model="claude-sonnet-5",
        max_tokens=1024,
        tools=tools,
        messages=messages,
    )

    if response.stop_reason == "end_turn":
        # Claude ist fertig. Gib den finalen Text aus und brich ab.
        for block in response.content:
            if block.type == "text":
                print(block.text)
        break

    elif response.stop_reason == "tool_use":
        # Finde die Tool-Use-Blöcke in der Antwort und führe jeden aus.
        tool_results = []
        for block in response.content:
            if block.type == "tool_use":
                result = run_tool(block.name, block.input)
                tool_results.append(
                    {
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": result,
                    }
                )

        # Schiebe die Antwort des Assistenten und unsere Tool-Ergebnisse
        # zurück in messages, dann erneut loopen, damit Claude antworten kann.
        messages.append({"role": "assistant", "content": response.content})
        messages.append({"role": "user", "content": tool_results})

    else:
        # Jeder andere stop reason, z. B. max_tokens oder refusal.
        # In messages hat sich nichts geändert, also hier stoppen. Erneutes Loopen
        # würde dieselbe Anfrage immer wieder bezahlen lassen.
        print(f"Stopped early: {response.stop_reason}")
        break

Drei Dinge, die auffallen:

  • Das Tools-Array teilt Claude mit, was verfügbar ist: einen Namen, eine Beschreibung und ein JSON-Schema für die Eingaben.
  • run_tool ist nur ein hartcodiertes Nachschlagen. In einer echten App würde dies deine Datenbank, eine API oder was auch immer ansprechen.
  • Die Schleife ist die Agentenschleife. Jede Iteration sendet die Nachrichten an Claude und unterscheidet je nach Stopp-Grund der Antwort. Bei end_turn ist Claude fertig, also gib den finalen Text aus und breche ab. Bei tool_use suche die Tool-Use-Blöcke, führe jeden davon aus, füge die Antwort des Assistenten und deine Tool-Ergebnisse zurück in messages ein und durchlaufe die Schleife erneut, damit Claude antworten kann. Bei allem anderen gib den Stopp-Grund aus und breche ab.

Lass diesen letzten Zweig nicht weg. Ohne ihn fügt eine Antwort, die bei max_tokens abgeschnitten wird, nichts zu messages hinzu, sodass die Schleife dieselbe Anfrage erneut sendet und du jedes Mal dafür bezahlst. Die Dokumentation listet jeden Stopp-Grund und was dagegen zu tun ist auf.

Es ausführen

Wenn du das Skript ausführst, siehst du zwei Runden:

  1. Runde eins: Der Stopp-Grund ist tool_use. Claude fordert get_weather für Austin an, und dein Code gibt die Temperatur und die Bedingungen zurück.
  2. Runde zwei: Der Stopp-Grund ist end_turn, und Claude sagt dir, dass du etwas Leichtes und Atmungsaktives tragen solltest.

Terminalausgabe der Agentenschleife: Runde 1 stoppt mit tool_use und ruft get_weather für Austin auf, dann stoppt Runde 2 mit end_turn, und Claude gibt seine endgültigen Kleidungsempfehlungen aus

Zwei API-Aufrufe, eine Tool-Ausführung, eine endgültige Antwort. Das ist die gesamte Schleife. Alles, was du mit der Claude API baust, wird ähnlich wie dies sein.

Dieselbe Schleife in der Produktion

In einer echten Umgebung treibt genau diese Schleife etwas wie einen Auto-Review-Endpunkt an: einen Compliance-Agenten, der einen Strukturbericht liest, die relevanten Bauvorschriften über ein Tool nachschlägt und Risikoergebnisse während der Arbeit nach und nach in die Datenbank zurückschreibt.

Ein Compliance-Review-Dashboard, das hochgeladene Strukturberichte auflistet, jeweils mit einer Schaltfläche „Auto-Review ausführen“, die den Agenten startet

Die Form der Schleife ist identisch mit dem, was du gerade ausgeführt hast. Die Unterschiede sind:

  • Echte Tools statt eines simulierten Wetter-Nachschlags.
  • Ergebnisse werden als Server-Sent Events an die Benutzeroberfläche zurückgestreamt.
  • Ergebnisse werden in einer Risikoergebnis-Tabelle gespeichert.

Der Review-Trace eines laufenden Compliance-Agenten: Dutzende von Tool-Aufrufen, die die Bauvorschriften-Bibliothek durchsuchen und bestimmte Vorschriftenabschnitte nachschlagen, während die Schleife iteriert

Zusammenfassung

  • Ein Agent ist Claude in einer Schleife: beobachten, entscheiden, handeln, wiederholen.
  • Die Schleife ist einfach: Sende Nachrichten mit Tools, führe jedes von Claude angeforderte Tool aus, gib das Ergebnis zurück und stoppe, wenn der Stopp-Grund etwas anderes als tool_use ist.
  • Du besitzt die Schleife und die Tools. Claude besitzt das Reasoning.
  • Dieselbe Schleifenform skaliert von einer simulierten Wetter-Demo bis zu einem produktiven Compliance-Agenten — nur die Tools und die Verkabelung ändern sich.
  • Wenn du die Schleife nicht selbst besitzen möchtest, führen Managed Agents genau diese Schleife für dich auf Anthropics Infrastruktur aus.