Problem (aus der Praxis)
Du willst ein Agent-System shippen, das echte Arbeit macht — nicht nur eine Wochenend-Demo.
Im Team sagt jemand: “Multi-Agent mit CrewAI.” Jemand anders: “LangGraph; Graphs sind leichter zu verstehen.”
Beides kann funktionieren. Beides kann in Prod auch gleich aussehen: langsam, teuer, schwer zu debuggen — wenn dir der Control Layer fehlt.
Die Frage ist nicht “welches ist cooler”. Die Frage ist: welches macht Failure Modes sichtbar und governable.
Schnelle Entscheidung (wer sollte was wählen)
- CrewAI: wenn du bewusst Role-basierte Multi-Agent Collaboration willst und Orchestration/Monitoring investieren kannst (Deadlocks/Thrash sind real).
- LangGraph: wenn du expliziten State, Transitions, Tests und Replay willst. In Prod oft die sicherere Default-Wahl.
- Ohne Budgets/Permissions/Monitoring: Graph-first tut meistens weniger weh.
Warum man in Prod die falsche Wahl trifft
1) “Demo wirkt krass” als Auswahlkriterium
Role-play Multi-Agent sieht beeindruckend aus. Es bringt aber:
- Coordination Overhead
- Waiting States
- Zyklen/Deadlocks
- mehr Tool Calls
Ohne Instrumentierung wird das leise teuer.
2) “Graph” wird mit “safe” verwechselt
Ein Graph ist nicht Governance. Er ist ein Ort, Governance hinzulegen.
Budgets/Permissions/Approvals/Validation bleiben Pflicht.
3) State ist nicht definiert
Wenn du nicht sauber beschreiben kannst:
- aktueller State
- erlaubte Transition
- Stop Conditions
…driftet es in “Model entscheidet alles”. Das heißt in der Praxis: Debugging ist Bauchgefühl.
Vergleichstabelle
| Kriterium | CrewAI | LangGraph | Was zählt in Prod | |---|---|---|---| | Abstraktion | Rollen + Kollaboration | State + Transition | Debuggability | | Determinismus | Niedriger | Höher | Replay + Tests | | Failure Handling | Emergent | besser encodebar | Stop Reasons | | Loop/Deadlock Risk | Höher | Mittel | On-call Load | | Best for | Collaboration | Explicit flows | Risiko-Toleranz |
Wo das in Production bricht
CrewAI-style Multi-Agent:
- Agents warten aufeinander (Deadlocks)
- Rollen “streiten” und loopen
- mehr Context → Token Overuse
- Tool Spam (noch mal suchen…)
LangGraph-style:
- State Machine wächst
- devs bauen “Model entscheidet” Nodes überall
- fehlende Validation macht Graphs zu “unsafe pipes”
Implementierungsbeispiel (echter Code)
Prod-Trick: Framework austauschbar halten. Control Layer bleibt.
from dataclasses import dataclass
from typing import Any, Callable
import time
@dataclass(frozen=True)
class Budgets:
max_steps: int = 40
max_tool_calls: int = 20
max_seconds: int = 120
class Stop(RuntimeError):
def __init__(self, reason: str):
super().__init__(reason)
self.reason = reason
class ToolGateway:
def __init__(self, *, allow: set[str], impls: dict[str, Callable[..., Any]]):
self.allow = allow
self.impls = impls
self.calls = 0
def call(self, tool: str, args: dict[str, Any], *, budgets: Budgets) -> Any:
self.calls += 1
if self.calls > budgets.max_tool_calls:
raise Stop("max_tool_calls")
if tool not in self.allow:
raise Stop(f"tool_denied:{tool}")
fn = self.impls.get(tool)
if not fn:
raise Stop(f"tool_missing:{tool}")
return fn(**args)
def run_framework(orchestration_fn, *, budgets: Budgets, tools: ToolGateway) -> dict[str, Any]:
started = time.time()
for step in range(budgets.max_steps):
if time.time() - started > budgets.max_seconds:
return {"status": "stopped", "stop_reason": "max_seconds"}
try:
out = orchestration_fn(step=step, tools=tools) # (pseudo)
if out.get("done"):
return {"status": "ok", "result": out.get("result")}
except Stop as e:
return {"status": "stopped", "stop_reason": e.reason}
return {"status": "stopped", "stop_reason": "max_steps"}export class Stop extends Error {
constructor(reason) {
super(reason);
this.reason = reason;
}
}
export class ToolGateway {
constructor({ allow = [], impls = {} } = {}) {
this.allow = new Set(allow);
this.impls = impls;
this.calls = 0;
}
call(tool, args, { budgets }) {
this.calls += 1;
if (this.calls > budgets.maxToolCalls) throw new Stop("max_tool_calls");
if (!this.allow.has(tool)) throw new Stop("tool_denied:" + tool);
const fn = this.impls[tool];
if (!fn) throw new Stop("tool_missing:" + tool);
return fn(args);
}
}Echter Incident (mit Zahlen)
Multi-Agent Support-Triage, role-based, Demo war super.
In Prod:
- Rolle A “double-checkt” und re-search’t
- Rolle B wartet auf Output von A
Impact:
- tool calls/run: 6 → 24
- p95 latency: 4,1s → 21,6s
- spend: +$530 vs baseline
- On-call: ~2 Stunden um zu checken, dass es Coordination ist, nicht Vendor-Outage
Fix:
- step limits + repeat detection
- dedupe für search calls
- degrade mode bei Search-Instability
Migrationspfad (A → B)
- CrewAI → LangGraph: happy path extrahieren, als States/Transitions codieren, edge cases bounded “agentic” lassen.
- LangGraph → CrewAI: Graph bleibt Orchestrator, einzelne Nodes als Rollen-Agenten.
Entscheidungshilfe
- Explicit state + replay wichtig → LangGraph-style.
- Rollen/Reviewer/Planner Pattern wichtig → CrewAI ok, aber hart budgetieren.
- Frühphase ohne Instrumentierung → eher graph-first.
Abwägungen
- Multi-Agent kann Quality erhöhen, erhöht aber Coordination-Fails.
- Graphs sind wartbarer, aber State Machine wird “echter Code”.
- Control Layer bleibt non-negotiable.
Wann du es NICHT nutzen solltest
- Kein Multi-Agent ohne Timeouts/Stop Reasons.
- Keine Graphs, die “Model entscheidet alles” sind.
- Framework nicht als Ausrede für fehlende Governance nutzen.
Checkliste (Copy/Paste)
- [ ] Governance framework-agnostic halten
- [ ] Stop Reasons + UI
- [ ] Repeat detection + tool dedupe
- [ ] Read-only start; Writes mit Approvals
- [ ] Canary changes; drift messen
- [ ] Golden tasks + replay
Sicheres Default-Config-Snippet (JSON/YAML)
budgets:
max_steps: 40
max_tool_calls: 20
max_seconds: 120
tools:
allow: ["search.read", "kb.read", "http.get"]
writes:
require_approval: true
monitoring:
track: ["tool_calls_per_run", "latency_p95", "stop_reason"]
FAQ (3–5)
Von Patterns genutzt
Verwandte Failures
Verwandte Seiten (3–6 Links)
- Foundations: Planning vs reactive · Tool calling basics
- Failure: Deadlocks · Tool spam
- Governance (EN): Budget controls · Tool permissions
- Production stack: Production stack