TAI BUI
Back to curriculum
LearnPython

Agent Framework Tradeoffs — LangGraph vs CrewAI vs AutoGen vs Agno

Most framework demos show the same thing (a research agent builds a report) and hide the same bug: the state schema fights the orchestration layer. Pick the framework whose abstractions match the shape of your problem. Anything else is glue you write twice.

TIME: ~45 minutesPREREQUISITES: Phase 11 · 09 (Function Calling), Phase 11 · 16 (LangGraph)

Learning Objectives

  • Match LangGraph, CrewAI, AutoGen, and Agno to the problem shape each core abstraction fits.
  • Compare the four frameworks on state, branching, observability, cost, and interoperability.
  • Decide when plain Python beats any framework, using the pre-build checklist.
  • Run the decision-tree script in main.py and explain why resume, interrupt, and fanout route to LangGraph first.

The Problem

You have a task that needs more than one LLM call. Maybe it is a research workflow (plan, search, summarize, cite). Maybe it is a code-review pipeline (parse diff, critique, patch, validate). Maybe it is a multi-turn assistant that books flights, writes emails, and files expense reports. You pick a framework.

Three days later, you discover the framework's abstractions leak. CrewAI gives you roles but fights you when the "researcher" needs to hand a structured plan to the "writer." AutoGen gives you chat between agents but has no first-class state so your checkpoint is a pickle of a conversation log. LangGraph gives you a state graph but forces you to name every transition before you know what the agent will do. Agno gives you a single-agent abstraction that screams when you try to fan out to three concurrent workers.

The fix is not "pick the best framework." It is to match the framework's core abstraction to the shape of your problem. The sections below draw that map.

Warm-up0/3
1. In function calling (Phase 11 · 09), who actually runs the tool after the model asks for it?Warm-up
A model output containing a structured call to get_weather for Oslo, followed by a dashed box for running the function whose runner is marked with a question mark, and then the next message.
Typed schematic, illustrative. Function name and argument are made up.
2. In LangGraph (Phase 11 · 16), what does attaching a checkpointer to a compiled graph give you?Warm-up
A three-node graph plan, search, write. One dashed arrow with a question mark runs from the graph to a box labelled checkpointer.
Typed schematic, illustrative.
3. Why does each extra LLM call in a multi-step pipeline add cost?Warm-up
Two pipelines, one with a single LLM call and one with three chained LLM calls, and two dashed boxes with question marks for cost and wait.
Typed schematic, illustrative.
Check: The Problem0/3
1. Why does CrewAI struggle when a researcher must hand a structured plan to a writer?Explain
A researcher task whose output is a structured plan with steps and sources, an arrow labelled context to a writer task, and a dashed box asking what the writer receives.
Typed schematic, illustrative. Plan fields are made up.
2. Why does the lesson say to match a framework's core abstraction to the problem shape instead of picking the best framework?Explain
A problem shape box about a researcher handing a structured plan to a writer, a CrewAI abstraction box, and a dashed box between them marked with a question mark.
Typed schematic, illustrative.
3. An Agno agent works well alone but becomes awkward when you fan out to three concurrent workers. Which idea from the lesson explains this?Analyze
A single Agno agent that works well, then an agent fanning out to three concurrent worker boxes along dashed arrows with a question mark, and a dashed box asking why it is awkward.
Typed schematic, illustrative.

The Concept

Agent framework matrix: core abstraction vs problem shape

Four frameworks dominate the 2026 landscape. Their core abstractions are not the same.

FrameworkCore abstractionBest fitWorst fit
LangGraphStateGraph: typed state, nodes, conditional edges, checkpointer.Workflows with explicit state and human-in-the-loop interrupts; production agents needing time-travel debugging.Loose, role-driven brainstorming where the topology is unknown.
CrewAICrew: roles (goal, backstory), tasks, process (sequential or hierarchical).Role-playing or persona-driven workflows with a short linear/hierarchical plan.Anything stateful beyond the crew's turn history; complex branching.
AutoGenConversableAgent pair: two or more agents that speak in turns until an exit condition.Multi-agent dialogue (teacher-student, proposer-critic, actor-reviewer) where the thinking emerges from the chat.Deterministic workflows with a known DAG; anything needing durable state across restarts.
AgnoAgent: a single LLM + tools + memory, composable into teams.Fast-to-build single agents and lightweight teams; strong multi-modality and built-in storage drivers.Deep, explicitly-branched graphs with custom reducers.

What "abstraction" actually means

A framework's core abstraction is the thing you draw on the whiteboard when you pitch the architecture.

  • LangGraph → you draw a graph. Nodes are steps, edges are transitions, and the state object at every point is typed. The mental model is a state machine.
  • CrewAI → you draw an org chart. Each role has a job description and a manager routes tasks. The mental model is a small team of specialists.
  • AutoGen → you draw a Slack DM. Two agents message each other; a third joins if you need a moderator. The mental model is chat.
  • Agno → you draw a single box with tools hanging off it. Put boxes next to each other for a team. The mental model is "agent with batteries included."

The state question

State is where most framework choices break down in production.

  • LangGraph. Typed state (TypedDict or Pydantic model), per-field reducers, first-class checkpointer (SQLite/Postgres/Redis). Resume, interrupt, and time-travel come built in. (See Phase 11 · 16.)
  • CrewAI. State flows as strings between tasks via the context field, or structured through output_pydantic. No durable per-crew store out of the box; you bolt on your own if the crew must survive a restart.
  • AutoGen. State is the chat history and any user-defined context. Conversation transcripts persist; arbitrary workflow state does not unless you write adapters.
  • Agno. Built-in storage drivers (SQLite, Postgres, Mongo, Redis, DynamoDB) attached to an Agent via storage=, so conversation sessions and user memories persist automatically. Not a full graph checkpointer; a session store.

The branching question

Most non-trivial agents branch. Who decides the branch matters.

  • LangGraph: you decide, via conditional edges. Routing is a Python function with named branches. Branches are first-class in the compiled graph; the checkpointer records which branch was taken.
  • CrewAI: the manager decides in hierarchical mode; in sequential mode you decide at build time. Routing is implicit in the task list; there is no first-class "if" outside the manager's prompt.
  • AutoGen: the agents decide via chat. Branching is emergent from who speaks next. GroupChatManager selects the next speaker; you can hand-write a speaker_selection_method but the default is LLM-driven.
  • Agno: the agent decides by which tool to call next. Teams have a coordinator/router/collaborator mode; branching beyond that is the developer's responsibility.

The observability question

  • LangGraph: OpenTelemetry via LangSmith or any OTel exporter. Every node transition is a trace span; checkpoints double as replayable traces. LangSmith is the first-party option; Langfuse/Phoenix also have adapters.
  • CrewAI: first-class OpenTelemetry since late-2025; integrations with Langfuse, Phoenix, Opik, AgentOps.
  • AutoGen: OpenTelemetry integration via autogen-core; AgentOps and Opik have connectors. Tracing granularity is per-agent-message, not per-node.
  • Agno: built-in monitoring=True flag plus OpenTelemetry exporters; tight integration with Langfuse for session traces.

Cost and latency

Expect some per-call overhead from any of the four (framework logic, validation, serialization). Rough order of increasing overhead: Agno ≈ LangGraph < CrewAI ≈ AutoGen. The difference is dominated by how much extra LLM routing the framework does. CrewAI's hierarchical manager spends tokens deciding who goes next; AutoGen's GroupChatManager likewise. LangGraph only spends tokens where you write llm.invoke. Agno's single-agent path is thin.

When cost per run matters, prefer explicit routing (LangGraph edges, AutoGen speaker_selection_method) over LLM-selected routing.

Interoperability

  • LangGraph ↔ LangChain tools, retrievers, LLMs. First-class MCP adapter (tools imported as MCP servers).
  • CrewAI ↔ tools inherit from BaseTool; LangChain tools, LlamaIndex tools, and MCP tools all adapt in. Crew-to-crew delegation via allow_delegation=True.
  • AutoGen → FunctionTool wraps any Python callable; MCP adapter available. Tight coupling to AG2 ecosystem for agent-to-agent patterns.
  • Agno → @tool decorator or BaseTool subclass; MCP adapter; tools can be shared across agents and teams.
Check: The Concept0/19
1. What is a Crew in CrewAI?Define
Three role boxes, researcher, writer and editor, in a row with arrows, inside a dashed outline labelled Crew equals question mark.
Typed schematic, illustrative. Role names come from Exercise 1.
2. How does AutoGen wrap an arbitrary Python callable as a tool?Define
A short Python function named search on the left, an arrow marked with a question mark, and an AutoGen agent box listing search as a tool.
Typed schematic, illustrative. Function name is made up.
3. Which framework attaches built-in storage drivers (SQLite, Postgres, Mongo, Redis, DynamoDB) directly to its Agent via storage= for session and memory persistence?Define
An agent box connected by a storage equals arrow to a box listing five storage drivers, and a dashed box asking which framework this is.
Typed schematic, illustrative.
4. In agent frameworks, what does the orchestration layer do?Define
A wide box labelled orchestration layer above three agent boxes, researcher, writer and editor, joined by dashed arrows marked with question marks.
Typed schematic, illustrative. Agent names come from the lesson's exercises.
5. What makes state "durable" in an agent framework?Define
Process 1 finishes three steps and is killed. Process 2 starts and needs the step 3 state, which is shown in a dashed box marked durable question mark.
Typed schematic, illustrative.
6. What is LLM-selected routing?Define
A three-line log: turn 1 next step search, turn 2 next step write, turn 3 next step finish, beside a dashed box asking what chooses the next step.
Typed schematic, illustrative. Step names are made up.
7. What is explicit routing?Define
A check node leading to a dashed box labelled next step picked by question mark, which has two branches, write and search.
Typed schematic, illustrative. Node names are made up.
8. What is a GroupChat in AutoGen?Define
Three agent boxes, researcher, writer and editor, exchanging arrows inside a dashed outline labelled GroupChat equals question mark.
Typed schematic, illustrative. Agent names come from Exercise 2.
9. What is a Team in Agno?Define
Two Agno agent boxes, a researcher with search tools and a writer with write tools, inside a dashed outline labelled Team equals question mark.
Typed schematic, illustrative. Agent names are made up.
10. What is a LangGraph StateGraph?Define
Four nodes plan, search, write and cite in a row joined by arrows, inside a dashed outline labelled StateGraph equals question mark.
Typed schematic, illustrative. Node names come from Exercise 1.
11. Why does LLM-selected routing cost more tokens per turn than explicit routing?Explain
Two stacked bars for one turn. The explicit routing bar has only a step work block. The LLM-selected routing bar has the same step work block plus a dashed block marked with a question mark.
Typed schematic, illustrative. Not to scale.
12. How does tracing granularity differ between LangGraph and AutoGen?Explain
Left, a LangGraph run through plan, search and write nodes. Right, an AutoGen chat with messages from researcher, writer and editor. Under each is a trace spans row whose span unit is a question mark.
Typed schematic, illustrative. Names are made up.
13. In AutoGen's default configuration, who decides the next branch?Explain
Researcher, writer and editor agent boxes. Dashed arrows with a question mark lead from the researcher's message to the other two, and a dashed box asks who decides the next speaker.
Typed schematic, illustrative.
14. How does Agno's persistence differ from LangGraph's?Explain
An Agno Agent with storage attached and a LangGraph graph with a checkpointer attached, each with an arrow down to a dashed box asking what is kept.
Typed schematic, illustrative.
15. Why does an agent that runs thousands of times a day favour explicit routing?Explain
Three runs of three steps each with a question mark on each routing decision between steps, a line saying thousands of runs per day, and a dashed box asking about extra tokens per run.
Typed schematic, illustrative.
16. Why do CrewAI and AutoGen carry more overhead than LangGraph in the lesson's rough cost ranking?Explain
An axis from lower to higher overhead. Agno and LangGraph sit at the low end and CrewAI and AutoGen at the high end, with a dashed box asking why the right pair is higher.
Ordinal order from the lesson, not measured values.
17. A CrewAI crew loses all progress after a redeploy and starts from scratch. Which fact about CrewAI explains this?Analyze
Tasks 1 and 2 done and task 3 running, then a redeploy, then a crew that starts again at task 1. A dashed box asks where the earlier progress was kept.
Typed schematic, illustrative.
18. After a crash, an AutoGen workflow restores its transcript but has lost which stage of the pipeline it had reached. Why?Analyze
Two panels. Before the crash, three transcript messages and stage reached editor. After the restart, the same three messages and stage reached question mark.
Typed schematic, illustrative. Message and stage names are made up.
19. A hierarchical CrewAI crew costs far more per run than expected, although each tool call is cheap. Which cause is most likely?Analyze
Three turns of a hierarchical crew. Each has a small tool block and a much larger dashed block marked with a question mark.
Typed schematic, illustrative. Not to scale.

The Skill

You can explain, in one sentence, why a given framework is right for a given agent problem.

Pre-build checklist:

  1. Draw the shape. Is this a graph (typed state, named transitions)? A role play (specialists hand off work)? A chat (agents talk until done)? A single agent with tools?
  2. Decide who branches. Developer-decided branching → LangGraph. Manager-agent-decided → CrewAI hierarchical. Chat-emergent → AutoGen. Tool-call-decided → Agno.
  3. Check the state budget. Do you need resume-from-checkpoint? Time-travel? Human interrupts mid-run? If yes, LangGraph is the default; Agno sessions cover conversation-scoped state.
  4. Check the cost budget. LLM-selected routing costs extra tokens per turn. If the agent runs thousands of times a day, prefer explicit routing.
  5. Budget the framework overhead. Every framework is another dependency. If the task is two LLM calls and a tool, write 30 lines of plain Python; no framework is cheaper than no framework.

Don't reach for a framework before you can draw the graph, the org chart, the chat, or the agent box. And don't pick one that makes you fight its state model for the thing you actually need.

Check: The Skill0/5
1. Per step 2 of the pre-build checklist, branching decided by a manager agent maps to which framework and mode?Explain
A manager agent box with arrows to two specialist boxes, and a dashed box asking for the framework and mode.
Typed schematic, illustrative.
2. A problem has two LLM calls and none of the roles, dialogue, resume, fanout, or interrupt flags. What does the decision tree in main.py return?Apply
A problem record with 2 LLM calls and the roles, dialogue, resume, fanout and interrupt flags all no, feeding recommend, whose return value is a question mark.
Typed schematic, illustrative. Field names are paraphrased from the stem.
3. A problem sets both the dialogue flag and the resume flag. Which framework does main.py return?Apply
A problem record with dialogue yes and resume yes feeding recommend, whose return value is a question mark.
Typed schematic, illustrative. Field names are paraphrased from the stem.
4. You have a two-call summarizer: fetch text, then summarize. Which choice fits best?Design
Two steps in a row, call 1 fetch text and call 2 summarize, and a dashed box asking what should wrap them.
Typed schematic, illustrative.
5. A proposer-critic review loop must also pause for human sign-off and resume after a restart. Which design fits the lesson's ordering?Design
A proposer and critic loop leading to a human sign-off pause, a restart marker below, and a dashed box asking for the design.
Typed schematic, illustrative.

The Decision Matrix

Problem shapePreferred frameworkWhy
Workflow DAG with typed state, human approvals, long-runningLangGraphFirst-class state, checkpointer, interrupts, time-travel.
Research / writing pipeline with distinct rolesCrewAI (sequential) or LangGraph subgraphsRole-per-task is cheap to express in CrewAI; scale up with LangGraph when branching gets complex.
Proposer-critic or teacher-student dialogueAutoGenTwo-agent chat is its native shape.
Single agent with tools, sessions, memoryAgnoThinnest setup, built-in storage and memory.
Thousands of parallel fanouts with reducersLangGraph + SendThe only one with a first-class parallel-dispatch API.
Quick prototype, no framework commitmentPlain Python + provider SDKNo framework is the fastest framework.
Check: The Decision Matrix0/5
1. A code-review tool where a proposer and a critic go back and forth until the critic approves maps most naturally to which core abstraction?Apply
A proposer and a critic exchanging a change and feedback in a loop, with an arrow to done when the critic approves.
Typed schematic, illustrative.
2. A problem has distinct roles and typed state, and no resume, interrupt, or fanout flags. What does recommend in main.py pick?Apply
A problem record with roles yes, typed state yes, and resume, interrupt and fanout no, feeding recommend, whose return value is a question mark.
Typed schematic, illustrative. Field names are paraphrased from the stem.
3. A research and writing pipeline has distinct roles and a short, mostly linear plan. Which framework does the decision matrix prefer first?Apply
Two stages, research and write, in a straight line, each owned by a different role, and a dashed box asking for the preferred first framework.
Typed schematic, illustrative. Stage and role names are made up.
4. A workflow must resume after a crash, accept a human approval mid-run, and fan out to three retrievers in parallel. Which framework is the right first pick?Design
A question fans out to three parallel retrievers, joins at an approval step where a person signs off, then reaches the answer. A crash can happen mid-run. A dashed box asks for the first-pick framework.
Typed schematic, illustrative.
5. You are building one support agent with a handful of tools and per-user memory that persists across sessions, with no branching. Which design fits best?Design
A single agent with a handful of tools, used in session 1 and session 2, with a per-user memory box linked to both sessions, and a dashed box asking for the design.
Typed schematic, illustrative.
Author's Note

I'd run python main.py before reading the tree. It prints seven hand-written cases, each with the framework it picked and the reason string, so you see every branch fire. --ask walks the same questions interactively and prints the answer as JSON.

The order of the checks in recommend is the opinion. Plain Python goes first, and only when a problem has two or fewer LLM calls and none of the roles, dialogue, resume, fanout, or interrupt flags. Next, resume, human interrupts, and fanout all go to LangGraph before dialogue or roles get a look, which is the state question from the checklist applied literally. One side effect worth noticing: a problem with roles and typed state lands on LangGraph, because the CrewAI branch only fires when has_typed_state is false.

Treat the tree as a starting point. The fallback sends anything unclear to LangGraph, and that is my default, not a measured result. Problem has eight fields where Exercise 3 suggests five, so try cutting it down and check whether the same seven cases still pass.

Exercises

  1. Easy. Take the same task ("research Anthropic's headquarters, write a 200-word brief, cite sources") and implement it in LangGraph (four nodes: plan, search, write, cite) and in CrewAI (three roles: researcher, writer, editor). Report token cost per run and lines of code.
  2. Medium. Build the same task in AutoGen (researcher ↔ writer chat, editor joins via GroupChat) and Agno (a single agent with search_tools and write_tools, plus a session store). Rank the four implementations on (a) cost per run, (b) ability to resume after a crash, (c) ability to inject a human approval before the write step.
  3. Hard. Build a decision-tree script pick_framework.py that takes a short problem description (JSON: {has_typed_state, has_roles, has_dialogue, has_parallel_fanout, needs_resume}) and returns a recommendation with one-sentence justification. Verify it on six cases you design yourself.

Key Terms

TermWhat people sayWhat it actually means
Orchestration"How the agents coordinate"The layer that decides which node/role/agent runs next.
Durable state"Resume after a restart"State that survives process death, attached to a checkpoint or session store.
LLM-selected routing"Let the model decide"A planner LLM picks the next step each turn; flexible but pays tokens on every decision.
Explicit routing"Developer decides"A Python function or static edge picks the next step; cheap and auditable.
Crew"A CrewAI team"Roles + tasks + process (sequential or hierarchical) bound into a single runnable.
GroupChat"AutoGen's multi-agent chat"A managed conversation between N agents with a speaker selector.
Team (Agno)"Multi-agent Agno"Route / coordinate / collaborate mode over a set of agents.
StateGraph"LangGraph's graph"Typed-state, node, conditional-edge, checkpointer abstraction.

Further Reading

Code

Ships With