Wann man dazu greift
- Teilaufgaben erst zur Laufzeit erkennbar werden.
- Worker hochspezialisierte Funktionen übernehmen.
- Aggregation zentral kontrolliert bleiben muss.
/pattern/orchestrator-workers/
Ein Orchestrator zerlegt eine Aufgabe dynamisch und weist Teilaufgaben spezialisierten Workern zu, die Aggregation bleibt zentral gesteuert.
Wann man dazu greift
Wann es nach hinten losgeht
Die Abwägung
Hochflexible Delegation wird gegen erheblichen Koordinations- und Integrationsaufwand erkauft.
Ein Orchestrator zerlegt den Auftrag, dispatcht parallel an Worker, dann führt er die Ergebnisse zusammen.
from langgraph.graph import StateGraph, END
from langgraph.constants import Send
class State(TypedDict):
task: str
subtasks: list[str]
results: dict[str, str]
answer: str | None
def decompose(state):
return {"subtasks": planner_llm(state["task"])}
def worker(state):
# Each invocation receives one subtask
return {"results": {state["subtask"]: research_llm(state["subtask"])}}
def fold(state):
return {"answer": synthesizer_llm(state["results"])}
g = StateGraph(State)
g.add_node("decompose", decompose)
g.add_node("worker", worker)
g.add_node("fold", fold)
# Fan-out: one Send per subtask
g.add_conditional_edges("decompose", lambda s: [Send("worker", {"subtask": t}) for t in s["subtasks"]])
g.add_edge("worker", "fold")
g.add_edge("fold", END)
g.set_entry_point("decompose")
orchestrator = g.compile()Der Orchestrator teilt die Aufgabe in 20 Mikro-Aufgaben auf. Der Overhead von Dispatch und Zusammenführen dominiert die eigentliche Arbeit.
Lösung · Eine Mindestchunkgröße festlegen; Teilaufgaben zusammenführen, die ein Kontextfenster oder einen Tool-Aufruf teilen.
Zwei Worker liefern widersprüchliche Daten. Der Zusammenführungsschritt mittelt oder wählt zufällig aus, ohne den Konflikt sichtbar zu machen.
Lösung · Den Zusammenführungsschritt dazu zwingen, Konfidenzwerte pro Quelle auszugeben, oder einen expliziten Konsistenzprüfknoten vor der finalen Antwort hinzufügen.
Patterns, Frameworks und Seiten durchsuchen.