KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
04. Supervisor 怎样分派而不替 Worker 做事? — keel 龙骨
指标 Agent 已经能完成一个独立任务。现在需要一个组件接收事件目标,决定生成哪些子任务,并把它们交给合适的 Worker。这个组件是 Coordinator;当所有路由和结果都回到它时,形成 Supervisor 拓扑。
指标 Agent 已经能完成一个独立任务。现在需要一个组件接收事件目标,决定生成哪些子任务,并把它们交给合适的 Worker。这个组件是 Coordinator;当所有路由和结果都回到它时,形成 Supervisor 拓扑。
Supervisor 是控制拓扑,不是“最聪明的 Agent”
flowchart TB
C[Supervisor / Coordinator]
C --> A[Metrics Agent]
C --> B[Change Agent]
C --> R[Reviewer]
A --> C
B --> C
R --> C
Worker 不互相直接转移任务。Coordinator 保持全局视图,决定:
- 创建哪些任务;
- 任务依赖和必需性;
- 使用哪个 capability;
- 何时并行、等待或取消;
- 结果是否足够进入汇聚;
- 整次运行何时结束。
它不应替代专业 Agent 完成所有分析。否则所谓团队只是一个主 Agent 的超长 prompt。
Registry 把可用 Agent 变成白名单
registry.register(metrics_worker)
registry.register(change_worker)
worker = registry.resolve(task.required_capability)
安全的 Registry 需要拒绝:
- 重复 Agent 名称;
- 同一 capability 存在无法消解的多个默认处理者;
- 请求未知 capability;
- Worker 声明和实际处理能力不一致;
- 通过模型输出动态导入任意 Python 类。
Registry 和工具注册表解决相似问题:模型可以提出候选名称,但程序只允许已注册能力。
Routing、Delegation 和 Execution 是三步
Routing:选择谁适合处理
Delegation:创建 assignment,改变任务 owner
Execution:被选中的 Worker 真正执行
把三步分开,才能回答“模型选错了”“分派状态写失败了”还是“Worker 执行失败了”。
路由可以有三种实现:
规则路由
required_capability == analyze_metrics -> metrics_analyst
稳定、快速、可测试,适合任务类型明确的系统。
分类器或模型路由
模型根据自然语言目标选择 capability。适合输入类别开放的情况,但输出仍必须落到 Registry 白名单,并记录置信度和 fallback。
混合路由
先用规则处理明确类别,剩余任务再交给模型;高风险或低置信度结果进入人工或安全 fallback。生产系统通常更适合这种方式。
Coordinator 的确定性骨架
def dispatch(task):
worker = registry.resolve(task.required_capability)
emit("task.assigned", task_id=task.task_id, agent=worker.name)
result = worker.execute(task)
validate_correlation(task, result)
emit(
"task.succeeded" if result.ok else "task.failed",
task_id=task.task_id,
agent=worker.name,
)
return result
真正代码还要处理异常、超时、取消、attempt 和敏感数据脱敏,但骨架中的不变量不能消失:先解析白名单,再记录 assignment,最后校验 result 与 task 的关联。
Supervisor 模式的优势和代价
优势:
- 容易观察完整任务图;
- 权限、预算和停止条件集中;
- Worker 上下文容易隔离;
- 适合 fan-out/fan-in 和最终汇聚。
代价:
- Coordinator 可能成为延迟和可用性瓶颈;
- 全部信息回流可能让其上下文膨胀;
- 错误路由会影响多个下游任务;
- 过度集中会让 Worker 退化为昂贵工具调用。
运行分派实验
python courses/advanced/multi-agent-collaboration/course/project/examples/01_task_contract.py
故意把任务 capability 改成 analyze_database。正确结果是 Registry 返回稳定的 no_capable_agent 错误,任务不进入 running,未知 Agent 也不会被动态创建。
检查理解
- Supervisor 为什么是一种拓扑,而不是业务身份?
- 路由成功是否表示任务已经执行?
- 为什么 Coordinator 必须校验返回结果的 task ID?
- 什么时候规则路由比模型路由更合适?
集中分派并不适合所有交互。下一章处理 Agent 直接把当前任务交给另一个 Agent 的 handoff。