When to reach for it
- Many agents contribute asynchronously.
- Shared state is more important than direct conversation.
- Intermediate results must remain persistent.
/pattern/blackboard/
Agents coordinate indirectly via a shared state surface where results, hypotheses, and tasks are deposited rather than using direct chat.
When to reach for it
When it backfires
The tradeoff
Highly decoupled collaboration is achieved against demanding state management and consistency requirements.
Specialists read and write a shared blackboard; each acts when its precondition is met. No fixed turn order.
from typing import TypedDict, Any
from langgraph.graph import StateGraph, END
class State(TypedDict):
board: dict[str, Any]
def diagnostic(state):
if "hypothesis" not in state["board"]:
return {"board": {**state["board"], "hypothesis": diagnose(state["board"])}}
return state
def log_analyst(state):
if "hypothesis" in state["board"] and "evidence" not in state["board"]:
return {"board": {**state["board"], "evidence": fetch_logs(state["board"])}}
return state
def fix_specialist(state):
if "evidence" in state["board"] and "remediation" not in state["board"]:
return {"board": {**state["board"], "remediation": propose_fix(state["board"])}}
return state
def is_complete(state):
board = state["board"]
return "hypothesis" in board and "evidence" in board and "remediation" in board
g = StateGraph(State)
g.add_node("diagnostic", diagnostic)
g.add_node("log_analyst", log_analyst)
g.add_node("fix_specialist", fix_specialist)
# Each specialist loops back until completion
g.add_conditional_edges("diagnostic", lambda s: END if is_complete(s) else "log_analyst")
g.add_conditional_edges("log_analyst", lambda s: END if is_complete(s) else "fix_specialist")
g.add_conditional_edges("fix_specialist", lambda s: END if is_complete(s) else "diagnostic")
g.set_entry_point("diagnostic")
blackboard = g.compile()The blackboard never reaches a terminal state. Specialists cycle indefinitely, rewriting the same entries.
Fix · Define a 'complete' predicate on the blackboard schema. When it holds, route to END regardless of which node is active.
Every specialist writes everything it knows into the shared state. The schema balloons and later specialists can't find what they need.
Fix · Enforce a typed schema per blackboard domain. Reject writes that don't match the declared fields.
Both are decentralised — no central node owns the control flow — so they sit side by side at the autonomous end of the spectrum, and they are the pair most often conflated. The difference is not whether they self-organise but the coordination substrate.
Swarm is push, Blackboard is pull.
It is the classic distributed-systems split: Swarm coordinates by message-passing — an agent names its successor and hands off both control and context; Blackboard coordinates by shared, stigmergic state — agents never address each other, they react to what is written on a shared board.
| Dimension | Blackboard | Swarm |
|---|---|---|
| Handoff vector | Indirect — a write to shared state | Direct — transfer_to(named_peer) |
| Who is addressed | The board (a state predicate) | A specific peer agent |
| Activation | Data-driven (“I have something to add now”) | Control-driven (the active agent passes the baton) |
| Where context lives | Persistently and visibly, on the board | Travels with each handoff |
| Adding an agent | A subscription — existing agents unchanged | Must appear in peers’ transfer_to sets |
| Synchrony | Natural fit for asynchronous, long-running work | Live baton-pass; control flows continuously |
| Termination | Quiescence — no agent has a relevant action left | An agent answers, or max_handoffs is reached |
several specialists incrementally build a shared artefact and partial results unlock further work, contributors are not simultaneously available, or you need to add and remove specialists without rewiring the others.
a single task must travel live between specialists, the next specialist depends on what the previous one just discovered, and no static plan can be drawn in advance.
Both forfeit the guarantees Pipeline and Graph give on path length, coverage and cost, and both make tracing non-optional. Swarm’s failure mode is hallucinated routing and unbounded loops — cap max_handoffs and schema-validate transfers; Blackboard’s is stall and hard debugging — add a liveness check and partition the board by trust.
Search patterns, frameworks, and pages.