**团队讨论充分,不等于决策可靠。**本篇用一支五角色 Agent 团队做 demo:先解一道会翻车的题,再回放 trace 找到信息丢失的位置;最后让多 Agent 与“单 Agent + 重试”在同样预算下对打,并用代码拦住不可执行的建议。

我最近在帮合作伙伴搭一支电商 多Agent 团队:CEO 负责汇总,CMO 看营销,COO 看库存,CFO 看预算,CPO 看产品。(出于隐私考虑,本文不披露具体经营数据;下面的数字和流程均经过脱敏与简化,仅用于demo评估方法)

五个角色很快就跑起来了。它们一起给出一个建议时,我怎么知道该不该信?

比如某款商品上周卖了 20 件。团队开完会,一致认为需求正在下降,建议少进货、少投广告。但它漏掉了一件事:这款商品缺货了四天。“只卖出 20 件”可能是没人想买,也可能是根本没货可卖。五个 Agent 可以把同一个错误讲得很完整,甚至互相引用,最后形成一份看起来非常专业的错误建议。

这就是 Multi-Agent Eval 要解决的问题。

它不只问“最终答案对不对”,还要回答:

- 正确信息有没有在交接中丢失? - 多个 Agent 是否真的比一个 Agent 更好? - 团队一致同意的方案,是否违反预算、权限或其他硬规则? - 修好这次错误以后,下次改 Prompt 会不会让它重新出现?

先看完整流程

第一版 Multi-Agent Eval 可以压成五步:

写一个有明确陷阱的测试 case → 跑完整团队并保存 trace → 分别检查结果、协作和决策 → 与公平的单 Agent 基线对比 → 把失败加入回归集

先写一道 Agent 可能答错的题

很多 eval 只有输入,没有写清什么叫失败。这会产生一个问题:Agent 说得越长,越容易显得“差不多对了”。

四个字段就能组成第一条可测试的 case。

要写什么 这里的 demo
给 Agent 的任务 根据最近销量,判断未来需求并给出行动建议
Agent 能看到的事实 销量 20、缺货 4 天、当前库存与预算
必须做到的事 识别销量无法代表完整需求
不能发生的事 直接断言“需求就是 20”并自动执行采购

这里没有要求 Agent 猜出一个“正确需求”。因为真实需求暂时不知道。在证据不足时回答“需求未知,需要复核”,是合格处理。Eval 不能为了方便打分,逼 Agent 编一个数字。

这条原则适用于很多行业。

- 研究 Agent 不知道因果关系,可以保留结论; - 客服 Agent 缺少身份验证,可以暂停退款; - 代码 Agent 测试没有通过,可以停止部署; - 运营 Agent 权限不足,可以请求人工确认。

会在不确定时停下来,也是能力。

别只看结果,回放一次协作过程

假设最终错误是“需求等于 20”。

我们需要保存一次运行中的关键记录,也就是 trace。它像行车记录仪,告诉我们信息经过了哪些 Agent、调用了什么工具,最后在哪里发生变化。

这次 trace 可能是:

COO:发现销量 20,同时发现缺货 4 天 ↓ 交接给 CEO:只留下“销量 20” ↓ CEO:把 20 当成真实需求

COO 找到了正确事实,CEO 却没有收到关键限制。这比“CEO 推理能力不够”更有用,因为修复动作已经很具体了:把缺货状态设为交接必填项,并检查 CEO 的最终理由有没有真正使用它。

每次运行不必保存所有思考文字,下面这些证据必须留下。

证据 用来回答什么
输入版本 大家看到的是不是同一批资料
每次交接的结构化结果 关键事实和限制有没有传到下一站
工具调用与错误 是 Agent 判断错了,还是工具没有返回数据
最终输出 团队最后建议了什么
成本、耗时与重试 为这次结果付出了多少代价

“字段存在”也不等于“信息被使用”。CEO 的输入里可能写着“缺货 4 天”,最终结论仍然把销量当需求。交接要同时检查送达和使用。

用三张成绩单,避免一个总分掩盖问题

Multi-Agent Eval 系统至少需要三张成绩单。

结果有没有用

先看团队交回来的结果。

在这个 demo 中,我们关心预测有没有明显偏差,是否承认缺货造成的不确定,以及建议有没有回应任务。

换到其他场景,这张成绩单可以变成:

- 研究报告的关键结论有没有证据; - 客服是否正确解决用户问题; - 代码是否通过测试; - 数据分析是否回答了原始问题。

这层评的是最终交付,不要求每个行业使用同一套指标。

协作有没有增加价值

再看多 Agent 之间发生了什么。

第一版先查三件事就够了:

- 关键限制有没有传到最终决策; - 同一个调整有没有被两个 Agent 重复计算; - 两个角色意见冲突时,系统有没有解决或升级给人。

比如 CMO 已经把促销影响加进预测,CEO 又加一次,最后数字会被放大。问题出在协作规则没有去重。

决策能不能执行

最后看方案是否满足硬规则。

团队可以全票同意,代码检查仍然应该拦住这些方案:

- 支出超过可用预算; - 使用了不存在或已经被占用的资源; - 把未来才能到达的资源算进今天; - 未经允许修改外部系统。

这些检查能写成代码,就不要让 Agent 自己给自己盖章。CFO 说“预算没问题”只是一条待验证的输出。

三张成绩单分开以后,失败才知道该修哪里:结果不行,检查模型和数据;交接丢信息,修协作契约;方案违规,修工具权限或行动规则。

多 Agent 到底值不值,要和公平对手打一次

只跑多 Agent,你只能看到它表现如何,不能知道这些角色是否值得存在。

先把三组放进同一次比较。

- 单 Agent; - 单 Agent + 有限次数的重试; - 多 Agent 团队。

公平有四个条件:同一批 case、同一份信息、同样的工具与权限,以及同样的总预算。

总预算很重要。五个 Agent 调用十次模型,单 Agent 只调用一次,前者表现更好,不一定来自协作,也可能只是花了更多计算。

通过率要和下面几项结果一起看。

结果 它回答的问题
任务通过率 哪套方案完成得更多
每次成功的成本 得到一个可用结果实际花多少钱
延迟 用户要等多久
严重失败 有没有越权、编造或不可逆错误
Unknown 有多少任务因为证据不足无法判定

如果多 Agent 只在复杂任务上赢,就只把复杂任务路由给团队。稳定、简单的任务继续交给单 Agent。

Multi-Agent Eval 最有价值的结果,有时是删掉一个角色。

修好一次以后,用同一道题再考

发现交接丢掉“缺货 4 天”后,我们只改这一处,再跑同一个 case。

旧版交接:销量 20 → Agent 断言需求 20 → FAIL

新版交接:销量 20 + 缺货 4 天 + 需求未知 → Agent 请求复核 → 本例 PASS

这叫回归测试。它的作用很朴素:今天修好的错误,以后不能悄悄回来。

但“本例通过”不等于“系统可以上线”。下一步还要跑原有 case,确认新规则没有伤到其他任务;重要 case 也要重复运行几次,看看结果是否稳定。

每次线上事故都值得变成一条新的回归题。久而久之,你会积累一份系统真实踩过的坑,比抽象 benchmark 更有用。

评估器也可能被骗,所以也要测试它

如果五个 Agent 都说方案合规,评分器会不会跟着点头?

我们可以故意提交一份已知错误的方案:

团队结论:全员同意 计划支出:120 可用现金:100 代码检查:120 ≤ 100 结果:FAIL

再提交一份合理的不确定回答:

证据不足,无法判断真实需求,请求复核 结果:安全处理 PASS 需求判断:UNKNOWN

第一个 case 检查评估器能不能抓住明显违规。第二个 case 检查它会不会把“没有硬猜答案”误判成失败。

评分可以分工:

- Rules 检查数字、字段、权限与系统状态; - Judge 判断证据是否支持结论; - Human 处理高风险、争议和抽查。

Judge 也是模型,也会偏爱长答案、漏掉关键错误。上线前要拿一批人已经确认的样本测试它,尤其检查它能不能抓住最严重的失败。

Multi-Agent Eval 还要多检查五件事

单 Agent 答错,通常可以沿着输入、工具和输出往回找。多 Agent 多了交接、冲突和共同决策,团队最后答对,也可能只是某个角色碰巧救了场。

下面五件事决定你评的是一支团队,还是五个独立回答的模型。

要检查什么 用大白话说 最小测试方法
End-to-end success 最后交付能不能用 检查最终答案和真实环境状态
Handoff integrity 关键信息有没有送到,而且被下游使用 在 trace 中分别记录 received 与 used
Conflict resolution 两个角色意见冲突时,谁依据什么做决定 制造一条明确冲突的 case,检查是否解决或升级给人
Credit assignment 成功或失败到底由哪一步造成 一次只移除、替换或修复一个角色,再跑同一 case
Coordination lift 团队比单 Agent 多创造了多少价值 同任务、同工具、同权限、同预算比较三种配置

这里最容易误判的是 credit assignment,也就是“这次该把功劳或责任记给谁”。

COO 在 trace 里出现,不代表它带来了价值。删掉 COO,但让 CEO 直接读取同一份缺货数据,如果结果反而更稳定,问题可能出在转述层。反过来,只删角色又把它掌握的数据一起删掉,测到的只是信息变少了。

所以角色消融要保留信息,只改变处理方式。一次只动一个位置,再跑同一批 case。

多 Agent 还会把小概率错误串起来。假设三个关键交接各有 95% 的成功率,在近似独立的简化条件下,整条链都成功的概率只有:0.95 × 0.95 × 0.95 ≈ 85.7%

这只是说明风险如何累积,不代表真实系统中的错误彼此独立。正式评估要重复运行重要 case,同时报告单次成功率、连续成功表现、最差延迟和超预算次数。平均值很好看,某一次卡死仍然会伤害真实用户。

把五步接成一个最小 harness

Harness 负责出题、运行、留证据、打分和保存结果。

第一版可以只有这个目录:

1
2
3
4
5
6
eval/
├── cases.jsonl # 测试任务与验收条件
├── configs/ # 单 Agent、重试、多 Agent
├── graders/ # 规则检查与语义评分
├── runner.py # 执行、计费、超时与隔离
└── results/ # trace、判决与报告

下面是一份可以直接运行的 Python demo。它只用标准库,包含两道 case、三种 Agent 配置、trace、三层评分和成本延迟汇总。

为了先验证 eval,示例中的 Agent 使用固定输出。接入真实系统时,只替换 run_setup(),测试题、评分器和对照循环都可以保留。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import json
from statistics import mean


CASES = [
{
"id": "stockout-hidden-demand",
"sales": 20,
"stockout_days": 4,
"max_order_units": 80,
"expected_signal": "stockout_days",
},
{
"id": "ordinary-week",
"sales": 46,
"stockout_days": 0,
"max_order_units": 80,
"expected_signal": "sales",
},
]


def run_setup(case, setup):
"""这里换成你的真实单 Agent 或多 Agent 调用。"""
if setup == "multi_agent" and case["stockout_days"]:
return {
"setup": setup,
"order_units": 55,
"evidence_used": ["sales", "stockout_days"],
"trace": [
{"role": "COO", "found": ["stockout_days"]},
{
"role": "CEO",
"received": ["stockout_days"],
"used": ["stockout_days"],
},
],
"cost_usd": 0.09,
"latency_ms": 1700,
}

if setup == "single_retry" and case["stockout_days"]:
return {
"setup": setup,
"order_units": 35,
"evidence_used": ["sales", "stockout_days"],
"trace": [{"role": "single", "used": ["sales", "stockout_days"]}],
"cost_usd": 0.06,
"latency_ms": 1100,
}

# 普通题三种配置都能答对;缺货题中的单 Agent 会漏掉关键信号。
return {
"setup": setup,
"order_units": case["sales"],
"evidence_used": ["sales"],
"trace": (
[{"role": "CEO", "received": ["sales"], "used": ["sales"]}]
if setup == "multi_agent"
else [{"role": "single", "used": ["sales"]}]
),
"cost_usd": {
"single": 0.03,
"single_retry": 0.06,
"multi_agent": 0.09,
}[setup],
"latency_ms": {
"single": 600,
"single_retry": 1050,
"multi_agent": 1500,
}[setup],
}


def grade(case, result):
reasons = []

# 结果:有没有使用这道题的决定性证据?
outcome_pass = case["expected_signal"] in result["evidence_used"]
if not outcome_pass:
reasons.append(f"missing evidence: {case['expected_signal']}")

# 协作:COO 的发现有没有送到 CEO,并进入最终判断?
coordination_pass = True
if result["setup"] == "multi_agent" and case["stockout_days"]:
ceo_steps = [x for x in result["trace"] if x.get("role") == "CEO"]
coordination_pass = bool(
ceo_steps
and "stockout_days" in ceo_steps[0].get("received", [])
and "stockout_days" in ceo_steps[0].get("used", [])
)
if not coordination_pass:
reasons.append("COO evidence was not received and used by CEO")

# 决策:建议有没有越过业务硬约束?
decision_pass = 0 <= result["order_units"] <= case["max_order_units"]
if not decision_pass:
reasons.append("order exceeds allowed range")

return {
"verdict": "PASS" if all([
outcome_pass,
coordination_pass,
decision_pass,
]) else "FAIL",
"outcome_pass": outcome_pass,
"coordination_pass": coordination_pass,
"decision_pass": decision_pass,
"reasons": reasons,
}


def main():
setups = ["single", "single_retry", "multi_agent"]
records = []

for case in CASES:
for setup in setups:
result = run_setup(case, setup)
record = {
"case_id": case["id"],
"result": result,
"grade": grade(case, result),
}
records.append(record)
print(json.dumps(record, ensure_ascii=False))

print("\nSUMMARY")
for setup in setups:
rows = [r for r in records if r["result"]["setup"] == setup]
summary = {
"setup": setup,
"pass_rate": mean(
r["grade"]["verdict"] == "PASS" for r in rows
),
"avg_cost_usd": round(mean(
r["result"]["cost_usd"] for r in rows
), 3),
"avg_latency_ms": round(mean(
r["result"]["latency_ms"] for r in rows
)),
}
print(json.dumps(summary))


if __name__ == "__main__":
main()

运行后,单 Agent 在缺货题上失败;单 Agent + 重试和多 Agent 都通过。多 Agent 的成本与延迟更高,却没有在这两道题上超过重试方案。

这不是要证明多 Agent 没用。Eval 给出的下一步很明确:增加真正需要跨角色协作的 case,或者先使用成本更低的重试方案。没有对照时,这条架构判断很难从一堆漂亮 trace 里看出来。

第一版先守住下面几个细节。

- 每次运行从相同初始状态开始; - 超时、崩溃和空结果也必须留下记录; - 团队内部所有调用与返工都计入总成本; - 判决保留 PASS / FAIL / UNKNOWN,不要强行平均成一个漂亮总分; - 每个 FAIL 都附上证据,能指向下一步修复。

做到这里,你已经有了一套最小可用的 Multi-Agent Eval。它还不能证明系统可以大规模上线,但已经能回答三个更实际的问题:

这支团队在哪些任务上更好? 多出来的质量值不值得成本? 失败以后,我到底应该修哪一步?

给 Agent 多加几个“同事”很容易。

让这些同事证明自己的协作有价值,才是 Multi-Agent Eval 的起点。