Most AI agent frameworks make you choose: parallel tool calls OR code generation.
That's a false dichotomy.
The best agent systems use all three strategically: sequential, parallel, AND code generation.
Here's the decision framework we use:
Sequential Tool Calls — When You Need Adaptive Behavior
- LLM decides the next step based on previous results
- Perfect for exploration (debugging unknown codebases, iterative research)
- Slow but flexible
Parallel Tool Calls — When Operations Are Independent
- Read multiple files simultaneously
- Query different APIs at once
- 3-5x faster than sequential for I/O-bound work
- Limited to flat JSON lists — no dependencies, no loops, no conditionals
Code Generation — When You Need Complex Control Flow
- Dependencies between operations (output of A feeds B)
- Loops over collections
- Conditional branching
asyncio.gatherfor true concurrency with dependent chains
The Critical Insight
Parallel tool calls can't express what code can.
You can't write "fetch user data, THEN fetch their orders" in a parallel tool call JSON array. The API syntax doesn't support it.
But you CAN express it as:
user = await get_user(id)
orders = await get_orders(user.id)
Or as parallel execution with dependencies:
results = await asyncio.gather(
get_user(id),
get_preferences(id)
)
orders = await get_orders(results[0].id)
Code is a tool. Parallel calls are a tool. Sequential calls are a tool.
Technical leaders building agentic systems need all three in the toolkit.
The Right Question
The question isn't "which approach is better?" — it's "which approach fits this specific operation?"
| Operation | Best Mode |
|---|---|
| Independent reads | Parallel |
| Dependent chains | Code generation |
| Adaptive exploration | Sequential |
Stop treating architectural patterns as religious choices. Start treating them as engineering decisions with clear tradeoffs.
