Multi-Agent Is Two Problems: Why TypeScript and Python Each Win Half"
8th March 2026
Will multi-agent be done better in JavaScript than Python? No. They solve different types of multi-agent. This is the most important distinction nobody is making clearly enough.
+-------------------------------------------------------------+ | "MULTI-AGENT" = TWO WORLDS | | | | WORLD 1: PARALLEL SUB-AGENTS <-- TypeScript wins | | "One brain spawns helpers to go fast" | | | | WORLD 2: COLLABORATIVE AGENT TEAMS <-- Python wins | | "Many brains working toward one goal" | +-------------------------------------------------------------+
World 1: Parallel Sub-Agents (TypeScript Dominates)
This is what OpenCode, Pi, and Claude Code do. One parent agent spawns child agents as tools to execute tasks faster.
The Pattern (OpenCode task.ts — 165 lines total)
USER: "Refactor the auth module and update the tests"
PARENT AGENT (build):
|-- task(type="explore", prompt="find all auth files") --+
|-- task(type="explore", prompt="find all auth tests") --+ PARALLEL
+-- waits... -+
|
|-- Got results from both explores
|-- task(type="general", prompt="refactor auth/login.ts")
|-- task(type="general", prompt="update auth tests")
+-- Synthesizes final answer
Why TypeScript Wins Here
// OpenCode: Sub-agent is just a new session + Promise
const session = await Session.create({
parentID: ctx.sessionID,
title: params.description,
permission: [/* restricted */],
})
const result = await SessionPrompt.prompt({
sessionID: session.id,
model, agent: agent.name,
parts: promptParts,
})
One function call. One await. Done. The sub-agent runs its own agent loop, uses restricted tools, returns a result. The parent doesn’t block — other sub-agents can run in parallel via Promise.all() on multiple tool calls.
What makes this easy in TypeScript:
- Non-blocking by default — spawning a sub-agent session is just another async operation
- Same-process — sub-agents share the file system, no serialization overhead
- Permission scoping — restrict what sub-agents can do with simple config
- Session resumption — task_id lets you continue a previous sub-agent
- Batch parallel —
Promise.all(toolCalls.map(execute))runs 25 tools at once
Python CAN do this (Strands does), but requires asyncio.create_task() + asyncio.Queue + asyncio.Event infrastructure. It’s 100+ lines vs 1 line.
World 2: Collaborative Agent Teams (Python Dominates)
This is what AutoGen, CrewAI, AgentScope, and Agno do. Multiple agents with distinct roles communicate, debate, and reach consensus.
AutoGen: Every Topology Imaginable
| Topology | File | What It Does |
|---|---|---|
| Round Robin | _round_robin_group_chat.py | Agents take turns speaking |
| Selector | _selector_group_chat.py (730 lines) | LLM picks next speaker |
| Swarm | _swarm_group_chat.py | Agents hand off via HandoffMessage |
| DiGraph | _digraph_group_chat.py (878 lines) | Directed graph with conditional edges |
CrewAI: Role-Based Teams
crew = Crew(
agents=[researcher, writer, reviewer],
tasks=[research_task, write_task, review_task],
)
# Researcher does research -> Writer writes -> Reviewer reviews
# With hierarchical: Manager decides WHO does WHAT and WHEN
Agno: Adversarial Teams
# Bull vs Bear analysts -- opposing perspectives
multi_agent_team = Team(
members=[bull_agent, bear_agent],
instructions="Send to BOTH analysts, synthesize their arguments..."
)
AgentScope: Broadcast Communication
# MsgHub -- every agent hears every other agent
with MsgHub(participants=[agent1, agent2, agent3]):
agent1() # agent2 and agent3 automatically hear agent1's response
agent2() # agent1 and agent3 automatically hear agent2's response
AutoGen gRPC: Agents on Different Machines
# WorkerRuntime -- agents communicate over gRPC across network # run_editor_agent.py -> Machine 1 # run_writer_agent.py -> Machine 2 # run_host.py -> Coordinator from autogen_ext.runtimes.grpc import GrpcWorkerAgentRuntime
Why Python Wins Here
- Richer type hierarchies — BaseGroupChat → SelectorGroupChat → MagenticOneGroupChat, deep inheritance that Python’s metaclasses make elegant
- Pydantic validators — CrewAI validates entire agent team configurations at construction
- Distributed runtime — AutoGen’s gRPC worker runtime (agents on separate machines) uses Python’s mature gRPC/protobuf ecosystem
- Graph-based routing — DiGraph with conditional edges, activation groups, cycle detection — graph theory maps to Python’s scientific computing culture
- State serialization — pickle, pydantic.model_dump(), BaseModel serialization for checkpointing team state across restarts
- Academic research — Most multi-agent research papers publish Python code. AutoGen’s MagenticOne has a published paper
The Scale Difference
TYPESCRIPT MULTI-AGENT:
OpenCode TaskTool: 165 lines <-- "spawn a helper"
OpenCode BatchTool: 181 lines <-- "run tools in parallel"
OpenCode Agent defs: 339 lines <-- "define agent types"
-----
685 lines total
PYTHON MULTI-AGENT:
AutoGen BaseGroupChat: 834 lines <-- "team foundation"
AutoGen GroupChatManager: 326 lines <-- "who speaks when"
AutoGen SelectorGroupChat:730 lines <-- "LLM picks speaker"
AutoGen SwarmGroupChat: 321 lines <-- "handoff protocol"
AutoGen DiGraph: 878 lines <-- "graph-based routing"
CrewAI Crew: 2,040 lines <-- "role-based teams"
------
5,129 lines total
+ gRPC distributed runtime
+ MagenticOne (Orchestrator + 4 specialized agents)
+ AgentScope MsgHub (broadcast patterns)
Python has 7x more multi-agent infrastructure because it’s solving a harder, more complex problem: multiple independent minds collaborating. TypeScript’s multi-agent is simple because it’s solving a simpler problem: one mind delegating to helpers.
Why Each Wins — The Fundamental Reasons
TypeScript Wins at Parallel Sub-Agents Because:
SUB-AGENTS ARE AN I/O PROBLEM:
This maps to Node.js's core design:
Promise.all([session1, session2, session3])
Key requirements:
+ Non-blocking session creation -> Node.js native
+ Parallel execution -> Promise.all
+ Real-time streaming to UI -> EventStream
+ User interruption mid-flight -> AbortSignal
+ Same-process, shared filesystem -> Single event loop
Python Wins at Collaborative Teams Because:
TEAM COLLABORATION IS A COMPUTATION/ORCHESTRATION PROBLEM:
"Who should speak next? What's the team state?
How do we route messages? How do we reach consensus?"
This maps to Python's core design:
Complex object hierarchies, graph algorithms, state machines
Key requirements:
+ Rich type hierarchies -> Metaclasses, deep inheritance
+ Graph-based routing -> DiGraph with conditional edges
+ State serialization/checkpoint -> Pydantic, pickle
+ Distributed execution -> gRPC, protobuf
+ Configuration validation -> model_validator decorators
+ Research-backed patterns -> Academic ecosystem
+ Team composition DSLs -> Python metaprogramming
The Hybrid Future
The real answer is: both, together.
+------------------------------------------------------+ | THE EMERGING ARCHITECTURE | | | | +-------------------------------------+ | | | PYTHON: The Brain Layer | | | | * Team composition & routing | | | | * Agent selection strategies | | | | * Cross-team orchestration | | | +-----------------+-------------------+ | | | A2A Protocol / MCP / gRPC | | +-----------------v-------------------+ | | | TYPESCRIPT: The Nervous System | | | | * Interactive agent execution | | | | * Parallel tool calling | | | | * Real-time streaming UI | | | +-------------------------------------+ | | | | Connected via: | | * A2A Protocol (agent discovery + communication) | | * MCP (tool/resource sharing) | | * HTTP/gRPC (cross-process communication) | +------------------------------------------------------+
OpenClaw already does this — it’s a TypeScript agent that can integrate with Python-based agents via channels. Mastra is catching up — its network/index.ts (2,609 lines) is building Python-level orchestration in TypeScript.
Final Verdict
| Scenario | Winner | Why |
|---|---|---|
| “Run 5 tasks in parallel” | TypeScript | Promise.all() — it’s an I/O problem |
| “Agent A reads, Agent B writes” | TypeScript | Permission-scoped sessions — simple delegation |
| “Manager assigns work to team” | Python | Hierarchical process, delegation protocols, role validation |
| “Agents on different machines” | Python | gRPC distributed runtime (AutoGen) |
| “Agents debate and reach consensus” | Python | Adversarial multi-agent, role-based teams |
| “Interactive coding with helpers” | TypeScript | Real-time TUI + parallel sub-agents |
| “Optimize the team itself” | Python | DSPy-style optimization over agent configurations |
TypeScript multi-agent = "one brain, many hands" (parallelism) Python multi-agent = "many brains, one goal" (collaboration) They're not the same problem. Neither language will replace the other.
More recent articles
- OpenUSD: Advanced Patterns and Common Gotchas. - 28th March 2026
- OpenUSD Mastery: From Composition to Pipeline — A SO-101 Arm Journey - 25th March 2026
- Learning OpenUSD — From Curious Questions to Real Understanding - 19th March 2026