Pick between AutoGen, CrewAI, LangGraph supervisor, and OpenAI Swarm for a deep-research multi-agent product. And defend the choice
Same topic, related formats. Practice these next.
Same topic, related formats. Practice these next.
You are building a deep-research multi-agent product where a planner agent decomposes a query, several worker agents fan out to retrieve and analyse, and a synthesizer composes the final report. Pick one of AutoGen GroupChat, CrewAI, LangGraph supervisor, or OpenAI Swarm / Agents SDK as the orchestration layer, and defend the choice against the other three.
LangGraph supervisor. The deep-research shape is a supervisor with conditional routing graph, and only LangGraph offers explicit routing, durable state via the checkpointer, and inspectability together.
Picture coordinating a small research team. AutoGen is a free-form brainstorm in a chat room. Anyone can speak. CrewAI is a relay race where each runner hands the baton to the next in order. Swarm is two friends passing a question back and forth via short notes. LangGraph is a project manager with a wall-sized chart, a save every step planner, and an interruptible workflow. For a planner workers synthesiser product where you need to know who is running, save partial progress, and let a human approve the next step, the project manager wins. The other three are good at different shapes.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example.
Everything important, quickly.
8 min: shape selection, three structural requirements, specific weaknesses of each alternative, Send for parallel fan-out, production posture with retrieval pairing.
from langgraph.graph import StateGraph, END
from langgraph.constants import Send
from langgraph.checkpoint.postgres import PostgresSaver
def plan(state):
return {"subqueries": planner_llm(state["query"])}
def dispatch(state):
# Parallel fan-out: one Send per subquery, each runs the worker node
return [Send("worker", {"subquery": sq}) for sq in state["subqueries"]]
def worker(state):
return {"findings": [analyse(retrieve(state["subquery"]))]}
def synthesise(state):
return {"report": synth_llm(state["findings"])}
g = StateGraph(dict)
g.add_node("plan", plan)
g.add_node("worker", worker)
g.add_node("synth", synthesise)
g.set_entry_point("plan")
g.add_conditional_edges("plan", dispatch, ["worker"])
g.add_edge("worker", "synth")
g.add_edge("synth", END)
app = g.compile(checkpointer=PostgresSaver.from_conn_string(POSTGRES_URL))
| Framework | Routing shape | Persistence | Best fit |
|---|---|---|---|
| LangGraph supervisor | Conditional edges + Send | Postgres checkpointer, time-travel | Planner fanout synthesizer |
| AutoGen GroupChat | Speaker selection (chat-shaped) | Shallow in 0.4 | Free-form analyst chat |
| CrewAI | Role/goal text, Hierarchical Process | Callbacks, no checkpointer | Sequential or hierarchical role pipelines |
| OpenAI Swarm / Agents SDK | Handoff via tool call | None native | Two-agent triage and handoff |
Real products, models, and research that use this idea.
What an interviewer would ask next. Try answering before peeking at the approach.
Red flags and common mistakes that signal junior thinking. Click to expand.
Defaulting to the 'depends on your team' non-answer. The deep-research shape has structural requirements (routing, persistence, inspectability) that select for LangGraph regardless of team taste.
The night-before-the-interview bullets. Scan these on the way to the call.
Primary sources. Skim if you want the original framing.