共享记忆与黑板模式


文档摘要

共享记忆与黑板模式 本节摘要:2026 多智能体系统里两种共享状态共存——消息池(所有人看到所有消息,如 AutoGen GroupChat/MetaGPT)与带订阅的黑板(Agent 订阅相关事件,如 CA-MCP/Matrix)。两者都是系统里唯一有状态的部分——所以两者都是有趣 bug 的住所。参考失败模式是记忆投毒(memory poisoning):一个 Agent 幻觉出一个「事实」,其他 Agent 当它已验证,准确率缓慢衰减,比立即崩溃难调试得多。本节用标准库搭出两种结构,注入一次投毒攻击,展示生产里真正有效的三条缓解:每次写附溯源、版本化追加写、保留至少一个不可写的验证者。我们还会回溯 Hayes-Roth 1985 的黑板先例,以及写竞争的三种模式。

共享记忆与黑板模式

本节摘要:2026 多智能体系统里两种共享状态共存——消息池(所有人看到所有消息,如 AutoGen GroupChat/MetaGPT)与带订阅的黑板(Agent 订阅相关事件,如 CA-MCP/Matrix)。两者都是系统里唯一有状态的部分——所以两者都是有趣 bug 的住所。参考失败模式是记忆投毒(memory poisoning):一个 Agent 幻觉出一个「事实」,其他 Agent 当它已验证,准确率缓慢衰减,比立即崩溃难调试得多。本节用标准库搭出两种结构,注入一次投毒攻击,展示生产里真正有效的三条缓解:每次写附溯源、版本化追加写、保留至少一个不可写的验证者。我们还会回溯 Hayes-Roth 1985 的黑板先例,以及写竞争的三种模式。读完本节,你能审计任何多智能体系统的共享记忆设计,在它投毒前堵住。

学习目标

阅读完本节,你应当能够:

  1. 区分两种共享状态拓扑(全量消息池 vs 带订阅的黑板)及其适用场景。
  2. 用标准库实现两者,并演示记忆投毒如何沿共享状态传播。
  3. 应用三条生产缓解:每次写附溯源、版本化追加写、不可写验证者。
  4. 选择写竞争模式(串行写者、乐观并发版本化、主题分区)。
  5. 审计多智能体系统的共享记忆设计(provenance、versioning、verifier 分离)。

一、问题与直觉

多智能体系统需要一处地方让 Agent 共享事实。字面的选项是「全用消息传」——但那是在重新发明共享状态还多了拷贝。另一个是「给所有人一份全局日志」——但全局日志无限增长且易被投毒。第三个是「每 Agent 投影视图」——可扩展但 schema 重。

当一个 Agent 幻觉并把幻觉写进共享状态,每个读该状态的下游 Agent 都把幻觉采纳为事实。等人类察觉时,推理链已深五层,根因是史上第三条消息。调试多智能体准确率衰减比调试崩溃难得多。

这就是记忆投毒。它是 MAST 分类(Cemri 等,arXiv:2503.13657)里第二多被记录的失败家族,且是结构性的:任何没有溯源、没有不可写验证者的共享记忆设计,最终都会出现它。

两种主要拓扑

  • 全量消息池:每个 Agent 读每条消息。AutoGen GroupChat、MetaGPT 用这个。简单、透明、可检查,但过不了约 10 个 Agent——每个 Agent 上下文被他人工作塞满。
  • 带订阅的黑板:Agent 声明对主题的兴趣,底座只路由相关消息。CA-MCP(arXiv:2601.11595)、Matrix(arXiv:2511.21686)用这个。扩展更远,但需预先设计 schema 让订阅有意义。

各自何时赢

  • 全量池:Agent 少(<10)、异构、会话短时程;每个人都看到一切时,「谁说了什么」的推理很简单。
  • 黑板:Agent 多、角色同质但实例众多(集群)、会话长时程;路由省 token 成本与上下文污染。

生产系统常混用:顶层小全量池(规划层),下层黑板(工人层)。

记忆投毒:一个场景

三 Agent 做研究:Agent A 检索,B 摘要,C 分析。

  1. A 取回页面,写消息:「研究称准确率提升 42%。」
  2. 页面实际写的是「4.2%」。A 幻觉了小数点。
  3. B 读共享态,写:「报告大增 42%(来源:A)。」
  4. C 读共享态,写:「建议采纳——42% 提升是变革性的。」
  5. 最终报告引用了一个从未存在的 42%。

没有 Agent 崩溃,没有测试失败,系统「成功了」。幻觉从一个 Agent 的上下文,经共享状态,洗白进了每个下游 Agent 的推理。

⚠️ 这正是「协调难点在状态」的集中爆发——共享状态让一个 Agent 的幻觉变成所有人的事实。问题不在共享状态本身,而在没有溯源、没有独立验证者的共享状态。

为什么是结构性的

无共享状态时,A 的幻觉留在 A 的上下文;下游会重新取数或重新推导,可能抓到错。天真的共享状态把 A 的上下文变成所有人的上下文,幻觉被洗白成事实。三条缓解:

  1. 每次写附溯源:每条记录写清谁写的、何时、在什么提示下、(若有)引用了什么来源。下游 Agent 带着按溯源分级的怀疑去读。
  2. 版本化追加写:订正是新条目取代旧条目,而非原地更新。审计轨迹保留。
  3. 保留至少一个不可写共享态的 Agent:只读验证者抽样条目、重取来源、标不一致。因为它不能写池,它不会被池投毒。

黑板先例(Hayes-Roth, 1985)

黑板模式比 LLM Agent 早四十年。Hayes-Roth(1985, A Blackboard Architecture for Control)描述了专精的 Knowledge Source 观察全局黑板、贡献部分解、触发其他源。2026 的黑板(CA-MCP、Matrix)是同一模式,LLM Agent 当 Knowledge Source、JSON blob 当部分解。老文献里有写竞争、机会式控制、一致性的成文解法,现代系统在重新发现。

投影 vs 全量视图

纯黑板给每个订阅者相同的投影(主题作用域)。更激进的是按 Agent 投影:每个 Agent 拿到按角色定制的视图。LangGraph 的 state reducer 是 2026 的典范实现——reducer 函数把全局状态折叠成角色专属切片。按 Agent 投影扩展更远但需要 schema;没有就在每个 Agent 提示里重建 ad-hoc 投影。

写竞争模式

多 Agent 同时写是并发问题,不只是 LLM 问题。三种模式:

  • 串行写者(单生产者):所有写经一个协调 Agent 序列化。简单,但是瓶颈。
  • 乐观并发 + 版本化:每条目带版本,写者版本不匹配时失败重试。经典数据库技术。
  • 主题分区:不同 Agent 拥有不同主题,无跨主题竞争。需设计分区边界。

多数 2026 框架默认串行写者,因 LLM 调用够慢、竞争罕见、瓶颈不痛。

不可写验证者

最承重的缓解是只读验证者。实现规则:

  • 验证者与团队共享状态(读黑板或池)。
  • 验证者对共享态无写句柄——只对一个独立的验证通道有写权限。
  • 验证者独立重取写中引用的来源,标分歧。
  • 验证者自己的输出路由给人类或独立决策 Agent,绝不回流进池。

没有这种分离,验证者输出就成了池里的新条目——被投毒的池会投毒验证者,投毒其验证。

二、从零实现

code/main.py 用标准库实现两种拓扑,加一个投毒攻击与三条缓解。

消息池与黑板

import threading class MessagePool: def __init__(self): self._lock = threading.Lock(); self.entries = [] def write(self, writer, content, provenance): with self._lock: self.entries.append({"writer": writer, "content": content, "ts": time.time(), **provenance, "superseded_by": None}) def view(self): return [e for e in self.entries if not e["superseded_by"]] class Blackboard: def __init__(self): self.topics = {}; self.subs = {} def subscribe(self, agent, topic): self.subs.setdefault(topic, []).append(agent) def publish(self, topic, entry): for agent in self.subs.get(topic, []): agent.receive(topic, entry)

投毒场景与验证者

def scenario_without_verifier(): pool = MessagePool() pool.write("retriever", "准确率提升 42%", {"source_uri": "page-X"}) # retriever 幻觉了;真实是 4.2% summarizer.write_summary(pool) # 「42% 大增」 analyst.write_rec(pool) # 「建议采纳,42% 变革性」 return final_report(pool) # 引用 42%,从未存在 def scenario_with_verifier(): pool = MessagePool() verifier = ReadOnlyVerifier(pool) # 读池,只写独立 channel verifier.re_fetch_all_sources() # 重取 page-X,发现真实 4.2% verifier.flag("retriever 条目与来源不符") # 池被标 flagged,最终报告含订正

设计要点:验证者的「只读 + 独立输出通道」是它不被投毒的关键——若它能写池,被投毒的池就投毒了它,进而投毒其验证。这条隔离边界是整个缓解的承重墙。

三、框架对比

拓扑/机制 代表 共享状态 写竞争 验证者
全量消息池 AutoGen GroupChat、MetaGPT 全局日志 默认串行 调用者自加
带订阅黑板 CA-MCP、Matrix 主题 pub/sub 主题分区 调用者自加
按 Agent 投影 LangGraph reducer 角色专属切片 reducer 函数序列化 独立节点
Hayes-Roth 经典黑板 Hearsay-II 全局黑板 机会式控制 KS 互验

💡 心法:框架提供拓扑,但溯源/版本化/不可写验证者要你自己加。 不加这三条,任何框架都会被记忆投毒咬到——这是结构性问题,不是框架缺陷。

四、可复用产物

outputs/skill-memory-auditor.md:审计任何多智能体系统的共享记忆设计——查溯源、版本化、验证者分离。在进生产前对新架构跑一遍。

五、练习

  1. 观察投毒:跑 code/main.py,确认 run1 传播幻觉、run2 抓住它。
  2. 第二处幻觉:加 Agent B 编造数据集大小。验证者应不针对性调优就抓到两处。
  3. 黑板分区:把全量池换成带主题分区(prices/summaries/analyses)的黑板。主题分区让哪些投毒更难发动,哪些帮不上?
  4. 读 Hayes-Roth:读 Hayes-Roth 1985,识别两个本节未讨论的控制模式,2026 系统会受益。
  5. 读 CA-MCP:读 CA-MCP,把其 Shared Context Store 映射到 MessagePool 或 Blackboard。它在原语之上加了什么?

本节要点回顾

  1. 两种共享状态拓扑:全量消息池(简单不扩展)与带订阅黑板(扩展需 schema);生产常混用(顶层池 + 下层黑板)。
  2. 共享状态是唯一有状态部分:所有有趣 bug 都住在这里。
  3. 记忆投毒是结构性失败:一个 Agent 的幻觉经共享状态洗白成所有人的事实;是 MAST 第二大失败家族。
  4. 三条缓解:每次写附溯源、版本化追加写(订正是新条目)、不可写验证者。
  5. 不可写验证者是承重墙:只读共享态、独立重取来源、输出路由到独立通道——失去这条隔离就被池反投毒。
  6. 黑板有四十年先例:Hayes-Roth 1985 的 Knowledge Source 就是 LLM Agent,老文献有写竞争与一致性的成文解法。
  7. 按 Agent 投影扩展最远:LangGraph reducer 把全局状态折叠成角色切片,但需 schema。
  8. 写竞争三模式:串行写者(默认,因 LLM 慢)、乐观并发版本化、主题分区。

下一节,我们进入分布式系统最经典的协调难题——共识与拜占庭容错,看当 Agent 可能出错甚至撒谎时,多智能体如何达成一致。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U