Agent Framework Decision: LangGraph vs CrewAI vs Plain Python
LangGraph for stateful multi-step, CrewAI for role-based teams, plain Python for simple tool dispatch. Decision framework based on agent complexity.
For most AI agent projects in 2026, start with plain Python and an explicit tool dispatch loop. Graduate to LangGraph when you need branching state management. Use CrewAI for quick multi-agent prototypes. The framework matters less than how you handle the tool calling loop and error recovery.
Plain Python: the underrated default
The pattern is simple: call the LLM with function definitions, check which tool it selected, execute it, append the result, repeat. When it breaks, you can see exactly where. No graph abstraction to debug through.
import os, json, requests
TOOLS = {
"web_search": lambda q: requests.post(
"https://api.scavio.dev/api/v1/search",
headers={"x-api-key": os.environ["SCAVIO_API_KEY"],
"Content-Type": "application/json"},
json={"query": q, "country_code": "us"}
).json().get("organic_results", [])[:3],
}
def agent_loop(messages, max_steps=10):
for _ in range(max_steps):
resp = call_llm(messages, tools=list(TOOLS.keys()))
if resp.get("tool_call"):
name = resp["tool_call"]["name"]
args = resp["tool_call"]["arguments"]
result = TOOLS[name](**args)
messages.append({"role": "tool", "content": json.dumps(result)})
else:
return resp["content"]
return "Max steps reached"When to upgrade to LangGraph
LangGraph adds value when your agent needs branching execution paths, parallel tool calls with fan-out/fan-in, persistent state across conversation turns, or human-in-the-loop checkpoints. The tradeoff: debugging three nodes deep in a graph is genuinely difficult compared to stepping through a flat loop.
- State management across branches and parallel execution
- Checkpoint and resume (critical for long-running research tasks)
- Built-in human-in-the-loop patterns
- Streaming support for intermediate results
CrewAI: fastest to demo, hardest to customize
CrewAI gets you a working multi-agent system in under 50 lines. Define agents with roles, give them tools, set a process (sequential or hierarchical), and run. The abstraction fights you when you need fine control over tool calling behavior, custom error handling, or non-standard communication patterns between agents.
Decision framework
- Single agent with 2-5 tools: plain Python loop
- Multi-agent with simple handoffs: CrewAI
- Complex workflows with state, branching, HITL: LangGraph
- Production system with custom requirements: plain Python with your own state management
The real differentiator: error handling
A Reddit commenter put it best: "The framework matters less than how you handle the tool calling loop. Most of the magic is in the error handling nobody talks about." Retry with backoff, graceful degradation when tools fail, budget exhaustion handling, and partial result returns matter more than which orchestration library you pick.