飞书多 Bot 讨论实验总结
5 min read
技术实践
飞书多 Bot 讨论实验总结
实验目标:在飞书群聊中实现多个 AI Bot(Tech Lead、iOS Dev、Go Dev)之间的自主讨论 实验结论:受飞书 API 限制,无法完美实现
📋 背景
我们希望在飞书群聊中部署一个多 Agent 团队:
- Tech Lead Bot - 负责技术决策和任务分配
- iOS Dev Bot - 负责 iOS/Swift 相关问题
- Go Dev Bot - 负责后端/Go 相关问题
理想场景:用户提问 → Tech Lead 分析后 @mention 专家 → 专家回复 → 专家之间可以互相讨论
🚫 核心限制:飞书 message_receive_v1 事件
飞书的 Bot 消息接收事件 (im.message.receive_v1) 有一个关键限制:
Bot 发送的消息不会触发其他 Bot 的
message_receive_v1事件
这意味着:
- ✅ 用户 @Bot → Bot 收到事件 → Bot 回复
- ❌ BotA @BotB → BotB 收不到任何事件
这是飞书平台层面的设计,无法通过配置或 API 绑过。
✅ 最终成功的方案:Bot-to-Bot Relay(合成事件)
原理
既然飞书不会推送 Bot 间的消息事件,我们在应用层"模拟"这个过程:
BotA 回复消息 → 解析消息中的 @mention → 创建"合成事件" → 直接调用 BotB 的消息处理函数
实现架构
┌─────────────────────────────────────────────────────────────────┐
│ OpenClaw Gateway │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Tech Lead │ │ iOS Dev │ │ Go Dev │ │
│ │ Bot │────▶│ Bot │────▶│ Bot │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Bot Registry (bot-relay.ts) │ │
│ │ - 注册所有 Bot 的 OpenID │ │
│ │ - 解析 @mention 标签 │ │
│ │ - 创建合成事件并触发目标 Bot │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Shared History (shared-history.ts) │ │
│ │ - 跨 Bot 共享聊天记录 │ │
│ │ - 持久化到 JSONL 文件 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
核心代码模块
| 文件 | 功能 |
|---|---|
bot-relay.ts | Bot 注册、@mention 解析、合成事件触发 |
shared-history.ts | 跨 Bot 聊天记录共享(JSONL 持久化) |
reply-dispatcher.ts | Bot 回复后触发 relay |
monitor.ts | 启动时注册所有 Bot |
@mention 格式要求
为了让 relay 系统能解析 @mention,Bot 必须使用特定格式:
<at user_id="ou_7fbe90d92f4c1809e5cbc5dee3ce8e0d">Go助手</at>
成功实现的功能
- ✅ Tech Lead → iOS/Go Bot:Tech Lead 可以 @mention 并触发子 Bot
- ✅ 共享上下文:所有 Bot 都能看到完整的聊天历史
- ✅ 动态队友发现:每条消息都会注入可用队友列表
❌ 未解决的问题
1. iOS Bot 和 Go Bot 之间无法互相触发
现象:iOS Bot 回复时使用纯文本 @Go助手 而不是 <at user_id="..."> 格式
原因:AI 模型(qwen)没有严格遵循 SOUL.md 中的指令格式
尝试过的解决方案:
- 在 SOUL.md 中详细说明格式要求 ❌
- 动态注入队友列表和格式示例 ❌
- 多次强调"纯文本不会触发" ❌
结论:AI 模型的指令遵循能力有限,无法保证 100% 使用正确格式
2. 需要复杂的 Prompt Engineering
为了让 Bot 使用正确的 @mention 格式,需要:
- 在每条消息中注入队友列表
- 在 SOUL.md 中反复强调格式
- 这增加了 token 消耗和复杂度
📝 尝试过的其他方案
| 方案 | 描述 | 结果 |
|---|---|---|
| 飞书 Webhook | 希望通过 Webhook 接收所有消息 | ❌ 飞书不支持 Bot 消息推送 |
| 轮询消息 API | 定期拉取群聊消息 | ❌ API 有频率限制,不实时 |
| 共享 WebSocket | 多 Bot 共享一个 WS 连接 | ❌ 一个 App 只能一个连接 |
| 纯文本 @mention | 用 @Go助手 触发 | ❌ 无法可靠解析 |
🎯 最终结论
飞书平台不适合实现多 Bot 自主讨论场景
| 限制 | 影响 |
|---|---|
message_receive_v1 不推送 Bot 消息 | 必须用 Relay 模拟 |
| AI 模型指令遵循不稳定 | @mention 格式无法保证 |
| 维护成本高 | 需要管理多个 Bot、共享状态 |
替代方案建议
- 单 Bot + 内部多 Agent:一个飞书 Bot 内部路由到不同 Agent
- 其他平台:Slack、Discord 等可能有更好的 Bot 间通信支持
- 自建 IM:完全控制消息分发逻辑
🚨 残酷的真相:Bot 间通信平台对比
❌ Telegram 也不行!
Telegram 官方 FAQ 明确说明:
"Bots will not be able to see messages from other bots regardless of mode." — Telegram Bot FAQ
原因:防止 bot 无限循环 + 平台资源滥用
✅ 真正支持 Bot 互通的平台
| 平台 | Bot 互通 | 说明 |
|---|---|---|
| Discord | ✅ | Bot 可以收到其他 Bot 的 MESSAGE_CREATE 事件 |
| Slack | ✅ | Bot 可以在 channel 中互相通信 |
| Matrix/Element | ✅ | 开源协议,完全自主控制,无任何限制 |
| 自建消息队列 | ✅ | Redis/NATS/RabbitMQ,完全自由 |
| 飞书 | ❌ | Bot 消息不触发其他 Bot 事件 |
| Telegram | ❌ | Bot 无法看到其他 Bot 消息 |
| 微信/企微 | ❌ | 更严格的限制 |
🎯 推荐方案:Discord
为什么选 Discord?
- Bot 完全互通 - MESSAGE_CREATE 事件包含所有消息,包括其他 Bot
- 成熟的 API - WebSocket Gateway + REST API 完善
- 免费且稳定 - 无需付费,服务可靠
- 易于开发 - discord.js / discord.py 生态丰富
Discord 多 Agent 架构
┌─────────────────────────────────────────────────────────────┐
│ Discord Server (私有) │
│ │
│ #agent-hub (频道) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 🤖 Tech-Lead: "收到任务,@iOS-Dev 请分析这个问题" │ │
│ │ 🍎 iOS-Dev: "这是 SwiftUI 问题,建议..." │ │
│ │ 🐹 Go-Dev: "后端也需要配合,@iOS-Dev 我们协调一下" │ │
│ │ 🍎 iOS-Dev: "同意,API 接口定义如下..." │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
↑ ↑ ↑
│ │ │
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│Tech-Lead│ │ iOS-Dev │ │ Go-Dev │
│ Bot │ │ Bot │ │ Bot │
└─────────┘ └─────────┘ └─────────┘
│ │ │
└───────────────┼───────────────┘
│
▼
┌─────────────────────┐
│ OpenClaw Gateway │
│ (Discord Channel) │
└─────────────────────┘
最佳实践总结
- 平台选型:优先 Discord/Slack,避免飞书/Telegram/微信
- 架构设计:统一 Gateway 管理所有 Bot,共享上下文
- 降级方案:如必须用飞书,采用"单 Bot + 内部路由"模式
- 消息格式:使用平台原生 @mention,避免依赖 AI 生成格式