Day 52: Blackboard vs Message Bus Orchestration

Day 52: Blackboard vs Message Bus Orchestration

A shared Google Doc “blackboard” feels collaborative until you cannot prove who wrote which step or why the Implementer ignored the Critic. For production agents, prefer a message bus (SQS / EventBridge) with typed envelopes — and reserve blackboards for read-mostly scratch that is still versioned.

⚡ TL;DR: Use EventBridge/SQS for agent handoffs with run_id, role, schema_version, and payload hash. Keep a small append-only artifact store for plans/diffs. Prefer bus over shared mutable docs when you need auditability.

When a blackboard is enough

Blackboards work for short, single-tenant research loops where humans watch live. They fail when multiple writers mutate the same plan section without optimistic locking.

# blackboard/scratch.py — OK for demos, not for prod apply
class Scratch:
    def __init__(self):
        self.notes: list[dict] = []
    def append(self, role: str, text: str):
        self.notes.append({"role": role, "text": text})  # ❌ no hash, no schema

Message bus envelopes

{
  "run_id": "run_7f3a",
  "role": "planner",
  "type": "PlanReady",
  "schema_version": 3,
  "payload_s3": "s3://agent-artifacts/run_7f3a/plan.json",
  "payload_sha256": "ab12…",
  "ts": "2026-09-11T15:00:00Z"
}
# bus/emit.py
import boto3, hashlib, json
eb = boto3.client("events")
s3 = boto3.client("s3")

def emit_plan(run_id: str, plan: dict, bucket: str):
    body = json.dumps(plan, sort_keys=True).encode()
    key = f"{run_id}/plan.json"
    s3.put_object(Bucket=bucket, Key=key, Body=body, ContentType="application/json")
    eb.put_events(Entries=[{
        "Source": "agents.planner",
        "DetailType": "PlanReady",
        "Detail": json.dumps({
            "run_id": run_id,
            "payload_s3": f"s3://{bucket}/{key}",
            "payload_sha256": hashlib.sha256(body).hexdigest(),
            "schema_version": 3,
        }),
        "EventBusName": "agent-orchestration",
    }])

✅ Consumers verify SHA before trusting the plan — bus messages stay small and auditable.

SQS vs EventBridge

Need Prefer
Competing consumers / work queues SQS (+ DLQ)
Fan-out (critic + metrics + audit) EventBridge
Exactly-once apply SQS FIFO + idempotency keys
Cross-account notify EventBridge
// consumer/idempotency.ts
const seen = new Set<string>();
export function once(key: string, fn: () => Promise<void>) {
  if (seen.has(key)) return; // ✅ at-least-once bus, exactly-once side effect
  seen.add(key);
  return fn();
}

Closing checklist

  • [ ] Typed envelopes with schema_version
  • [ ] Artifacts in object storage with content hash
  • [ ] DLQ + alarm on poison messages
  • [ ] Idempotency keys on apply tools
  • [ ] Prefer bus when multiple roles write sequentially

Series navigation

Day 51: Multi-Agent Roles: Planner, Implementer, Critic · Day 53: Avoiding Agent Ping-Pong

Last updated September 11, 2026


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply