Startseite / Artikel

Neuaufbau eines Claude-Code-Stil-Agenten mit LangChain Deep Agents

Wie das Harness eines Programmier-Agenten funktioniert – vom Kernloop über Tools, Planung, Speicher, Subagenten bis hin zu sandbox-basierten Genehmigungen – Schritt für Schritt mit DeepAgents neu aufgebaut.

Verlag: REACTAPP.TOP16 Min. Lesezeit3592 Wörter

Quellen: **Build Your Own Claude Code Using Langchin: A Deepdive Into LangChain’s Deep Agents**

Ein Programmieragent ist kein Chatbot

Es ist leicht, sich einen Programmieragenten als intelligenteren Chatbot vorzustellen – doch dieses Bild ist falsch. Die Fähigkeiten von Claude Code stammen nicht allein vom Modell selbst, sondern vom um das Modell herum aufgebauten agilen Framework. Dieses Framework bildet die Steuerungsplattform: das unsichtbare System, das dem Modell Werkzeuge zur Dateiüberprüfung, eine Umgebung zum Ausführen von Code, ein Gedächtnis für bereits durchgeführte Aktionen sowie eine Checkliste zur Aufrechterhaltung des richtigen Weges bietet. Entfernt man dieses Framework, ist ein Sprachmodell lediglich ein Textgenerator; setzt man es wieder ein, verhält sich dasselbe Modell wie ein fähiger, autonomer Softwareentwickler.

Unser Ziel ist es, Schritt für Schritt zu untersuchen, wie ein Agent im Stil von Claude Code funktioniert, und jedes Element mit der deepagents-Bibliothek von LangChain neu aufzubauen. Am Ende sollte die Funktionsweise klar werden, denn man wird selbst einen solchen Agenten erstellt haben.

Der zentrale Kreislauf

Eine Sitzung beginnt mit der Nachricht des Benutzers. Es kann sich dabei um eine beiläufige Frage dazu handeln, was sich in einer Dateiordner befindet, oder um eine umfangreiche Aufgabe wie die Überarbeitung des Anmeldesystems und das Aktualisieren der dazugehörigen Tests. Das Modell liest diese Nachricht, bevor es einen nächsten Schritt wählt, und von dort aus teilt sich der Ablauf. Wenn eine Aktion erforderlich ist, beantragt es ein Werkzeug, erhält die Ausgabe zurück und beginnt den Prozess erneut – dieser Zyklus ist sowohl bei einer einstufigen als auch bei einer fünfzigstufigen Aufgabe identisch. Sobald es in gewöhnlicher Prosa antwortet, ohne ein Werkzeug anzufordern, bricht der Loop ab und der Benutzer sieht das Ergebnis. Das Fehlen eines Werkzeugaufrufs ist genau das Signal dafür, dass der Agent seine Arbeit für abgeschlossen hält.

Das Feld „entscheidet über den nächsten Schritt“ kombiniert drei Phasen, die in der Forschung zu Agenten beschrieben werden: das Sammeln von Kontext durch das Lesen von Dateien, das Handeln durch das Bearbeiten und Ausführen von Befehlen sowie die Überprüfung durch das Ausführen von Tests. Sie laufen nicht als separate Modi ab, sondern sind einfach unterschiedliche Toolaufrufe, die innerhalb einer Schleife ablaufen.

Es gibt einen bewussten Wechsel der Arbeitsweise, nämlich den Planungsmodus. Normalerweise plant und handelt der Agent gleichzeitig. Im Planungsmodus befindet sich vor der Schleife eine Kontrollstelle. Der Agent untersucht die Situation und erstellt einen Vorschlag, ohne etwas zu ändern: Dateien werden gelesen und Ideen ausgearbeitet, doch Bearbeitungen und Befehle warten, bis der Benutzer zustimmt, und erst danach läuft die normale Schleife. Das dient als Sicherheitsventil für umfangreiche oder risikoreiche Aufgaben. Es ist nicht dasselbe wie die To-Do-Liste, die der Agent für jede Aufgabe selbst führt, denn der Planungsmodus ist eine Pause, die vom Benutzer ausgelöst werden muss und deren Genehmigung ausdrücklich erforderlich ist.

Das Diagramm lässt weiterhin die um den Loop herum angeordneten Komponenten aus: die Komprimierung, wenn der Speicher voll wird, die Subagenten, die ihre eigenen privaten Loops ausführen, sowie die Berechtigungs- und Sandbox-Schicht, die zwischen „eine Funktion ausführen“ und dem eigentlichen System steht. Keine dieser Komponenten verändert den Loop – sie umgeben ihn lediglich.

Vier Fähigkeiten befinden sich innerhalb dieses Systems und sorgen dafür, dass der Loop stabil bleibt. Die Planungsfunktion lässt den Agenten zunächst nachdenken. Tools fungieren als seine „Hände“. Die Kontextverwaltung verhindert, dass lange Aufgaben den Speicher überlasten. Subagenten übernehmen Nebenaufgaben in eigenen privaten Loops, damit der Hauptthread nicht überlastet wird. Sie versorgen den Loop mit Ressourcen, ohne ihn jemals neu zu schreiben.

Unter all dem befindet sich die Schicht, die am wichtigsten ist. Wenn der Agent die reale Welt berühren will, indem er eine Datei bearbeitet, einen Befehl ausführt oder das Netzwerk nutzt, erreicht die Aktion nicht direkt den Rechner. Zunächst muss sie durch Berechtigungsregeln und einen Sandkasten, wobei keine andere Sicherheitsmaßnahme im Design so viel Gewicht hat. Stellen Sie sich vor, man versuche, einen Agenten sicher zu halten, indem man einer seiner Anweisungen eine Zeile wie „Bitte löschen Sie nichts Wichtiges“ hinzufügt. Das ist lediglich ein Zettel mit Notiz, den ein Modell übersehen, falsch verstehen oder ignorieren kann. Eine echte Schutzmaßnahme befindet sich außerhalb des Modells: eine Berechtigungsregel, die einen Toolaufruf kategorisch ablehnt, sowie ein Betriebssystem-Sandkasten, der einen gefährlichen Befehl unabhängig von den Präferenzen des Modells stoppt.

Der reine Engine

Bevor man auf Bibliotheken zurückgreift, ist es hilfreich, den Engine ohne Zusätze anzusehen. Dies ist ein vollständiger, funktionsfähiger Agent-Zyklus.

def run_agent_loop(client, user_message, tools, tool_functions, max_turns=20):
    messages = [{"role": "user", "content": user_message}]
    for _ in range(max_turns):
        # 1. Ask the model what to do next.
        response = client.messages.create(
            model="claude-sonnet-4-6", max_tokens=1024, tools=tools, messages=messages
        )
        messages = [*messages, {"role": "assistant", "content": response.content}]

        # 2. Plain text and no tool request? The job is done.
        tool_uses = [b for b in response.content if b.type == "tool_use"]
        if not tool_uses:
            return "".join(b.text for b in response.content if b.type == "text")
        # 3. Run each requested tool and hand the results back. 4. Repeat.
        results = [
            {"type": "tool_result", "tool_use_id": call.id,
             "content": tool_functions[call.name](**call.input)}
            for call in tool_uses
        ]
        messages = [*messages, {"role": "user", "content": results}]
    raise RuntimeError(f"agent loop did not finish within {max_turns} turns")

Es umfasst ungefähr dreißig Zeilen, und der Rest des Designs besteht aus dieser Schleife mit zusätzlichen Elementen. Stärkere Tools werden in tool_functions abgelegt. Ein Planer notiert Anmerkungen in messages. Ein Kompressor kürzt messages, sobald diese anwachsen. Ein Subagent ist einfach dieselbe Funktion, die erneut aufgerufen wird – mit einer neuen, leeren messages-Liste. Die Berechtigungsprüfung findet in der Lücke zwischen dem Modell, das ein Tool anfordert, und der Zeile statt, die es ausführt. Die Obergrenze max_turns ist jener Paranoia-Aspekt, den jedes echte System beibehält – schließlich verbraucht ein in einer Schleife steckendes Modell endlos Geld.

Jeder Programmierungsagent besitzt dieses „schlagende Herz“, die Agentenschleife, die Worte in Handlungen umsetzt – und sie ist fast peinlich einfach:

  1. Fragen Sie das Modell, was als Nächstes zu tun ist.
  2. Das Modell antwortet entweder in plain Text oder bittet darum, ein Tool zu verwenden.
  • Falls ein Tool angefordert wird, führt das System das Tool aus und gibt das Ergebnis an das Modell zurück.
  • Gehen Sie zum Schritt 1 zurück.
  • Wenn das Modell in reinem Text antwortet, ohne Tool-Anfrage, ist die Aufgabe erledigt – stoppen Sie dann und zeigen Sie die Antwort an.
  • Das Lesen einer Datei, das Ausführen eines Befehls und die Bearbeitung von Code durchlaufen alle diesen einen Zyklus. Stellen Sie sich einen Auftragnehmer vor, dem eine Aufgabe und eine Checkliste gegeben werden: Prüfen Sie, was als Nächstes zu tun ist, führen Sie es aus, überprüfen Sie das Ergebnis, wählen Sie erneut und melden Sie erst zurück, wenn die Liste leer ist. Der Schleifenzyklus übernimmt dabei die Rolle des Urteils dieses Auftragnehmers. Zudem skaliert er sich selbst, da eine einfache Frage möglicherweise nur einen Durchlauf benötigt, während eine umfassende Refaktorierung Dutzende von Toolaufrufen erfordert – und niemand muss im Voraus die Anzahl der Schritte festlegen.

    Aufbau mit Deep Agents

    Es ist nicht notwendig, die while-Schleife manuell zu schreiben. Die Erstellung eines Deep Agents stellt automatisch eine funktionierende Schleife bereit. Beginnen Sie damit, die Bibliothek sowie einen Modellanbieter zu installieren.

    pip install deepagents langchain-anthropic
    

    Erstellen Sie anschließend den einfachsten möglichen Agenten.

    from deepagents import create_deep_agent
    
    def get_weather(city: str) -> str:
        """Get the weather for a given city."""
        return f"It's always sunny in {city}!"
    agent = create_deep_agent(
        model="anthropic:claude-sonnet-4-6",
        tools=[get_weather],
        system_prompt="You are a helpful assistant.",
    )
    result = agent.invoke(
        {"messages": [{"role": "user", "content": "What's the weather in San Francisco?"}]}
    )
    

    Die Aufrufung von create_deep_agent gibt einen Agenten zurück, bei dem der Schleifenmechanismus bereits integriert ist, und .invoke() führt genau den oben beschriebenen Zyklus aus. Es spielt für das Framework keine Rolle, welches Modell dahintersteht – ob OpenAI, Google oder Anthropic – der Schleifenablauf bleibt derselbe.

    Tools sind die Hände

    Während der Schleifenmechanismus das „Motor“ ist, sind Tools die „Hände“. Ohne sie kann ein Modell nur sprechen. Mit guten Tools kann es eine Codebasis lesen, ändern und das Ergebnis überprüfen. Echte Programmierwerkzeuge lassen sich in vier Kategorien einteilen:

    • Lesewerkzeuge scannen die Umgebung, ohne etwas zu ändern: read_file öffnet eine Datei, glob findet Dateien nach Nammemustern wie allen .py-Dateien, und grep sucht in Dateien nach bestimmtem Text. Anfänger verwechseln oft die letzten beiden, doch glob findet Dateien nach ihrem Namen und grep nach deren Inhalt.
  • Die Bearbeitungstools ändern Inhalte sicher: write_file erstellt neue Dateien und edit_file modifiziert einen Teil einer bestehenden Datei.
  • Ein Ausführungstool startet Shell-Befehle, genau die gleichen, die man in einer Terminalkonsole eintippt.
  • Ein Delegierungstool, task, weist eine Unteraufgabe an einen Hilfsagenten weiter.
  • Warum sollte der Agent nicht cat zum Lesen und sed zur Bearbeitung verwenden? Das wäre möglich, doch speziell entwickelte Tools haben zwei Vorteile. Erstens die Token-Verwaltung: Ein dediziertes Lesetool kann vor dem Laden die Größe einer Datei prüfen und gegebenenfalls reduzieren, während cat den gesamten Inhalt ausgibt und dadurch die Kontextfenstergröße überschreiten kann. Zweitens sind die Berechtigungen übersichtlicher: Ein Aufruf des bekannten edit_file-Tools teilt dem System genau mit, was vor sich geht, sodass Sicherheitsregeln angewendet werden können, während ein freier Shell-Befehl undurchsichtig und riskant ist.

    Es gibt hier eine amüsante Besonderheit. Die Modelle haben aus dem öffentlichen Internet, das voller Stack Overflow-Antworten ist, in denen cat und sed verwendet werden, gelernt – weshalb selbst fortgeschrittene Modelle aus Gewohnheit auf die reine Shell zurückgreifen. Der Systemprompt muss sie daher nachdrücklich daran erinnern, ihre eigentlichen Werkzeuge statt der Shell-Skripte zu verwenden.

    Deep Agents liefert das vollständige Set bereits integriert mit: Planung, Dateisystemwerkzeuge, Ausführung und Delegation. Benutzerdefinierte Werkzeuge werden als verzierte Funktionen hinzugefügt.

    import subprocess
    from langchain_core.tools import tool
    
    MAX_OUTPUT_CHARS = 20_000  # roughly 5k tokens
    @tool
    def run_tests(path: str = ".") -> str:
        """Run the project's pytest suite and return its output.
        Output is truncated to the last 20k characters (failures appear at the
        end). The run is killed after 5 minutes.
        """
        try:
            result = subprocess.run(["pytest", path], capture_output=True,
                                    text=True, check=False, timeout=300)
        except subprocess.TimeoutExpired:
            return "pytest timed out after 300s"
        output = result.stdout + result.stderr
        if len(output) > MAX_OUTPUT_CHARS:
            return ("[... output truncated to the last 20,000 characters ...]\n"
                    + output[-MAX_OUTPUT_CHARS:])
        return output
    agent = create_deep_agent(
        model="anthropic:claude-sonnet-4-6",
        tools=[run_tests],            # merged in alongside the built-ins
        system_prompt="You are a coding assistant. Always run tests after editing.",
    )
    

    Der @tool-Decorator macht eine gewöhnliche Funktion für das Modell aufrufbar. Seine Dokumentation ist von großer Bedeutung, da das Modell sie als Handbuch betrachtet, das angibt, wann und wie das Tool verwendet werden soll.

    Planung vor Handlung

    Wenn man einem einfachen Modell eine komplexe Anfrage übermittelt, gerät es oft ins Stocken: ein Aufruf hier, ein weiterer dort – ohne Gesamtplan und manchmal im Kreislauf. Gute Programmieragenten vermeiden das, indem sie vor dem Eingreifen einen Plan erstellen. Sie schreiben eine strukturierte To-Do-Liste, die die Aufgabe in klare Schritte unterteilt, arbeiten sich dann daran ab und markieren jeden Punkt als in Bearbeitung oder abgeschlossen. Es ist wie bei einem Koch, der das gesamte Rezept liest, bevor er den Herd einschaltet – so wird Schritt vier nicht erfunden, während Schritt drei bereits verbrennt.

    Hinter diesem Ansatz steckt ein cleverer ingenieurtechnischer Trick. Während einer langen Sitzung gerät das ursprüngliche Ziel unter all den Ausgaben der Tools verloren, wodurch das Modell es aus den Augen verliert. Um dem entgegenzuwirken, fügt das System die aktuelle To-Do-Liste nach den Tool-Aufrufen wieder in das Gespräch ein – genauso wie ein Kollege eine Checkliste als Erinnerung über den Schreibtisch schiebt.

    In Deep Agents ist dies das integrierte Tool write_todos. Es muss nichts konfiguriert werden, denn die Standard-Systemanweisung lehrt den Agenten, vor dem Handeln zu planen und die Liste im Laufe der Schleife stets auf dem neuesten Stand zu halten.

    Kontextverwaltung

    Die schwierigste Ingenieursleistung findet hier statt. Jedes Modell verfügt über ein Kontextfenster, eine feste Obergrenze für seinen Arbeitsspeicher. Ein paar große Dateien sowie einige Befehle füllen diesen schnell, und sobald er überläuft, beginnt der Agent, Informationen zu ignorieren – sogar die Anweisungen, mit denen er begonnen hat. Coding-Agents bewältigen dies mit zwei Strategien:

    1. Dateien dienen als externer Speicher. Anstatt ein umfangreiches Suchergebnis in das Chat-Fenster zu schreiben, speichert der Agent es auf der Festplatte und behält nur den Dateinamen bei; er öffnet die Datei erneut, wenn er die Details benötigt.
    2. Sobald das Gespräch die Grenze erreicht, wird eine Komprimierung ausgelöst. Der Agent stoppt den Kreislauf, konsolidiert die älteren Austausche, speichert die wichtigsten Fakten im Langzeitspeicher ab und löscht den überfüllten Kurzzeitgedächtnisbereich.

    Stellen Sie sich das Schreiben eines umfangreichen Berichts vor: Niemand kann alle Informationen im Kopf behalten. Man macht Notizen, ordnet die Unterlagen ab und legt eine einseitige Zusammenfassung auf den Schreibtisch. Beides ist bereits in Deep Agents integriert, das ein virtuelles Dateisystem zur Speicherung großer Ergebnismengen sowie Middleware für die automatische Zusammenfassung bereitstellt – somit ist diese Speichermanagement-Funktion bereits ab dem Moment der Erstellung des Agents vorhanden.

    Subagenten: Teilen und erobern

    Manche Aufgaben sind zu umfangreich für ein einziges Gespräch. Das Durchsuchen einer riesigen Codebasis kann bedeuten, dass fünfzig Dateien gelesen werden müssen, und fünfzig Dateien sollten den sauberen Speicher des Haupt-Agenten nicht überlasten. Die Lösung sind Unteragenten. Der Haupt-Agent startet einen Hilfsagenten, weist ihm eine spezifische Aufgabe zu, wie beispielsweise die Suche nach dem Ort, an dem die Authentifizierungslogik liegt, und der Hilfsagent arbeitet in seinem eigenen separaten Kontextfenster. Nach Abschluss liefert er eine prägnante Zusammenfassung. Ein Manager, der Forschungsarbeiten an einen jüngeren Mitarbeiter delegiert und eine einzeilige Zusammenfassung erhält, hält auf dieselbe Weise seinen „Schreibtisch“ ordentlich.

    Es gibt auch eine Sicherheitsmaßnahme: Unteragenten ist es strengstens verboten, eigene Unteragenten zu starten. Andernfalls könnte ein verwirrter Agent eine endlose Kette von verschachtelten Hilfsagenten erzeugen, was zu einem außer Kontrolle geratenen Prozess führt, der den API-Budget aufbraucht. Eine strenge Tiefenbeschränkung sorgt dafür, dass die Delegation sicher bleibt.

    Deep Agents enthält ein integriertes task-Tool zur Erstellung von Hilfsprogrammen. Spezialisierte Tools, wie ein dedizierter Code-Sucher, werden mit einfachen Wörterbüchern beschrieben.

    code_searcher = {
        "name": "code-searcher",
        "description": "Searches the codebase to find where specific logic lives. "
                       "Use this for any open-ended 'where is X?' question.",
        # ⚠️ NOTE: the key is `system_prompt`, NOT `prompt` (see correction below).
        "system_prompt": "You are an expert at navigating codebases. Use the grep "
                         "and glob tools to locate relevant files, then report a "
                         "concise summary of what you found and where. Do not make "
                         "any edits.",
    }
    
    agent = create_deep_agent(
        model="anthropic:claude-sonnet-4-6",
        tools=[run_tests],
        system_prompt="You are a coding assistant.",
        subagents=[code_searcher],
    )
    

    Der Hauptagent weiß nun, dass es einen Spezialisten gibt, wodurch sein eigenes Gedächtnis für die eigentliche Programmierarbeit frei bleibt.

    Sicherheit und menschliche Genehmigung

    In dieser Phase kann der Agent Dateien bearbeiten und Shell-Befehle auf einem echten Rechner ausführen, was Überlegung erfordert. Ein enthusiastischer Agent könnte versehentlich falsche Dateien löschen oder zerstörerische Aktionen ausführen. Kraft ohne Kontrolle stellt eine echte Gefahr dar. Programmieragenten setzen Kontrollmechanismen in zwei Ebenen um:

    1. Erlaubnislisten und Verweigerungsregeln ermöglichen es sicheren Tools wie dem Lesen von Dateien, automatisch zu laufen, während zerstörerische Tools wie das Löschen von Dateien eine Genehmigung benötigen.
    2. Genehmigungsanfragen, auch als menschliche Einmischung bezeichnet, sorgen dafür, dass der Agent vor riskanten Aktionen anhält und um Zustimmung bittet. Der Benutzer genehmigt, ändert oder lehnt die Aktion ab, anschließend setzt sich der Kreislauf fort.

    Die grundlegende Regel der Agentensicherheit besagt, dass eine Anweisung keine Sicherheitsgrenze darstellen darf. Dem Modell mitzuteilen, nichts Wichtiges löschen zu dürfen, ist eine höfliche Bitte und keine Barriere – schließlich kann das Modell einfach darüber hinweghalluzinieren. Die Durchsetzung muss außerhalb des Modells, im Kontrollmechanismus, stattfinden. Eine Berechtigungsregel kann einen Toolaufruf ablehnen, und ein Sandbox-System kann gefährliche Shell-Befehle auf Betriebssystemebene blockieren, egal wie sehr das Modell deren Ausführung wünscht. Aus diesem Grund benötigt das Ausführen von Tools einen geeigneten Backend. Höflichkeit ist keine Sicherheit.

    Deep Agents legt seine Grenzen im Kontrollmechanismus fest. Der Zugriff auf die Shell erfordert einen Backend, und LangGraphs integrierter Unterbrechungsmechanismus pausiert die Ausführung vor riskanten Operationen.

    from deepagents import create_deep_agent
    # Import path for backends can vary by version - check the current
    # "Backends" page in the Deep Agents docs.
    from deepagents.backends import LocalShellBackend
    
    agent = create_deep_agent(
        model="anthropic:claude-sonnet-4-6",
        system_prompt="You are a coding assistant working inside this project.",
        backend=LocalShellBackend(),   # enables the `execute` shell tool
    )
    

    Falls ein gesperrtes Tool angefordert wird, stoppt der Loop und das Ergebnis enthält einen __interrupt__-Payload, der die ausstehende Aktion sowie die verfügbaren Optionen auflistet: approve, edit, reject oder respond. Nach der Entscheidung wird die Ausführung fortgesetzt.

    from langgraph.types import Command
    
    result = agent.invoke({"messages": [...]}, config)
    result["__interrupt__"]   # the pending action + allowed decisions — show your user
    
    # You decide; the loop picks up exactly where it paused:
    agent.invoke(Command(resume={"decisions": [{"type": "approve"}]}), config)
    # ... or {"type": "reject"} — the tool is never run, and the model is told so.
    

    Reale Grenzen gehören in die Steuerung, niemals nur in die Anweisung.

    Gedächtnis über Sessions hinweg

    Standardmäßig verliert ein Agent alles, sobald eine Konversation beendet wird. Ein wirklich nützlicher Assistent sollte sich an die Codierkonventionen eines Projekts, an die Präferenzen des Benutzers sowie daran erinnern, wo er gestern aufgehört hat. Zwei Mechanismen erledigen diese Aufgabe. Das Checkpointing speichert den genauen Zustand des Agents, sodass eine lange Aufgabe auch bei Unterbrechungen weiterläuft und von derselben Stelle aus fortgesetzt werden kann. Das Langzeitgedächtnis bewahrt Fakten auf, die länger bestehen als jede einzelne Konversation – beispielsweise dass ein Projekt mit vier Leerzeichen eingefasst wird.

    Da Deep Agents auf LangGraph läuft, entsteht die Persistenz durch das Einbinden eines Checkpointers.

    from deepagents import create_deep_agent
    from langgraph.checkpoint.memory import InMemorySaver
    
    agent = create_deep_agent(
        model="anthropic:claude-sonnet-4-6",
        tools=[run_tests],
        system_prompt="You are a coding assistant.",
        checkpointer=InMemorySaver(),   # remembers state within a session
    )
    # A "thread_id" ties messages together into one ongoing conversation.
    config = {"configurable": {"thread_id": "project-alpha"}}
    agent.invoke(
        {"messages": [{"role": "user", "content": "Start refactoring the auth module."}]},
        config=config,
    )
    # Later, same thread_id - the agent remembers the earlier turn:
    agent.invoke(
        {"messages": [{"role": "user", "content": "Now update the tests too."}]},
        config=config,
    )
    

    InMemorySaver gilt nur solange das Programm läuft. Für eine Überlebensfähigkeit nach Neustarts sollte er durch einen mit einer Datenbank unterstützten Checkpointer ersetzt werden.

    Alles in einem Agenten

    Zusammengefügt bilden die einzelnen Komponenten einen Agenten: eine Kernschleife zusammen mit benutzerdefinierten Tools, Planungsfunktionen, Kontextverwaltung, einem Hilfssubagenten, einer Shell sowie gespeichertem Zustand – insgesamt sieben Teile.

    from deepagents import create_deep_agent
    from deepagents.backends import LocalShellBackend
    from langchain_core.tools import tool
    from langgraph.checkpoint.memory import InMemorySaver
    
    # --- A custom tool (Part 2) — token-budgeted, see Part 2 for the full body ---
    @tool
    def run_tests(path: str = ".") -> str:
        """Run the project's pytest suite and return its (truncated) output."""
        import subprocess
        try:
            result = subprocess.run(["pytest", path], capture_output=True,
                                    text=True, check=False, timeout=300)
        except subprocess.TimeoutExpired:
            return "pytest timed out after 300s"
        output = result.stdout + result.stderr
        return output if len(output) <= 20_000 else "[... truncated ...]\n" + output[-20_000:]
    
    # --- A specialized subagent (Part 5) — note the `system_prompt` key ---
    code_searcher = {
        "name": "code-searcher",
        "description": "Finds where specific logic lives in the codebase. "
                       "Use for open-ended 'where is X?' questions.",
        "system_prompt": "You navigate codebases using grep and glob, then report a "
                         "concise summary of what you found. You never make edits.",
    }
    
    # --- A system prompt that teaches good behavior (Parts 2 & 3) ---
    SYSTEM_PROMPT = """You are a careful coding assistant.
    Workflow:
    1. Plan the task as a to-do list before doing anything.
    2. Use your built-in read, grep, and glob tools to explore - never the raw shell
       equivalents like cat or grep.
    3. Make focused edits.
    4. ALWAYS run the tests after editing, and fix anything that breaks.
    5. Delegate broad codebase searches to the code-searcher subagent.
    """
    
    # --- Assemble the agent (Parts 1, 4, 6, 7 handled by the harness) ---
    agent = create_deep_agent(
        model="anthropic:claude-sonnet-4-6",                  # Part 1: the loop, model-agnostic
        tools=[run_tests],                                     # Part 2: custom hands
        system_prompt=SYSTEM_PROMPT,                           # Parts 2 & 3: behavior + planning
        subagents=[code_searcher],                             # Part 5: delegation
        backend=LocalShellBackend(root_dir=".", virtual_mode=False),  # Part 6: shell access
        interrupt_on={"execute": True,                         # Part 6: the brakes —
                      "write_file": True, "edit_file": True},  #   approval before anything destructive
        checkpointer=InMemorySaver(),                          # Part 7: memory across turns
    )
    # Part 4 (context management) and built-in planning come on automatically.
    
    config = {"configurable": {"thread_id": "my-project"}}
    result = agent.invoke(
        {"messages": [{"role": "user", "content": "The login tests are failing. Fix them."}]},
        config=config,
    )
    print(result["messages"][-1].content)
    

    Weniger als hundert Zeilen erzeugen einen Programmieragenten, der plant, sucht, bearbeitet, Tests ausführt, Aufgaben an Helfer weiterleitet, sich innerhalb eines Sandboxes aufhält und seinen Kontext bewahrt. Seine Struktur entspricht der von Claude Code: eine einfache Schleife, umhüllt von Werkzeugen für Planung, Speichermanagement, Delegation sowie Sicherheitsmechanismen, die außerhalb des Modells liegen.