广播群组
Note
状态: 实验性。旧版 WhatsApp 广播数组仍受支持。
概述¶
智能体群线程使用顶层 broadcast 配置,在同一条入站消息上运行多个智能体。每个智能体在自己的会话中运行。频道限定条目可以通过提及选择参与者,并允许有限数量的后续轮次,以便智能体可以基于同级回复进行构建。
频道允许列表和群激活规则仍然适用。对于 Discord、Slack 和 Telegram 上的限定条目,显式提及任何已配置参与者都可以满足房间的提及门控,即使该参与者不是常规路由智能体。旧版 WhatsApp 条目保留其现有准入行为。
实时 WhatsApp QA 通道包含 whatsapp-broadcast-group-fanout,它验证一条被提及的群消息可以由两个已配置智能体产生不同的可见回复。
配置¶
智能体群线程¶
使用形如 "<channel>:<peerId>" 的键,例如
"discord:123456789"、"slack:C0123"、"telegram:-100123" 或
"whatsapp:1203@g.us"。值可以是智能体 ID 数组或严格对象:
{
agents: {
ownership: "explicit",
entries: {
reviewer: {
name: "Reviewer",
groupChat: { mentionPatterns: ["@reviewer\\b"] },
},
writer: {
name: "Writer",
groupChat: { mentionPatterns: ["@writer\\b"] },
},
},
},
bindings: [{ agentId: "reviewer", match: { channel: "telegram" } }],
broadcast: {
"telegram:-100123": {
agents: ["reviewer", "writer"],
mentionGating: true,
maxRounds: 2,
maxTurns: 4,
},
},
}
普通频道路由仍需要一个智能体;上述绑定在群分发前选择
Reviewer 进行准入。在房间被其频道配置允许后,发送 @reviewer @writer Review
this draft。两个参与者都可以回复初始消息,并在预算内
通过一个后续轮次添加新内容。发送 @writer 可仅为初始轮次选择
Writer。
| 对象字段 | 默认值 | 约定 |
|---|---|---|
agents |
必填 | 已配置的智能体 ID;最多 16 个参与者。 |
mentionGating |
true |
选择显式提及的参与者;如果没有匹配项,则选择全部。 |
maxRounds |
1 |
1 到 4 的整数,包括初始轮次。 |
maxTurns |
agents.length |
1 到 32 的整数;针对一条入站消息启动的参与者轮次总数。 |
未知对象字段会被拒绝。限定数组使用相同默认值:
"slack:C0123": ["reviewer", "writer"] 会执行一个带提及选择的初始轮次。对于同一 peer,限定 WhatsApp 键优先于非限定键。不支持非限定对象条目。
maxTurns 统计协调器启动的智能体运行,包括通过或失败的运行。在并行启动前同步预留槽位,因此并行参与者不会超支预算。如果预算小于符合条件的参与者数量,则配置顺序决定哪些轮次启动。一个轮次可以通过分块、预览或消息工具发送产生多条平台消息。这些投递由智能体运行和频道传输控制;maxTurns 不统计、缓冲或限制物理消息。
Telegram、Discord 和 Slack 会为限定群线程禁用其共享预览和进度草稿,以免并发参与者相互覆盖草稿。最终回复、块回复和消息工具发送仍然可用。
默认轮次预算覆盖每个已配置智能体一个轮次。要让每个智能体运行两次,请设置 maxRounds: 2,并将 maxTurns 设为参与者数量的两倍。
提及选择¶
选择仅使用当前入站文本中显式的 @ 样式匹配,并为参与者集合计算一次。普通文本中的名称或单独的表情符号不会选择参与者。提及模式依次从智能体的 groupChat.mentionPatterns、messages.groupChat.mentionPatterns,然后是其身份派生模式解析。当你希望分别称呼参与者时,请为参与者提供不同的模式。
当 mentionGating: true 时,匹配项仅为第 1 轮选择匹配的参与者;没有匹配项则选择全部。当 mentionGating: false 时,选择所有参与者。此选项不会关闭频道的 requireMention 策略、发送者允许列表或命令授权。
有界后续轮次¶
在完成一轮后,只有在同时满足 maxRounds 和 maxTurns 的情况下才能运行另一轮。符合条件的参与者是在上一轮产生最终回复的参与者,或在同级参与者的最终回复中被点名提及的参与者。每个参与者的最终文本在摘要中限制为 4,000 个字符;同级文本合计限制为 16,000 个字符。每个参与者都会收到一份来自该轮同级最终回复的带来源、大小受限的摘要,并附有指示:仅在添加新内容时回复,否则返回 NO_REPLY。通过不会产生可见的最终回复。
所有参与者通过都会结束线程。达到任一限制或取消也会停止后续轮次。每个延续都有自己内部标识;它不是对物理入站消息的重放。顺序策略会改变一轮内的启动顺序;它不会将该轮变成每个参与者都能看到同一轮较早回复的流水线。
预算状态保存在内存中,作用域为频道、账户、会话、线程和根入站消息。它不可在重启后恢复:Gateway 重启会丢失活动轮次和预算状态。普通入站去重仍是独立的保护机制。
参与者标签¶
当限定条目配置了多个参与者时,Discord、Slack 和 Telegram 的回复会以粗体参与者名称开头。配置的数量控制标签显示,即使提及选择、轮次预算或静默只留下一个响应者。WhatsApp 的展示方式保持不变。
基本设置¶
旧版单遍设置使用未限定的 WhatsApp 对等 ID 作为键,并使用代理 ID 数组作为值:
- 群聊:群组 JID(例如
120363403215116621@g.us) - 私聊:发送者的 E.164 电话号码(例如
+15551234567)
结果: 当 OpenClaw 在此聊天中回复时,它会运行全部三个代理。
列出的每个代理 ID 都必须存在于已配置的名册中:配置验证会拒绝数组和对象中的未知 ID。删除代理时会将其从两种形式中移除。
运行时成员关系在存在时使用规范的 agents.entries 名册,包括空名册。仅当 agents.entries 不存在时,才使用旧版 agents.list。
处理策略¶
broadcast.strategy 设置代理如何处理消息:
| 策略 | 行为 |
|---|---|
parallel(默认) |
所有代理同时处理;回复可以按任意顺序到达。 |
sequential |
代理按数组顺序处理;每个代理等待前一个完成。 |
完整示例¶
{
"agents": {
"entries": {
"code-reviewer": {
"default": true,
"name": "Code Reviewer",
"workspace": "/path/to/code-reviewer",
"sandbox": { "mode": "all" }
},
"security-auditor": {
"name": "Security Auditor",
"workspace": "/path/to/security-auditor",
"sandbox": { "mode": "all" }
},
"docs-generator": {
"name": "Documentation Generator",
"workspace": "/path/to/docs-generator",
"sandbox": { "mode": "all" }
}
}
},
"broadcast": {
"strategy": "parallel",
"120363403215116621@g.us": ["code-reviewer", "security-auditor", "docs-generator"]
}
}
工作原理¶
消息流程¶
1. 传入消息到达
一条频道消息到达。
2. 路由和准入
OpenClaw 应用频道允许列表、群组激活规则以及已配置的 ACP 绑定所有权。
3. 广播检查
如果没有已配置的 ACP 绑定拥有该路由,OpenClaw 会检查限定频道/对等键,然后检查 WhatsApp 的旧版对等键。
4. 如果广播适用
- 选定的参与者会在轮次和回合限制内处理消息。
- 每个代理都有自己的会话键和隔离上下文。
- 代理并行(默认)或顺序处理。
- WhatsApp 音频附件在扇出之前只转录一次,因此代理共享一份转录文本,而不是分别发起 STT 调用。
5. 如果广播不适用
OpenClaw 分派普通路由,或分派在路由期间选定的已配置 ACP 会话路由。
Note
群组线程不会绕过频道允许列表、命令授权或独占 ACP 绑定。参与者提及准入会扩展上文所述的房间提及门控。
会话隔离¶
广播组中的每个代理都保持完全独立的:
- 会话键(
agent:alfred:whatsapp:group:120363...对比agent:baerbel:whatsapp:group:120363...) - 对话历史(同级回复仅通过有界的后续摘要共享)
- 工作区(如果已配置,则使用独立沙箱)
- 工具访问(不同的允许/拒绝列表)
- 记忆/上下文(独立的
IDENTITY.md、SOUL.md等)
在 Discord、Slack 和 Telegram 上,回复投递和完成钩子使用响应参与者的会话,并且本地媒体使用该参与者的媒体根目录解析。这也适用于只有一个参与者的限定条目,其回复没有参与者名称标签。
在 WhatsApp 上,有一个输入是有意共享的:群组上下文缓冲区(用于上下文的最近群组消息)按对等共享,因此所有广播代理被触发时都会看到相同的上下文。扇出完成后会清除一次。
这使得每个代理可以拥有不同的个性、模型、技能和工具访问权限(例如只读与读写)。
示例:隔离的会话¶
在群组 120363403215116621@g.us 中,代理为 ["alfred", "baerbel"]:
用例¶
- 专业代理团队:一个开发群组,其中
code-reviewer、security-auditor、test-generator和docs-checker各自从自己的角度回答同一条消息。 - 多语言支持:一个支持聊天,
support-en、support-de、support-es用各自的语言回复。 - 质量保证:
support-agent回答,同时qa-agent审查,并且只在发现问题时回复。 - 任务自动化:
task-tracker、time-logger和report-generator都消费同一条状态更新。
最佳实践¶
1. 保持代理专注
给每个代理一个单一、明确的职责(formatter、linter、tester),而不是一个通用的 "dev-helper" 代理。
2. 使用描述性 ID 和名称
3. 配置不同的工具访问
{
"agents": {
"entries": {
"reviewer": {
"default": true,
"tools": { "allow": ["read", "exec"] }
},
"fixer": { "tools": { "allow": ["read", "write", "edit", "exec"] } }
}
}
}
reviewer 是只读的。fixer 可以读取和写入。
4. 监控性能
当存在许多代理时,优先使用 "strategy": "parallel"(默认值),将广播组控制在少数几个代理,并为更简单的代理使用更快的模型。
5. 故障保持隔离
代理独立失败。某个代理的错误会被记录(Broadcast agent <id> failed: ...),并且不会阻塞其他代理。
兼容性¶
提供商¶
带渠道限定的条目使用跨渠道插件的共享核心分发路径。Discord、Slack 和 Telegram 额外支持参与者提及准入和名称标签。旧版无限定条目仅适用于 WhatsApp(web 渠道)。
路由¶
广播组可与现有路由协同工作:
{
"bindings": [
{
"match": { "channel": "whatsapp", "peer": { "kind": "group", "id": "GROUP_A" } },
"agentId": "alfred"
}
],
"broadcast": {
"GROUP_B": ["agent1", "agent2"]
}
}
GROUP_A:只有 alfred 响应(正常路由)。GROUP_B:agent1 和 agent2 都响应(广播)。
Note
优先级: broadcast 优先于普通路由绑定。已配置的 ACP 绑定(bindings[].type="acp")是独占的:当其中一个匹配时,OpenClaw 会分发到已配置的 ACP 会话,而不是扇出广播。
故障排除¶
代理未响应
检查:
- 代理 ID 存在于
agents.entries中(配置验证会拒绝未知 ID)。 - 带限定的渠道/对等方键与房间匹配。旧版 WhatsApp 键使用类似
120363403215116621@g.us的群组 JID,或用于私信的类似+15551234567的 E.164。 - 消息通过了正常门控(提及/激活规则仍然适用)。
调试:
成功的扇出会记录 Broadcasting message to <n> agents (<strategy>)。
只有一个代理响应
检查: 显式提及可能只选择一个参与者,maxTurns 可能只允许一次运行,或者其他代理可能通过。还需检查对等方是否仅在普通路由绑定中,或匹配独占的已配置 ACP 绑定。
修复: 将普通路由绑定的对等方添加到广播配置中,或者如果希望扇出广播,则移除/更改已配置的 ACP 绑定。
性能问题
如果许多代理时较慢:减少每个组的代理数量,使用更轻量的模型,并检查沙箱启动时间。
示例¶
示例 1:代码审查团队
{
"broadcast": {
"strategy": "parallel",
"120363403215116621@g.us": [
"code-formatter",
"security-scanner",
"test-coverage",
"docs-checker"
]
},
"agents": {
"entries": {
"code-formatter": {
"default": true,
"workspace": "~/agents/formatter",
"tools": { "allow": ["read", "write"] }
},
"security-scanner": {
"workspace": "~/agents/security",
"tools": { "allow": ["read", "exec"] }
},
"test-coverage": {
"workspace": "~/agents/testing",
"tools": { "allow": ["read", "exec"] }
},
"docs-checker": { "workspace": "~/agents/docs", "tools": { "allow": ["read"] } }
}
}
}
群组中的一段代码片段可以产生四个视角:格式修复、安全发现、覆盖缺口和文档小问题。
示例 2:多语言流水线
{
"broadcast": {
"strategy": "sequential",
"+15555550123": ["detect-language", "translator-en", "translator-de"]
},
"agents": {
"entries": {
"detect-language": { "default": true, "workspace": "~/agents/lang-detect" },
"translator-en": { "workspace": "~/agents/translate-en" },
"translator-de": { "workspace": "~/agents/translate-de" }
}
}
}
API 参考¶
配置模式¶
type BroadcastGroupConfig = {
agents: string[];
mentionGating?: boolean;
maxRounds?: number;
maxTurns?: number;
};
type BroadcastConfig = {
strategy?: "parallel" | "sequential";
[key: string]: string[] | BroadcastGroupConfig | "parallel" | "sequential" | undefined;
};
字段¶
strategy"parallel" | "sequential"(路径)默认值:"parallel"- 如何在每一轮中处理符合条件的代理。
parallel会同时启动预留轮次;sequential按配置顺序运行它们。 [channel:peerId]string[] | BroadcastGroupConfig(路径)- 带渠道限定的对等方 ID。数组使用群组线程默认值;对象配置提及选择、轮次和参与者轮次预算。最多 16 个代理。
[peerId]string[](路径)- 旧版 WhatsApp 群组 JID 或 E.164 电话号码。每个列出的代理处理一个轮次,没有内部后续轮次或参与者选择。
限制¶
- 共享上下文: 后续摘要包含有界的同级最终结果,而不是完整的同级会话或工具历史。
- 消息顺序: 并行响应可能以任何顺序到达。
- 速率限制: 参与者共享渠道账户的传输限制;一个轮次可能产生多条平台消息。
- 恢复: 轮次和轮次预算状态保存在内存中,无法在 Gateway 重启后恢复。
- 控制 UI: 专用的团队线程会话尚不可用。每个参与者保留自己的会话。
相关¶
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw