一个 OpenClaw 实例,多个飞书机器人身份。每个 Agent 在飞书中显示为独立的机器人——拥有自己的名称、自己的头像、自己的群组 membership。用户看到的是独立的助手;幕后,一个单一的 Gateway 负责调度一切。
30秒架构说明
OpenClaw Gateway (单一实例)
├── Agent: orchestrator ←→ 飞书应用 1 (总调度 bot)
├── Agent: content-writer ←→ 飞书应用 2 (写作 bot)
├── Agent: code-expert ←→ 飞书应用 3 (开发 bot)
└── Agent: analyst ←→ 飞书应用 4 (分析 bot)
三个配置块必须对齐:
| 块 | 在 openclaw.json 中的位置 | 用途 |
|---|
channels.feishu.accounts | 每个机器人的飞书凭证 | 将 accountId 映射到 appId/appSecret |
bindings | 消息路由规则 | 将 accountId 映射到 agentId |
agents.list | Agent 定义 | 将 agentId 映射到 workspace/model/tools |
accountId 是将它们联系在一起的关键。在任何一处出错,路由都会静默失效。
快速开始
1. 创建飞书应用
在 open.feishu.cn/app 为每个 Agent 创建一个企业应用。启用 "Bot" 能力。记录每个应用的 AppID 和 AppSecret。
2. 运行设置辅助脚本
scripts/setup-feishu-bots.sh orchestrator:cli_xxx:secret1 writer:cli_yyy:secret2 coder:cli_zzz:secret3
生成三个 JSON 块,可直接粘贴到 openclaw.json 中。
3. 注册 Agent 并重启
将生成的配置添加到 openclaw.json,然后:
openclaw doctor && openclaw gateway restart
4. 测试每个机器人
分别向每个飞书机器人发送消息。验证每个都使用正确的 Agent 身份响应。
参考文件
关键教训(节省时间)
1. accountId 必须在3处匹配:channels.feishu.accounts.{key}、bindings[].match.accountId,以及账户配置内的 agent 字段。一个拼写错误 = 静默路由失败。
2. 绑定类型必须是 "route":使用 "delivery" 或任何其他值会导致网关启动失败,且没有有用的错误消息。
3. 飞书应用必须已发布:草稿状态的应用无法接收消息。这是 "机器人无响应" 的首要原因。
4. allowAgents 必须完整:如果你的 orchestrator 生成了子 agent,每个可生成的 agent ID 都必须在 allowAgents 中。新增 agent 但未列入 = spawn 权限错误。
5. agentToAgent 必须保持关闭:启用 agentToAgent.enabled: true 会破坏所有子 agent 的 spawn(已知 bug #5813)。保持为 false。请参阅 references/troubleshooting.md 获取完整的诊断流程图。
脚本
| 脚本 | 用法 |
|---|
scripts/setup-feishu-bots.sh | ./setup-feishu-bots.sh ... — 生成 channels、bindings 和 agents.list JSON 块 |
One OpenClaw instance, multiple Feishu bot identities. Each Agent appears as an independent bot in Feishu — own name, own avatar, own group memberships. Users see separate assistants; behind the scenes, a single Gateway dispatches everything.
Architecture in 30 Seconds
OpenClaw Gateway (single instance)
├── Agent: orchestrator ←→ Feishu App 1 (总调度 bot)
├── Agent: content-writer ←→ Feishu App 2 (写作 bot)
├── Agent: code-expert ←→ Feishu App 3 (开发 bot)
└── Agent: analyst ←→ Feishu App 4 (分析 bot)
Three configuration blocks must align:
| Block | Location in openclaw.json | Purpose |
|---|
channels.feishu.accounts | Feishu credentials per bot | Maps accountId → appId/appSecret |
bindings | Message routing rules | Maps accountId → agentId |
agents.list | Agent definitions | Maps agentId → workspace/model/tools |
The
accountId is the key that ties them together. Get it wrong in any one place and routing breaks silently.
Quick Start
1. Create Feishu Apps
One enterprise app per Agent at open.feishu.cn/app. Enable "Bot" capability. Record each app's AppID and AppSecret.
2. Run the setup helper
scripts/setup-feishu-bots.sh orchestrator:cli_xxx:secret1 writer:cli_yyy:secret2 coder:cli_zzz:secret3
Generates the three JSON blocks ready to paste into openclaw.json.
3. Register agents and restart
Add the generated config to openclaw.json, then:
openclaw doctor && openclaw gateway restart
4. Test each bot
Send a message to each Feishu bot independently. Verify each responds with the correct Agent identity.
Reference Files
Critical Lessons (Save Hours)
1. accountId must match in 3 places: channels.feishu.accounts.{key}, bindings[].match.accountId, and the agent field inside the account config. One typo = silent routing failure.
2. Binding type must be "route": Using "delivery" or any other value causes gateway startup failure with no helpful error message.
3. Feishu apps must be published: Draft-state apps cannot receive messages. This is the #1 "bot not responding" cause.
4. allowAgents must be complete: If your orchestrator spawns sub-agents, every spawnable agent ID must be in allowAgents. New agent added but not listed = spawn permission error.
5. agentToAgent must stay OFF: Enabling agentToAgent.enabled: true breaks all sub-agent spawning (known bug #5813). Keep it false.
See references/troubleshooting.md for the full diagnostic flowchart.
Scripts
| Script | Usage |
|---|
scripts/setup-feishu-bots.sh | ./setup-feishu-bots.sh ... — Generates channels, bindings, and agents.list JSON blocks |