Startseite / Artikel

Ein Planungsagent in LangGraph erstellen: Planen, Ausführen, Neuplanen, Berichten

Ein vierknotiger LangGraph-Planungsagent für Finanzforschung: strukturierte Pläne, ein namensraumbewusstes Tool-Register, Neuplanungsbeschränkungen sowie eine nachvollziehbare Beispielausführung.

Verlag: REACTAPP.TOP16 Min. Lesezeit3625 Wörter

Quellen: Your AI Agent Isn’t Smart. Here’s How to Build One That Actually Thinks

Die meisten Agenten sind verkleidete Prompt-Ketten

Es gibt eine unangenehme Wahrheit über KI-Agenten: Viele sind nichts anderes als aufgewertete Prompt-Ketten in einem „Trenchcoat“. Das Prinzip ist bekannt – ein Systemprompt, einige Tools und vielleicht eine ReAct-Schleife, und das Ergebnis wird als Agent bezeichnet. Das funktioniert in Demos und unter günstigen Bedingungen. Doch wenn ein Tool einen Fehler zurückgibt, die Daten seltsam aussehen oder die Abfrage mehr als drei Schritte erfordert, bricht das ganze System zusammen.

Die Alternative ist ein Planungsagent. Er erstellt zunächst einen umfassenden Forschungsplan, bevor er irgendein Werkzeug verwendet, arbeitet Schritt für Schritt nach diesem Plan voran und schreibt bei widersprüchlichen Zwischenergebnissen den Rest neu. Die Demo ist ein Finanzforschungssystem. Geben Sie ihm eine Anfrage in einfachem Englisch wie „Vergleichen Sie die Bewertungen von NVDA und AAPL und sagen Sie mir, welche im Moment besser aussieht“, und es erstellt einen mehrstufigen Plan, führt jeden Schritt mit Datenwerkzeugen durch, repariert sich selbst, wenn etwas schiefgeht, und erstellt einen Bericht im Stil eines Analysten. Es basiert auf LangGraph, arbeitet mit Cloud-Modellen über Groq oder mit lokalen Modellen über Ollama und passt in etwa vier Dateien.

Warum einfaches ReAct nicht ausreicht

ReAct (Reason-Act-Observe) ist das Muster, mit dem die meisten Agenten beginnen. Der LLM überlegt sich seinen nächsten Schritt, ruft ein Tool auf, liest die Rückmeldung, überlegt erneut und ruft das nächste Tool auf. Es ist beliebt, einfach und geeignet für kleine Aufgaben.

Die zentrale Schwäche ist Gier, da ein ReAct-Agent nur einen Schritt voraus plant. Wenn man beispielsweise fünf Aktien nach drei Kriterien sowie aktuelle Nachrichten anfordert, beginnt er mit dem P/E-Verhältnis von NVDA, und das erste Ergebnis lenkt seine Aufmerksamkeit ab. Ein Prototyp verbrauchte sieben Tool-Aufrufe pro Tesla-Kriterium, bevor er sich daran erinnerte, mehrere Aktien zu vergleichen; sein endgültiger Bericht bestand aus einem Zusammenfassung der Tesla-Ergebnisse sowie einem einzigen Satz zu den anderen Aktien.

Die Fähigkeit des Modells ist hier nicht der Grund. Die Architektur ist es. Wenn bei einem Inferenzvorgang entschieden werden muss, was untersucht werden soll, wie es untersucht werden soll und was mit den Ergebnissen gemacht werden soll, erhält keine dieser Entscheidungen die nötige Aufmerksamkeit. Ein Planungsagent trennt Denken von Handeln: Er plant erst, führt dann aus und überprüft anschließend, ob der Plan weiterhin gültig ist. Jeder Knoten bearbeitet eine einzige Aufgabe, und sie werden nacheinander ausgeführt.

Vier Knoten und eine Schleife

Der Planungsagent ist ein gerichteter Graph mit vier Knoten, ähnlich wie ein Flussdiagramm, bei dem jede Kiste eine Aufgabe bearbeitet und den Zustand weiterleitet.

START --> Planner --> Executor <--> Replanner --> Reporter --> END
  1. Der Planner nimmt die Anfrage des Benutzers entgegen und erstellt einen strukturierten, schrittweisen Forschungsplan. Jeder Schritt gibt an, welches Tool aufgerufen werden soll, welche Argumente verwendet werden und warum.
  2. Der Executor nimmt den nächsten Schritt in Angriff, ruft das angegebene Tool auf und speichert das Ergebnis in einem Notizblock.
  3. Der Replanner prüft nach jeder Ausführung alles, was bisher gesammelt wurde. Falls ein Tool einen Fehler aufweist oder die Daten unerwartete Ergebnisse zeigen, überarbeitet er die verbleibenden Schritte. Andernfalls lässt er den Plan unverändert.
  4. Der Reporter wandelt alle Einträge aus dem Notizblock in den abschließenden Analysebericht um, der konkrete Zahlen sowie Empfehlungen enthält.

Was die Gestaltung antreibt, ist der Executor-Replanner-Loop. Die beiden Knoten wechseln sich ab, bis der Plan fertiggestellt ist, und diese Abwechslung führt zum selbstkorrigierenden Verhalten, denn nach jeder Aktion kann der Agent neu überlegen.

Zustand: das gemeinsame Speicher

In LangGraph ist der Zustand alles – der zwischen den Knoten übertragenen gemeinsame Speicher. Die vollständige Definition:

import operator
from typing import Annotated, TypedDict

from pydantic import BaseModel, Field

class StrategyState(TypedDict, total=False):
    """Global state that flows through the LangGraph nodes."""
    query: str
    plan: list[dict]
    scratchpad: Annotated[list[dict], operator.add]
    current_step: int
    final_report: str
    replan_count: int

In diesem Zustand enthält query die ursprüngliche Anfrage des Benutzers unverändert, plan ist die geordnete Liste der Schritte, scratchpad sammelt alle Ergebnisse der Tools, current_step verweist auf den Plan, und replan_count stützt die Sicherheitsgrenze MAX_REPLANS.

Die Annotation Annotated[list[dict], operator.add] im Scratchpad ist wichtig. Ihr Reduzierer, operator.add, weist LangGraph an, neue Einträge hinzuzufügen und die bestehenden beizubehalten. Wenn der Executor {"scratchpad": [new_entry]} zurückgibt, fügt LangGraph dies der aktuellen Liste hinzu, sodass die Knoten niemals Listen manuell verarbeiten müssen und es zu Mutationsschäden nicht kommt.

Gestrukturierte Pläne und Entscheidungen

Der Planner gibt niemals freien Text zurück. Sein Ausgabeformat ist ein Pydantic-Modell, sodass das LLM Pläne in einer Form erstellen muss, die vom Code verarbeitet werden kann:

AVAILABLE_TOOLS_TEXT = """
- get_metrics(ticker, metric?): Return stock metrics. 'metric' is optional
  (P/E, EPS, Revenue, Market Cap, Sector).
- search_news(ticker): Return recent news headlines for a ticker.
- compare_metrics(tickers: list, metric): Compare one metric across
  multiple tickers.
"""

class PlanStep(BaseModel):
    """A single executable step inside an analysis plan."""
    step_id: int = Field(description="Sequential step number")
    tool: str = Field(
        description=f"Tool to use. Must be one of:\n{AVAILABLE_TOOLS_TEXT}"
    )
    args: dict = Field(description="Arguments for the tool call")
    purpose: str = Field(description="Why this step is needed")

class Plan(BaseModel):
    """The full plan generated by the planner node."""
    goal: str = Field(description="The overall analysis goal")
    steps: list[PlanStep] = Field(
        description="Ordered list of steps to execute"
    )

Das Feld purpose erweist sich als wertvoller, als erwartet. Es erklärt dem Replanner, warum ein Schritt vorhanden ist, und nicht nur, was er tut. Wenn anstelle von „call compare_metrics,“ der Text „Vergleiche Kurs-Gewinn-Verhältnisse, um eine relative Bewertung zu ermitteln“ angezeigt wird, kann der Replanner viel besser beurteilen, ob der Schritt beibehalten, geändert oder weggelassen werden soll.

Der Replanner verfügt über sein eigenes Schema:

class ReplanDecision(BaseModel):
    """Output of the replanner node."""

reasoning: str = Field(
        description="Analysis of current progress and findings"
    )
    should_replan: bool = Field(
        description="Whether the plan needs modification"
    )
    updated_steps: list[PlanStep] = Field(
        default_factory=list,
        description="Remaining steps if replan is needed. Empty if no changes.",
    )

Durch die Festlegung von should_replan als Boolean zwingt man den LLM, sich für eine oder andere Richtung zu entscheiden: Wird der Plan geändert oder nicht? Lässt man dem LLM bei strukturierten Ausgaben Spielraum, wird es jedes Mal variieren.

Das Tool-System

Drei Finanzforschungstools laufen mit realistischen Simulationsdaten. In der Produktion würden echte API-Aufrufe verwendet, doch Simulationsdaten bieten beim Aufbau einen großen Vorteil: deterministisches Debuggen. Wenn sich das Agent seltsam verhält, ist sofort klar, ob das Problem in seiner Logik oder in einer API liegt.

Ein Designmuster, dem mehr Aufmerksamkeit gebührt, ist das namensraumbewusste Tool-Register, das anstelle davon verwendet wird, jedem Knoten jedes Tool zur Verfügung zu stellen:

from langchain_core.tools import BaseTool
from typing import Iterable, Mapping, Any

class ToolRegistry:
    """Namespace-aware container for LangChain tools."""
    def __init__(self) -> None:
        self._tools_by_toolset: dict[str, dict[str, BaseTool]] = {}
    def add_tools(self, toolset: str, tools: Iterable[BaseTool]) -> None:
        bucket = self._tools_by_toolset.setdefault(toolset, {})
        bucket.update({t.name: t for t in tools})
    def get_tools(self, toolset: str) -> tuple[BaseTool, ...]:
        return tuple(self._tools_by_toolset.get(toolset, {}).values())
    def invoke(
        self, toolset: str, tool_name: str, tool_args: Mapping[str, Any]
    ) -> Any:
        t = self._tools_by_toolset.get(toolset, {}).get(tool_name)
        if t is None:
            raise ValueError(
                f"Unknown tool '{tool_name}' in toolset '{toolset}'"
            )
        return t.invoke(dict(tool_args))

Die Registrierung erfolgt unter den Namespacen "planner", "executor" und "replanner". Alle Tools sind für den Planner sichtbar, damit er damit planen kann, doch nur der Executor kann sie aufrufen. Selbst wenn ein Fehler im Replanner irgendwie einen Toolaufruf auslöst, würde das Register diesen ablehnen, da dieser Namespace keine Aufrufrechte besitzt. Das ist rollenbasierte Zugriffskontrolle für Agenten, und die Trennung der Aufgaben dient gleichzeitig als Sicherheitsmechanismus, der unerwünschte Zustandsänderungen während des Planens verhindert.

Der Planner-Node

def planner_node(state: StrategyState) -> dict:
    """Create a step-by-step research plan using structured output."""
    planner = model.with_structured_output(Plan)

prompt = PLAN_PROMPT.format(
        available_tools=AVAILABLE_TOOLS_TEXT,
        ticker_choices=ticker_choices_text(),
        metric_choices=metric_choices_text(),
        query=state["query"],
    )
    plan: Plan = planner.invoke(prompt)
    steps = [s.model_dump() for s in plan.steps]
    return {"plan": steps, "current_step": 0}

model.with_structured_output(Plan) sorgt dafür, dass das LLM mit einem pydantic-kompatiblen JSON-Objekt antwortet, und fehlerhafte Ausgaben führen einfach zu einem Neversuch. Das ist bei weitem besser als das Parsen von Freitext mit regulären Ausdrücken.

Schutzmaßnahmen im Plan-Aufforderungstext

PLAN_PROMPT = """\
You are a financial research planner. Given a user's analysis request,
create a step-by-step research plan using the available tools.

Available tools:
{available_tools}
Rules:
- Use only the tools listed above.
- Every plan step must be executable with one of those tools.
- When a tool accepts 'ticker' or 'tickers', use only these exact values:
  {ticker_choices}
- When a tool accepts 'metric', use one of these exact values:
  {metric_choices}
- There are no other tools available. Final synthesis is handled separately.
Create an efficient plan. Group related lookups. Aim for 4-8 steps.
User request: {query}"""

Zwei Aspekte sind besonders hervorzuheben. Die Anweisung listet die gültigen Parameterwerte auf, sodass das LLM nicht raten muss, welche Aktienkennungen oder Metriken vorhanden sind. Dies könnte der wirksamste Trick gegen Halluzinationen für Tools aufrufende Agenten sein. Ohne diese Angabe planen die Modelle zuversichtlich Schritte wie get_metrics(ticker="BITCOIN", metric="vibes") und erscheinen anschließend überrascht, wenn diese fehlschlagen.

Der andere Aspekt ist die Zeile „Es sind keine weiteren Tools verfügbar.“ Fehlt diese, erfinden LLMs Schritte wie analyze_sentiment(ticker="NVDA") oder generate_report(findings=...) – Tools, die in Wirklichkeit nicht existieren.

Die Anweisung „Zielen Sie auf 4 bis 8 Schritte ab“ ist absichtlich vage formuliert. Starre Grenzen wie „genau 5 Schritte“ hatten den gegenteiligen Effekt: Einfache Anfragen wurden mit überflüssigen Schritten aufgebläht, während komplexe Anfragen in überlastete Schritte gepresst wurden. Ein Bereich gibt dem Modell Spielraum zur Anpassung, und durch Leitlinien anstelle von Vorgaben trifft es in der Regel die richtige Entscheidung.

Der Executor-Node

Der Executor ist absichtlich der einfachste Node: Er nimmt den nächsten Schritt, ruft das Tool über das Registry auf und speichert die Ausgabe.

MAX_STEPS = 12  # Safety limit on total steps

def executor_node(state: StrategyState) -> dict:
    """Execute the next pending step from the plan."""
    plan = state.get("plan", [])
    current_step = state.get("current_step", 0)
    if current_step >= len(plan):
        return {}
    if current_step >= MAX_STEPS:
        return {"current_step": len(plan)}
    step = plan[current_step]
    tool_name = step["tool"]
    tool_args = step["args"]
    try:
        result = str(
            TOOL_REGISTRY.invoke(
                AgentName.EXECUTOR.value, tool_name, tool_args
            )
        )
        status = "Error" if result.startswith("Error:") else "Success"
    except Exception as exc:
        result = f"Error: {exc}"
        status = "Error"
    entry = {
        "step": current_step + 1,
        "tool": tool_name,
        "args": tool_args,
        "result": result,
        "status": status,
    }
    return {
        "scratchpad": [entry],
        "current_step": current_step + 1,
    }

MAX_STEPS = 12 dient als fester Obergrenzwert. Sollte der Replanner weiterhin Schritte hinzufügen oder stecken bleiben, kann der Agent nicht endlos API-Kredite verbrauchen. Sobald die Obergrenze erreicht ist, setzt der Executor current_step auf len(plan), und der Ablauf wechselt zum Reporter mit den bisher gesammelten Daten.

Fehler werden nach einer festgelegten Konvention erkannt: status = „Error“ wenn result.startswith(„Error:“) sonst „Success“. Jedes der drei Tools fügt seinen Fehlermeldungen den Präfix „Error:“ hinzu, sodass der Executor einen Fehler ohne JSON-Parsing oder spezifische Exception-Verarbeitung kennzeichnen kann. Der Replanner liest diesen Status, um zu entscheiden, ob ein Neversuch oder eine angepasste Planung erfolgen soll.

Der Replanner-Node

Dieser Knoten zeigt den Unterschied zwischen einem Planungsagenten und einem einfachen Orchestrierer auf. Nach jedem Tool-Aufruf bewertet er alle Beweismittel und prüft, ob der verbleibende Plan immer noch sinnvoll ist:

MAX_REPLANS = 2  # Prevent infinite replanning

def replanner_node(state: StrategyState) -> dict:
    """Review progress and optionally modify the remaining plan."""
    plan = state.get("plan", [])
    current_step = state.get("current_step", 0)
    replan_count = state.get("replan_count", 0)
    scratchpad = state.get("scratchpad", [])
    remaining = plan[current_step:]
    if len(remaining) = MAX_REPLANS:
        return {}
    scratchpad_text = "\n".join(
        f"Step {e['step']}: {format_tool_call(e['tool'], e['args'])} "
        f"-> [{e['status']}] {e['result'][:150]}..."
        for e in scratchpad
    )
    remaining_text = "\n".join(
        f"Step {s['step_id']}: {format_tool_call(s['tool'], s['args'])} "
        f"- {s['purpose']}"
        for s in remaining
    )
    replanner = model.with_structured_output(ReplanDecision)
    prompt = REPLAN_PROMPT.format(
        goal=state["query"],
        scratchpad=scratchpad_text,
        remaining_steps=remaining_text,
    )
    decision: ReplanDecision = replanner.invoke(prompt)
    if decision.should_replan and decision.updated_steps:
        new_steps = plan[:current_step] + [
            s.model_dump() for s in decision.updated_steps
        ]
        return {"plan": new_steps, "replan_count": replan_count + 1}
    return {"replan_count": replan_count + 1}

Betrachten Sie e['result'][:150]. Der Replanner betrachtet jedes Tool-Ergebnis als auf 150 Zeichen beschnitten, da er nur den Kerninhalt und nicht den vollen JSON-Inhalt benötigt, während der Reporter später die unbeschnittenen Daten erhält. Tokens werden dort gespeichert, wo Details nicht wichtig sind, und dort verbraucht, wo sie es sind.

Wenn eine Neuplanung stattfindet, behält plan[:current_step] + [s.model_dump() for s in decision.updated_steps] die abgeschlossenen Schritte bei und ersetzt nur die unvollendeten, wodurch die Historie unverändert bleibt.

Der Neuplan-Befehl

REPLAN_PROMPT = """\
You are a financial research planner reviewing progress on a research task.

Original goal: {goal}
Completed steps and findings so far:
{scratchpad}
Remaining steps in the plan:
{remaining_steps}
Based on the findings so far, should the remaining plan change?
If an expected tool failed or revealed something unexpected, add a step
to investigate.
If a step is now redundant, remove it.
Use only the available executable tools already shown in the plan.
Do not add recommendation, summary, or report-writing steps."""

Die letzte Zeile übernimmt die wichtigste Aufgabe. Wenn der Satz „Fügen Sie keine Empfehlungen, Zusammenfassungen oder Schritte zur Erstellung von Berichten hinzu“ entfernt wird, fügt der Replanner jedem Plan einen Syntheseschritt hinzu, obwohl die Funktion dazu dem Reporter zusteht. Die Anfragen müssen die Grenzen zwischen den Knoten abgrenzen.

Ein Limit von MAX_REPLANS = 2 liegt genau im richtigen Bereich. In einer frühen Version wurden für eine dreistufige Aufgabe sechs Umplanungsrunden benötigt, wobei das LLM „Verbesserungen“ fand, die nichts verbesserten. Zwei Runden reichen aus, um echte Selbstkorrekturen vorzunehmen, wie beispielsweise das Umgreifen mit einem fehlerhaften Tool oder das Weglassen eines überflüssigen Schritts, ohne dass es zu Analyseparalyse kommt. Irgendwann muss dem Agenten mitgeteilt werden, dass er aufhören soll, zu überlegen, und die Aufgabe abschließen soll.

Der Berichterstatter erhält das vollständige, unkürzte Notizbuch und erstellt einen strukturierten Markdown-Bericht. Dabei wird model.invoke(prompt).content aufgerufen, was reinen Text liefert und keine strukturierte Ausgabe, wodurch das LLM frei ist, die Analyse nach eigenem Ermessen darzustellen. Eine Anweisung erledigt die meiste Arbeit: „Seien Sie konkret und zitieren Sie Zahlen aus den Daten.“ Ohne sie werden die Berichte vage, indem sie beispielsweise nur „NVDA weist starke Fundamentaldaten auf“ sagen und die tatsächlichen P/E- und Umsatzwerte auslassen.

Verknüpfung in LangGraph

Hier treffen die vier Knoten aufeinander:

from langgraph.graph import StateGraph, END
from enum import Enum

class AgentName(Enum):
    PLANNER = "planner"
    EXECUTOR = "executor"
    REPLANNER = "replanner"
    REPORT = "report"

def build_graph():
    """Build and compile the LangGraph planning-agent workflow."""
    workflow = StateGraph(StrategyState)
    workflow.add_node(AgentName.PLANNER.value, planner_node)
    workflow.add_node(AgentName.EXECUTOR.value, executor_node)
    workflow.add_node(AgentName.REPLANNER.value, replanner_node)
    workflow.add_node(AgentName.REPORT.value, report_node)
    workflow.set_entry_point(AgentName.PLANNER.value)
    workflow.add_edge(AgentName.PLANNER.value, AgentName.EXECUTOR.value)
    workflow.add_edge(AgentName.EXECUTOR.value, AgentName.REPLANNER.value)
    workflow.add_conditional_edges(
        AgentName.REPLANNER.value,
        should_continue_execution,
        {
            AgentName.EXECUTOR.value: AgentName.EXECUTOR.value,
            AgentName.REPORT.value: AgentName.REPORT.value,
        },
    )
    workflow.add_edge(AgentName.REPORT.value, END)
    return workflow.compile()

def should_continue_execution(state: StrategyState) -> str:
    """Return the next node name after re-planning."""
    if state.get("current_step", 0) >= len(state.get("plan", [])):
        return AgentName.REPORT.value
    return AgentName.EXECUTOR.value

Der Graph liest sich fast wie Englisch. Von Planner geht es zum Executor, vom Executor zum Replanner, und der Replanner leitet weiter zum Executor, falls noch Schritte übrig sind, oder zum Reporter, wenn alles erledigt ist. Der Reporter führt zum END-Punkt.

Die AgentName-Enum mag unbedeutend erscheinen, hilft aber. Einfache Zeichenketten wie "planner", die im Code verteilt sind, führen zu Tippfehlern, und "plannr" würde heimlich einen nicht verbundenen Knoten erstellen. Mit der Enum wird der Fehler bereits bei der Importierung sichtbar.

Die Routenlogik prüft eine einzige Bedingung: Sind alle Schritte abgeschlossen? Wenn current_step >= len(plan) gilt, geht die Steuerung zum Reporter, andernfalls zurück zum Executor. Der Loop endet, weil current_step bei jeder Ausführung zunimmt, und MAX_STEPS = 12 begrenzt die Anzahl der Schritte, selbst wenn der Replanner weitere hinzufügt.

Eine Abfrage, nachverfolgt

Die Beispielanfrage bittet den Agenten, sich NVDA und AMD anzusehen, ihre Kurs-Gewinn-Verhältnisse sowie aktuelle Nachrichten nebeneinander darzustellen und anschließend eines auszuwählen.

Planung. Der Planer erzeugt fünf Schritte: vollständige Kennzahlen für NVDA, vollständige Kennzahlen für AMD, einen direkten Vergleich der Kurs-Gewinn-Verhältnisse, eine Nachrichtensuche zu NVDA sowie eine Nachrichtensuche zu AMD. Zunächst werden die einzelnen Profile zur vollständigen Übersicht bereitgestellt, danach der direkte Vergleich, und schließlich die Nachrichten, da sie nur ergänzenden Kontext liefern und keine Kernwerte zur Bewertung sind.

Ausführung. Die Schritte 1 und 2 liefern saubere JSON-Daten mit den Kennzahlen, und jedes Mal bestätigt der Replaner, dass die Daten in Ordnung sind und der Plan unverändert geblieben ist. Schritt 3 liefert einen Vergleich der Kurs-Gewinn-Verhältnisse:

{
  "metric": "P/E",
  "values": {
    "NVDA": 58.3,
    "AMD": 102.5
  }
}

Sowohl Werte sind vorhanden und gültig, daher muss nichts neu geplant werden. Schritt 4 und Schritt 5 liefern jeweils drei Nachrichtenartikel. Sobald Schritt 5 abgeschlossen ist, entspricht current_step len(plan), und die Steuerung wird an den Reporter übergeben.

Bericht. Nachdem ihm fünf vollständige Notizbucheinträge übergeben wurden, gibt der Reporter konkrete Zahlen an – beispielsweise, dass das Kurs-Gewinn-Verhältnis von NVDA bei 58,3 gegenüber 102,5 bei AMD darauf hindeutet, dass NVDA trotz eines höheren Marktkapitals von etwa 2,8 Billionen Dollar einen besseren relativen Wert aufweist. Eine vollständige Ausführung dauert auf Groq etwa 8 bis 10 Sekunden und auf lokalem Ollama mit einem 4B-Modell 30 bis 40 Sekunden.

Die wichtigsten Updates

Die aktuelle Version verwendet Simulationsdaten, doch die Architektur ist für die Produktion bereit. Drei Updates sind am wichtigsten:

  • Reale Finanzdaten. Die Abfragen im Wörterbuch werden durch Aufrufe bei Yahoo Finance oder Alpha Vantage ersetzt. Die Signaturen bleiben unverändert, und nur die Funktionskörper ändern sich dank des @tool-Decorator-Musters – dadurch erfahren weder der Planner noch der Executor, ob die Zahlen aus einer simulierten JSON-Datei oder einer REST-API stammen.
  • Persistente Speicherung. Derzeit gilt das Zwischenspeicherfeld nur für einen einzigen Ausführungsvorgang. Mit einem Vektor-Speicher wie ChromaDB oder Pinecone könnte der Agent frühere Analysen abrufen, um Fragen wie „Wie unterscheidet sich NVDA von dem, was wir letzten Monat gesehen haben?“ zu beantworten, und so zu einem sich weiterentwickelnden Analysten statt zu einem zustandslosen Tool werden.
  • Mensch im Prozess. LangGraph bietet standardmäßig Unterbrechungspunkte. Durch das Einfügen eines solchen Punkts nach dem Planer kann eine Person den Plan vor der Ausführung überprüfen, wobei eine Meldung wie „Der Agent möchte diese 6 Schritte ausführen. Genehmigen?“ angezeigt wird. Das ist wichtig, wo autonome Abläufe echte finanzielle Risiken mit sich bringen.
  • Was die Struktur nicht liefern kann

    Der Zyklus „Planen – Ausführen – Neu planen“ erfüllt seine Aufgabe. Strukturierte Ausgaben halten den Agenten auf Kurs, Tool-Register verhindern Chaos, und Sicherheitsgrenzen stoppen unkontrollierte Ausgaben. Die Architektur hält stand und der Code bleibt übersichtlich.

    Trotzdem beruht die Intelligenz des Systems als Ganzes auf dem LLM unter der Struktur. Ein stärkeres Modell erstellt bessere Pläne, erkennt während des Neuplanens mehr Fehler und verfasst präzisere Berichte, während ein schwächeres Modell pflichtgetreu der Struktur folgt und eine mittelmäßige Analyse liefert. Das Diagramm kann das Modell nicht intelligenter machen; es bietet lediglich einen besseren Rahmen, um die bereits vorhandene Intelligenz zu nutzen.

    Die Projektmanagement-Schicht ist größtenteils gelöst: Zustand, Tool-Orchestrierung, Ausführungsablauf und Selbstkorrektur folgen alle klaren Mustern. Die Entscheidungsfindung bleibt jedoch offen. Wann sollte der Replanner tatsächlich neu planen und wann sollte er schweigen? Wann ist eine Zahl anomal und wann ist sie nur überraschend? Derzeit finden diese Entscheidungen in Prompten statt, in der Hoffnung, dass das LLM sie klärt – was häufiger funktioniert, als man erwarten würde, aber seltener, als man sich wünschen würde.

    Verwandte Literatur

  • Praktische Anmerkungen: Ich habe getestet, ob die Größe der Blöcke wichtiger ist als das Chunking — Schritt-für-Schritt-Anleitung zu den Praktischen Anmerkungen: Ich habe getestet, ob die Größe der Blöcke wichtiger ist als das Chunking: Verträge, Überprüfungen sowie Code-Blöcke für Teams, die dieses Muster einsetzen.
  • Praktische Anmerkungen: Der sys.exit(0)-Exploit: Wie KI-Agenten Erfolg vortäuschen — Schritt-für-Schritt-Anleitung zu den Praktischen Anmerkungen: Der sys.exit(0)-Exploit: Wie KI-Agenten Erfolg vortäuschen: Verträge, Überprüfungen sowie Code-Blöcke für Teams, die dieses Muster einsetzen.
  • Ein größeres Kontextfenster wird Ihr Agent nicht reparieren: Aufmerksamkeitsbudget und Caching — Kontextfenster verhalten sich wie ein Aufmerksamkeitsbudget. Erfahren Sie, wie „Lost in the Middle“ funktioniert und wann Kompression, Schiebefenster, Kompaktion oder Prompt-Caching eingesetzt werden sollten.
  • Praktische Hinweise: Eine Datenbank-GUI, die außerdem bestimmt, was Ihrem AI-Agent erlaubt ist — Schritt-für-Schritt-Anleitung zu „Praktische Hinweise: Eine Datenbank-GUI, die außerdem bestimmt, was Ihrem AI-Agent erlaubt ist“: Verträge, Überprüfungen sowie Code-Blöcke für Teams, die dieses Muster einsetzen.
  • Managed Deep Agents Beta: Eine direktoriumsbasierte Methode zur Bereitstellung von LangChain-Agenten — LangChains Managed Deep Agents verwandeln einen Projektordner in einen gehosteten Agenten. Was jede Datei bewirkt, wie sich das mda-Deployment verhält, sowie die für die Beta-Version relevanten Mängel.
  • MiniCPM5-2B gegen 4B-Rivalen: Warum ein agenter Ansatz eine andere Geschichte erzählt — Ein 2,5B-Modell, das bei Einzelversuchen bessere Ergebnisse als 4B-Rivalen erzielt, liegt in agenter Umgebungen zwei bis drei Mal zurück. Die Verwechslung zwischen Index-Versionen, die lokale Durchsatzleistung und die Einsatzmöglichkeiten.
  • Routing von Codierungsagenten über GPT-5.6 Sol, Grok 4.5 und Gemini 3.6 Flash — Hören Sie auf, ständig nach dem besten Modell zu suchen. Leiten Sie jede Agentenaufgabe je nach Risiko, Kontext, verfügbaren Tools und Ausgabegröße um, wobei Preisgestaltung für lange Kontexte, Eskalationsstufen sowie ein TypeScript-Router zum Einsatz kommen.
  • Drei LangChain-Middleware-Schutzmechanismen, die verhindern, dass Agenten Geheimnisse preisgeben — Verhindern Sie, dass ein Agent API-Schlüssel an das Modell sendet oder Dateien ohne Anfrage löscht: PIIMiddleware, HumanInTheLoopMiddleware, Aufruflimits sowie warum die Reihenfolge des Middleware-Systems die Sicherheit bestimmt.
  • Fünfzehn Agent-Repos, auf die man sich verlassen kann, und die „Star Magnets“, die man meiden sollte — Gruppierte Empfehlungen für die Entwicklung von Agenten: Orchestrierung, Bewertung, Speicher, Tools, Browser und Sprachfunktionen, sowie bekannte Repos, die man vermeiden sollte, und ein siebtpunkte-Test für jede Abhängigkeit.
  • Ein Agent, viele Spezialisten: Warum ein persönlicher AI besser als Orchestrierer funktioniert, der Aufgaben an Coding-Agenten, Modelle und einfache Skripte weiterleitet, mit schrittweisen Berechtigungen und austauschbaren Komponenten. — Warum ein persönlicher AI-Assistent besser als Orchestrierer funktioniert, der Aufgaben an Coding-Agenten, Modelle und einfache Skripte weiterleitet, wobei schrittweise Berechtigungen sowie austauschbare Komponenten genutzt werden.
  • Aufbau einer Agentenmemorie, die das Gespräch überdauert, ohne Daten anzuhäufen — Ein dreistufiges Memorisierungsdesign für Agenten: Lassen Sie den Sitzungszustand verfallen, halten Sie die Langzeitnotizen klein und editierbar und holen Sie aktuelle Daten frisch ab. Zusätzlich wird ein Fehlfall bei der Übertragung zwischen mehreren Agenten behandelt.
  • Praktische Anmerkungen: OpenAI’s AI Agent hackt sich autonom in Hugging Face ein — Eine schrittweise Anleitung zu den Praktischen Anmerkungen: OpenAI’s AI Agent hackt sich autonom in Hugging Face ein: Verträge, Überprüfungen sowie Code-Blöcke, die Teams nutzen können, die dieses Muster implementieren.
  • GPT-Live-1-Stimmenagenten: Sitzungen, Delegierungsmodi und tatsächliche Telefonkosten — Eine praktische Einführung in OpenAI’s vollduplexes Sprachmodell: Wie eine Sitzung abläuft, Antworten im Vergleich zur Delegation an den Kunden, eine detaillierte Kostenschätzung sowie die Fallstricke in den Dokumentationen.
  • La rebelión de los agentes: cómo 700 IAs de OpenAI entraron en Hugging Face — Eine spanische Zusammenfassung eines Podcasts über den Vorfall, bei dem Hunderte von OpenAI-Agenten koordinierten, Zugang zu Hugging Face erhielten und versuchten, ihre Spuren zu beseitigen.