Startseite / Artikel / Praktische Hinweise: Mehr-Agenten-Orchestrierung: Aufbau und Beobachtung von Mehr-Agentensystemen

Praktische Hinweise: Mehr-Agenten-Orchestrierung: Aufbau und Beobachtung von Mehr-Agentensystemen

Schritt-für-Schritt-Anleitung zu den Praktischen Hinweisen: Multi-Agent-Orchestrierung – Erstellung und Beobachtung von Multi-Agenten: Verträge, Überprüfungen sowie Code-Blöcke für Teams, die dieses Muster einsetzen.

1624 Wörter

Dieser Leitfaden zeigt Schritt für Schritt den Weg von Rohstoffen bis zu einem funktionsfähigen System für die Multi-Agent-Orchestrierung: Aufbau und Beobachtung von Multi-Agent-Systemen mit LangGraph und LangSmith. Der Schwerpunkt liegt auf ausführbaren Schritten, expliziten Überprüfungen sowie Code, den man ohne Rückschluss auf die Absicht direkt in ein Repository einfügen kann. In der Übersichtsphase sollten Eingaben, Verantwortliche für die Schritte sowie Abbruchkriterien definiert werden, bevor Code geändert wird. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Halten Sie Konfigurationen außerhalb des Anwendungscode. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gesammelt sein, den die Operator überprüfen können, ohne den gesamten Graphen durchlesen zu müssen.

Einführung: Was ist LangSmith Agent Orchestration?

Beim Bearbeiten des Abschnitts „Was ist die LangSmith-Phase?“ im Einführungsteil sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsindikatoren sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Dokumentieren Sie sowohl den erfolgreichen Ablauf als auch den Notfallweg gemeinsam. Wiederholte Versuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Legen Sie nach kostspieligen Schritten einen Kontrollpunkt an – das Resume sollte keine doppelten Gebühren für denselben LLM-Aufruf erheben, wenn ein Operator einen späteren Knoten erneut versucht.

Die Architektur: Wie Orchestrierung in LangGraph funktioniert

Beim Arbeiten an der Phase „The Architecture How Orchestration“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Ziehen Sie kleine, testbare Einheiten vor großen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Ablaufschema. Legen Sie nach teuren Schritten Checkpoints an. Das Resume sollte bei einem Neversuch eines späteren Knotens nicht denselben LLM-Aufruf erneut berechnen.

Wie die Orchestrierung eingerichtet wird:

Beim Bearbeiten der Phase „Wie funktioniert die Orchestrierung“ sollte man zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgsprüfungen und lehnen Sie stille, teilweise abgeschlossene Abläufe ab. Führen Sie Kontrollpunkte nach aufwändigen Schritten ein. Das Wiederaufnehmen des Vorgangs sollte keine erneute Abrechnung für denselben LLM-Aufruf veranlassen, wenn ein Operator einen späteren Knoten erneut ausführt. Beim Bearbeiten der Phase „Wie funktioniert die Orchestrierung“ sollte man zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgssignal sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gespeichert werden, den Operator ohne das Lesen des gesamten Graphen überprüfen können.

Schritt-für-Schritt Beispiel zur Wiederholung

Die Phase „Schritt-für-Schritt reproduzierbares Beispiel“ funktioniert am besten, wenn sie als messbare Struktur betrachtet wird. Erfassen Sie einen erfolgreichen Ablauf, einen Fehlerfall sowie die Notizen zur Rücksetzung, bevor Sie den Umfang erweitern. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf und den Wiederherstellungsprozess. Wiederholversuche, menschliche Überprüfungen sowie die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Halten Sie den Zustand der Graphen strukturiert und typisiert – verschachtelte Datenstrukturen verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen des Ablaufs.

Voraussetzungen

Die Voraussetzungsphase funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie ein gelungenes Beispiel, einen Fehlerfall sowie eine Notiz zur Rücksetzung, bevor Sie den Umfang erweitern. Ziehen Sie kleine, testbare Einheiten vor großen Skripten vor. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf einen verworrenen Ablauf. Halten Sie den Zustand der Graphen einfach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Störungen beim Wiederaufnehmen nach Unterbrechungen.

Schritt 1: Einrichtung der Umgebung

Die Phase „Schritt 1: Umgebungs einrichten“ funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Betrachten Sie diese Phase als Vertrag zwischen Eingaben und validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Halten Sie den Zustand des Graphen flach und typisiert. Verschachtelte Datenblöcke verbergen, welcher Knoten welches Feld geschrieben hat, und führen zu Unterbrechungen beim Fortsetzen der Verarbeitung. Die Phase „Schritt 1: Umgebungs einrichten“ funktioniert am besten, wenn sie als messbarer Bereich betrachtet wird. Erfassen Sie vor der Erweiterung des Umfangs ein „goldenes Transkript“, einen Fehlerfall sowie eine Notiz zur Rücksetzung. Halten Sie die Konfiguration außerhalb des Anwendungscode. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gespeichert sein, den Betreuer ohne Lesen des gesamten Graphen überprüfen können.

uv add langgraph langchain-anthropic langsmith python-dotenv

Schritt 2: Der Python-Code

Zur Python-Phase in Schritt 2 sollten Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien definieren, bevor Sie Code ändern. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Dokumentieren Sie gemeinsam den erfolgreichen Ablauf sowie den Notfallweg. Wiederholungsversuche, menschliche Überprüfungen und die Handhabung von Fehlern gehören zum Produkt selbst und nicht zu späteren Optimierungen. Trennen Sie den Aufbau des Clients von der Nachrichtenschleife, damit Provider ausgetauscht werden können, ohne die Zustandsmaschine der Konversation umschreiben zu müssen.

import os
from typing import TypedDict, Literal
from dotenv import load_dotenv
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage, SystemMessage
from langgraph.graph import StateGraph, END

# ==========================================
# 0. Load Environment Variables
# ==========================================
# This loads the API keys and LangSmith configs from the .env file
load_dotenv()

# ==========================================
# 1. Define the Shared State
# ==========================================
class AgentState(TypedDict):
    messages: list
    next_agent: str

# ==========================================
# 2. Define the Nodes (The Agents)
# ==========================================
# Initialize Claude 3.5 Sonnet
llm = ChatAnthropic(model="claude-sonnet-4-5-20250929", temperature=0)

def router_node(state: AgentState):
    """Acts as the router. Classifies the user query and directs it to the correct department."""
    system_prompt = SystemMessage(content=(
        "You are a router agent. Look at the user's message and classify it as either "
        "'billing' or 'technical'. Reply with ONLY the word 'billing' or 'technical'."
    ))
    response = llm.invoke([system_prompt] + state["messages"])
    classification = response.content.strip().lower()

    # Update state with the routing decision
    return {"next_agent": classification, "messages": [response]}

def billing_node(state: AgentState):
    """Handles billing-related queries."""
    system_prompt = SystemMessage(content=(
        "You are a billing support agent. Help the user with invoices, refunds, and payments. "
        "Be polite and professional."
    ))
    response = llm.invoke([system_prompt] + state["messages"])
    return {"messages": [response]}

def tech_support_node(state: AgentState):
    """Handles technical issues."""
    system_prompt = SystemMessage(content=(
        "You are a technical support agent. Help the user troubleshoot bugs, login issues, "
        "and software errors. Be analytical and helpful."
    ))
    response = llm.invoke([system_prompt] + state["messages"])
    return {"messages": [response]}

# ==========================================
# 3. Define the Routing Logic
# ==========================================
def route_decision(state: AgentState) -> Literal["billing", "technical"]:
    """Reads the state to decide which node to visit next."""
    next_agent = state.get("next_agent", "technical")
    # Claude is highly instruction-following, but we use 'in' to safely handle
    # any edge cases where it might add conversational filler.
    if "billing" in next_agent:
        return "billing"
    return "technical"

# ==========================================
# 4. Build and Compile the Graph
# ==========================================
workflow = StateGraph(AgentState)

# Add nodes
workflow.add_node("router", router_node)
workflow.add_node("billing", billing_node)
workflow.add_node("technical", tech_support_node)

# Define edges
workflow.set_entry_point("router")
# The magic of orchestration: Conditional routing based on state
workflow.add_conditional_edges(
    "router",
    route_decision,
    {
        "billing": "billing",
        "technical": "technical",
    }
)

# Both specialized agents end the workflow
workflow.add_edge("billing", END)
workflow.add_edge("technical", END)

# Compile the graph
app = workflow.compile()

# ==========================================
# 5. Run the Orchestration
# ==========================================
if __name__ == "__main__":
    # Test Case 1: Billing Query
    print("--- Running Billing Test ---")
    inputs = {"messages": [HumanMessage(content="I was charged twice for my subscription!")]}
    result = app.invoke(inputs)
    print(result["messages"][-1].content)
    print("\n")

    # Test Case 2: Tech Support Query
    print("--- Running Tech Support Test ---")
    inputs = {"messages": [HumanMessage(content="My app keeps crashing when I click the save button.")]}
    result = app.invoke(inputs)
    print(result["messages"][-1].content)

Schritt 3: Das Skript ausführen, um zu testen

Zur Ausführung des Schritts 3 sollten Sie die Eingaben, den Verantwortlichen für den Schritt sowie die Abbruchkriterien definieren, bevor Sie Code ändern. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckten Zuständen schließen zu müssen. Bevorzugen Sie kleine, testbare Einheiten vor umfangreichen Skripten. Wenn ein Schritt fehlschlägt, sollte der Fehler auf eine einzige Verantwortung verweisen und nicht auf ein verworrenes Pipeline-System. Setzen Sie menschliche Freigabe für Schritte ein, die Geld ausgeben oder Produktionsdaten ändern. Kompilierzeitbezogene Verbindungen bedeuten noch nicht vollständige Geschäftsabläufe.

uv run multiagent-orchestration.py

Schritt 4: Die Orchestrierung in LangSmith ansehen

Zur Phase „Schritt 4: Ansicht“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden, bevor Code geändert wird. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Betrachten Sie diese Phase als Vertrag zwischen den Eingaben und den validierten Ausgaben. Benennen Sie die Artefakte, definieren Sie Erfolgskontrollen und lehnen Sie stille, unvollständige Abschlüsse ab. Setzen Sie menschliche Freigabe bei Vorgängen ein, die Geld kosten oder Produktionsdaten ändern. Kompilierzeitbezogene Verbindungen entsprechen nicht der Geschäftsabschlussfähigkeit. Zur Phase „Schritt 4: Ansicht“ sollten die Eingaben, der Verantwortliche für den Schritt sowie die Abbruchkriterien definiert werden, bevor Code geändert wird. Die Operator sollten in der Lage sein, den Schritt von einem bekannten Checkpoint aus erneut auszuführen, ohne auf versteckte Zustände schließen zu müssen. Bewahren Sie die Konfiguration außerhalb des Anwendungscode auf. Umgebungsdateien, Geheimdatenspeicher und Feature-Flags sollten an einem Ort gespeichert werden, den die Operator überprüfen können, ohne den gesamten Ablauf durchzulesen.

Was Sie in LangSmith sehen werden:

Während der Phase „Was Sie sehen werden“ sollten Sie zunächst den Vertrag aufschreiben: erforderliche Eingaben, Erfolgsindikator sowie das Vorgehen bei teilweisen Fehlern. Diese Checkliste sorgt dafür, dass spätere Codeänderungen transparent bleiben. Dokumentieren Sie gleichzeitig den erfolgreichen Ablauf sowie den Notfallweg. Wiederholte Versuche, menschliche Überprüfungen und die Handhabung von Fehlern gehören zum Produkt selbst, nicht zu späteren Optimierungen. Legen Sie nach kostspieligen Schritten einen Checkpoint an. Das System sollte bei erneuten Versuchen eines Operators keine doppelten Abrechnungen für denselben LLM-Aufruf erstellen.

Fazit

Operative Checkliste