"Nobody told me to act. I just kept watching the board until I saw something only I could add, scribbled it, and stepped back. Half the room never spoke."
A Knowledge Source Waiting for Its Turn
A blackboard system is a group of specialist agents that never call each other; they coordinate entirely through one shared data structure, reading the current partial solution, contributing a piece when they recognize a piece they can supply, and letting a control component decide who writes next. This is the oldest coordination pattern in distributed AI, born in 1970s speech understanding, and it is the direct ancestor of the shared scratchpad that modern multi-agent language-model systems pass between agents. Because the blackboard is shared state with concurrent contributors, it inherits every problem of a distributed store: consistency when two agents write, contention when many want access, and the control problem of deciding whose contribution matters now. This section shows the pattern from first principles, builds a working blackboard solver, and traces the through-line from Hearsay-II to today's shared-memory agents.
The previous section sorted distributed AI architectures into centralized, decentralized, and hybrid. The blackboard is the canonical hybrid: the agents are decentralized specialists with no direct knowledge of one another, yet a central data structure and a central scheduler tie them into one problem-solver. It is worth studying not as a historical curiosity but because it isolates, in its simplest form, the design tension that every shared-memory multi-agent system since has had to manage: how do independent contributors cooperate through common state without a rigid call graph, and what does that shared state cost?
The original setting was speech understanding. The Hearsay-II system (Erman and colleagues, 1980) had to turn an acoustic signal into a sentence, a problem with no single algorithm that works top to bottom. Instead it had separate experts for acoustics, phonetics, words, syntax, and semantics, each able to refine the others' guesses. None could solve the sentence alone, but each could improve a partial hypothesis posted by another. The blackboard architecture was invented to let them do exactly that, and the vocabulary it introduced (blackboard, knowledge source, opportunistic control) is still the vocabulary we use.
1. The Three Parts of a Blackboard System Beginner
Every blackboard system, from Hearsay-II to a present-day agent scratchpad, decomposes into the same three parts, and naming them sharply is most of the battle. The first is the blackboard itself: a shared, globally readable data structure that holds the evolving solution, usually organized into levels of abstraction (signal, syllable, word, phrase). The second is a set of knowledge sources: independent specialist modules, each with a precondition ("I can act when the board contains X") and an action ("I will add or refine Y"). A knowledge source is exactly an agent in the sense of this part of the book: it perceives the shared state and acts on it, but it has no model of the other agents. The third is the control component: a scheduler that, at each step, inspects the board, sees which knowledge sources are triggered, and chooses one to run.
The defining property is indirection. Knowledge sources are mutually anonymous; phonetics does not know that syntax exists, only that the board sometimes contains word hypotheses it can sharpen. This is the same decoupling that a message queue or a shared database gives a distributed service: producers and consumers communicate through state, not through direct addresses, so you can add a new specialist without touching any existing one. That flexibility is the blackboard's headline strength and we return to it in Section 5.
In a blackboard system, agents never invoke each other. They cooperate by leaving and reading marks on a shared structure, the way strangers coordinate at a physical whiteboard without being introduced. This single design choice (replace the call graph with shared state plus a scheduler) is what makes it trivial to add a heterogeneous expert, and it is the same choice that reappears whenever modern multi-agent systems pass a shared scratchpad between models. The price, paid in full by any shared store, is that the state itself becomes the thing you must keep consistent and the thing everyone contends for.
2. Why This Is a Distributed-Systems Pattern Intermediate
It is tempting to file the blackboard under classical AI and move on, but that misses why it belongs in a book about scaling out. A blackboard is shared mutable state with concurrent contributors, which is the precise object that distributed-systems theory spends its energy on. The moment two knowledge sources can write, you face the consistency question we developed in Chapter 2: if acoustics and phonetics both update the same hypothesis, what does a reader see, and in what order do writes take effect? A single-process blackboard sidesteps this with a lock, but the question does not vanish; it only becomes cheap. Distribute the board across machines and the same consistency, ordering, and atomicity concerns return at full strength.
The resemblance runs deeper than analogy. A parameter server, the workhorse of Chapter 11, is a blackboard whose entries are model weights: workers read the current parameters, compute a contribution (a gradient), and write it back, while a coordination policy decides how updates are merged and how stale a read may be. The vocabulary differs (push, pull, bounded staleness) but the architecture is the blackboard's: many anonymous contributors coordinating through one shared store they all read and write. Seeing that the parameter server is a blackboard in numerical clothing is a useful way to carry intuition between the two parts of the book.
Three classic costs of any shared store therefore apply directly to a blackboard, and they are worth stating as a small table because the rest of the section keeps returning to them.
| Cost | How it shows up on a blackboard | General treatment |
|---|---|---|
| Consistency | Concurrent writes to the same hypothesis must order correctly so readers see a coherent partial solution. | Chapter 2 |
| Contention | Many knowledge sources want the board at once; a global lock serializes them and caps throughput. | Chapter 11 |
| Control | Which triggered knowledge source should run next, given limited write access? | Section 3 below |
The control row is special: it is the one cost unique to the blackboard rather than borrowed from storage systems, and it is the one the original architects spent the most ingenuity on. We take it next.
3. The Control Problem: Who Writes Next Intermediate
At any instant several knowledge sources may be triggered, each able to add something to the board, and the system can run only one at a time on the shared state. Choosing which one to run is the control problem, and the blackboard's answer is opportunistic control: do not fix the order of reasoning in advance; instead, at each step, pick the contribution that most advances the current partial solution. If the board now contains strong word hypotheses, run the syntax source; if it contains a fresh acoustic segment, run phonetics. Reasoning flows opportunistically wherever the evidence is strongest, sometimes bottom-up from signal to sentence, sometimes top-down from an expected phrase back to the sounds it predicts.
Formally, the control component maintains a set of triggered knowledge sources and selects one to maximize an estimated utility. If $T(t)$ is the set of knowledge sources triggered by the board state at step $t$, opportunistic control chooses
$$k^{\star}(t) = \arg\max_{k \in T(t)} \; u_k\big(\text{board}(t)\big),$$where $u_k$ scores how much running source $k$ is expected to advance the solution. The scoring can be as crude as a fixed priority ordering or as rich as a learned estimate of expected information gain. The crucial point is that the order of reasoning is data-driven, decided at run time from the contents of the board, not wired into a fixed pipeline. This is what lets a blackboard integrate experts whose right order of application is not known ahead of time, which is the situation in speech, in sensor fusion, and, as we will see, in multi-step language-model reasoning.
A common way the original authors explained opportunistic control was a room of detectives sharing one whiteboard of clues. Nobody works in a fixed order. Each watches the board, and whenever one spots a clue only they can interpret, they step up, add a deduction, and sit back down. The case is cracked not by a chain of command but by whoever can contribute most at each moment. The quiet detectives who never found a clue they could use are not failures; they are just knowledge sources whose precondition never fired.
4. A Blackboard You Can Run Intermediate
The pattern is clearest in code. We solve the classic cryptarithm $\text{SEND} + \text{MORE} = \text{MONEY}$, where each letter stands for a distinct digit, using three knowledge sources that cooperate through one shared assignment. No single source solves it: a LeadingDigit source posts the constraint that the leading letters cannot be zero, a CarryReasoning source deduces from digit counts that $\text{M} = 1$, and only then does a Search source complete the remaining letters by constrained search over what the others have already pinned. The control loop is opportunistic in the small: it tries the cheap constraint-posting sources before the expensive search, running the first source whose precondition fires.
from itertools import permutations
LETTERS = "SENDMORY"
class Blackboard:
"""The single shared data structure every knowledge source reads and writes."""
def __init__(self):
self.assign = {} # letter -> digit, the emerging solution
self.facts = [] # human-readable trace of contributions
self.solved = False
def post(self, who, msg):
self.facts.append(f"[{who}] {msg}")
def ks_leading_nonzero(bb):
"""Knowledge source: leading letters of a numeral cannot be zero."""
changed = False
for L in ("S", "M"):
if L not in bb.assign.get("_forbidden_zero", set()):
bb.assign.setdefault("_forbidden_zero", set()).add(L)
bb.post("LeadingDigit", f"{L} must be non-zero (leading digit)")
changed = True
return changed
def ks_carry_reasoning(bb):
"""Knowledge source: a 5-digit sum of two 4-digit addends forces M = 1."""
if "M" not in bb.assign:
bb.assign["M"] = 1
bb.post("CarryReasoning", "sum is 5 digits, addends 4 -> M = 1")
return True
return False
def ks_search(bb):
"""Knowledge source: complete the assignment by constrained search,
respecting whatever the other sources already pinned on the board."""
forbidden = bb.assign.get("_forbidden_zero", set())
fixed = {k: v for k, v in bb.assign.items() if k in LETTERS}
free = [c for c in LETTERS if c not in fixed]
pool = [d for d in range(10) if d not in set(fixed.values())]
for combo in permutations(pool, len(free)):
cand = dict(fixed); cand.update(dict(zip(free, combo)))
if any(cand[L] == 0 for L in forbidden):
continue
send = cand["S"]*1000 + cand["E"]*100 + cand["N"]*10 + cand["D"]
more = cand["M"]*1000 + cand["O"]*100 + cand["R"]*10 + cand["E"]
money = cand["M"]*10000 + cand["O"]*1000 + cand["N"]*100 + cand["E"]*10 + cand["Y"]
if send + more == money:
bb.assign.update(cand); bb.solved = True
bb.post("Search", f"SEND={send} MORE={more} MONEY={money}")
return True
return False
# The control component: an opportunistic scheduler. It asks each knowledge
# source whether it can contribute and runs the first that can, cheap sources
# (constraint posting) before the expensive search.
KNOWLEDGE_SOURCES = [
("LeadingDigit", ks_leading_nonzero),
("CarryReasoning", ks_carry_reasoning),
("Search", ks_search),
]
def control_loop(bb, max_cycles=20):
for cycle in range(1, max_cycles + 1):
for name, ks in KNOWLEDGE_SOURCES:
if ks(bb):
print(f"cycle {cycle}: control activated {name}")
break
else:
print(f"cycle {cycle}: no source could contribute; halting"); break
if bb.solved:
print(f"cycle {cycle}: blackboard reports solution found"); break
bb = Blackboard()
control_loop(bb)
print("\n--- blackboard trace ---")
for f in bb.facts:
print(f)
sol = {k: v for k, v in bb.assign.items() if k in LETTERS}
print("\nfinal assignment:", {k: sol[k] for k in LETTERS})
Blackboard; the opportunistic control_loop decides which one writes next, and the solution accretes on the board cycle by cycle.cycle 1: control activated LeadingDigit
cycle 2: control activated CarryReasoning
cycle 3: control activated Search
cycle 3: blackboard reports solution found
--- blackboard trace ---
[LeadingDigit] S must be non-zero (leading digit)
[LeadingDigit] M must be non-zero (leading digit)
[CarryReasoning] sum is 5 digits, addends 4 -> M = 1
[Search] SEND=9567 MORE=1085 MONEY=10652
final assignment: {'S': 9, 'E': 5, 'N': 6, 'D': 7, 'M': 1, 'O': 0, 'R': 8, 'Y': 2}
The structure of Output 27.4.1 is the whole lesson. Each cycle is one read-decide-write step against shared state: the control loop reads the board, picks the highest-value triggered source, and lets it write. The constraints posted in cycles 1 and 2 are what make cycle 3 cheap, exactly the cooperative refinement the architecture is built for. Nothing here is parallel yet, but every line that touches bb.assign is a place where, on a distributed board, you would need the consistency control of Table 27.4.1.
The Blackboard class and its lock-free single-process access are fine for a demo, but a real multi-agent system puts the shared state in a store that already solves consistency and concurrent access. With Redis you replace the entire class with a hash and atomic operations, and many agent workers can read and write the same board across machines:
import redis
r = redis.Redis() # the shared blackboard
# A knowledge source contributes atomically; no hand-written lock needed.
r.hset("board:cryptarithm", "M", 1) # post a fact
r.rpush("board:trace", "CarryReasoning: M = 1") # append to the trace
forbidden = r.sadd("board:forbidden_zero", "S", "M") # post a constraint
state = r.hgetall("board:cryptarithm") # any worker reads current state
Blackboard plus its access discipline collapse to atomic store operations, and the store handles the durability, concurrency, and cross-machine reads that a distributed board needs. The opportunistic control loop stays exactly as written; only the board changes.5. Strengths, Weaknesses, and the Coupling Point Intermediate
The blackboard's strength is integration. Because knowledge sources are anonymous and communicate only through state, you can assemble a problem-solver out of wildly heterogeneous experts (a neural acoustic model, a symbolic grammar, a lookup table) and add a new one without rewiring the others. When the right sequence of reasoning is unknown or varies by input, opportunistic control discovers a good order at run time instead of forcing you to hard-code a pipeline. These are the same properties that make the pattern attractive again for orchestrating language-model agents whose useful order of operations is genuinely input-dependent.
The weakness is the mirror image of the strength: the blackboard is a single coupling point and a single bottleneck. Every contribution flows through one shared structure, so it is a contention hotspot under concurrency (the throughput cap of Table 27.4.1) and a single point of failure if it is not replicated. Control can also thrash, spending more effort deciding who should run than the runs themselves save, and a poorly tuned utility $u_k$ can starve a source that holds the key insight. These are not reasons to avoid the pattern; they are the engineering bills that come due when shared state is the medium of coordination, and they are precisely the bills the rest of this book teaches you to pay.
Who: A machine learning engineer at an insurance company building automated claim-document understanding.
Situation: Incoming claims arrived as scanned PDFs needing OCR, layout analysis, entity extraction, and a fraud-signal check, each handled by a different model.
Problem: The team wired the four models into a fixed left-to-right pipeline, but real documents arrived in every condition, and the right order of processing varied wildly from one claim to the next.
Dilemma: Keep the rigid pipeline and pay for the cases it handled badly (a clean digital PDF still forced through OCR, a low-quality scan reaching extraction with garbage), or replace the call graph with something that could reorder reasoning per document.
Decision: They rebuilt it as a blackboard: each model became an anonymous knowledge source posting to a shared document state, with an opportunistic controller choosing which to run from what the board already contained.
How: The shared state lived in a Redis hash exactly as in Code 27.4.2; the controller scored triggered sources (skip OCR when the board already held digital text, run the fraud check only once entities were posted) and ran the highest-scoring one each cycle.
Result: Throughput rose because clean documents skipped expensive stages, and adding a fifth specialist (a signature detector) needed no change to the existing four, since none of them addressed each other.
Lesson: When the useful order of heterogeneous experts depends on the input, a blackboard's opportunistic control beats a fixed pipeline, and anonymity through shared state is what makes the new expert free to add.
The blackboard is the same shared-state idea that runs through the whole book, met here in its purest multi-agent form. It is the parameter server of Chapter 11 with hypotheses instead of weights, governed by the consistency models of Chapter 2, and it returns once more as the shared memory of distributed agent orchestration in Chapter 32. Whenever you meet a system in which independent contributors coordinate by reading and writing one store, you are looking at a blackboard, and the questions to ask are always the three in Table 27.4.1: how is it kept consistent, how is contention bounded, and who decides who writes next?
6. The Modern Echo: Shared-Memory Agents Advanced
The blackboard never really left; it changed substrate. A multi-agent language-model system with a shared scratchpad, working memory, or state object that agents read and write is a blackboard whose knowledge sources are prompted models. A planner agent posts a plan, a retrieval agent posts evidence pulled from the vector stores of Chapter 25, a critic agent reads the draft and posts a revision, and an orchestrator plays the control component, deciding which agent acts on the shared state next. The consistency and contention questions of Table 27.4.1 reappear immediately: what happens when two agents write the scratchpad concurrently, and who arbitrates? We develop the distributed-orchestration answer in Chapter 32; here the point is only that the architecture is the one Hearsay-II introduced, now with much larger knowledge sources.
The shared-memory pattern is enjoying an explicit revival in multi-agent language-model research. Several 2024 to 2025 systems name the blackboard directly: work on blackboard-style multi-agent coordination replaces fixed agent-to-agent message passing with a shared workspace that any agent can read and any control policy can schedule, reporting better robustness than rigid pipelines on multi-step reasoning. In parallel, agent frameworks such as LangGraph and AutoGen have converged on a shared mutable state object passed between nodes, which is a blackboard in all but name, and CrewAI and similar stacks add shared memory that specialist agents read and write. The open research questions are exactly the classical ones scaled up: how to schedule which agent writes next (the opportunistic-control problem with a learned utility), how to keep the shared state consistent when agents run concurrently across machines, and how to stop the shared store from becoming the bottleneck. The 1980 architecture turns out to be a clean lens on the newest systems, which is why it opens this chapter's treatment of coordination.
The next section turns from coordination through shared state to coordination through explicit negotiation. Where the blackboard's agents never address one another, the Contract-Net Protocol of Section 27.5 has agents announce tasks, bid for them, and award contracts directly, the complementary answer to "who does what" when the work, rather than a shared hypothesis, is the thing being divided.
You are asked to design a blackboard system that parses a noisy log line into structured fields (timestamp, level, service, message). Name three knowledge sources, and for each state its precondition (what must be on the board before it can act) and its action (what it writes). Then describe one situation in which opportunistic control would run them out of the obvious left-to-right order, and explain why a fixed pipeline would have failed there. Relate your answer to why Hearsay-II needed run-time control rather than a fixed sequence of stages.
Extend Code 27.4.1 in two steps. First, add a fourth knowledge source ks_parity that posts the constraint forcing $\text{D} + \text{E}$ to end in $\text{Y}$ with a carry, and confirm from the trace that it fires before Search and further shrinks the work. Second, replace the fixed source ordering in control_loop with an explicit utility score $u_k$ per source (for example, cheap constraint sources score higher than search), and select the triggered source with the maximum score as in the $k^{\star}(t)$ rule of Section 3. Report how the cycle trace changes and argue whether your utility produces the same answer faster.
Suppose the blackboard of Code 27.4.1 is moved to a store shared by $W$ concurrent knowledge-source workers, every contribution requires taking a global lock held for $\tau$ seconds, and a worker is triggered on average every $\lambda$ contributions of wall-clock work. Using the contention row of Table 27.4.1, give a back-of-the-envelope expression for the maximum useful contribution rate as a function of $W$ and $\tau$, and identify the $W$ beyond which adding workers stops helping. Connect your result to the parameter-server staleness trade-off of Chapter 11: what would relaxing the single global lock to per-entry locks buy, and what consistency guarantee from Chapter 2 would you give up?