常驻 Agent vs 无状态 Agent:多渠道 AI 架构的两条路
作者:Arvin
日期:2026-03-13
关键词:AI 架构、多渠道通信、Session 设计、有状态 vs 无状态
引言
当你在私聊和群聊中与同一个 AI 助手交互时,有没有想过:为什么它在不同渠道上表现不一样? 这个问题看似简单,但解决方案却取决于一个更根本的架构决策。
本文通过对比两个真实系统------GolemBot (无状态)和 OpenClaw/Javis(常驻)------来深度分析多渠道 AI 架构的设计权衡。
第一部分:两种架构的对比
1.1 GolemBot:无状态的 Session-Per-Request 模式
工作流程:
用户消息(来自 Feishu、Telegram、Discord 等)
↓
GolemBot 接收
↓
生成 Session Key(基于消息来源)
↓
调用 claude --resume <sessionId>
↓
Claude Code 处理 → 返回结果
↓
结果发送回用户
↓
Session 关闭(或休眠)
关键特征:
- 每条消息触发一个 Claude Code 进程
- 进程处理完立即关闭(或进入待命状态)
- 无持续性的内存占用
- Session 通过文件系统持久化(session ID → 历史记录)
优势:
- 轻量级,单位成本低
- 易于水平扩展(可以部署多个 GolemBot 实例)
- 故障隔离(一个 session 的问题不影响其他)
- 无须长时间维护内存连接
劣势:
- 启动开销大(每次 ~1-2 秒)
- 无法维护实时的"思维状态"
- 多渠道问题需要在 session key 层面解决
1.2 OpenClaw/Javis:常驻的 Always-On 模式
工作流程:
启动时
↓
Javis 常驻 session 启动
↓
等待消息...
↓
消息1 进来 → 处理(session 保活,上下文累积)
消息2 进来 → 处理(同一 session,记忆延续)
消息3 进来 → 处理(持续学习)
...(永不关闭)
关键特征:
- 启动一次,永久运行
- 内存中维护完整的对话历史
- 可以访问本地文件系统(memory/、skills/)
- 与向量数据库(LanceDB)集成
优势:
- 无启动延迟,响应快速
- 可以维护真正的"思维连续性"
- 能够实现复杂的自适应行为
- 天然支持长期学习和改进
劣势:
- 内存持续占用(成本高)
- 单点故障风险
- 难以水平扩展
- 需要持续的运维监控
第二部分:多渠道一致性问题的两种解决方案
2.1 问题的本质
当同一个用户通过不同渠道(DM、群聊)与 AI 交互时,系统需要识别"这是同一个人",并保持一致的行为。
表现症状:
- 用户在 DM 中详细讨论了一个话题
- 用户在群聊中提到同一话题时,AI 表现得像"新手"
- 或者,AI 在群聊中暴露了用户在 DM 中的隐私信息
这个问题的根源不在 AI,而在消息路由和 session 管理。
2.2 GolemBot 的解决方案:Session Key 统一
问题根源(之前的实现):
javascript
// 错误的做法
const sessionKey = msg.chatType === 'group'
? `feishu:${msg.chatId}` // ❌ 整个群共用一个 session!
: `feishu:${msg.chatId}:${msg.senderId}`; // ✅ DM 有用户标识
结果:
- 用户 A 在群里发消息 → 群 session
- 用户 B 在群里发消息 → 同一个群 session(混淆!)
- 用户 A 在 DM 发消息 → 用户 A 的 DM session
- 用户 A 在群里发消息 → 新的群 session(与 DM 不连贯!)
解决方案(修复后):
javascript
// 正确的做法
const sessionKey = `feishu:${msg.senderId}:${msg.chatId}`;
// 统一规则:始终包含用户标识
结果:
- 用户 A 在 DM 发消息 → session:
feishu:ou_A:oc_DM - 用户 A 在群 1 发消息 → session:
feishu:ou_A:oc_群1 - 用户 A 在群 2 发消息 → session:
feishu:ou_A:oc_群2 - 用户 B 在群 1 发消息 → session:
feishu:ou_B:oc_群1(不同的 session!)
关键点:
- session key 中必须包含用户 ID
- 这样保证了每个用户的历史是独立的
- 但同一用户在不同渠道仍然是同一个 session 历史
2.3 OpenClaw/Javis 的解决方案:LanceDB 语义检索
问题根源(OpenClaw 中):
Javis 有两个独立的 session:
1. 群聊 session(当 Javis 在群里被 @ 时启动)
2. DM session(当用户在 DM 里找 Javis 时启动)
这两个 session 互不相知
→ 群聊中看不到 DM 的上下文
→ DM 中看不到群聊的信息
解决方案(Plan C - LanceDB):
所有消息(无论来自哪个渠道)
↓
自动向量化并存储到 LanceDB
↓
Javis 处理消息时:
1. 接收消息(可能来自群聊或 DM)
2. 在 LanceDB 中进行语义检索:
"这条消息涉及的话题"
→ 搜索相关的历史对话
3. 将检索结果注入当前对话上下文
4. 生成响应(有完整的上下文)
关键点:
- 不依赖 session key,而是靠语义相似性
- LanceDB 作为"全局大脑",存储所有对话
- 每个 session 的主要作用是"实时交互",而不是"保存历史"
- 历史由向量数据库管理
第三部分:两种方案的深度对比
3.1 设计哲学的差异
| 维度 | GolemBot(无状态) | Javis(常驻) |
|---|---|---|
| 基本假设 | 每次交互都是独立的 | 连续对话中的一环 |
| 状态管理 | 文件系统(sessionId → 文件) | 内存 + 向量数据库 |
| 上下文来源 | 同一 session key 的历史 | 语义搜索 + 当前上下文 |
| 隐私模型 | Session key 天然隔离 | 需要在检索层实现隔离 |
| 成本模型 | 按调用次数计费 | 按常驻时间计费 |
3.2 实际工程考虑
GolemBot 的权衡:
优点:
- 易于部署和扩展
- 成本可控(按需计费)
- 故障恢复简单(重启一个 session)
缺点:
- 需要频繁启动 Claude Code 进程(启动开销)
- Session key 设计需要考虑各种渠道组合
- 无法实现实时的"思维连贯性"
Javis 的权衡:
优点:
- 启动快速(已常驻)
- 可以实现复杂的自适应行为
- 天然支持长期学习
缺点:
- 内存占用大(always-on)
- LanceDB 需要额外的向量化和检索成本
- 单点故障风险
- 隐私和信息隔离需要额外设计
3.3 多渠道一致性的本质差异
GolemBot 的思路:
- 问题:群消息和 DM 消息被分配了不同的 session key
- 解决:在 key 生成时统一规则(加入用户 ID)
- 结果:同一用户在所有渠道共享一个 session 历史
Javis 的思路:
- 问题:群聊和 DM 是两个独立的 session,无法直接共享上下文
- 解决:在向量层实现全局的语义检索
- 结果:同一用户的所有对话都在"同一个大脑"里,可以随时调用
第四部分:选择哪一个架构?
4.1 场景分析
选择 GolemBot(无状态)如果:
- 你需要支持高并发用户
- 成本控制是首要考虑
- 对话是相对独立的(不需要深度的长期记忆)
- 需要快速扩展到多个平台
- 可以承受每次启动的 1-2 秒延迟
适用场景:聊天机器人、FAQ 助手、简单的信息查询
4.2 选择 Javis(常驻)如果**:
- 你需要支持深度、长期的对话
- 延迟要求很高(毫秒级)
- 需要 AI 具备自适应和学习能力
- 可以承受较高的基础设施成本
- 多渠道的上下文连贯性很重要
适用场景:个人助手、研究伙伴、长期项目管理、多渠道协作
第五部分:混合架构的未来
5.1 最优架构可能是混合的
实际上,两种模式各有其优势。未来的 AI 架构可能会采取混合策略:
┌─────────────────────────────────────┐
│ 网关层(Gateway) │
│ - 消息路由 │
│ - 优先级判断 │
│ - 简单查询 vs 复杂任务分类 │
└──────────┬──────────────────────────┘
│
┌─────┴─────┐
▼ ▼
┌─────────┐ ┌──────────────┐
│ 轻量级 │ │ 深度交互 │
│ Bot │ │ Agent │
│(无状态) │ │(常驻) │
└─────────┘ └──────────────┘
│ │
└─────┬─────┘
▼
┌────────────────┐
│ LanceDB │
│ (全局记忆) │
└────────────────┘
这样的架构可以:
- 用无状态 bot 处理简单、高并发的查询
- 用常驻 agent 处理复杂的长期项目
- 都通过 LanceDB 共享全局的知识和上下文
结论
多渠道 AI 的"一个大脑"问题没有唯一的解决方案,而是两条不同的路:
-
GolemBot 的路 :在消息路由层统一识别
- 方法:修复 session key 的生成逻辑
- 成本:低(只需改一行代码)
- 适用:无状态、高并发的场景
-
Javis 的路 :在记忆层实现全局融合
- 方法:LanceDB 语义检索 + 上下文注入
- 成本:高(需要向量化和检索)
- 适用:常驻、深度交互的场景
两条路的共同点:都是在系统的某个层级上做出设计决策,从而达到"无论在哪个渠道,都是同一个我"的效果。
选择哪一条路,取决于你的系统架构、成本预算和应用场景。
附注
这篇文章源于对两个真实系统的深度对比:
- GolemBot:https://github.com/0xranx/golembot
- OpenClaw:https://github.com/openclaw/openclaw
两个系统都成功地解决了多渠道 AI 的问题,只是采取了截然不同的设计哲学。没有绝对的"更好",只有"更适合"。
理解这两条路的区别,对于设计你自己的多渠道 AI 系统很有启发意义。