A runnable, framework-free catalog of multi-agent communication & orchestration patterns.
How do AI agents actually talk to each other? Read the code, run it in one command, steal the pattern.
Most "AI agent" tutorials hand you a heavyweight framework and hide the one thing that actually matters: how agents coordinate. This repo does the opposite. Each pattern is ~40 lines of plain Python you can read in a sitting, with a diagram, a "when to use" note, and a one-command demo.
- π§ 7 production-grade patterns β from a single ReAct loop to event-driven swarms.
- πͺΆ Framework-free β pure Python + a 2-dependency core. No LangChain, no magic.
- β‘ Runs with zero setup β every pattern works offline via a deterministic stub LLM. Add a free Groq key for real reasoning.
- π Observable β a built-in tracer prints exactly who said what to whom.
- β
Tested + CI β
pytestsmoke-tests every pattern on Python 3.10β3.12.
| # | Pattern | Communication style | Use it when⦠|
|---|---|---|---|
| 01 | OrchestratorβWorker | hierarchical fan-out/in | a task splits into independent parallel subtasks |
| 02 | Supervisor / Router | single-hop delegation | route each request to one of several specialists |
| 03 | ReAct (Reason+Act) | model β tools loop | an agent must use tools / look things up to answer |
| 04 | Multi-Agent Debate | adversarial + judge | hard/contested questions needing scrutiny |
| 05 | Blackboard | shared state (indirect) | contribution order is unknown; specialists pile on |
| 06 | Message Bus (pub/sub) | decoupled event-driven | loose coupling + horizontal scale |
| 07 | A2A Handoff | point-to-point transfer | triage then hand control to a specialist with context |
Each folder has its own README with a Mermaid diagram and trade-offs.
These patterns are really three answers to one question β how does work get from one agent to another?
flowchart TB
subgraph DIRECT[1 - Direct / hierarchical]
O[orchestrator] --> W1[worker]
O --> W2[worker]
S[supervisor] -->|route| Spec[specialist]
end
subgraph SHARED[2 - Shared state]
A1[agent] <--> BB[(blackboard)]
A2[agent] <--> BB
end
subgraph EVENT[3 - Event-driven]
P[publisher] --> BUS{{message bus}}
BUS --> C1[subscriber]
BUS --> C2[subscriber]
end
| Coupling | Patterns | Trade-off |
|---|---|---|
| Tight (caller knows callee) | Orchestrator-Worker, Supervisor, A2A Handoff | simple, debuggable; scales poorly |
| Shared (via common state) | Blackboard | flexible ordering; contention risk |
| Loose (via events) | Message Bus | scalable, resilient; harder to trace |
There's no "best" β pick the loosest coupling your problem actually needs.
# 1. clone
git clone https://github.com/hari9618/agentic-patterns.git
cd agentic-patterns
# 2. install (2 runtime deps)
pip install -r requirements.txt
# 3. run any pattern β works immediately, no API key needed
python run.py --list
python run.py react
python run.py orchestrator-worker -i "Compare SQL and NoSQL for a chat app"Example trace (offline stub β note the visible reasoning β tool loop):
=== ReAct: reason + act tool loop ===
Input: What is 23 * 47 + 19?
<- [react-agent] THOUGHT: I should use a tool to be sure. ACTION: calculator :: What is 23 * 47 + 19?
* [tool:calculator] 1100
<- [react-agent] THOUGHT: I now have enough to answer. FINAL: 1100
--- FINAL ---
1100
cp .env.example .env
# get a free key at https://console.groq.com/keys and paste it:
# GROQ_API_KEY=gsk_...
python run.py debate -i "Microservices are the right default for new startups"That's it β the same code now runs on llama-3.3-70b via Groq. Swap in any
provider by adding a class with a chat(messages) -> str method in
core/llm.py.
agentic-patterns/
βββ core/ # shared building blocks (read these first)
β βββ agent.py # the tiny Agent abstraction
β βββ llm.py # Groq client + offline StubLLM + get_llm()
β βββ message.py # Message (to a model) vs Envelope (between agents)
β βββ bus.py # in-process pub/sub message bus
β βββ tools.py # tool registry + safe calculator
β βββ tracing.py # "who said what to whom" logger
βββ patterns/ # one folder per pattern: pattern.py + README + diagram
β βββ p01_orchestrator_worker/
β βββ ...
β βββ p07_a2a_handoff/
βββ tests/ # smoke-tests every pattern, offline
βββ docs/ # design notes & a pattern-selection guide
βββ run.py # CLI: python run.py <slug>
Two ideas do most of the work (core/message.py):
Messageβ a turn you send to a model (role,content).Envelopeβ a message that travels between agents (sender,recipient,intent,reply_to).
Keeping these separate is the mental model that makes multi-agent systems click.
flowchart TD
START{What does the task need?} --> TOOLS{Use tools / lookups?}
TOOLS -->|yes, one agent| REACT[ReAct]
TOOLS -->|no| MANY{Many sub-problems?}
MANY -->|independent + parallel| ORCH[Orchestrator-Worker]
MANY -->|pick one expert| SUP[Supervisor/Router]
MANY -->|contested / high-stakes| DEB[Debate]
START --> SCALE{Need loose coupling / scale?}
SCALE -->|order unknown, shared context| BB[Blackboard]
SCALE -->|event-driven, many agents| BUS[Message Bus]
SCALE -->|transfer control in a conversation| A2A[A2A Handoff]
See docs/choosing-a-pattern.md for the long version,
and docs/architecture.md for how the core primitives fit together.
make install # deps
make test # pytest (offline, no key)
make lint # ruff
make demo # run all 7 patterns back-to-backCI runs lint + tests on Python 3.10/3.11/3.12 β see .github/workflows/ci.yml.
- Reflection / self-critique loop (generate β critique β revise)
- PlannerβExecutor with a re-planning step
- Hierarchical teams (supervisor of supervisors)
- Parallel orchestrator-worker with
asyncio - Async message bus backed by Redis Streams
- Provider adapters: Anthropic Claude, OpenAI
Contributions welcome β see CONTRIBUTING.md. New patterns
just drop a folder in patterns/ and an entry in the registry.
MIT β see LICENSE. Built to be read, forked, and reused.
If this helped you understand agent design, a β helps others find it.