n4nAI

Blackboard architecture for multi-agent orchestration

Blackboard architecture multi-agent defined: a shared-memory coordination pattern for LLM agents, with components, example code, and common misconceptions.

n4n Team5 min read993 words

Audio narration

Coming soon — every post will get a voice note here.

A blackboard architecture multi-agent system coordinates autonomous agents through a shared, structured workspace rather than direct message passing or a hardcoded control flow. Each agent monitors the blackboard, contributes when its local trigger conditions are met, and otherwise stays idle—producing emergent problem solving from independent specialists.

The pattern originated in speech recognition and signal processing, but it maps cleanly onto LLM agent pipelines where the problem space is messy and decomposes unpredictably. The blackboard holds partial solutions; agents are knowledge sources that know how to extend those partials.

Core components

The blackboard

A blackboard is not a log or a queue. It is a mutable, typically hierarchical state store. Sections might include query, raw_docs, extracted_facts, contradictions, outline, draft. Agents read relevant sections and write new ones.

{
  "query": "Why did the 2008 crisis spread globally?",
  "raw_docs": ["doc1", "doc2"],
  "extracted_facts": null,
  "outline": null,
  "draft": null
}

Immutability is optional; in practice you want versioned writes or at least timestamps to avoid lost updates when agents run concurrently. Treat the blackboard schema as an API contract. If you let agents scribble arbitrary keys, you lose the primary benefit: a inspectable, debuggable workspace.

Knowledge sources (agents)

Each agent encapsulates a capability and a precondition. It does not know about other agents. It only knows: “If the blackboard looks like X, I can produce Y.”

class Agent:
    def triggers_on(self, changed_section: str, bb: dict) -> bool:
        ...
    def run(self, bb: dict) -> None:
        ...

Agents can be pure functions, LLM chains, or long-running workers. The blackboard architecture multi-agent approach treats them as pluggable predicates plus side effects.

Control shell

Classic blackboard systems use a scheduler that scans triggers after every write. In LLM deployments, you can replace the busy loop with an event emitter or just a simple sequential sweep if latency tolerances are loose. The control shell holds no domain logic; it only decides which triggered agents to invoke and in what order when multiple fire.

A production control shell usually adds concurrency limits, dead-letter sections for failed writes, and priority weighting so a fact_checker outranks a style_polish agent when both trigger.

How coordination emerges without a central planner

There is no orchestrator that says “retriever runs, then extractor, then writer.” Instead, the retriever triggers on query being set. Once it writes raw_docs, the extractor’s precondition (raw_docs present, extracted_facts absent) becomes true. The control shell invokes it. The writer waits until outline and extracted_facts exist.

This decoupling means you can drop in a new agent—say a contradiction_checker that triggers on extracted_facts—without touching any other agent’s code. The workspace is the only contract.

Crucially, triggers can be negative or temporal. An agent can fire because facts is missing 60 seconds after raw_docs appeared, indicating the extractor crashed. That kind of self-healing falls out naturally; in a DAG you would need explicit timeout nodes.

Why engineers reach for this pattern

Decoupling and fault isolation

If the writer agent throws, the extractor and retriever keep functioning. The blackboard persists; you can restart the writer and it picks up where the state indicates. Contrast this with a linear DAG orchestrator where a mid-stage failure blocks everything downstream unless you build compensation logic.

Handling partial and evolving state

Real tasks rarely present all inputs upfront. A user might add a clarifying constraint mid-run. With a blackboard, that’s just another write; agents watching that section react. In a rigid orchestrator you’d need to abort and re-plan.

Parallelism and incremental progress

Multiple agents can work on disjoint sections simultaneously. A citation_formatter and a style_editor can both operate on draft once present, as long as they write to draft_formatted and draft_styled respectively, avoiding write conflicts.

Debuggability

Because all shared state lives in one structured object, you can snapshot the blackboard at any step and replay. Try doing that with a mesh of peer-to-peer agent messages—you end up building a blackboard anyway to get observability.

A concrete implementation sketch

Below is a minimal but realistic loop. We use a Python Blackboard that notifies subscribed agents. For LLM calls, we point the OpenAI client at a gateway that fronts many models; this keeps agent code free of provider-specific retry logic.

class Blackboard:
    def __init__(self):
        self.state = {}
        self.agents = []

    def subscribe(self, agent):
        self.agents.append(agent)

    def write(self, section, value):
        self.state[section] = value
        self._sweep(section)

    def _sweep(self, changed):
        for agent in self.agents:
            if agent.triggers_on(changed, self.state):
                agent.run(self)

class RetrieverAgent:
    def triggers_on(self, changed, state):
        return changed == "query" and "raw_docs" not in state
    def run(self, bb):
        # call search API
        bb.write("raw_docs", ["snippet1", "snippet2"])

class ExtractorAgent:
    def __init__(self, client):
        self.client = client
    def triggers_on(self, changed, state):
        return changed == "raw_docs" and "facts" not in state
    def run(self, bb):
        docs = bb.state["raw_docs"]
        resp = self.client.chat.completions.create(
            model="anthropic/claude-3.5-sonnet",
            messages=[{"role":"user","content":f"Extract facts:\n{docs}"}]
        )
        bb.write("facts", resp.choices[0].message.content)

Point the client at an inference gateway such as n4n.ai and you get automatic fallback across providers without writing your own rate-limit backoff—useful when many agents fire LLM calls concurrently.

The control shell here is _sweep: naive, but sufficient for many batch-style agent jobs. For production, add priority queues and concurrency limits. You would also persist state to Redis or Postgres so a process restart does not lose the workspace.

Common misconceptions

“It’s just a message bus”

A message bus delivers events to subscribers; the receiver decides what to do. A blackboard is state-centric. Agents react to state predicates, not just “a message arrived.” This difference matters: an agent can trigger because a condition has not been met (e.g., facts missing after raw_docs present for 30 seconds), which a pure pub/sub model handles awkwardly.

“You need a complex rule engine”

The trigger logic is often a few boolean expressions. You do not need a RETE engine. If your triggers grow beyond simple predicates, that’s a signal your agents are too fine-grained, not that the architecture is heavy.

“LLM agents can’t use it because they need dialogue”

LLM agents frequently maintain internal reasoning, but their external coordination can still be blackboard-driven. The blackboard stores shared artifacts; each agent may run a chain-of-thought internally before writing. Multi-agent debate can be modeled as agents writing to hypothesis_A and critique_A sections. The blackboard architecture multi-agent pattern accommodates stateless and stateful agents alike.

“It doesn’t scale”

Scale problems are about the blackboard store, not the pattern. Use a real database with row-level locking or CRDTs behind the Blackboard interface and you can run hundreds of agents. The decoupled nature actually helps scale because agents are independently deployable workers that can be containerized and horizontally scaled.

When not to use it

If your task is a fixed sequence of three steps with no possibility of branching or late input, a simple linear script is clearer. The blackboard architecture multi-agent system earns its keep when decomposition is discovered at runtime, when agents are added/removed frequently, or when partial failure must not halt the whole pipeline.

Use it because the workspace is the simplest contract that allows emergent coordination—not because it sounds academic.

Tagsmulti-agent-orchestrationarchitecturedesign-patterns

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All multi-agent orchestration patterns posts →