Production AI Agent Architecture: Patterns, die im echten Betrieb halten

April 10, 2026 · 17 min read · ai-agents, architecture, production, llm-engineering, claude
Production AI Agent Architecture: Patterns, die im echten Betrieb halten

Die meisten Agent-Tutorials enden bei “das Modell ruft Tools in einer Schleife, fertig”. Das funktioniert für eine Demo. Es bricht beim ersten 500er eines Tools zusammen, beim ersten Nutzer, der etwas Off-Script fragt, oder spätestens, wenn die Token-Rechnung in einem einzelnen Task über 20 Dollar geht. Production AI Agent Architecture ist der Satz Patterns, der diese Schleife am Leben hält, wenn die Realität zuschlägt.

Ich betreibe gerade 10 Agenten in Produktion. Bash-Skripte, die claude -p aufrufen, per systemd-Timer geplant, Ergebnisse landen in Telegram. Nichts Spektakuläres. Sie liefern jeden Tag, weil die Architektur um die Schleife herum langweilig und bewusst aufgebaut ist. Dieser Guide ist genau dieses Playbook: die Patterns, die Must-haves, die Anti-Patterns und klare Empfehlungen, was wann sinnvoll ist.

Wenn Sie erst noch die Build-vs-Buy-Frage klären wollen, starten Sie mit dem Agents Build-vs-Buy Guide. Diese Seite ist der Hub für alles, was nach der Build-Entscheidung kommt.

Was “Production” für einen Agenten wirklich heißt

Ein produktiver Agent ist kein Prompt, der auf Ihrem Laptop funktioniert. Er ist ein System mit vier Eigenschaften:

  1. Begrenzte Kosten pro Lauf. Sie können die Frage beantworten: “Was ist das Maximum, das ich ausgebe, wenn das heute 10.000-mal läuft?”
  2. Begrenzte Zeit pro Lauf. Es gibt einen harten Deckel. Wenn der Agent in Minute 20 noch läuft, killt ihn etwas.
  3. Reproduzierbare Entscheidungen. Wenn ein Nutzer den Output reklamiert, können Sie nachspielen, was der Agent gesehen hat und warum er so gehandelt hat.
  4. Graziöses Versagen. Wenn ein Tool kaputtgeht oder ein Modell verweigert, erholt sich der Agent entweder oder eskaliert sauber. Er loopt nie still vor sich hin.

Alles unten zahlt auf eines dieser vier Punkte ein. Wenn eine Architekturentscheidung das nicht tut, raus damit.

Ein “Demo-Agent” hat nichts davon. Er funktioniert, weil Sie als Autor selbst der Error-Handler, der Budgetdeckel und der Replay-Mechanismus sind, vor dem Terminal sitzend. Produktion heißt, der Agent läuft ohne Sie.

Der Router-Planner-Executor-Split

Das mit Abstand nützlichste Pattern, das ich nutze. Den Agenten in drei Rollen aufspalten, jede mit einem anderen Modell.

  • Router: ein schnelles, günstiges Modell (Haiku) entscheidet, welche Capability oder welcher Agent dispatcht wird. Input ist die Nutzeranfrage und ein kurzer Capability-Katalog. Output ist ein einzelner Capability-Name.
  • Planner: ein Reasoning-Modell (Sonnet oder Opus mit Extended Thinking) plant den Ansatz für die gewählte Capability. Input ist die Nutzeranfrage und die verfügbaren Tools. Output ist ein strukturierter Plan.
  • Executor: die Tool-Use-Schleife. Setzt Calls ab, behandelt Fehler, reicht Ergebnisse zurück. Üblicherweise Sonnet. Kann dasselbe Modell wie der Planner sein oder ein günstigeres.

Warum drei:

  • Trennung der Verantwortlichkeiten. Der Router denkt nicht darüber nach, wie die Arbeit gemacht wird. Der Planner führt keine Tools aus. Der Executor entscheidet nicht über Strategie.
  • Kostenkontrolle. Die meisten Anfragen brauchen nie ein Reasoning-Modell. Der Router filtert die für Haiku-Cent heraus.
  • Qualitätskontrolle. Der Planner bekommt einen sauberen, fokussierten Prompt ohne das Rauschen von Tool-Definitionen und Ergebnissen. Der Executor bekommt einen klaren Plan ohne die Mehrdeutigkeit des ursprünglichen Nutzer-Inputs.

Eine Skizze in TypeScript, auf das Skelett reduziert:

import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic();

// 1. ROUTER - Haiku picks the capability
async function route(userMessage: string): Promise<string> {
  const res = await client.messages.create({
    model: "claude-haiku-4-5-20251001",
    max_tokens: 50,
    system: "Return one of: search, write, schedule, escalate. Nothing else.",
    messages: [{ role: "user", content: userMessage }],
  });
  return (res.content[0] as { text: string }).text.trim();
}

// 2. PLANNER - Sonnet with thinking plans the steps
async function plan(capability: string, userMessage: string) {
  const res = await client.messages.create({
    model: "claude-sonnet-4-6",
    max_tokens: 2000,
    thinking: { type: "enabled", budget_tokens: 4000 },
    system: `You plan steps for the "${capability}" capability. Return a JSON array of steps.`,
    messages: [{ role: "user", content: userMessage }],
  });
  return res.content;
}

// 3. EXECUTOR - tool-use loop with bounded iterations
async function execute(plan: unknown, tools: Anthropic.Tool[], maxSteps = 10) {
  const messages: Anthropic.MessageParam[] = [
    { role: "user", content: JSON.stringify(plan) },
  ];
  for (let i = 0; i < maxSteps; i++) {
    const res = await client.messages.create({
      model: "claude-sonnet-4-6",
      max_tokens: 4096,
      tools,
      messages,
    });
    if (res.stop_reason === "end_turn") return res;
    // dispatch tool calls, append tool_result, continue
  }
  throw new Error("max_steps exceeded");
}

Der Claude API Tool-Use Guide geht tief in die Executor-Schleife. Diese Seite bleibt auf Architektur-Ebene.

ReAct, Plan-then-Execute und Reflexion

Drei benannte Patterns, die Sie kennen sollten. Pro Capability eines wählen. Nicht in derselben Schleife mischen.

ReAct (Reason + Act). Das Modell wechselt im selben Kontext zwischen “Gedanke” und “Aktion”. Es erklärt, warum es gleich ein Tool aufruft, ruft es auf, beobachtet das Ergebnis, erklärt wieder. Das ist das, was jede moderne Tool-Use-Schleife per Default liefert. Gut für kurze Tasks mit unvorhersehbarer Form: “finde die letzte Rechnung für diesen Kunden und fasse zusammen, was sich geändert hat”. Größte Schwäche: der Kontext wächst schnell, die Kosten wachsen mit. Jeder Turn trägt die bisherigen Tool-Ergebnisse mit, also kostet der 15. Turn das Zehnfache des ersten. Plane das ein.

Plan-then-Execute. Der Planner produziert vorab einen vollständigen Plan. Der Executor läuft den Plan Schritt für Schritt ab. Wenn ein Schritt scheitert, planen Sie ab der Fehlerstelle neu statt von vorn. Besser für mehrstufige Tasks mit vorhersehbarer Form (Daten-Pipelines, Checklisten-Tasks). Günstiger, weil der Planner einmal pro Task läuft, nicht pro Schritt. Leichter auditierbar, weil der Plan ein einzelnes Artefakt ist, das Sie loggen und replayen können. Der Trade-off: wenn der Task wirklich adaptives Verhalten braucht, zerbricht ein starrer Plan an der ersten Überraschung.

Reflexion-Loop. Der Executor liefert ein Ergebnis. Ein separater Evaluator-Call (gleiches oder anderes Modell) bewertet es gegen Kriterien. Ist die Note schlecht, versucht es der Executor erneut, mit dem Feedback des Evaluators angehängt. Am stärksten bei Tasks, bei denen Verifizieren leichter ist als Tun: Code-Generierung (kompiliert er?), Zusammenfassungen gegen eine Rubrik, strukturierte Extraktion (hat jedes Pflichtfeld einen Non-Null-Wert?). Begrenzen Sie die Schleife: ein Retry lohnt sich meistens, drei nicht. Nach zwei gescheiterten Versuchen eskalieren.

Meine Empfehlung: Default ist Plan-then-Execute für geplante Jobs und ReAct für interaktive Arbeit. Reflexion nur an den Stellen, an denen Sie günstig automatisch bewerten können. Wickeln Sie nicht den ganzen Agenten in einen Reflexion-Loop; wickeln Sie den riskanten Schritt. Der Qualitätsgewinn konzentriert sich dort, die Kosten bleiben begrenzt.

Production-Must-haves

Jeder Agent, den ich betreibe, hat alle davon. Keiner ist optional.

  • Budget-Cap pro Lauf. Das Claude Code SDK hat --max-budget-usd. Wer rohes SDK nutzt, baut es selbst. Input- plus Output-Tokens zählen, mit Preis multiplizieren, beim Erreichen des Caps abbrechen. Das Pattern steht im Claude-Code-SDK-Agents-Post.
  • Iterations-Limit. Ein harter Deckel auf Tool-Calls pro Task. Ich nutze 10 für die meisten Agenten, 30 für Recherche. Wird er erreicht, beendet die Schleife mit einem spezifischen Fehler, nie still.
  • Timeouts. Pro-Tool-Call-Timeout (5-30s je nach Tool) und Pro-Lauf-Timeout (5-15 Min). Tool-Timeout liefert ein tool_result mit is_error: true. Run-Timeout killt den Prozess.
  • Strukturierte Inputs und Outputs. Tool-Use überall. Kein “bitte gib JSON in Ihrer Antwort zurück”. Der Extended-Thinking-Post ist die Referenz dafür, wie man Reasoning sauber vom strukturierten Output trennt.
  • Observability. Jeder Model-Call, jeder Tool-Call, Token-Counts und Outcomes gehen in ein Log mit Trace-ID. Nicht “in stdout gedruckt”. In eine Datei, die Sie sechs Monate später greppen können.
  • Replay-Mechanismus. Mit einer Trace-ID können Sie rekonstruieren: den exakten Prompt, die exakten Tool-Antworten, die exakte Entscheidung. Können Sie das nicht, können Sie nicht debuggen. Können Sie nicht debuggen, können Sie nicht verbessern.

Der Replay-Punkt ist der, den Teams gerne weglassen und später bereuen. Bauen Sie ihn an Tag eins ein. Eine JSONL-Datei pro Lauf reicht. Eine Zeile pro Event: Timestamp, Trace-ID, Event-Typ (model_call, tool_call, tool_result, error), Payload. Alte Dateien gzippen. Mindestens 30 Tage aufheben. Beim ersten Nutzer, der sagt “Ihr Agent hat am Dienstag was Komisches gemacht”, sind Sie froh.

Ein Layout, das sich bewährt: ein Verzeichnis pro Tag, eine Datei pro Lauf, benannt <trace_id>.jsonl. Der Agent schreibt im Verlauf, nicht erst am Ende, damit ein Crash nicht den halben Trace verschluckt. Packen Sie eine winzige CLI dazu, die eine Trace-ID einliest und eine menschenlesbare Zusammenfassung druckt; das zukünftige Ich dankt dem heutigen Ich.

Error-Handling-Patterns, bei denen keine Daten verloren gehen

Der Default-Fehlermodus von Agenten ist “weitermachen und es schlimmer machen”. Vier Patterns stoppen das.

Graziöses Tool-Failure. Wenn ein Tool wirft, geben Sie ein tool_result mit is_error: true und einer kurzen Botschaft zurück (“rate limited, retry in 30s”). Das Modell liest es, passt sich an, versucht oft eine andere Parametermenge. Nicht durch die Schleife hochreichen. Die Schleife entscheidet, ob der Agent sich erholen kann.

Bounded Retry. Pro Tool-Call maximal drei Versuche mit Exponential-Backoff. Danach ist das tool_result ein harter Fehler und das Modell wählt entweder ein anderes Tool oder hält an. Kein endloses Retry. Kein “nur noch einmal”.

Human-Eskalation. Manche Tasks sind nicht autonom abschließbar: mehrdeutiger Input, fehlende Credentials, regulatorisch heikle Entscheidungen. Geben Sie dem Agenten ein escalate_to_human(reason, context)-Tool. Bei mir postet dieses Tool in einen Telegram-Thread, hängt den Run-Trace an und wartet. Der Agent ist für jetzt fertig. Den Bot-Teil zeigt der Telegram-Bot-Post.

Kosten-Killswitch. Wenn die akkumulierten Kosten eines Laufs den Cap überschreiten, hält die Schleife an, loggt das Überschreiten und benachrichtigt. Sie versucht nicht “noch einmal fertig zu werden”. Das ist die wichtigste Zeile Code im ganzen System, weil ohne sie ein durchgehender Agent hunderte Dollar verbrennen kann, bevor es jemand merkt. Ich setze zwei Schwellen: einen Soft-Warn bei 70 Prozent (loggen, weiterlaufen) und einen Hard-Halt bei 100 Prozent (sofort stoppen, eskalieren). Der Soft-Warn erlaubt Ihnen, Caps anhand realer Daten zu tunen, statt zu raten.

Idempotente Run-IDs. Jeder Lauf bekommt eine UUID. Tools mit Seiteneffekten nehmen die Run-ID als Korrelations-Token entgegen. Wenn der Agent abstürzt und neu startet, können die Tools eine Wiederholung erkennen und den Seiteneffekt überspringen. Ohne das riskiert jedes Retry doppelte Mails, doppelte Rechnungen, doppelte Belastungen. Billig zu bauen, später unmöglich sauber nachzurüsten.

State-Management ohne überborstende Prompts

Die falsche Antwort ist “alles in die Conversation-History packen”. Die richtige Antwort hängt von der Lebensdauer des States ab.

  • Stateless pro Request. Default. Kein Memory zwischen Aufrufen. Jeder Lauf startet frisch. So sollten 80 Prozent der Agenten laufen. Leichter zu testen, leichter zu erklären, günstiger.
  • Conversation-Memory innerhalb einer Session. Messages über Turns hinweg anhängen. Prompt-Caching auf dem stabilen Prefix (System-Prompt, Tools, frühe Turns) nutzen, damit die Cache-Hit-Rate über 80 Prozent bleibt. Tut sie das nicht, invalidiert irgendetwas das Prefix und Sie zahlen jeden Turn den vollen Preis.
  • Externer State. Persistenter State lebt in einer Datenbank, nie in der Prompt-History. Der Agent fragt ihn über Tools ab: get_user_preferences, get_last_invoice_id. Prompts bleiben klein und begrenzt. Skaliert linear in Task-Komplexität, nicht in Nutzer-Lebenszeit.
  • Scratchpad vs. finaler Output. Die internen Überlegungen, Tool-Ergebnisse und halbfertigen Entwürfe des Modells bleiben in einem Scratchpad, der den Agenten nie verlässt. Der nutzerseitige Output ist ein separater, validierter Payload. Das gilt auch für Logs: kein Scratchpad an Endnutzer oder Monitoring-Dashboards ausliefern. Das leakt Prompts und verwirrt Leser.

Ein fünftes Pattern, das oft übersehen wird: Compaction. Wenn die Conversation-History eine Schwelle reißt, fassen Sie die ältesten Turns in eine einzelne kompakte Message zusammen, werfen die Originale weg und machen weiter. Richtig gemacht, setzen Sie den Token-Count zurück, ohne den roten Faden zu verlieren. Falsch gemacht, verlieren Sie genau das Detail, das der nächste Turn gebraucht hätte. Meine Regel: nur compacten, wenn ein Turn vollständig abgeschlossen ist (Tool gerufen, Ergebnis genutzt, Entscheidung getroffen). Nie mitten im Reasoning.

Tool-Design-Prinzipien

Das Modell kann Ihren Source-Code nicht lesen. Es liest die Tool-Beschreibung und das JSON-Schema. Das ist der gesamte Vertrag.

  • Aussagekräftige Namen und Docs. search_invoices(customer_id, date_range) schlägt query. Die Beschreibung sagt dem Modell, wann es das Tool nutzen soll und was zurückkommt.
  • Ein Konzept pro Tool. Keine überladenen Parameter. Ein do_thing(action, target, extras)-Tool scheitert öfter als drei separate Tools create_thing, update_thing, delete_thing. Das Modell findet das richtige selbst.
  • Schmale Schemata. Pflichtfelder als Pflicht, optionale klar markiert, wo möglich Enums. Jeder freie String ist ein wartender Fehler.
  • Idempotent, wo möglich. Retries dürfen keine doppelten Seiteneffekte erzeugen. Client-generierte IDs oder Upserts. Wenn ein Tool nicht idempotent sein kann (E-Mail senden), sagen Sie das in der Beschreibung, damit das Modell vorsichtig retried.
  • Rate-Limit-aware. Tools handhaben Backoff intern. Der Agent sollte nie “429 too many requests” sehen; er sollte “rate limited, retry in 5s” sehen und entscheiden, ob er wartet oder etwas anderes probiert.

Fehler als Daten zurückgeben. Wenn ein Tool scheitert, sollte das tool_result mit is_error: true einen strukturierten Payload enthalten, mit dem das Modell etwas anfangen kann: {"error": "not_found", "suggestion": "try search_invoices with a wider date range"}. Freie Stack-Traces verschwenden Tokens und lehren das Modell nichts. Fehler wie jeden anderen Output behandeln: typisiert, gewollt, nützlich für den nächsten Turn.

Tools versionieren, nicht Prompts. Wenn Sie das Schema eines Tools ändern, heben Sie die Version an und halten Sie die alte Definition für ein Deprecation-Fenster aufrufbar. Prompt-Änderungen sind leicht; Tool-Vertrags-Änderungen brechen Agenten still. Behandeln Sie Tool-Schemata wie eine öffentliche API, denn für Ihren Agenten sind sie genau das.

Mehr Patterns und lauffähiger Code im Tool-Use Guide. Der Build-an-MCP-Server-Post zeigt, wie Sie Tools als wiederverwendbaren Server paketieren, sobald Sie mehr als eine Handvoll haben.

RAG innerhalb von Agenten

Retrieval taucht auf zwei Wegen auf. Wählen Sie bewusst.

Retrieval als Tool. search_docs(query) liefert die Top-N-Chunks. Das Modell entscheidet, wann es aufruft. Gut, wenn der Agent vielfältige Anfragen bedient und Sie vorher nicht wissen, welche Dokumente relevant sind. Kosten: zusätzlicher Tool-Call-Roundtrip pro Retrieval, unvorhersehbare Chunk-Anzahl.

Retrieval als Context-Injection. Sie laufen Retrieval vor dem Model-Call, hängen die Ergebnisse vorn an den System-Prompt und cachen das Ergebnis. Gut, wenn der relevante Kontext vorhersehbar ist (Onboarding-Agent, Produkt-Support mit kleinem FAQ). Kosten: größere Prompts, niedrigere Cache-Hit-Rate, wenn die Retrieval-Ergebnisse oft wechseln.

Mein Default: Tool-basiert für offene Agenten, Injection für schmale Agenten mit bekanntem Corpus. Sie können mischen. Vollständige Pipeline-Details im RAG-Pipeline-Tutorial und im Vector-DB-Vergleich.

Verwechseln Sie RAG nicht mit Memory. RAG retrieved aus einem Corpus, für den der Agent gebaut wurde. Memory ist “was hat dieser Agent über diesen Nutzer über Sessions hinweg gelernt”. Anderes Problem, anderes Pattern.

Memory-Patterns, die wirklich nützen

Die meisten “AI-Agent-Memory”-Produkte sind eine Vektor-Datenbank plus Retrieval, hübsch eingepackt. Entscheiden Sie, ob Sie Memory wirklich brauchen, bevor Sie es einbauen. Wenn Sie das Problem mit externem State plus Tools lösen können, machen Sie das stattdessen.

Drei nützliche Memory-Typen:

  • Episodisch. Was in dieser Session passiert ist. Lebt in der Conversation-History, begrenzt durch ein Token-Budget.
  • Semantisch. Fakten, die der Agent über den Nutzer oder die Welt gelernt hat, persistent über Sessions hinweg. Lebt in einer Datenbank. Der Agent liest sie zu Session-Beginn über ein Tool, schreibt Updates über ein Tool. Prompts wachsen nicht unbegrenzt.
  • Prozedural. How-to-Patterns, die der Agent nutzt. Fast immer scripted, nicht gelernt. Lebt als Prompt-Fragmente oder Beispiele im Codebase, versionskontrolliert.

Default ist kein Memory. Episodisch hinzufügen, wenn der Agent auf frühere Turns referenzieren muss. Semantisch nur, wenn es einen konkreten nutzerseitigen Grund gibt (“Agent soll meine Zeitzone über Sessions hinweg merken”). Prozedural ist Code, nicht Memory. Behandeln Sie es wie Code.

Single-Agent vs. Multi-Agent

Die meisten Probleme sind Single-Agent mit spezialisierten Tools. Multi-Agent wird überbenutzt, weil es spannender zu bauen ist. Widerstehen Sie.

Multi-Agent lohnt sich, wenn eines davon stimmt:

  • Unterschiedliche Modelle passen zu unterschiedlichen Subtasks. Haiku routet, Sonnet plant, Opus übernimmt den reasoning-lastigen Kern. Das ist im Grunde der Router-Planner-Executor-Split, den die meisten ohnehin in einem einzigen logischen Agenten machen.
  • Parallelität ist die Komplexität wert. Drei unabhängige Recherche-Anfragen parallel, dann ein Synthese-Schritt. Der Koordinations-Aufwand wird durch die Wall-Clock-Ersparnis bezahlt.
  • Klare Handoff-Verträge. Agent A produziert Output X in einem Schema, Agent B konsumiert X. Wenn der Vertrag unscharf ist, haben Sie keine zwei Agenten; Sie haben einen Agenten mit einem Kommunikations-Bug.

Mein Take: Default Single-Agent, bis Sie einen konkreten Grund haben. Wenn ich sage, ich betreibe “10 Agenten”, meine ich 10 separate Bash-Skripte, jedes mit einem schmalen Job, jedes intern Single-Agent. Das ist kein Multi-Agent-System. Das sind 10 kleine Systeme. Der Unterschied zählt.

Tests für Agenten, die Sie wirklich shippen können

Wenn Ihr einziger Test “ich habs einmal laufen lassen, ging” ist, haben Sie keine Tests.

  • Golden Tasks. Eine kuratierte Menge von 10-50 realistischen Inputs mit erwartetem Verhalten. Laufen bei jedem Commit, der Prompt- oder Tool-Code berührt. Das sind keine Unit-Tests des Modells; das sind Unit-Tests der Entscheidungen Ihres Agenten.
  • Snapshot-Assertions auf strukturierten Outputs. JSON vergleichen, nicht Prosa. Whitespace normalisieren. Bekannt-variable Felder (Timestamps, IDs) variieren lassen. Form und entscheidungstragende Felder asserten.
  • Cost-Budget-Assertions. Jeder Golden Task hat einen maximalen Kostensatz. Wenn eine Prompt-Änderung die Kosten darüber schiebt, scheitert der Test. Sie merken es vor der Rechnung.
  • Offline-Eval mit Fixtures. Tool-Antworten mocken. Asserten, dass der Agent die richtigen Tools in der richtigen Reihenfolge gewählt hat. Das fängt “Agent ruft search_docs nach dem Refactor nicht mehr”-Bugs ab, die Augen-Tests nicht sehen.
  • Production-Shadow-Traffic. Echter Traffic, echte Outputs, im Lauf der Zeit gelabelt. Eine Stichprobe von Production-Läufen geht wöchentlich durch eine menschliche Sichtung. Trends in der Outcome-Qualität informieren Prompt- und Tool-Änderungen.
  • Regressions-Suite bei Modell-Upgrades. Wenn eine neue Modell-Version erscheint, lassen Sie das volle Golden-Task-Set auf alt und neu laufen. Outputs, Kosten und Latenz seitlich vergleichen. Upgraden, wenn das neue Modell auf den Metriken gewinnt, die für Sie zählen, nicht weil es neuer ist. Manchmal ist das alte Modell für Ihren Task besser.

Cost-Assertions sind der Test-Typ, den die meisten Teams weglassen, und sie zahlen dafür. Eine schlechte Prompt-Änderung kann Ihre Rechnung in einer Woche verdreifachen, im Output sieht es fein aus. Der Test scheitert; Sie fixen es; weiter. Kein All-Hands-Postmortem nötig.

Deployment-Patterns

Wie der Agent in Produktion wirklich läuft. Vier verbreitete Formen.

  • Claude Code CLI headless. claude -p "task" in einem Bash-Skript, per Cron oder systemd-Timer geplant. Minimale Infrastruktur, voller MCP-Tool-Zugriff. Genau das nutze ich für 10 Production-Agenten. Details im Claude-Code-SDK-Agents-Post.
  • SDK in einer App eingebettet. Ein Node- oder Python-Service importiert das SDK und legt eine API offen. Gut, wenn der Agent Teil eines nutzerseitigen Produkts ist. Sie ownen Server, Auth, Rate-Limits.
  • Worker-Queue. Tasks landen in einer Queue (Redis, SQS, RabbitMQ). Worker picken auf, lassen den Agenten laufen, schreiben Ergebnisse zurück. Gut, wenn Läufe lang sind und Sie horizontal skalieren müssen.
  • Webhook-getriggert. Ein API-Endpoint empfängt ein Event, feuert den Agenten ab, antwortet asynchron. Gut für Integrationen (GitHub-Events, Telegram-Messages, Formulareingaben).

Nehmen Sie die kleinste Form, die passt. Ein Cron-Skript ist ein Deployment. Sie brauchen kein Kubernetes für einen Agenten, der viermal am Tag läuft.

Die langweilige Architektur, die liefert

Was ich tatsächlich betreibe, als Referenzpunkt, nicht als Empfehlung zum 1:1-Kopieren.

  • 10 Agenten. Jeder ein Bash-Skript in /home/user/, das claude -p --model opus mit einem spezifischen Task-Prompt aufruft.
  • Jedes Skript per systemd-Timer mit OnCalendar= in Madrid-Zeit geplant. Timer handhaben DST korrekt; Cron nicht.
  • Jedes Skript loggt nach /var/log/<agent>.log. Bei Erfolg hängt es einen Marker an. Bei Fehler exit non-zero.
  • Jedes Skript endet mit einem telegram-notify.sh "message"-Call, damit ich Outcomes in Telegram sehe und nicht in Logs lese.
  • Das Ganze läuft auf einem Debian-VPS. Kein Kubernetes, kein Docker, keine Queue. Nur systemd, Bash und die Claude-API.

Das ist die Architektur. Sie verarbeitet mein Morgen-Briefing, die Wochenplanung, Job-Screens, Content-Follow-ups und mehr. Nichts davon beeindruckt einen Platform-Engineer. Alles davon liefert zuverlässig, kostet unter 50 Dollar im Monat, und ich kann jeden Fehler aus einem Terminal in zwei Minuten debuggen.

Die Lektion ist nicht “kopieren Sie dieses Setup”. Die Lektion ist: jede Komponente oben ist da, weil eine frühere, fancier Version gescheitert ist und durch etwas Langweiliges ersetzt wurde. Ihre Architektur sollte sich genauso entwickeln.

Anti-Patterns, die ich am häufigsten sehe

  • Zuerst ein Framework bauen. Ein Agent, dann ein zweiter, dann ein dritter. Nach drei extrahieren Sie die geteilten Stücke. Nicht vorher. Frameworks, die geschrieben werden, bevor Agenten existieren, lösen Probleme, die nicht existieren.
  • Über-Engineering des Tool-Katalogs. Die meisten Production-Agenten brauchen 5 bis 10 Tools. Ich sehe 40-Tool-Kataloge, in denen 30 Tools nie genutzt werden. Das Modell wird schlechter darin, aus einer langen Liste zu wählen. Kürzen.
  • Sich für immer auf eine bestimmte Modell-Version verlassen. Modell im Code pinnen, aber Upgrades planen. Neue Versionen werden alle paar Monate günstiger, schlauer oder beides. Planen Sie ein Quartal für Migrationsarbeit ein. Lassen Sie keinen drei Jahre alten Pin Ihre Architektur sein.
  • Den Nicht-Happy-Path ignorieren. 80 Prozent der Production-Agent-Arbeit sind Edge-Cases, Retries, Eskalationen und Kosten-Eindämmung. Wenn Ihr Design-Doc nur Happy-Path ist, haben Sie den Agenten nicht designt. Sie haben die Demo beschrieben.
  • Nur in Production testen. Bauen Sie Offline-Evals früh. Es ist sehr viel billiger, eine Regression in einem Golden Task zu finden als in einer Nutzerbeschwerde.

Wie es weitergeht

Das hier ist der Hub. Folgen Sie den Fäden, die für Sie relevant sind.

Production-Agenten sind nicht schwer, weil die KI schwer ist. Sie sind schwer, weil das umgebende System langweilig, begrenzt, beobachtbar und wiederherstellbar sein muss. Bauen Sie dieses System zuerst. Das Modell ist der einfache Teil.

Schriftliches Angebot in 24 Stunden

5 Felder. Ich antworte innerhalb von 24 Stunden – entweder mit einem Festpreis-Angebot samt Umsetzungsdauer oder mit einer klaren Absage inklusive Begründung.

Anfrage eingegangen

Ich antworte innerhalb von 24 Stunden mit einer ehrlichen Einschätzung.

Lieber direkt sprechen? 30-Minuten-Roadmap-Gespräch →