如何设计多 Agent 的协作与动态切换机制?
多个 Agent 一起干活,难点不在"每个 Agent 多聪明",而在谁在什么时候把控制权交给谁,以及交接时带走了什么。 协作机制决定信息怎么流动,切换机制决定路由是否可靠;两者都做不好,就会出现"互相甩锅"和"乒乓转交"。
1. 结论:协作靠共享产物,切换靠显式交接协议
| 机制 | 控制权 | 信息载体 | 优点 | 风险 |
|---|---|---|---|---|
| 主管路由(Supervisor) | 集中在主管 | 主管转述 + 产物 | 易观测、易限流 | 主管成瓶颈 |
| 交接(Handoff) | 点对点转移 | 交接信封 | 低延迟、贴近真实流程 | 易乒乓、上下文膨胀 |
| 黑板(Blackboard) | 无中心 | 共享状态区 | 灵活、天然异步 | 冲突写、难定责 |
| 投票/辩论(Debate) | 并行后裁决 | 各自结论 | 提升准确率 | 成本翻倍 |
| 流水线(Pipeline) | 固定顺序 | 上一步产物 | 简单可预测 | 不能回头 |
生产系统的默认答案:主管路由 + 结构化产物 + 显式交接协议,其余机制按需叠加。
2. 机制:一次交接的时序
用户 ──▶ 前置分类器(规则优先,模型兜底)
│ 无法确定归属
▼
┌─────────────┐ handoff(reason, summary, artifacts) ┌─────────────┐
│ 接单 Agent │ ─────────────────────────────────────▶ │ 专家 Agent │
└─────────────┘ └──────┬──────┘
▲ │
│ 回传(outcome, artifacts, confidence) │
└──────────────────────────────────────────────────────┘
守卫:hop_count ≤ 3,已访问集合去重,无对应能力则升级人工
交接信封(Envelope)是这套机制的契约,只带三样东西:为什么转、已确认的事实、产物引用。全量对话不转,需要时按 id 取。
3. 交接信封与路由守卫
{
"handoff_id": "h-7f21",
"from": "front_desk",
"to": "billing_specialist",
"reason": "user_asks_refund",
"confidence": 0.86,
"facts": {"order_id": "A1029", "paid_at": "2026-10-02", "amount": 299},
"artifacts": [{"id": "obj-8821", "kind": "chat_digest", "tokens": 320}],
"constraints": {"locale": "zh-CN", "sla_seconds": 90},
"hop_count": 1
}
配套的路由代码必须带三条守卫:能力校验、跳数上限、访问集合去重。
CAPS = {"front_desk": {"faq", "order_query"},
"billing_specialist": {"refund", "invoice"},
"tech_specialist": {"bug_diagnose", "log_query"}}
def route(env: dict, pending: list, hops: set) -> str:
target = env["to"]
if env["reason"] not in CAPS.get(target, set()): # ① 能力校验
return escalate(env, why="目标 Agent 无此能力")
if env["hop_count"] >= 3: # ② 跳数上限
return escalate(env, why="转交次数超限")
if (target, env["reason"]) in hops: # ③ 防乒乓
return escalate(env, why="重复转交,判定为无法自动处理")
hops.add((target, env["reason"]))
return target
def dispatch(env, agent_fn, hops):
try:
out = agent_fn(env) # 专家只读信封 + 按需取产物
except ToolError as exc:
return handback(env, why=f"tool_failed:{exc.code}") # 明确回退,不静默吞错
return out
三条守卫缺任何一条,线上都会出现"两个 Agent 来回转交直到超时"的经典故障。
4. 动态切换:规则优先,模型兜底
路由本质是分类问题,不要一上来就让模型判断:
| 判定方式 | 延迟 | 准确率 | 适用 |
|---|---|---|---|
| 关键词/正则 | 微秒 | 高(命中时) | 明确指令、固定入口 |
| 规则引擎(状态、权限、SLA) | 毫秒 | 高 | 有明确业务状态 |
| 小模型分类 | 百毫秒 | 中高 | 意图多但边界清晰 |
| 大模型自主决定 | 秒级 | 中,易漂移 | 开放式、长尾输入 |
推荐流水线:先跑规则,命中即走;未命中交给小模型分类;仍不确定才让大模型决定,且大模型只能在候选集合内选,不能凭空造出一个 Agent。
5. 常见追问
问:交接时上下文怎么传? 传"结论 + 引用",不传原文。原文落对象存储,信封里放 id 与摘要;专家 Agent 需要细节时按 id 拉取。这样既避免上下文膨胀,也避免转述失真。
问:怎么避免 Agent 之间互相甩锅?
明确"谁接单谁负责收尾":接单方必须返回 outcome(解决/升级/需补充信息)之一,不能只回一句"不归我管"。再加一条规则:同一 reason 只能转一次。
问:权限怎么隔离?
按 Agent 分配工具白名单,而不是共享全局工具表;写操作统一走审批网关,且在信封里带 constraints,让下游知道当前会话的合规边界。
问:怎么观测多 Agent 系统?
一条 trace 贯穿到底:handoff_id 作为关联键,记录每次转交的原因、耗时、token、产物 id。看板至少要有转交次数分布、乒乓率、升级人工率三个指标。
小结
多 Agent 协作的设计重点是"接口"而非"智能":用共享产物承载信息,用交接信封约束转交,用能力校验、跳数上限、访问集合防乒乓,用规则优先的路由降低成本。这套约束做扎实,多 Agent 才是加分项;否则只是把单 Agent 的错误放大若干倍。