当你兴冲冲地给团队搭了一个 AI 助理,让 100 个人同时使用它时——你有没有想过,张三告诉 Bot 的偏好,会不会在李四的对话里冒出来?
这不是假设。这是我在实际部署 OpenClaw(一个开源 AI Agent 框架)时踩到的真实地雷。
本文用一次从零到一的架构设计过程,彻底讲清三件事:
1. Sub-Agent 和 Multi-Agent 到底有什么区别
2. 100 个用户共用一个 Bot 时,记忆污染是怎么发生的
3. 怎么用一套三层记忆模型彻底消灭它
一、先搞清概念:Sub-Agent ≠ Multi-Agent
很多人(包括我)一开始分不清这两个词。但在 OpenClaw 的架构里,它们的生命周期完全不同:
Sub-Agent = 临时外包
主 Bot 遇到复杂任务时,临时拉起一个隔离的执行线程。它有自己的上下文,但 60 分钟后自动销毁,不保留任何记忆。
典型场景:主 Bot 说"我派个小弟去查 500 行日志",查完汇报结果,小弟原地消失。
Multi-Agent = 独立员工
每个 Agent 都是一个持久化的独立进程,拥有自己的:
- Workspace(工作目录)
- SOUL.md(人格契约)
- MEMORY.md(长期记忆)
- 独立的通道绑定(比如各自对应不同的 Telegram Bot)
典型场景:JIRA 客服 Bot、项目管理 Bot、运维告警 Bot,各司其职,互不干扰。
一句话判断:如果你的 Bot 需要"记住昨天发生了什么",就必须用 Multi-Agent。Sub-Agent 是阅后即焚的。
二、100 个用户共用一个 Bot,记忆会怎样污染?
假设你用 Multi-Agent 创建了一个 JIRA Bot,绑定到钉钉群,团队 100 个人都在用它建单子、查进度。
这里有两层隔离需求,很多人只看到了第一层。
第一层:对话隔离(OpenClaw 原生支持)
OpenClaw 提供了 session.dmScope 配置项,控制对话流的隔离粒度:
配置值
效果
main(默认)
所有人共享同一条对话流——灾难
per-peer
按发送者 ID 隔离
per-channel-peer
按通道 + 发送者隔离(推荐)
设置 per-channel-peer 后,张三和李四的聊天记录就互相看不到了。这一层是纯配置,一行 JSON 搞定。
但这只解决了"看不到别人说了什么"。
第二层:记忆隔离(OpenClaw 原生不支持)
这才是真正的地雷。
OpenClaw 的长期记忆存储在 Agent 级别的 MEMORY.md 文件里。所有用户的交互产生的记忆,全部混写在同一个文件中。
这意味着:
- 张三说"我喜欢用 Epic 类型建单",Agent 记住了
- 李四来建单时,Agent 可能自动选了 Epic——因为它"记得"有人喜欢这样
对话隔离了,但记忆没有隔离。 Agent 的大脑被所有用户共享,它分不清哪段记忆属于谁。
三、三层记忆模型:彻底消灭污染
解法是把 Agent 的记忆拆成三层,按照"共享范围"逐级收窄:
┌──────────────────────────────────┐
│ SOUL.md(只读) │
│ Agent 的人格与行为约束 │
│ 所有用户共享,启动后不可变 │
├──────────────────────────────────┤
│ MEMORY.md — Agent 级共享知识 │
│ "PROJ 项目有 Bug/Story/Epic" │
│ "Sprint 周期两周" │
│ 仅存放客观事实,所有用户可读 │
├──────────────────────────────────┤
│ memory/users/{channel}_{uid}.md │
│ "张三习惯用 Epic 建单" │
│ "张三上次查的是 PROJ-1234" │
│ 严格按用户隔离,互不可见 │
└──────────────────────────────────┘
目录结构长这样:
workspace-jira/
├── SOUL.md
├── MEMORY.md
└── memory/
├── shared/
│ └── jira_projects.md
└── users/
├── dingtalk_uid_001.md
├── dingtalk_uid_002.md
└── telegram_uid_003.md
核心规则:
- 向上共享:所有用户都能读到公共知识(项目结构、Sprint 配置)
- 向下隔离:每个用户只能读写自己的记忆文件
- 写入判决:Agent 每次要"记住"什么东西时,先判断——这是"项目事实"还是"用户偏好"?前者写共享文件,后者写用户文件
四、怎么落地?
从务实角度,按复杂度递进选择:
方案 A:SOUL 指令约束(最快)
直接在 SOUL.md 里写明记忆分层规则,让 Agent 自己按规则读写文件。零代码,但依赖模型的指令遵循能力。
方案 B:Custom Skill 自动化路由(最稳)
开发一个 user-memory Skill,封装 read/write 操作。Skill 自动从当前 Session 提取 peer ID,路由到对应的用户记忆文件。Agent 不需要自己操心文件名。
方案 C:外部数据库(最重)
用 Redis 或 SQLite 替代文件系统,key 为 {agent}:{channel}:{uid}。除非你有上万用户,否则属于过度工程。
建议先用 A + B 组合起步。
五、顺手带走的经验
回顾整个设计过程,几个认知升级值得记录:
-
不要混淆框架术语和通用概念。OpenClaw 的 "Sub-Agent" 有严格的技术定义(临时、60 分钟归档),不要拿通用的"子代理"概念去套。RTFM 永远是第一步。
-
对话隔离 ≠ 记忆隔离。前者是"看不到别人的聊天记录",后者是"Agent 不会把别人的习惯套在你身上"。很多架构设计只做了前者就以为万事大吉。
-
Skills 天然是全局共享的。Multi-Agent 架构下,技能代码只需要部署一份(就像 Linux 的
/usr/bin/),不同 Agent 通过配置赋权使用。代码公有,状态私有。 -
文件系统是最朴素也最可靠的隔离手段。OpenClaw 用 Markdown 文件做记忆存储,听起来原始,但它天然支持按目录隔离、按文件名路由、用 Git 追踪变更。不要小看简单设计的力量。
这篇文章源于一次真实的架构设计讨论。如果你也在搭建多用户 AI Agent 系统,希望这套三层记忆模型能帮你绕过我趟过的坑。