模式矩阵 /模式白皮书/C6
ADPS Agent 设计模式白皮书
C6 · Choreography · 编舞
多个 Agent 在没有中央 Orchestrator 的情况下订阅、处理并发布事件。
文档状态:本页为公开评审稿。模式定义与分类可供讨论和引用;场景化示例用于说明机制,不代表已经核验的企业案例。具名实践另见案例库。ADPS 欢迎业界提交带来源、测量口径和发布授权的案例。
| 坐标 | 协作 Collaboration × 编舞 Choreography(扩展拓扑) |
| 成本 | 高(多 agent、事件驱动,链路长、可观测开销高) |
| 模式组 | 协作模式 |
| 模式简介 | 多个 Agent 在没有中央 Orchestrator 的情况下订阅、处理并发布事件。 |
问题
编排(Orchestration)模式有一个中央指挥,挨个命令每个 agent "你做这步、再做那步"。这套结构在大多数场景下是对的,但它有两个会顶到天花板的硬约束:中央指挥本身是单点,它挂了整条流程就停;每加一个新 agent,都要回去改中央指挥的逻辑。当 agent 的数量和种类不断增长、业务边界又分属不同团队时,这个中央点会从协调者变成瓶颈。
编舞用于降低多 Agent 之间的直接耦合。每个 Agent 只订阅相关事件,处理后将结果发布到共享事件流。全局行为由各 Agent 的“订阅—处理—发布”规则共同形成。新增 Agent 时,只需配置其订阅和发布事件。
编舞与编排的主要差异在控制权位置:编排由中央节点持有 plan,编舞将控制分散到事件订阅者。
坐标说明:协作 × 编舞
编舞当前作为扩展拓扑登记,不占用核心六列。
- 纵轴 · 协作:编舞描述的是多个 agent 怎么协同,没有单个 agent 的版本,所以纵轴稳稳落在协作模块。
- 横轴 · 编舞(扩展拓扑):链式、路由、并行、循环、层级和编排都存在可识别的控制点。编舞不设置中央控制点,由事件协调 Agent 行为,因此作为扩展拓扑处理。
核心拓扑需要横切多个认知功能。编舞目前主要集中在协作模块;event sourcing、黑板式推理和事件审计可以形成相邻映射,但生产实例仍不足。因此先登记为扩展模式。若后续在协作之外出现两到三个认知功能的稳定生产实例,再评估是否升级为核心列。
解决方案与机制
编舞由四件工程要素构成:
- 共享事件介质:一条事件总线(pub/sub)、一块共享黑板、或一种留痕机制(stigmergy)。所有 agent 通过它间接通信,互相不直接点对点调用。
- 自治的订阅—反应单元:每个 agent 声明自己订阅哪些事件,事件到达时判断要不要动、怎么动,动完把结果作为新事件发布回去。它不知道、也不需要知道下一个该谁接。
- 涌现的全局行为:没有任何一处持有完整流程。整体协作是所有局部规则在事件流上跑出来的结果。这是编舞的全部威力,也是它全部的麻烦来源。
- 显式的终止与可观测:因为没有中心来宣布"任务完成了",必须用显式的终止事件(terminal event)或编排式 saga 的补偿链来界定边界;同时每个事件必须带关联 ID(correlation ID),否则出了问题无法回溯因果链。
适用场景
- agent 种类多、分属不同团队、要独立演进的生态:每个团队拥有自己的 agent,订阅总线即可加入,不需要去改一个全公司共用的中央编排器。
- 高吞吐事件流、中央编排会成瓶颈或单点的场景:风控、内容审核、监控告警这类持续有事件涌入、又要求高可用的系统。
- 环境高度动态、流程无法预先固定的场景:你事先列不全"该走哪些步骤",只能让 agent 各自对当下的事件做反应。
- 要求弹性、不能有中央故障点的场景:没有中央指挥可挂,单个 agent 失效只损失它那一块职能。
已知失效方式
- 缺少事件可观测性:编舞没有中央 trace,每个事件必须携带 correlation ID,并支持按因果链 replay。Observability Harness 是前置条件。
- 事件风暴 / 无限回环:A 发事件触发 B,B 反应又发事件触发 A,循环不收敛。必须做幂等、加事件 TTL、做回环检测。
- 完成态无人宣布:去中心化之后,"这个任务到底结束没有"变成一个没人能直接回答的问题。要用显式终止事件或 saga 补偿来界定,不能含糊。
- 在简单流程中使用编舞:固定流程通常优先使用编排。只有当团队独立演进、耦合、吞吐或单点可用性成为主要约束时,才需要编舞。
- 想在编舞上强加全局约束:去中心化和治理是天然对冲的。需要强一致的审批、配额、合规约束时,要么保留一个薄的中央 gate(混合式),要么承认编舞不适合这一段。
验证指标
- 事件可追溯率:能否从 correlation ID 的事件日志重建完整因果链。无法回放的链路不能进入生产编舞。
- 收敛率 / 事件风暴率:协作是否到达 terminal event,还是陷入重复发布。任何失控回环都应触发熔断和复盘。
- 耦合影响面:新增或下线一个 Agent 时,需要改动哪些发布者、订阅者和共享 schema。改动范围持续扩大说明事件契约仍然耦合。
- 端到端延迟:与编排对照组比较,并把消息排队、重试和最终一致性等待分别记录。
最小实现
# 编排(对照组):中心持有完整计划,挨个命令
orchestrator.run(task):
for step in plan(task):
result = agents[step].execute() # 中心调度
state.update(result) # 中心收口
return state.result
# 编舞:无中心,各自订阅 + 反应 + 发事件
bus = EventBus() # 共享事件介质
class ChoreographedAgent:
subscribes_to = [...] # 我只关心这些事件
def on_event(self, e):
if self.should_act(e): # 自治判断
out = self.act(e)
bus.publish(out, correlation_id=e.cid) # 反应完发新事件,不回报中心
for a in agents:
bus.subscribe(a.subscribes_to, a.on_event)
bus.publish(initial_event) # 点火,之后全靠涌现
# 完成 = 某个 terminal 事件出现;回溯 = 按 correlation_id 串起整条因果链
生产实现以 EventBus 作为共享介质;subscribes_to 和 on_event 定义订阅处理单元;系统不由单一节点持有 plan;correlation_id 和 terminal 事件提供可观测性与终止判断。
场景化示例
设想一个内容风控平台。第一版由中央编排器依次调用垃圾、欺诈、合规和品牌检测器。随着检测器和责任团队增加,每次新增能力都要修改共享编排器,它逐渐成为单点。第二版改成事件驱动协作:检测 Agent 订阅 content.received 并发布 flag.spam、flag.fraud 等事件;策略 Agent 聚合标记;升级 Agent 订阅高危事件并发布 case.opened。新增检测器只需遵守事件契约并订阅总线,但共享 schema、终止条件和治理 gate 仍要集中管理。
系统先为每个事件加入 correlation ID,并支持按 case 全链路 replay。在“案件是否已处置完成”这一环节保留轻量编排式 saga,用于定义完成态。生产系统通常采用事件驱动协作与中央终止控制的混合结构。事件驱动 Agent runtime 与互操作协议可作为实现参考,生产效果仍需由具名案例补充。
相邻模式
- 可观测性(G4):硬前置依赖。编舞没有中央 trace,全靠关联 ID 的事件日志回溯因果。没有 G4,编舞不可调试、不可上生产。
- 编排(散落在层级 / 治理):编排集中控制,编舞通过事件分散控制,生产系统可以混合使用。
- 扇出聚合(C2):扇出由中央节点执行 fan-out 和 gather;编舞将处理结果直接发布到事件流。
- 失败日记(记忆模块 M4):event sourcing 将状态变化记录为不可变事件流,可作为编舞系统的历史状态来源。
- 爆炸半径控制(G2)/ 审批门(G1):与编舞天然对冲。需要强治理约束的链路,要么保留薄中央 gate,要么不在那一段用编舞。
工程判断
编舞把协作控制分散到各参与者的本地规则中,并通过事件推进全局流程。它降低中心耦合,同时要求完整的事件契约、因果追踪、完成态定义和补偿机制。
企业证据
当前没有与本模式绑定的公开评审案例。模式定义不因此视为已经获得企业验证。
案例收录要求说明业务约束、实现结构、已知失败和迁移边界。参见 贡献与评审规则。