Letzten Monat beobachtete ich, wie ein Agent 47 API-Aufrufe tätigte, um eine Frage zu beantworten, die er mit zwei hätte lösen können. Das Setup sah vernünftig aus – Tool-Aufrufe aktiviert, Speicherpuffer vorhanden, Fehlerbehandlung auf dem Papier. Der Agent wusste einfach nicht, welches Werkzeug er zuerst verwenden sollte, rief immer wieder dasselbe auf und hatte keine Möglichkeit zu wissen, dass er in einer Schleife lief.
Das passiert, wenn man einen Agenten baut, ohne seine tatsächlichen Fehlermodi zu verstehen. Architektur ist entscheidend. Hier sind meine Erkenntnisse aus der Produktion von Agenten.
Die drei Kernmuster
Ein KI-Agent benötigt drei Dinge, um zu funktionieren: eine Möglichkeit zu entscheiden, was zu tun ist, Zugriff auf Werkzeuge und Speicher darüber, was passiert ist. Die Art und Weise, wie Sie diese drei Dinge verbinden, bestimmt, ob Ihr Agent sauber läuft oder Tokens verbrennt, indem er sich im Kreis dreht.
Muster 1: Einfaches Routing (Entscheidung → Werkzeug → Antwort)
Dies ist die Grundlage. Der Agent sieht eine Benutzeranfrage, wählt ein Werkzeug aus, führt es aus und gibt ein Ergebnis zurück. Keine Schleifen. Keine Rekursion. Einzelner Entscheidungspunkt.
from anthropic import Anthropic
client = Anthropic()
def route_and_execute(user_message: str) -> str:
tools = [
{
"name": "lookup_price",
"description": "Get current price for a product",
"input_schema": {
"type": "object",
"properties": {
"product_id": {"type": "string"}
},
"required": ["product_id"]
}
},
{
"name": "check_stock",
"description": "Check inventory for a product",
"input_schema": {
"type": "object",
"properties": {
"product_id": {"type": "string"}
},
"required": ["product_id"]
}
}
]
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=[{
"role": "user",
"content": user_message
}]
)
# Check response type
for block in response.content:
if block.type == "tool_use":
tool_name = block.name
tool_input = block.input
# Execute tool (mock implementation)
if tool_name == "lookup_price":
result = f"Price for {tool_input['product_id']}: $29.99"
elif tool_name == "check_stock":
result = f"Stock for {tool_input['product_id']}: 15 units"
else:
result = "Tool not found"
return result
# If no tool was called, return text response
return response.content[0].text if response.content else ""
# Usage
response = route_and_execute("What's the price of product ABC-123?")
print(response)
Dies funktioniert gut für unkomplizierte Aufgaben – Kundenserviceanfragen, Datenabrufe, einzelne Entscheidungen. Es scheitert, wenn die Antwort mehrere Schritte erfordert.
Muster 2: Agentenschleife (Entscheiden → Werkzeug → Bewerten → Wieder entscheiden)
Wenn eine Aufgabe mehrere Schritte erfordert – etwas recherchieren, dann berechnen, dann formatieren – benötigen Sie eine Schleife. Der Agent trifft eine Entscheidung, führt sie aus, erhält Feedback und entscheidet, was als Nächstes zu tun ist. Die Falle: Ohne Abbruchbedingungen wird dies unendlich.
def agentic_loop(user_message: str, max_iterations: int = 5) -> str:
tools = [
{
"name": "search_knowledge_base",
"description": "Search internal docs for information",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string"}
},
"required": ["query"]
}
},
{
"name": "calculate_metric",
"description": "Perform calculation on data",
"input_schema": {
"type": "object",
"properties": {
"values": {"type": "array", "items": {"type": "number"}},
"operation": {"type": "string", "enum": ["sum", "average", "max"]}
},
"required": ["values", "operation"]
}
}
]
messages = [{
"role": "user",
"content": user_message
}]
for iteration in range(max_iterations):
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=messages
)
# Check if we have a final answer
if response.stop_reason == "end_turn":
return response.content[0].text if response.content else ""
# Process tool calls
if response.stop_reason == "tool_use":
# Add assistant response to message history
messages.append({
"role": "assistant",
"content": response.content
})
# Execute tools and collect results
tool_results = []
for block in response.content:
if block.type == "tool_use":
# Mock execution
if block.name == "search_knowledge_base":
result = f"Found docs on: {block.input['query']}"
elif block.name == "calculate_metric":
values = block.input['values']
op = block.input['operation']
if op == "sum":
result = f"Result: {sum(values)}"
elif op == "average":
result = f"Result: {sum(values)/len(values)}"
else:
result = f"Result: {max(values)}"
else:
result = "Unknown tool"
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})
# Add tool results back to messages
messages.append({
"role": "user",
"content": tool_results
})
return "Max iterations reached"
# Usage
result = agentic_loop("Find our Q3 revenue data and calculate the average monthly value")
print(result)
Schlüsselpunkt: Das max_iterations-Limit ist nicht optional. Ich habe gesehen, wie Agenten über 100 Aufrufe erreichten, weil niemand eine Obergrenze gesetzt hat. Setzen Sie es standardmäßig auf 5 und erhöhen Sie es nur, wenn Tests beweisen, dass Sie mehr benötigen.
Muster 3: Hierarchische Planung (Planen → Teilaufgaben ausführen → Synthetisieren)
Für komplexe Arbeitsabläufe – Berichte analysieren, Kampagnen planen, Systeme debuggen – zerlegen Sie das Problem zuerst in Teilaufgaben. Lassen Sie den Agenten planen, dann den Plan ausführen und dann synthetisieren. Dies gibt Ihnen Einblick, was der Agent zu tun glaubt, bevor er Tokens damit verschwendet.
Tool-Aufrufe: Einrichtung und Fehlermodi
Tool-Aufrufe in Claude (seit März 2025) sind zuverlässig, aber die Einrichtung ist wichtig. Sie definieren Werkzeuge als JSON-Schemas. Das Modell entscheidet, welches Werkzeug mit welchen Parametern aufgerufen wird. Sie führen das Werkzeug aus und geben die Ergebnisse zurück.
Die meisten Fehler stammen aus zwei Quellen:
1. Vage Werkzeugbeschreibungen
Schlecht: "search" - search for information
Gut: "search_customer_database" - search by email, name, or ID. Returns customer record with purchase history. Use this when you need to verify customer details before processing orders.
Das Modell wählt Werkzeuge basierend auf Beschreibungen aus. Vage Beschreibungen führen zur falschen Werkzeugauswahl.
2. Fehlendes Fehlerfeedback
Wenn ein Werkzeug fehlschlägt, teilen Sie dem Agenten genau mit, warum. Geben Sie nicht nur eine generische Fehlermeldung zurück. Im obigen Code für die Agentenschleife geht jedes Werkzeugergebnis als Nachricht zurück. Wenn eine Suche fehlschlägt, sagen Sie "No results found for query 'xyz'. Try a different search term." anstelle von "Error."
Speicher: Zustandslose vs. Persistente
Agenten müssen den Kontext speichern. Sie haben zwei Möglichkeiten:
Konversationsverlauf (zustandslos): Übergeben Sie den gesamten Nachrichtenverlauf jedes Mal an das Modell. Funktioniert für kurze Interaktionen. Wird schnell teuer. Token-Kosten = O(Konversationslänge) pro Aufruf.
Persistenter Speicher: Speichern Sie eine Zusammenfassung der Konversation, wichtige Fakten und Protokolle der Werkzeugausführung in einer Datenbank. Übergeben Sie nur relevanten Kontext. Token-Kosten bleiben konstant.
Verwenden Sie für Produktionsagenten persistenten Speicher. Speichern Sie die letzten 10–15 Nachrichten im Verlauf und eine rollierende Zusammenfassung. Wenn die Konversation länger als ca. 20 Nachrichten ist, lassen Sie das Modell eine Zusammenfassung erstellen und separat speichern.
Ein Muster zum Testen heute
Wählen Sie Muster 1 (Einfaches Routing) und implementieren Sie es für eine reale Aufgabe in Ihrem System – Kundensuche, Datenabruf, alles Einzelschrittige. Definieren Sie 2–3 Werkzeuge mit spezifischen Beschreibungen. Führen Sie 10 Testabfragen durch und prüfen Sie:
- Hat es das richtige Werkzeug ausgewählt? (Wenn nicht, schreiben Sie die Beschreibung neu.)
- Hat es die richtigen Parameter verwendet? (Wenn nicht, ist Ihr Eingabeschema unklar.)
- Beantwortet die Ausgabe tatsächlich die Frage des Benutzers?
Sobald das funktioniert, wechseln Sie zu Muster 2. Mehrstufige Agenten sind nicht schwieriger – sie sind nur Muster 1 in einer Schleife. Aber fügen Sie die Schleife nur hinzu, wenn einzelschrittig nicht ausreicht.