OpenClaw 中的 AI 助手为什么无法跨群组共享上下文?从第一性原理重新思考多渠道 Agent 架构
Q:一个 user_id 对应的是一个人吗?A:是的。Q:一个 chat_id 对应的是不同的"地点"吗?A:是的。Q:一个人在不同的地点应该有"分身"吗?A:不应该。那么,为什么我们现在的设计是"按 chat_id 创建独立 Session"?因为当前的架构缺乏一个更高层的抽象——用户级别的、跨越所有 chat_id 的统一 Session。
OpenClaw 中的 AI 助手为什么无法跨群组共享上下文?从第一性原理重新思考多渠道 Agent 架构
引言
想象一个场景:你有一个名叫 Javis 的 AI 助手。你在飞书的 A 群组告诉它某个技术决策,然后切换到 B 群组,却发现 Javis "忘记了"你在 A 群说过的话。你切换到私聊,结果 Javis 也不知道你在群里讨论过什么。
看起来像是"两个不同的 Javis"在回复你——但实际上,你确实在和同一个人说话。
这不是 bug,而是 OpenClaw(一个开源 AI 代理框架)的架构设计选择的直接结果。本文将深入剖析这个问题的根本原因,以及我们如何从第一性原理出发重新思考多渠道 AI Agent 的设计。
第一部分:问题现象 & 身份认同的困惑
现象:同一个人,不同的"记忆"
当你和 Javis 互动时:
- 在 A 群组:Javis 知道群里讨论过的技术方案、决策过程、参与者意见
- 在 B 群组:Javis 对 A 群的任何内容都一无所知
- 在私聊里:Javis 既不知道 A 群的事,也不知道 B 群的事
- 切回 A 群:Javis 突然"恢复记忆",知道所有的讨论
本质认同问题
从 Feishu(飞书)API 的角度看:
- user_id(开放平台的用户标识):
ou_39f130f8fa1b499c91dee8bdb1eff90a—— 唯一标识一个用户 - chat_id(会话标识):可以是
oc_group_a、oc_group_b、oc_dm_xxx—— 标识不同的聊天渠道
从第一性原理出发:
- 你是一个人:你的 user_id 是唯一的
- Javis 是一个助手:应该也是一个统一的大脑
- 群组、私聊只是"窗口":就像打开电话、微信、邮件,你还是同一个你
那么问题来了:为什么 Javis 在不同的"窗口"里,就变成了不同的自己?
第二部分:根本原因 - OpenClaw 的 Session 隔离机制
当前架构:按 chat_id 创建 Session
OpenClaw 的核心设计是这样的:
Feishu 消息进来
↓
识别 chat_id(这是 A 群组还是 B 群组?)
↓
如果是新的 chat_id → 创建一个新的 Session
↓
这个 Session 处理该 chat_id 的所有消息
↓
Session 拥有独立的:
- 内存状态
- 推理过程
- 上下文管理
- 决策历史
为什么这样设计?
这个选择看似是一个无奈的妥协,但背后有合理的工程考量:
1. 隐私隔离
- A 群组讨论了你的年度计划(机密)
- B 群组只是日常闲聊
- 如果 Javis 不隔离这两个上下文,机密信息可能被无意中透露给 B 群的人
2. 上下文管理
- 一个 LLM 的 context window(上下文窗口)有限制
- 如果把所有会话的信息都混在一起,token 会快速耗尽
- 只记得该 chat_id 的对话,可以保持较高的相关性和效率
3. 并发处理
- 如果 A 群、B 群同时发来消息
- 统一的大脑会产生竞争条件(race condition)
- 用独立的 Session 更容易并发处理
看似合理的设计,实际的代价
问题在于,这个设计选择带来了一个难以接受的结果:
一个人在不同的地方和你聊天,却因为 chat_id 的不同,产生了"多重人格"。
你在 A 群说:“我们决定用技术方案 X”
然后在 B 群问:“我们之前决定用什么方案?”
B 群里的 Javis:“不知道,你没在 B 群说过”
从 B 群的 Javis 的视角,这是"正确"的——因为它的 Session 确实没有 A 群的记录。但从你的角度,这是荒谬的——你在和同一个助手说话,它怎么会"健忘"呢?
第三部分:当前的尝试 & 它们为什么还不够
尝试 1:LanceDB 的语义存储
有人想到了一个办法:建立一个全局的向量数据库(LanceDB),把所有会话的内容都存储进去。这样,即使 Session 隔离,Javis 也可以主动查询任何历史内容。
A 群消息 ──┐
B 群消息 ──┼──→ 向量化 ──→ LanceDB(全局记忆)
DM 消息 ────┘ ↓
Session A 可以查询
Session B 也可以查询
看起来不错,但问题是:
- ✅ 数据确实被存储了
- ❌ 但 Session 不会主动去查
除非你明确说"查一下之前的决策",否则 Javis 只会用当前 Session 的上下文来回答。这实际上变成了被动的记忆系统,而不是主动的一体化大脑。
尝试 2:强制注入机制
有人想,那就修改 Prompt,告诉 Javis “每次回复前都主动查一下 LanceDB”。
System Prompt:
"在每次生成回复前,主动从 LanceDB 搜索相关历史信息..."
看起来也不错,但新问题出现了:
- ❌ 什么是"相关"?搜索范围无法精确定义
- ❌ 每次都查,performance 成本高
- ❌ Session 隔离的问题依然存在——你还是在和"两个 Javis"说话,只是它们偶尔会查一下共享的记忆
第四部分:从第一性原理出发的新架构
根本问题的重新定义
让我们回到本质:
Q:一个 user_id 对应的是一个人吗?
A:是的。
Q:一个 chat_id 对应的是不同的"地点"吗?
A:是的。
Q:一个人在不同的地点应该有"分身"吗?
A:不应该。
那么,为什么我们现在的设计是"按 chat_id 创建独立 Session"?
答案是:因为当前的架构缺乏一个更高层的抽象——用户级别的、跨越所有 chat_id 的统一 Session。
新架构:一个大脑,多个窗口
┌──────────────────────────────────┐
│ Javis Agent(唯一的大脑) │
│ - 统一的思维过程 │
│ - 单一的内存状态 │
│ - 所有 user_id 的一个实例 │
└──────────────────────────────────┘
↑ ↑ ↑
消息进入 处理 回复
│ │ │
┌────┴────┬─────┴────┬─────┴────┐
│ │ │ │
Window A Window B Window C Window DM
(A 群组) (B 群组) (C 群组) (私聊)
关键点:
- 唯一的大脑:每个 user_id 对应一个 Javis 实例,而不是每个 chat_id
- 多个窗口:不同的 chat_id 只是输入/输出的管道,不产生新的思维
- 统一的内存:无论在哪个窗口收到的信息,都被记录到同一份内存里
- 隐私约束在应用层:不是架构层面的隔离,而是 Prompt 层面的隐私规则
这样做的好处
1. 一致性
你在 A 群说的话,Javis 在 B 群也知道。不再有"忘记"的问题。
2. 完整的推理链
Javis 的思考过程是连贯的。A 群的讨论会自然地影响 B 群的回复(如果相关的话)。
3. 真正的"一个人"
从第一性原理的角度,这符合人的直观理解:一个助手,一个大脑,多个沟通渠道。
4. 隐私通过规则实现
不需要架构层的"强制隔离"。而是在 Prompt 里明确标注:
[隐私级别] 来自 A 群的私密信息
[可见范围] 仅限 A 群相关讨论时使用
[警告] 不能在 B 群、私聊中暴露
Javis 作为一个足够聪明的助手,理解这些约束,自然不会跨越界限。
第五部分:工程实现的关键点
如何修改 OpenClaw
这个新架构的实现思路很清晰:
改变 Session 创建的粒度
现在(错误):
message.chat_id → 创建/查找 Session
应该(正确):
message.user_id → 创建/查找 Agent Instance
这样,同一个用户的所有消息,无论来自哪个 chat_id,都进入同一个 Agent Instance。
消息的标准化与路由
每条消息进来时,需要标注:
{
"user_id": "ou_xxx",
"chat_id": "oc_group_a",
"chat_type": "group",
"sender_name": "Alice",
"privacy_level": "public", // 或 "private"
"content": "..."
}
隐私约束在 Prompt 层实现
System Prompt 增加约束信息:
当前窗口: ${window.type}
隐私规则:
- [私密] 来自 DM 的信息不能在群聊中提及
- [公开] 群聊中讨论的技术方案可以跨群引用
- [内部] 仅涉及 user_id:ou_xxx 的信息不能暴露给其他用户
并发处理
如果同时来自 A 群、B 群、DM 的三条消息,同一个 Agent Instance 可以:
- 用队列化处理(顺序)
- 或用更细粒度的锁(性能优化)
第六部分:启示与对其他框架的意义
这个问题的通用性
OpenClaw 面临的这个问题,不是 OpenClaw 特有的,而是所有多渠道 AI Agent 框架的共同挑战:
- Discord 的 bot
- Slack 的应用
- 微信机器人
- Telegram bot
- ……
任何在多个渠道工作的 AI 助手,都会面临这个选择:用 chat_id(或 channel_id)创建独立实例,还是用 user_id 创建统一实例?
为什么这个问题没有被广泛关注?
-
大多数场景不需要跨渠道一致性
一个仅在 Discord 特定频道工作的 bot,用户不会期望它在 DM 里"记得"频道的讨论。 -
技术债务被忽视
问题存在,但不紧迫。LanceDB 这样的"记忆补丁"暂时解决了最坏情况。 -
架构重构成本高
改变 Session 的创建粒度,会影响整个框架的核心逻辑。
OpenClaw 的机会
OpenClaw 正在构建一个通用的、可扩展的 Agent 框架,它有机会从一开始就做对。
如果 OpenClaw 从第一性原理出发,采用"一个大脑,多个窗口"的架构,它会成为:
- ✅ 更符合人类直觉的 Agent 框架
- ✅ 更容易构建多渠道协调 Agent 的平台
- ✅ 更有竞争力的开源项目
结论:从隐喻回到现实
"一个大脑,多个窗口"不仅是一个架构原则,更是对什么是"一个人"的定义的重新思考。
在飞书上,当我和 Javis 互动时,我本能地认为我在和一个一致的、连贯的、有记忆的助手说话。我不期望它在 A 群"一个样",在 B 群"另一个样"。
但当前 OpenClaw 的架构给了我的体验是:多个"分身"在不同的地方回复我。
这不是技术限制,而是架构设计的选择。
而我们有机会做出不同的选择。
后记:这个问题的启蒙来源
这篇文章源于一个真实的对话。一个 OpenClaw 开发者在实现 Javis(一个多渠道 AI 助手)时,发现了这个问题。他提出了一个简单而深刻的问题:
“为什么我在和同一个人(按 user_id)说话,但系统把我当作在和不同的人(按 chat_id)互动?”
这个问题打破了我对架构的一些假设,促使我重新从第一性原理思考:什么是一个 Agent?它的身份应该如何定义?
答案并不复杂。但实现它,需要从根本上改变我们对多渠道 Agent 的思考方式。
更多推荐




所有评论(0)