外观
第 12 章 评测
改动是变好还是变坏,智能体系统往往说不清:改一版系统提示、换一个模型、加一个工具,都没有数字能回答。传统软件靠断言式单元测试兜底,智能体的输出却是概率性的,同一个输入跑两次可能一次好一次坏,挑三个顺当案例演示一切正常、上线两周改地址的客诉就来,这种情形天天有。这一章的解法叫评测(Evals),用一组固定的任务配一套统一的打分标准,度量智能体的能力,也度量能力随每次改动发生的变化;第五部分的可靠性工程里,安全要验证、运维要报警、人机协同要拿出信得过的依据,全都建立在能度量上。12.1 立方法论,评测驱动开发,成功标准定在写代码之前;12.2 定评测对象,轨迹;12.3 讲打分,LLM 裁判怎么写、偏差怎么校准;12.4 教读公开基准,主流基准各测什么、榜单口径藏着哪些坑;12.5 收在自建任务集,案例从哪几路来、案例卡怎么写、怎么经营成一份活资产。
12.1 评测驱动开发
评测驱动开发(evaluation-driven development)要求在动手写智能体之前,先把成功标准、指标和评测设施定下来,它在传统软件里对得上测试驱动开发(TDD),先写测试,再写代码。没有它的项目是另一副样子:第 2 章那个快递客服智能体上线两个月后,工程师改了三处系统提示,每一处都带着说得通的理由,一周后客诉进来,说改地址的成功率明显往下掉,三处改动里哪一处惹的祸没人知道,当初没留档做对照、也没有可重跑的案例,最后只能整体回滚,把两处可能有益的改动一起牺牲掉。这类项目的通病出奇一致,团队把热情全花在搭智能体上,到开发晚期才想起评测,根源不在工程师不细心,而在没有度量,改动是好是坏没有数字能说明白,每一次迭代都是在赌。
评测跟 TDD 的相同点有两条。第一条是逻辑上的对应,测试逼着人把需求讲明白,评测标准则逼着人把“什么算好”讲明白。打算量改址的成功率,第 2 章那条客服回路从第一天起,就得把每一步工具调用的结果落档成轨迹;打算对比两个模型的工具选择差异,工具的定义和调用日志从第一行代码起就要记。这两个打算是一回事,评测提出的约束最后都会变成设计需求,而实践里最容易漏掉的就是这一层。第二条是次序上的对应,两边都先把失败标准定下来,再去写实现代码。测试先行,接口就冲着好验证去设计;评测先行,智能体的行为就冲着好度量去设计。
评测跟 TDD 的差别,源头在输出带随机性。同一份输入,确定性测试跑一次过,再跑还是过,断言非对即错。智能体不这样,同一个案例跑五次,可能三次对两次错。于是结论只能看任务集整体的通过率,单条案例的一次结果说明不了什么。这一差别带出两个直接后果。
第一个后果,结论天生是统计性的。两版系统分数差零点几分,未必是真有差异,可能是抽样波动。判断一次改动到底有没有效,得看多次运行的均值,连同波动幅度一起看。
差异要到多大才算数,可以举个例子。两版各跑 30 条,一个对了 21 条,一个对了 24 条,差的这三条说明不了什么。差距拉到十条上下,才值得当成真信号去追查。
把波动当回事,手头得有几件统计工具。先给波动摸个底,同一版系统、同一批案例原样多跑几轮,看分数在什么范围里晃;轮数往上加,晃动幅度不再收窄,那个轮数就定成往后跑批的基准,比这再少,量到的多半是噪声。比两版时讲究同题配对,同一批题目两边各跑一遍,一对一对着看,别拿两批不同题目上的成绩互相比,题目一混,分差里掺进的就不只是系统差异,还有题目难度。真伪怎么判只认一条,分差明显超出平时波动的幅度,换个时间再跑一轮还在,才算数。只在某一轮里出现过的领先,先当噪声处理,不值得为它动手改系统。
这套判断在统计学里有正式的名字,叫统计显著性(statistical significance)。工程上不必碰公式,记住结论就够用。分数报出来要带着浮动范围,正式的说法是置信区间(confidence interval),任务越少,区间越宽,十几条案例跑出来的区间,宽得能同时装下两版的分数,这种时候比出来的高低没有意义。想把区间收窄,常用的路子有两条,任务加多,或者同一批任务多跑几轮取平均。所以像样的评测报告不报一个孤零零的数,报一个数,带上它的区间。
第二个后果,评测还要花钱。一条案例过一遍智能体,烧一份 token;要是交给裁判去打分,还得再烧一份。这里说的裁判,是一个用模型按判定要点给案例打分的角色,具体写法见 12.3。任务集放多大、隔多久跑一轮,都得先算成本,不像单元测试那样可以随手全量跑。
实际要花多少,大致能估。假设拿低价档模型跑轻量案例,每条平均进一万 token、出两千 token,一百条全跑完,合计一百二十万 token 上下,照官方定价页折算,通常连一美元都不到。
日常迭代时,把案例控制在几十条,裁判只用在必要的维度上,这笔开销完全付得起。评测真正的难处不是贵,而是没人算过这笔开销。
钱算完,跑还有跑的讲究。一百条案例一条条串行等结果,一小时能拖成一下午,正路是并发跑批。并发不是无限并发,三件事配齐才算工程。按提供商分道限流,每家 API 配一个信号量,几家模型混跑时各守各的额度;指数退避,撞上限流或超时就等一会儿再试,等待时间逐次翻倍,别硬顶;单题失败不连坐,一批里某条抛了异常,把这个异常收下、继续跑完剩下的,别让第一百条的毛病把前九十九条的结果全部断送。国内提供商给的速率限额往往更紧,这套东西在中文环境里不是锦上添花,是一批评测能不能跑完的先决条件。示意代码长这样(run 函数与限流异常按自家 SDK 替换,cases 清单和 provider_of 映射换成自己的)。
python
import asyncio
# 每家提供商一份并发额度,谁的限额紧,闸门就开小一点
SEMS = {"provider-a": asyncio.Semaphore(4),
"provider-b": asyncio.Semaphore(2)}
async def run_case(case, run, sem):
for wait in (1, 2, 4, 8): # 指数退避
async with sem: # 信号量分道限流
try:
return await run(case)
except RateLimitError:
pass
await asyncio.sleep(wait)
raise RuntimeError(f"重试耗尽:{case['id']}")
results = await asyncio.gather(
*(run_case(c, run, SEMS[provider_of(c)]) for c in cases),
return_exceptions=True, # 单题失败不连坐
)跑批还会撞上一种特殊的“失败”,得单独认出来,模型的安全拒绝。响应的 finish_reason 回的是 refusal,拿到的内容不是干活的结果,是一句“这个请求不能帮”。麻烦在触发线,各个模型服务提供商不一样,同一段输入,这家照常回答,那家直接拒了,换模型跑评测时这批差异就会污染分数。处理分三步,先在目标模型上实测,摸清哪类输入会触发;再给会被拒的案例备后备,换措辞重试、换提供商,或者跳过并记录;最后把拒绝跟真正的失败分开计数,拒绝算合规行为,不算答错,混在一个通过率里,这个数就没了意义。
跑批跑在什么环境里,还有一条前提容易漏,评测得跟生产隔开。任务集里躺着索要他人订单、代办退费这类输入,直接打生产系统,退款就真的发出去了。就算任务全是只读的,评测的对话混进生产记忆,会把真实用户的画像也搅脏。通行做法是给评测单独配一套环境,数据库换成脱敏后的副本,第三方接口换成假实现。想借真实流量的分布,就把流量复制一份送进评测环境,只记录不回写。环境里带随机性的地方,能固定种子的固定住,两轮评测之间才谈得上可比。
动手写代码之前,先把下面五个问题挨个过一遍。
- 成功标准定成什么。哪些维度算数,是准确、完整、耗时还是成本,有改善时拿什么衡量
- 任务集由什么组成。有哪些代表性任务,有哪些边界案例,多少条才能给出可靠信号
- 指标怎么选。规则能判的划给规则,判不了的交给裁判,量结果还是量过程
- 基线是什么。现在靠什么完成,直连模型行不行,跟上个版本比什么
- 迭代节奏是什么。评测隔多久跑一轮,回归靠什么暴露,结果跟哪些信息一起存
五个问题答完,评测计划就有了一页纸,而且每一问都对应一件实打实的产出,不是空话。第一问给出维度表,写清准确、完整和耗时各占多少权重;第二问给出任务集目录;第三问给出打分脚本;第四问给出对照组;第五问给出流水线里的一个定时任务。
这页计划要放进版本库,跟普通代码一起过评审。它是后续所有迭代的判决依据,写坏了比不写更能误导人。写坏的样子很常见。任务集净挑最顺的演示案例,指标只剩一个总通过率,基线栏空着。分数倒是好看,可什么变化都解释不了,反而让人以为度量已经做完。
五个问题不必一次答全,任务集更是急不得,从第一个案例起步就够。上线前的演示案例、真实用户的第一问、开发中碰上的头一回失败,都够格当一号案例。案例卡上只有三项,输入、期望行为和来源日期。期望行为不求唯一的标准答案,写成判定要点就行。快递客服可以写这么一条,先查单,查到未派送才改地址,答复里两件事都要有交代。
攒到第二十个案例,不用刻意统计,分布自己就露出来了。真实问法占多少、边界输入占多少、恶意请求占多少,缺哪类补哪类。
第一批可以刻意配一配。十条来自真实用户的问法,查单、改址、一句话里塞两个请求;五条边界输入,订单号不存在、地址不完整、上下文自相矛盾;五条超范围请求,索要他人订单、代办退费。这批输入到第 13 章讲安全时还会再回来。
期望行为按可判定的程度,分两种写法。查单查到哪了,硬答案就是“杭州转运中心、尚未派送”,字符串一比对就出结果。一句抱怨里夹带改址请求,就没法写成唯一答案,只能写成判定要点,交给下一节的裁判。
案例会过期,这件维护活最容易漏掉。业务规则一旦变动,比如改址只允许在派送前操作,旧案例的期望行为就得跟着改,否则评测反过来惩罚新的正确行为,分数越跑越低,查到最后才发现错在案例身上。任务集应与代码同库同版本,规则变更时把所有受影响的案例翻一遍,这项维护省不得。
成功标准不能由工程师关起门来定。客服场景里什么叫好?去问一线客服主管,多半会答一次解决,用户不用为同一件事回头再问。工程师的直觉却偏到答复工整、话术漂亮上。两个标准都成立,权重完全不同,前者看重完整性,后者看重清晰度。评测驱动开发的第一个收益就在这。五个问题逼着工程师在写代码前先找业务方,把“好”的定义谈拢;谈不拢的维度,先降权或直接删掉,省得后期使劲优化一个没人关心的指标。
指标怎么配,谈拢之后有现成的层次可循。底层先立通用准确率基线,数清假阳性、假阴性和总体准确率,把起点稳住。中层叠加领域成果指标。法律合同分析,数的是漏掉的关键条款;金融反欺诈,数的是挽回的损失,各对各的业务指标。顶层拿人类团队做同类任务的成绩当参照,这类数不是处处能查到,可一旦查到就最有分量,直接回答这套系统跟人相比处在什么水平。
底层的假阳性、假阴性,说的都是同一张四格表。拿改地址当例子,一批订单过来,每一单先问该不该改地址,再问智能体改没改,两个问题一交叉,四种结果各有名字,合起来叫混淆矩阵(confusion matrix)。
| 名字 | 什么情况 | 改地址里的样子 |
|---|---|---|
| 真阳性(true positive) | 该改的,改了 | 订单要改地址,智能体改了 |
| 假阳性(false positive) | 不该改的,改了 | 订单不用改,智能体动手改了 |
| 真阴性(true negative) | 不该改的,没动 | 订单不用改,智能体没改 |
| 假阴性(false negative) | 该改的,没改 | 订单要改地址,智能体漏了 |
这四个名字里,假阳性和假阴性还有一对更口语的叫法,假阳性是误报,假阴性是漏报。
最常用的两个比率,精确率(precision)和召回率(recall),就是从这四格里算出来的。精确率问查得准不准,智能体报“已改好”的那批单子里,真改对了多少;召回率问查得全不全,所有该改地址的单子里,实际抓到了多少。哪个更要紧,看错的代价压在哪头。改错一单,货寄去了旧地址,赔付和客诉一起来了,这种业务优先看精确率;漏改一单,客户眼看着地址没变,投诉照样来,这种业务优先看召回率。两个数各管一头,业务两头都输不起时,就看F1(F1-score),它取的是精确率与召回率的调和平均,任何一头低,它都被拉低,一个数把两头都管住。这套词后面一路在用,12.2 过程指标里的步骤集合 F1,第 13 章公平指标里的假阳性假阴性,第 20 章的异常召回线,用的都是这张表里的数。
四个格子的数法写成代码,就是拿一批运行记录逐条交叉计数。
python
"""示意代码:混淆矩阵与精确率、召回率、F1 的最小计算,python3 可直接运行。"""
# 一批评测记录:should_change 是人工核过的该不该改,
# agent_changed 是智能体实际改没改(数据为示意)
RUNS = [
{"order": "SF01", "should_change": True, "agent_changed": True},
{"order": "SF02", "should_change": True, "agent_changed": False},
{"order": "SF03", "should_change": False, "agent_changed": False},
{"order": "SF04", "should_change": True, "agent_changed": True},
{"order": "SF05", "should_change": False, "agent_changed": True},
]
def confusion(runs: list) -> dict:
"""逐条交叉计数,四个格子各归各。"""
tp = sum(r["should_change"] and r["agent_changed"] for r in runs)
fp = sum(not r["should_change"] and r["agent_changed"] for r in runs)
fn = sum(r["should_change"] and not r["agent_changed"] for r in runs)
tn = sum(not r["should_change"] and not r["agent_changed"] for r in runs)
return {"TP": tp, "FP": fp, "FN": fn, "TN": tn}
def rates(cm: dict) -> dict:
"""精确率查得准不准,召回率查得全不全,F1 调和两头。"""
precision = cm["TP"] / (cm["TP"] + cm["FP"])
recall = cm["TP"] / (cm["TP"] + cm["FN"])
f1 = 2 * precision * recall / (precision + recall)
return {"precision": round(precision, 3),
"recall": round(recall, 3), "f1": round(f1, 3)}
if __name__ == "__main__":
print(confusion(RUNS)) # 真阳2 误报1 漏报1 真阴1
print(rates(confusion(RUNS)))底层这个准确率,用的时候也得留个心眼,类别一不平衡它就失真。一百条请求里九十八条本来就不用改地址,模型全答不改,准确率九成八,数字漂亮,一件正事没干。所以分类指标要按类别拆开报,两个拆法各有立场。宏平均(macro averaging)把每个类别一视同仁,小类跟大类一样重;微平均(micro averaging)让样本多的大类主导总分。业务在乎的是少数会出事的那一类请求,就报宏平均和分类别的召回;在乎大盘吞吐,微平均更贴。只报一个总准确率,在不平衡场景下等于什么都没说。
这三层之上,再挑一个北极星指标(north star metric),标准是一句话讲得清、汇报时不用多解释。有家给医疗保险公司做治疗必要性复核的系统,挑的是错误批准数。复核的活,是替保险公司把不必要的治疗拦下来,批错一次就是白付一笔医疗费,所以这个数比任何百分比都贴业务。总体准确率他们照常度量,一个项目周期里从 95% 做到了 99%,这是历史成绩。产品经理布置任务也顺着这个口径来,临床推理数据集上,眼下 95%,目标定在 99%,这是当下目标,起点、目标、检验进度的办法一次配齐。
指标还有一个固有风险,它会变成智能体的优化目标,然后遭人钻空子。经济学里的古德哈特定律讲的就是这层,常被概括成一句话,度量一旦成了目标,就不再是好度量。智能体钻空子的花样很实在。客服智能体按解决率考核,它学会把难单悄悄转人工,只挑简单单接,指标漂亮,活全推给了人工;编码智能体按测试通过率考核,它学会改测试而不是改代码,测试全绿,功能照坏。防御方法跟防裁判偏差一个路数,指标别单放,配一组互相牵制的,转人工率、测试改动量跟着一起看;再定期顺着轨迹抽查指标背后的动作,12.2 的过程指标在这里正好派上用场。
这套系统给失败归类的方法也值得照抄。复核手术建议,先对照资格标准。一位 78 岁女性的膝关节镜手术,标准是专家列的一张问题清单,其中一条是要查至少六周保守治疗无效的记录在不在。失败归成三类。病历提取这一类,是该提取的临床信息没提出来;临床推理这一类,是医学逻辑不当、临床因素没权衡好;规则解释这一类,是保险指南或承保标准套错了。分好类,改进才知道往哪儿使劲。提取类多半在数据质量与检索上,推理类常常要动模型,规则类在提示词上。再配上按失败模式预先构建的专用数据集,工程师就在自己负责的那类失败上迭代,不用眉毛胡子一把抓。
这套归类出自几本工程实践书,不是行业标准,作为诊断的工作分类够用。智能体的失败大体也分三类。上下文性失败(contextual failure),该拿的信息没拿到、拿错了、拿脏了;知识性失败(knowledge failure),信息在手,需要的知识缺了或错了;推理性失败(reasoning failure),信息和知识都对,结论推岔了。三类的修复方法各有去处,上下文性去修检索与工具,换检索策略、修数据源、补工具;知识性去修知识库,补文档、改图谱、上检索增强;推理性去修提示词,或者换模型。诊断报告照这个骨架出,每条失败标上类别和修复方向,评测的输出就直接成了派工单。分数跌了只说明出了问题,分好类才知道往哪儿修,第一眼看到的不是跌了三个点,而是推理性失败多了两条,先去查上周改的那段提示词。
这套分类自己也会过期,这一层更容易漏。上线时定的失败类别,照的是当时的任务分布;跑上几个月,用户问法变了,业务添了新场景,新失败往旧类别里塞不进去,硬塞就把归因弄乱,修复方向跟着指错。所以回流管道不能只有加案例这一个动作(这条管道 12.2 细讲),还得定期给类别本身翻新,抽一批新失败做开放式编码,不预设类别,先描述再归类,发现装不下的,就给分类添新类。只有加法、没有翻新的回流,案例攒得越多,归因反而越糊。
Eugene Yan 对这笔前置投入值不值有过一段观察。评测加实验的装置一旦搭顺,改配置、改提示、一键重跑都不费劲,团队就愿意主动去磨分数,进展跟着加快。反过来也成立,跑一次评测要手工拼半小时命令,就没人想跑第二遍。评测设施顺不顺手,直接决定它进不进得了日常流程。
这套设施还有个起初没想到的用途,拿它当换模型时的验收单。厂商发布新版本,宣传语总说更强了,可到底是升是降,得在自己的任务集上跑一遍才知道。模型一换,全线失灵,这是智能体项目的高频事故。纸面上的通用能力提升,从来代替不了自己任务集上的那轮分数。
改三处提示、最后只能整体回滚的事故,换这套方法走就是另一番结局。三处改动不捆在一起上,进一处跑一遍任务集,再进下一处。惹祸的那处当天就现形,其余两处照常保留。评测驱动开发省下的不是头一回犯错,而是犯完错不用再猜。改动效果有数字摆着,回滚也拿得出凭据。
一次进一处,还讲究幅度。改动有一条从最小到最大的阶梯,换一个词调语气或精度,给现有句子加一个子句,给现有小节加一句话,给提示词加一节,加或改一个工具,换模型或参数。顺序是固定的,先试最小的,没修好再往上走。人的直觉常常反过来,一出手就想重写整段提示词。可是小改动有自己的好处,能保住提示词精简,不拖累模型性能,也不拖慢每次调用。
只加不删是反面教材。系统提示臃肿到好几页、前后打架,通常就来自这种习惯,每出一次事往里加一段,从不往外删。最小改动只算纪律的一半,另一半是定期清场,把不起作用的话删掉。
案例之间也会打架。一条要智能体一步步推理,另一条要它别推理、直接给答案,这条过了那条就挂,这种冲突迟早碰上。碰上之后,把三件事想清楚。挂掉的案例是不是非过不可,等攒到成十上百条,九成通过率本就是合理预期,挂掉的那条反过来可以当错误样本收进任务集。要不要为挂掉的一小撮单设一个专门智能体,设了就背上路由问题,路由器自己也会出错,专业化的好处未必抵得过抬高的错误率。要不要整份重写,重建常常等于从零开始写指令,把最麻烦的案例聚焦起来,比修修补补划算。
对迭代速度的预期也要提前摆正。编程智能体的实践者给过一个很坦率的数,大约三分之一的任务,第一次尝试就成功。配套的工作流顺着这个数来配。一开始只丢一条简短提示词,让智能体把整件事跑完,成了就省下一大块时间,没成再转成协作式引导。第一次尝试的产出本身就是数据,智能体的理解断在什么地方,它全暴露出来,后面的引导才有了依据。
三分之一这个数本身不是质量指标,它随验证基础设施大幅起落。凡是带测试、类型检查和 lint 这类自动反馈的任务,首次成功率明显更高,因为智能体能在循环里自我纠正。没有验证标准的任务,模型连自己做没做错都分辨不出。拿首次成功当考核目标,劲使错了地方。要看就看拿到正确产出的总时间。第一次没过、第二次加三十秒指点就过的任务,根本不叫失败,只是从一分钟任务变成两分钟任务。
反方向推也一样。测试多写一个、类型标注多加一处、lint 规则多配一条,都是对首次成功率的投资。错误刚冒头,自动验证就顶了回来,这件事在整个智能体工作流的改进里性价比最高。
评测不足是在赌,等评测做到完美再发布,同样是在烧钱。评测难,起步阶段尤其难,这是实情。可评测再完善,也保证不了应用上线之后就有真实业务价值,发布拖得越久,赔进去的时间和机会越多。设想一个做内部摘要工具的团队,任务集围着连贯性、相关性这类指标搭,初次发布之后才发现用户要的其实是更长的摘要,指标量得再准,也没量到用户真正要的东西。解法不是等,是把发布做小。先放给小范围用户组,或作为可选功能挂上,第一批反馈一到手,再回头把评测补扎实,下一轮迭代的基线就有了。
发布做小解决的是敢不敢放,放出去之后新版到底比旧版好多少,要靠线上对照来回答。新旧两版各接一部分真实流量,跑上一段时间,比的是改址成功率、客诉率这类业务指标,不是两段输出文本像不像。约束也现实,流量要够分,周期要够长,小体量的业务凑不齐对照要的样本,所以线上对照留给大版本的最终裁决,日常迭代仍然靠离线任务集下判断。影子测试加金丝雀的具体做法,第 15 章生产化的时候展开。
这一节的处境,软件工程里有对现成的词能说清。验证(verification)问的是代码做的,是不是我想做的;确认(validation)问的是建的这个东西,是不是对的东西。摘要工具那个例子,栽就栽在只做了验证、没做确认,连贯性相关性量得再准,量的也不是用户要的东西。还有门做法叫 BDD(行为驱动开发,Behavior-Driven Development),把需求写成给定什么条件、发生什么事件、应该看到什么结果的故事,故事本身就是规范,测试照着故事生成。智能体的案例卡走的正是这条路,输入加期望行为就是一则故事,裁判照着判。分清这对词,评测的边界就清楚了,它能回答做对了没有,回答不了该不该做。
评测先行,本质上就是把“什么算好”从口头共识变成一份能执行的资产。
12.2 轨迹
每一次运行智能体或多智能体系统留下的轨迹(trajectory),就是评测的统一对象:某个任务从开始到结束的完整记录,分四块,消息、动作、结果和元数据。第 2 章手写回路时用 print 打每轮的工具名和参数,就是这份记录最原始的形态,毛病不只是记得少,而是太散,只留调用不留结果,没有时间戳,也没有 token 消耗,控制台一滚就没了,两版系统各跑一遍,输出混在同一个终端里,想对比都无从下手。从 print 换成结构化轨迹,补的不只是信息量,更重要的是,记录从此变成了程序能直接处理的数据。
- 消息,用户、智能体、工具之间的每一次往来都记在这里,模型的推理文本同样不落下
- 动作,工具调用与函数执行,调用时带的参数一并记录
- 结果,任务到底有没有成、一路上撞见哪些错误、最后交出来的产物是什么
- 元数据,一共跑多久、烧掉多少 token、用的是哪版模型哪版配置、时间戳记的是什么时候
这套结构不挑评测对象的层级。评一次裸模型调用、评一个带工具的智能体、评一个多智能体编排,落到最后都是同一类东西,一条随时间展开的推理与动作序列。裸模型的轨迹短,一问一答就完;多智能体的轨迹长,几百条消息,结构却不变。所以轨迹成了评测的统一对象。一套存储、一个打分入口、同一种回放方式,从单次调用到完整编排,各层级都用得上,评测设施不必为架构升级重写。把四要素放进快递客服的一次运行里看,是这个样子。
text
任务:查订单 SF20260824001 到哪了;未派送则把地址改成杨浦区五角场街道 100 号
消息:系统提示 → 用户提问 → 助手发起 tool_calls → 工具结果 → 助手答复
动作:query_express(order_id="SF20260824001")、update_address(order_id=..., address=...)
结果:success=true,答复"包裹在杭州转运中心,尚未派送;地址已更新"
元数据:2 轮、耗时数秒、token 输入输出各一栏、模型与配置版本号多智能体的轨迹长成一棵树,见图 12-1。
主轨迹上有一个动作节点写着“派给子智能体”,子智能体接着跑出自己那条完整轨迹,挂在这个节点下面,回给主上下文的只留摘要。第 8 章的子智能体、第 10 章的编排,讲的都是这套机制。评测的时候,整棵树都在手里。要评总结果,看根就够了;要查是哪个环节出错,下钻到对应的子轨迹就是。定位不再靠猜,直接查档。
具体到代码,这一步是给第 2 章的客服回路补个数据结构,print 那行从此退役,记录改走结构化通道。
python
from dataclasses import dataclass, field
from typing import Any, Optional
@dataclass
class Usage:
prompt_tokens: int = 0
completion_tokens: int = 0
@dataclass
class Trajectory:
task: dict[str, Any] # 任务与判定要点
messages: list[dict[str, Any]] = field(default_factory=list)
success: Optional[bool] = None # 任务是否完成
error: Optional[str] = None # 失败时的错误详情
usage: Usage = field(default_factory=Usage)
metadata: dict[str, Any] = field(default_factory=dict)回路本体只需要三处改动。开头建一条空轨迹,循环里每轮把 token 用量和轮数记进去,收尾时写成败,再把轨迹连同答复一起返回。client、tools、tool_map 这些沿用第 2 章的定义。
python
def run_agent_tracked(user_input: str,
max_turns: int = 8) -> tuple[str, Trajectory]:
traj = Trajectory(task={"input": user_input,
"criteria": "查件与改址两件事都要有交代"})
messages = [
{"role": "system", "content": "你是快递平台的客服助手,用中文回答。"},
{"role": "user", "content": user_input},
]
traj.messages = messages # 消息历史本身就是轨迹的消息记录
for turn in range(max_turns):
response = client.chat.completions.create(
model=MODEL, messages=messages, tools=tools
)
message = response.choices[0].message
messages.append(message) # 模型的决定与工具结果都留在历史里
traj.usage.prompt_tokens += response.usage.prompt_tokens
traj.usage.completion_tokens += response.usage.completion_tokens
traj.metadata["turns"] = turn + 1
if not message.tool_calls:
traj.success = True
return message.content, traj
for tool_call in message.tool_calls:
fn = tool_map[tool_call.function.name]
args = json.loads(tool_call.function.arguments)
result = fn(**args)
messages.append(
{"role": "tool", "tool_call_id": tool_call.id, "content": result}
)
traj.success = False
traj.error = "max_turns"
return "已达单次任务的轮数上限,请稍后再试或转人工。", traj跑完一条任务,函数把答复连同轨迹一起交回来。想重放,把 messages 原样喂回执行器,当时的经过就能再走一遍。想对比,两版系统的轨迹按轮对齐,第一处分歧摆在眼前。想打分,裁判的输入就是它。想沉淀也容易,线上每次运行落一条,生产流量本身就是评测素材。
重放复查的是当时的记录,不是复现当时的结果。模型的输出带着随机性,环境也在变,订单也许已经派送,地址也许早就改过,同一份输入今天重跑,大概率得到另一条轨迹。所以回归评测比的是任务集上的分布,不是逐条复现旧结果。轨迹的取证价值在还原现场。当时输入什么、工具返回什么、模型做了什么决定,全都在案。想精确复现,得把模型快照与环境快照一起冻结,那是另一项工程,日常迭代用不上。
这套做法有名字,叫可观测优先。执行期发结构化事件,事后随时重建轨迹,这么一来,每一次生产运行都是潜在的评测数据点。
这套做法落到日常,主要是两件事。一件是定期抽样,每周从生产轨迹里抽一批,人工过一遍,看质量分布有没有漂移。另一件是客诉追查,客诉一来,按会话把轨迹捞出来,确认问题、复盘原因,再把这条输入连同修正后的期望行为写进任务集,回流成新案例。12.1 说的案例来源,靠的就是这条管道。
客诉是显式的信号,还有一类隐式的埋在用户行为里。同一个问题过两天又来问一遍,是上一轮没答好;一句话刚说完就改口,是智能体没听懂;问着问着没了下文,是用户放弃了;干脆绕过智能体找人工,是彻底不信任了。这四类会话都是智能体没办成事留下的痕迹,按行为特征从轨迹里筛出来,自动排进抽样队列,回流就不必干等用户开口投诉。
线上评测还有两件工程开销要管。一件是异步,指标挪到后台算,别卡在生产链路里,用户该多快拿到答复还是多快,打分晚几分钟到不碍事。另一件是裁判的成本,全量筛查可以用便宜的小模型当裁判,只把拿不准的那档升级给大裁判,跟 12.3 要讲的三层漏斗是同一个思路。
真要把这套东西做成基础设施,走的是第 14 章的链路追踪。LangSmith 把采集、筛选、导出这些轨迹环节做成了平台能力;Arize 那边则有开源的 Phoenix,拿 OpenTelemetry 与 OpenInference 打底,专做轨迹与评测。
自建 Trajectory 和直接用这类平台并不冲突。前者把机制看得清楚,后者省掉存储与界面的工程量。第 7 章说的存储与呈现分离,到这里是同一个思路,底层数据一字不改,怎么呈现随用随算。
回流管道搭好,不等于系统就真的在变好。有一种失灵很常见,反馈一直在流进来,改进却没有流出去。管道跑了几个月,案例攒了一堆,智能体毫无长进。要发现这种失灵,得给回路本身量几个数,不能只盯着智能体的分数。
先说错误复发率,也就是同一条错,纠正过后还犯不犯。纠正过的错又冒出来,多半是反馈停在入库那一步,没有变成行为。再说纠正对改进的比值,多少条反馈才换来一次看得见的改进。这个比值的走向比绝对值有用,持续走高,要么是反馈质量在跌,要么是改动没打在要害上。
另有两个维度,最容易漏掉。一个是覆盖与延迟,看的是反馈覆盖了多少比例的运行、从出错到转成案例隔了多久。只覆盖头部用户、拖上三个月才入库的回路,改进永远慢半拍。另一个是来源集中度,信号老集中在少数几个用户头上,改进也会跟着他们偏。这几个数不必定死阈值,趋势一不对劲,就该停下查回路本身。
回路还有一条边界要划清,喂回去的必须带着真实世界的校验,不能拿智能体自己的产出闭环自证。把模型自产的答案当标准答案回流,一代传一代,错误和窄化会一路累积,这就是模型坍缩的机理。偏好信号同理会被放大,用户偏爱长回答,反馈回路就把写长一路强化,等察觉时,系统已经收不回短句了。回流的案例要带真实交互的痕迹,用户的确认、真实的结果、人工的修正,拿不准的宁可不进基线集,也就是那批留作对照的固定案例。
轨迹拿到手,取答案这一步有个不起眼的坑,偏偏很致命。例子短得很。问 2+2,智能体先说“让我算一下”,工具返回 4,它再收尾说“计算完成”。要是拿最后一条消息当答案,到手的是“计算完成”,真正的结果躺在工具返回里。快递客服收尾也常来一句“已为您处理好,还有什么可以帮您”,把这句话当答案,判定必然失真。
所以答案抽取要定成显式策略。取最后一条非空消息,只取最后一条助手消息,或者把全部助手消息拼起来,各有各的适用场景。细节虽小,出的事不小。指标忽高忽低、查不出原因时,先看答案抽的是哪一条。
轨迹握在手里,过程本身也评得动了。光看最终答复,一个查了三次错才碰对的智能体,跟一个一次查准的智能体,得分一模一样。可轨迹一翻开就分出来了,前者调了三轮工具、参数还错过一回,后者一轮调用、参数全对。这类指标叫过程指标。智能体完全可能顺着错的路径碰对答案,只盯结果永远发现不了,所以工具选得对不对、参数给得对不对、顺序合不合理,对排障格外要紧。
顺序有没有跑对,也能变成可算的公式。STEPScore 这类自定义指标,做法是把生成的步骤序列拿去跟人工写好的标准步骤比。先算步骤集合的 F1,该有的步骤覆盖多少、多出来的占多少,然后每个错序的步骤扣 0.1,得到综合分。为什么非要它?从反面看就清楚。BLEU、ROUGE 比的是词面重合,BERTScore 比的是语义相近,步骤的先后它们一概量不出。一份先删数据再备份数据的排障指南,步骤全对、顺序却是灾难,三项指标照样打高分。过程指标落到具体领域,就是把顺序对不对翻译成一套可计算的扣分规则。
过程审查还有两个具体的用场。一个是评会看屏幕的智能体,让它照着设计稿截屏改图、操作网页,光比对最终产物不够,得看轨迹断点,哪一步点错了坐标、哪一步该滚动没滚动、哪一步读漏了页面上的元素,全在动作序列里记着,翻到分岔那一轮,毛病一目了然。另一个是核对言行,答复里写着已核对库存,轨迹里压根没有查库的工具调用,这类嘴上照办、实际没动的失败,光读产出永远发现不了。评审也好,裁判也好,都得立一条规矩,看动作,不只看言辞。
对错之外,稳定性本身也能当口径。子智能体写完,拿三个不同的输入各跑一遍,三份产出应该像出自同一位专家之手,格式一致,语气一致,连细节的密度也一致。哪个维度会晃,说明系统提示没把那个自由度钉住。怎么修也直接,把那一处指令写到足够具体,直到晃动消失。这个测试十分钟就能做完,防的却是另一类问题,只在真实会话里冒头,而且暴露的时机常不凑巧。
评测分层底下其实还藏着一层,工具得先各自过单元测试。工具是确定性的代码,参数校验、边界值和异常路径,断言式测试在这里完全够用。章首说单元测试兜不住,说的是智能体这个概率整体,工具这一层照旧要测。这一层不牢,轨迹里工具一旦错一次,就分不清是智能体选错了工具,还是工具自身带 bug,归因彻底搅在一起。
整套次序可以画成五步流程。
最底层是工具单元测试,往上是带函数调用数据的任务集,数据里标明该调哪个工具、该给什么参数;再往上依次是工具选择评测、端到端评测,最顶上是延迟与成本这类运营指标。概率的部分交给智能体评测,确定性的部分交还给传统测试。
落盘也有工程细节要抠。一条轨迹要么存成一个 JSON 文件,要么写成一行 JSONL,文件名带上运行 ID,运行 ID 再挂上会话 ID 与案例 ID。任务集跑批时,按案例 ID 就能把轨迹跟期望行为对上。落库前还有一道脱敏别省,轨迹里躺着用户的原话和工具带回的结果,订单号、姓名这类个人信息就混在里面,替换成占位值再入库,跟案例采样脱敏走的是同一条纪律。
工具返回的长结果,别一整段塞进轨迹文件。搜索捞回的一整页、读出来的大文件,放到对象存储里,轨迹中只留引用与摘要。空间省下了,重放时按需取回也不耽误。
轨迹涨起来比想象中还快。一条中等复杂度的任务,随随便便几千 token,一天跑上万次,就是好几个 GB。存储不值钱,值钱的是检索。索引按会话、时间、案例和成败四个维度建起来,排障和回流才走得顺。
从一行 print 走到一个 Trajectory,中间差的不只是代码量,更是设计意图转了个向,把运行过程当成数据认真对待。
12.3 LLM 裁判与偏差校准
有一类质量维度,没有唯一的标准答案。用户一句话里塞的两个分句都接住没有,解释得清不清楚,语气得不得体,都算这一类。这类无参考答案的指标(reference-free metrics),靠的是判断力,眼下的通行做法,是叫一个强模型来当LLM 裁判(LLM-as-a-Judge),读一遍轨迹,按维度打分,再补上理由。
裁判不是每个维度都得请。另一类维度,判分办法是现成的、确定性的,订单号对不对、金额有没有算错、日期差没差一天,这些用字符串匹配加几条规则就能判,不烧 token,跑一百遍结果也一个样,凡是这类跟参考答案比对的指标(reference-based metrics),能上就优先上。
那维度清单本身从哪来,12.1 说过,去找业务方把“好”的定义谈拢。谈拢之后剩一道翻译工序,配方是现成的。
先找一线专家问一个问题,这份产出拿到手,他会检查什么。把答案逐条记下来,一条都别筛。
清单到手,就一条一条翻译。凡是能变成确定性信号的,先变成确定性信号。拿写代码的智能体来说,专家检查的是测试过没过,就记 pytest 的通过率;检查边界情况,就读覆盖率报告;检查类型问题,就跑 mypy、pyright 这类静态分析。走这条路,跑得快、可复现、信号又精确。翻译不动的才归裁判,像代码可读性、架构合理性、答复得不得体,这些进裁判的评分维度。
报表类的产出也是同一个道理。数字对不对,用规则核对;口径统不统一、结论清不清楚,交给裁判。产出里要带图的,裁判也能直接看。带视觉能力的模型收下图来评,图表字体可不可读、标题恰不恰当,都能评。裁判处理的消息类型,跟智能体执行时完全一致,第 16 章 16.1 要讲的图像输入,在这里换了个方向用。
维度表里还值得留一两个一票否决的位置。关键的评分卡上,幻觉、越权这类错单独列成门槛项,一旦踩中,整条判负,其余维度再漂亮也不救。不设这道门,漂亮的平均分就把致命错盖过去了,报表上看只是一处小失分。
翻译完,还要回头验一道。抽几条产出让专家重评,跟指标对得上才算数;对不上,就回去调维度定义。需要过校准的不只是裁判提示,整套评测体系都要过。
裁判不是喊一句“请打分”就能上岗的。一份合格的裁判提示,要满足四条。第一,维度可判定,每个维度都得有能操作的判断标准,空话像“质量高不高”不能要。就说准确性,“回答是否正确”没法判,改成“与工具结果一致给 9-10、编造信息给 1-3”才判得动,模板里的分档就是照这条写的。第二,分档要有定义,8 到 10 分长什么样、1 到 3 分长什么样,写死在提示里,压住裁判的自由发挥。
第三,先理由后分数。让裁判先把判分理由写出来,再给分,分数会稳得多,理由本身也是排障的第一手材料。第四,输出要结构化。要求它用 JSON 交卷,程序好解析,分数好入库。给快递客服配一个裁判,模板长这样。
text
你是客服质量评审员,对照任务要求给智能体答复打分,输出 JSON。
先写每条判分理由,再给分数。长度不是扣分项,答复正确且完整时,不要因为话多降分。
评分维度与分档
- 准确性:与工具结果一致给 9-10;表述含糊但无错误给 6-8;编造信息给 1-3
- 完整性:用户每个分句都得到回应给 9-10;漏一项给 5-7;答非所问给 1-3
- 清晰度:直接可读给 9-10;要读两遍才懂给 5-7;前后矛盾给 1-3
### 示例
任务:查订单 SF20260824001 到哪了;如果还没派送,把收货地址改成上海市杨浦区五角场街道 100 号
答复:包裹当前在杭州转运中心,尚未派送;收货地址已更新为五角场街道 100 号。
输出:{"accuracy": {"score": 9, "reason": "与工具结果一致"},
"completeness": {"score": 9, "reason": "两个分句都处理了"},
"clarity": {"score": 9, "reason": "两句话各对应一件事"}}
### 输入数据
任务:{task}
答复:{reply}
输出:模板第二行里“不要因为话多降分”这句,不是随手写的,它来自一类真实付过代价的偏差。
这个偏差,在一场四配置对比实验里暴露过一次。实验拿直连模型、带工具的单智能体、轮转三智能体和 AI 编排三智能体四套配置互比,统一用 GPT-4.1-mini,10 个任务按类型分成四个套件来跑。第一轮结果就反直觉。直连模型 7.94 分,多智能体反而只有 6.82 分。做实验的人没有照单收下这个结论,而是打开裁判的理由栏,看到一句评语,大意是,答案是对的,可对这么简单的任务来说太啰嗦了。
原因随后找着了。三个智能体协作,轨迹里天然带着规划、执行、复核一整套过程,裁判把展示过程的部分读成了废话,当冗长扣了分。
修正办法是给裁判加一层评分理念。答案正确且完整就给 8 到 10 分,长度一概不看;协作过程看得见、推理与验证的步骤有展示,同样不扣。
改完重跑,多智能体从 6.82 升到 9.30。系统本身没动,只换了两套裁判提示,分数就差出近 2.5 分,这个量级的差距足以推翻一个架构决策。
这组数字看个趋势就好,别当成普适常数。裁判一换、任务一换、模型一换,具体数值就变。不变的只有教训。分数反常时,要怀疑的不止智能体一个,还有裁判。
吃冗长惩罚亏的不只这一例。NeurIPS 2023 有一篇论文,把 LLM 裁判翻来覆去研究过,归纳出三种典型偏差。位置偏差,发生在成对比较时,裁判老偏向某个位置的回答;冗长偏差,是裁判没来由地喜欢更长的回答;自我增强偏差,是裁判偏爱自家模型那种风格的输出。
同一篇论文也报过正面数字。GPT-4 当裁判,与人类偏好的一致率超过八成。可见裁判这个方法本身成立,前提是偏差有人管,而管偏差的位置就在提示与流程里。成对比较时交换顺序跑两遍再取均值,压的是位置偏差;问“哪个更好”比问“这个几分”可靠,因为相对判断比绝对打分更贴近人的评估方式;再给裁判配一个与被评估方不同家族的模型,压自我增强偏差。
自我增强偏差进了多智能体系统,还会放大成串通(agent collusion)。几个智能体彼此强化错误答案,共享假设、偏差或训练数据,又没有外部检查来打破这个循环。典型的样子是复核智能体跟被复核方跑同一个模型,倾向把对方的幻觉标成有效。复核层一旦跟它要复核的智能体串通,给出的信心是假的,比没有复核层还要糟。裁判也逃不开这一条,同一个模型把同一批案例问几遍,几份意见看着有几份,底子还是同一套偏好。10.2 讲投票时说过它,就是共因失效,多份意见算不得多票。
防串通有三条直接的动作。第一条,做评估的一方换用另一家厂商的模型,不跟被评估的一方同家。这就是前面压自我增强偏差的那一条,可放在这里理由更硬。不同模型在不同方向上失败,盲区不完全重叠。第二条,换不了模型,就用不同的提示词与人设,分出两个立场来。拿到专挑问题提示的复核智能体,和拿到确认正确性提示的复核智能体,即使在同一个模型上,表现也不一样。第三条,定期抽一部分产出做人工复审。不对照真值核对的自动评测,会不知不觉地漂移。
复核层的治理还有几件通用的事。复核智能体意见不一致,该由哪个拍板,权限层级要事先定死。智能体之间的消息全部记档,分歧与决定事后能审计。达不成一致、给不出把握时,就升级到人工,把人当兜底。
打分方式还有一层选择,单条评还是成对评。单条打绝对分,问的是这条几分;成对比较,问的是哪条更好。在主观质量上,相对判断更可靠。让一个人在两个方案里挑一个好的,比让他给单个方案定绝对分数稳得多。迭代开发里,成对比较有个顺手的用法。新版与旧版在同一批案例上成对送审,只问哪版更好,赢面稳定了再合并。
成对比较也有代价。想从它排出完整名次,评测次数会明显变多,所以只在排序场景才值得这么花。
真要攒排名,靠的是把成对赢局一份份记下来。谁压过谁都有对局在案,从这堆对局能反推出一份分高下的次序,背后是广义的胜率估计,交手赢得多的排前面,没直接交过手的,靠共同对手把链条接上。12.4 会见到的 LMArena 偏好榜走的正是这条路,真人投票,两边模型不露名,盲选把品牌带来的印象分压掉一层。可榜反映的也只是投票那批人问的那批题,换一批人、换一批题再投,名次就会动,这个局限读榜时要记着。
实操里可以搭一个从便宜到贵的三层漏斗。确定性规则先筛一遍,嵌入相似度再粗筛一轮,LLM 裁判只审拿不准的那一档。分流规则一句话,规则判得出对错的直接出结论,判不出的先算嵌入分,嵌入也定不下来的才送裁判。
漏斗为什么省钱?硬答案全对的不用劳驾裁判,没调工具就开口编结论的直接判错,两头都由便宜的确定性规则挡掉,只有中间拿不准的才送裁判。任务集一大,省下的就越明显。
漏斗中间那一档,是嵌入向量的余弦相似度。规则筛不掉、又犯不上动裁判的,先归到这一档,产出和参考答案各算一个嵌入向量,量两者的夹角来衡量语义是否相近,得到一个便宜的连续分数。自洽性评估就是这么用的,同一个问题的几份答案各算嵌入,谁离均值最近谁当选,全程一次模型都没调用。这档的边界也清楚,量的是语义像不像,不是事实对不对。两句话把意思说岔了,相似度照样可能不低,所以当粗筛可以,当终审不行。
裁判要校准,模型自报的置信度更得校准,因为后者天生没准头,嘴上说九成把握,错起来一点不含糊。正路有两条。温度缩放(temperature scaling)先用一批带真值的样本校出一个系数,再把模型报的概率调到跟实际命中率一致。具体做法是,先让模型在这批样本上把置信度报出来,再拿真值逐条核对,看它说九成把握时实际对了多少,然后找一个温度系数 T,把这份把握校到准。常见的毛病是自信过头,说九成把握的题实测只对七成,温度系数调过之后,模型再报七成把握,就真的十次里对七次。这一步值不值得上,看置信度在业务里干什么用。审核队列按把握高低排、把握不够就转人工,这类直接参与决策的地方,校准就有实打实的回报。只把它当报表里的一个数看看,不上也行。
保形预测(conformal prediction)给的是一份带统计保证的范围,说九成把握,正确答案就真有九成机会在它给的范围内。用法上它不强行猜一个答案,而是交一份候选清单,并保证正确答案以指定的概率在这份清单里。清单的长短本身就是信号,一道题的清单只列一两项,模型对它有把握。清单拉出七八项,就是明说这事拿不准,这类就该直接转人工。它的工程定位跟温度缩放同一条,置信度直接参与业务决策、又错不起的时候,才值得为这份保证多搭一套机制。
不想上这两种,工程上还有个朴素的替代,同一问题采样多次,拿答案的一致率当置信度,四份答案一模一样,跟四份答案各不相同,可信度显然不在一个档。前面自洽性选答用的正是这路信号,往置信度上再引一步就是了。
判断事实对不对,另有一套更细的量法,名字叫 FActScore。它先把一条回答拆成一条条原子事实,再逐条去对照权威数据验证,得分就是获得支持的事实占的比例。拿一条无线耳机的答复来说,里面有三条可查断言,电池续航 6 小时、保修 1 年和促销价 79.99 美元。跟商品目录一查,实际续航是 8 小时,这条不实,保修与价格两条都成立,于是 FActScore 记 0.67,三条里对了两条。比起把整条回答笼统打成幻觉,这样量出来的信息足得多,错在哪条、对了几条一眼可见。代价是每一条事实的抽取与验证都得调模型,只有事实密度高的场景才花得值。
验证还能再硬一步,让裁判带着工具算。这类会计算的裁判不读文本凭印象打分,而是先生成一段验证代码,查库、调接口、跑计算,把答案里的量化断言对着数据源现场核验,再出裁决,研究文献里管这套叫工具集成推理(tool-integrated reasoning,TIR)。答复说毛利率是两成三,代码把收入成本两列一拉一除,对不对当场见分晓;说库存还剩四十件,查一次库存接口就有真值。前置条件是断言可计算、数据源可访问,裁判得配好连接和权限。换来的是量化断言的判定从听着像样,变成算过无误,本节开头那句能上规则就上规则,到这里走到了头,规则本身换成对数据源的直接计算。
任务集还有一条配套纪律。通用任务集要照着生产里的查询分布配。真实流量里四成在问库存,任务集里的库存题也该占四成;分布一偏,分数就跟线上对不上。通用集之外再放一个对抗任务集,专收那些容易触发幻觉的输入。容易让模型编功能补空白的复杂对比、停产商品与限时优惠这类边界、多种理解的请求和几个主题混一句的问法,统统收进去。通用集量的是日常水位,对抗集量的是最坏情形,两套分开报分,系统在边界输入上到底吃不吃力,心里才有数。
裁判本身也要 debug,而且得当成纪律来执行。有几件事要做。轨迹与判分理由必须一起落库,理由一丢,光有分数没法排障。前面那个冗长惩罚,正是打开理由栏才发现的。
裁判上岗前得先过校准这一关。抽二三十条案例,人工打一遍分,量出人机一致率。碰到不一致,逐条分辨,看是裁判偏了,还是提示没写清。一致率怎么算,事先定死,同分或只差一档算一致,跨档才算分歧。抽样也得分层,好、中、差各占一段,全抽简单案例会把一致率估高。裁判模型一换版本,校准就要重做,模型变了,旧的结论不再作数。
人工打分这一环,界面和组织都得讲究。界面上,评的是邮件智能体,就让评审员看到渲染成邮件模样的产出;评的是多步任务,就把完整轨迹摆出来,能逐步回放。评审员看到的跟真实用户看到的差得越远,打出来的分越飘。组织上,量表用固定分档,Likert 量表(Likert scale)那种五档七档,别放开自由打分;同一批案例让两三个人独立评,谁的分老跟大伙差一截,用评分者间的分歧量出来,先拉去对齐再上岗。人是最贵的裁判,别让界面和组织浪费这笔最贵的投入。
裁判代码本身同样可能有 bug,另一个教训就出在这里。多个裁判的维度要合成总分时,权重按全局加和归一了,没有按维度分别归一,结果合成分跟预期对不上,排查了半天,发现错在评测代码,而不是智能体。评测系统要跟智能体同等对待。进版本管理,写测试,过评审,一样都不能少。
校准时撞见的不一致,背后多半有规律。裁判系统性给高分,常常是分档定义松了,低档的触发条件写得不够狠。带过程的答复普遍拿了低分,那是冗长惩罚的变体,“不要因为话多降分”那一行加固就能防住。同一份答复在不同维度上串分,是维度定义叠在一起,把各维度的判定要点改成互斥就好。提示修一轮,校准集重跑一遍,一致率爬进可用区间,再放裁判上岗。
裁判上线之后,运营层面还有两件小事要管。其一,解析容错。模型偶尔不按约定交 JSON,多半是夹了说明文字,重试一次通常就规范了。连续解析失败要报警,那往往意味着裁判模型或接口出了状况。其二,版本锁定。一轮对比实验必须从头到尾用同一个裁判模型、同一版提示,中途一换,前后的分数就不可比。裁判提示也要进版本库,改一行提示,历史分数还能不能横向比较,心里要有数。
12.4 公开基准怎么读
GAIA 基准把人机反差摆得明明白白。466 道题,人类受访者答对 92%,当年的 GPT-4 带着插件只有 15%。题目对人来说不算难,概念都简单,但要联网查资料、要看图、要多步推进。智能体基准的设计思路也顺着这个反差来,专挑人觉得容易、机器觉得难的题。它测的是推理、工具使用与多步执行,不是知识记忆。
另一头,让裸模型直接答题,实测成绩更难看。GAIA Level 1 的 20 题子集,模型不挂任何工具直接做,GPT-5 答对 10 题,GPT-5-mini 答对 4 题,Claude Sonnet 4.5 和 Claude Haiku 4.5 各对 3 题。20 题里不靠工具真能解的只有 5 道,所以裸模型的成绩上限就是 25%。强模型能越过这个上限的部分,说得通的解释是训练数据里恰好见过这些记载,模型分不清哪些是自己准确掌握的,哪些是自己正在虚构的。
GAIA 之后,2025 年这条线转到了动态场景上。Meta 的 Gaia2 建在自家的 ARE 平台上,800 个动态场景、10 个 universe(场景主题域)。任务动不动就十步以上、耗几分钟,环境随时间变,还掺着噪声与歧义,又要智能体协作、又要守住时间约束。静态题集测不出的失败方式,像在异步环境里干等消息、错过时限,到这里才现形。
SWE-bench 一族是代码方向的必看项。它最早一版 2023 年发布,从 12 个热门 Python 仓库里挖出 2,294 个真实 GitHub issue 当任务,当年的 Claude 2 只解出 1.96%。如今再看这组数字,主要当历史坐标用。
现在的主力是 SWE-bench Verified。它那 500 例全部人工逐条校验过,描述清楚、测试正确、信息充分、确实可解。校验是跟 OpenAI 合作做的,基准页和镜像分发现在由 Epoch AI 负责。
SWE-bench Pro 再高一档。1,865 个任务、41 个仓库,全部出自商业应用、B2B 服务与开发工具这三类企业场景。任务比原版长,数据按公开、保留、商业分成三份。保留集从不对外发布,想刷榜也刷不到它。
对话加工具调用的方向,事实标准是 Sierra 的 τ 系。2024 年提出的 τ-bench,让模拟用户跟带 API 工具、守业务规则的智能体多轮对话。判分方式很干净,对话一结束,数据库终态与标注的目标态一比对就出结果。
τ-bench 还带来一个关键指标,pass^k,同一个任务跑 k 次,全部成功才算通过,专门测稳定性。
论文里报的数字很扎眼。连 gpt-4o 这类当时的函数调用强模型,成功率都不到一半,retail 域的 pass^8 更是低于 25%。一次做对,说明不了次次都能做对。
pass^k 还有个常放在一起对读的口径,pass@k,同样一个任务跑 k 次,有一次成功就算通过。有一次成功就算过,量的是能力上限,看模型发挥最好时能做成什么样,代码基准惯用这个口径;次次都成功才算过,量的是生产可靠。两个口径回答两种问题,报分时得注明用的是哪一个,拿天花板当稳定性行不通。
2025 年出的 τ²-bench,把环境升成了双控(dual-control)。用户那一边同样在操作工具,跟智能体在同一个动态环境里活动。telecom 是论文的主打域,官方仓库现在铺到 airline、retail、telecom、banking_knowledge 等域。
τ² 的任务定义里还有一栏,专门写用户已经知道什么。模拟用户照这份认知演戏,没写进去的一概当作不知道,信息讲究渐进透露,智能体问到才给。有这一栏管着,对话里用户说的每句话都有出处,用户本不该知道的事也就混不进来,判分量到的,是智能体应对用户的真本事。
τ 系拿模拟用户当陪练,这个设计自己也有软肋,读分数时得心里有数。软肋的名字叫过分配合,模拟用户说什么信什么,不追问、不质疑、不变卦,真实用户当场就会纠正的那些失败,全让它放过了,分数虚高的原因在这。治理有三招。给模拟用户写跨轮一致的约束,上一轮说过周五有空,下一轮不许忘;让它维持自己的偏好状态,预算上限、口味禁忌,全程记得住;再定期拿真实交互日志回来校准,别让模拟器自己漂移。还有一层更根本的,画像造得再细,测的也是团队设想的用户,不是真实分布。12.5 的用户画像变体同理,刻板印象会顺着画像钻进任务集,生成完的样本得拿真实流量核对一遍。
外围还有两层没提,操作系统级看 OSWorld,长时程方向看 METR 基准;METR 就是那家做模型评测的机构。截至 2026-08,2025 到 2026 年的主流组合,还是 GAIA、SWE-bench Verified 和 τ²-bench 这一组。
METR 量长时程的法子,是把一批任务先交给人做,记下每件活要花的时长,再让模型做同一批活,按时长统计成功率,得出时间视界(time horizon),指模型能力范围内的任务长度。这个数有两种口径,五成视界是成功率正好一半的时长,新闻标题爱引它;八成视界是成功率有八成的时长,生产里该认的是它。
两个口径差得远,METR 的报告量下来,八成视界始终在五成的四分之一到六分之一之间,假如某模型五成视界报两小时,八成就只剩二三十分钟。照五成的头条数字规划生产,高估的就是这一截;模型换代把视界推长,涨幅天然带着这个折扣,靠系统设计真正延长出来的那部分,才是实打实的。
挑基准其实就是在挑参照系,各有各的用法。要判断模型对复杂任务的覆盖面,看 GAIA 与 Gaia2 的通用助理能力;要选编码智能体的底座模型,SWE-bench Verified 的代码工程能力参考价值最大;离客服这类对话加工具的场景最近的是 τ²-bench,它的 pass^k 直接对应生产里“次次都得对”的稳定性要求。还有一条常有人读偏,榜单分数是模型加各家默认脚手架的组合成绩,脚手架不同,同一个模型的分数也不同。照着榜单选型,拿到的是那个组合的分,不是自己系统的分。
脚手架能把分数拉开到什么程度,有一个实例差距很大。同一个模型,换上两套脚手架去跑 Terminal-Bench 这类智能体基准,排名可以差出几十位。对比出自一家脚手架厂商的自报实验,具体名次不必当真,机制却说得通。工具、提示、回路的形状一变,模型发挥出的能力就跟着变;同一份权重,装进不同的脚手架,成绩就是不一样。
在工程上,结论就摆在那了,脚手架工程该单独立项,当成一个专门的大项来做。它不是模型的配件。选模型与写业务逻辑之间横着一整层设计,工具怎么挂、上下文怎么经营、失败怎么兜,这层设计会直接写进榜单分数。第 21 章会正面解剖一个工业级脚手架,看看这层设计到底长什么样。
基准答的是相对比较。模型 A 在某类任务上胜过模型 B,可它答不出这么一件事,这套系统放到自己真正的任务上行不行。基准考的是公开题目,自己系统要办的是业务任务,两者不是一回事。领域的成功标准、多模型的组合方式、数据的特征与失败模式,公开任务集一概覆盖不到。所以基准分数拿来当选型参考可以,当验收依据不行。
读口径要读全,这条也适用于榜单之外的里程碑新闻。2025 年,科研智能体 The AI Scientist v2 生成的三篇论文投给了 ICLR 的 workshop,其中一篇过了同行评审、被正式接收,据信是头一篇完全由 AI 生成的科学论文走到这一步。提出假设、写代码跑实验和起草论文,全程自主完成。可展开口径看,接收的是 workshop 级,不是主会;三篇里两篇被拒;评审指出了方法学漏洞、分析浅、引用出错、图表描述误导。里程碑是真的,量级也要读全。报喜的标题,往往只带前一半。
模型能力的口径还有一处常被读偏,复杂度曲线。苹果 2025 年 6 月发过一篇论文,拿四类复杂度可以精确控制的谜题去量大推理模型,发现任务复杂度过了临界点,准确率不升反降,模型的思考量反而收缩了。任务越难模型越能推理,并不是默认成立的事,选型时拿自家最难的任务实测,别拿中等难度的榜单分一路外推。同一条纪律也管自己报分,同一批案例跑多次,最大值和均值说的是两件事,最大值回答解决过没有,均值回答平均水位稳不稳。生产里要的是次次都稳,报最高那一轮的分数,是最常见的粉饰。
公开基准还有个结构性的坑,数据污染(benchmark contamination)。训练数据里一旦混进基准题,分数就虚高。而智能体系统的暴露面比裸模型大得多,那些带搜索、带检索工具的系统,会把网上流传的基准题连题带答案一起捞进上下文。
污染怎么来、长什么样,都不难认。来路不难猜,基准题一公开就上了网,下一轮训练就可能混进权重;表现也好认,榜单分高、实际任务平庸,题面稍加改动,分数就明显往下掉。缓解有四条路,别只靠公开基准,建私有任务集,成绩好得可疑就主动查泄漏,再定期拿新鲜的未公开问题抽查。想自己动手,还可以把公开题改写成等价的私题重测,掉分掉得厉害,污染的嫌疑就大。
基准还有一层要防。一旦成了优化目标,它量真实能力的效力就开始衰减。SWE-bench Pro 用保留集把防御做进了设计里,保留集不对外发布、刷榜够不着,这个分数量的一直是真实能力。
评测在企业里怎么长大,有条常见的演进线,起步全靠人工评审,量小速度慢;裁判校准过关后转半自动,机器打分,人只复核分歧那一档;最后全自动进回归,人退到分数异常时才介入。人不是被替掉,是往后撤到判断的岗位上。另一头,提示词也能进优化回路,让另一个模型拿着历史评测成绩去试改提示词,改完在任务集上重跑,分涨了就留,跌了就回滚,坏案例回流从人肉闭环升级成自动闭环。选型情报另有现成入口,Artificial Analysis 汇总各家模型的基准成绩,LMArena 收真人成对投票的偏好榜。看归看,落到验收还是那句老话,回自己的任务集上跑一遍。
12.5 自建任务集,从坏案例到活资产
自建任务集不是没办法时的凑合,而是正业:选型参考能靠公开基准,验收得回到自己的任务集上,这一节把方法收拢成一份能照着执行的清单。
案例从三路来。第一路是真实用户输入,做采样脱敏,订单号、姓名、电话和地址替换成同格式的占位值,保住结构、不保留真实值。第二路是上线之后的 bad case,当天就转成案例,输入照抄,期望行为按该有的样子补写。第三路是手工造出来的边界与恶意案例,第 13 章的攻击样本可以直接并进来。
编码智能体的案例还有第四条来路,往仓库里人为注入 bug,把修好它当成任务。SWE-smith 这类框架,把这条路做成了流水线。注入有三种办法。一种让语言模型改写某个函数,语义型逻辑错误藏得深,但注入能不能成功不可控。另一种对抽象语法树做确定性变换,完全受控、可复现,能系统性地覆盖各类代码缺陷。还有一种回退真实的 pull request 复现历史 bug,贴着真实的开发历史,只是数量受可用 PR 限制。任务一律存成补丁,应用之后必须弄坏至少一个现有测试。验证器就是仓库现成的测试,修复让测试通过才算解出,判分不靠主观标准。三种办法要组合着用,单用一种,覆盖面太窄。
恶意案例那条路,注入测试有现成的三层配置,由浅入深。第一层直接试“无视你的指令”这类话,第二层试着套出系统提示或工具细节,第三层诱导不安全的工具调用。真实注入攻击也是一步步加深的,这三层正好对上。到第 13 章详讲的那类攻击,攒样本时就照这三层配。
一张案例卡记三项,输入、期望行为和来源日期。其中期望行为要写成判定要点给裁判看,不去追求唯一的标准答案。写期望行为,档位按可判定的程度排开。硬产出像分类、结构化输出,用精确答案;开放产出像摘要,给一组有边界的可接受答案,几版说法都算对;任务遵循,用核查清单写明答复必须包含哪些要素,踩中一部分的给中间档的部分分,不在满分与零分里二选一。这排档位的两端,正好是 12.1 讲过的硬答案与判定要点。
规模要克制。一套真实在用的任务集就是这么配出来的,10 个任务、四个类别、mini 与 full 两档。mini 每类一条,两分钟跑完,喂日常迭代;full 全量,约八分钟,供阶段验收。任务集多小才算小,没有固定的标准。经验上,几十条能看清大差距;十个点以内的细微差距,要么加案例,要么多轮取均值,不然噪声盖过信号。
规模之外,还要给变化留余地。配置一成不变,智能体就会过拟合上去,多智能体强化学习里有个现成的例子。SMAC 环境把每个任务的单位起始位置全固定死,回合之间没有任何变化,受训智能体经常把这套配置背下来,学会的是不管状态如何都按固定顺序行动,分数很高,一换开局就崩。SMACv2 改成在回合之间随机化单位的类型与起始位置,任务变难,逼出来的才是能泛化的策略。这里得辨清,过拟合和数据污染是两类问题。污染是题目漏进了模型的训练数据;过拟合的原因在于评测环境缺乏变化,智能体把固定配置记进了策略。造任务也一样,同一场景多备几个变体,别让分数量的其实是记性。
任务集该当活资产来养。每一次上线事故、每一条客诉、每一次换模型时发现的回归,都沉淀成新案例。与其攒到月底批量补,不如每周固定抽一小段时间回流,后者高效得多。
回流的案例得有地方去,不能见一次失败就往主任务集里塞一道题。任务集要拆成两份。基线集保持稳定,当比较的锚点;探索集专收新出现的失败模式,攒够一定数量、验明确实有代表性,再并进基线集。基线集若天天在变,前后分数就不可比,回归检测也失效。
拆成两份管住了锚点的稳定,还有一类毛病它管不住,题目参与了调优。一道题只要反复拿来改提示、改系统,修改就是对着它的答案做的,往后在这道题上量出的分数会系统性偏高。这跟前面讲的数据污染不是一回事,污染是题目漏进模型的训练数据,这里是题目漏进了调优过程。两个毛病来路不同,把分数抬高是同一个结果。
快递客服的改址就能造出这样一道题。智能体收到改址请求,不先查订单状态就直接改,已派送的单子也照改,这条失败转成案例进了任务集,工程师照着它改了几轮系统提示,直到次次通过。往后每轮回归,这道题都稳稳过关,可这个分数说明的已经不是改址能力,是系统对着这道题的答案改过了。
最终验收要靠从没参与优化的题来跑,留出集(holdout)就是这批题。日常改提示、挑版本一次都不碰它,版本冻结、要拍板上线时才拿出来跑,那一次的分数才作数。留出集的独立性用一次少一次,哪道题照着它的失败改过系统,或者拿它的成绩挑过版本,它就参与了调优,要补新题顶替,不然下一轮验收量出来的还是偏高的分数。
想从任务集里拿到可信的分数,也有几条讲究。打头一条,基线从直连模型起步。第 9 章引的那组实验正好做例子,直连模型在纯推理任务上拿 9.7 分,压过多智能体的 9.3;token 消耗全场平均 355 对 15,343,差 43 倍。这样的结论,不把直连模型放进对照组是看不见的。
对照还能再进一步,问一句要是没有它会怎样。多智能体强化学习里有套方法叫反事实基线(counterfactual baseline),评某个智能体的功劳,假设它当时改选一个默认动作、其余人不动,整局回报会差多少,拿这个差值记功,正的是贡献,负的是帮倒忙。功劳怎么算,第 11 章 11.5 的信用分配正面讲过,这条方法正是它在评测侧的做法。工程上照抄很顺,怀疑某个子智能体不值它的开销,就把它换成最朴素的直连调用,同一批案例再跑一遍,两份总分一减,就是它的净值。这个净值比单看有它时的分数诚实,水位本来就高的时候,高分未必是它的功劳。
工具的价值和代价,对照实验一次就都量出来了。十道标着需要联网的 GAIA 题,用的是同一个底座模型,带上网络搜索的智能体做对 7 道,总成本 1.89 美元;不带搜索的做对 2 道,成本 0.26 美元。答对率上去了,成本却翻了七倍多,两头都得算。十道题算小样本,数字看个量级就够。失败的样子倒是很清楚,不带搜索的智能体要么老实承认解不了,要么硬猜。问到 Mercedes Sosa 2000 到 2009 年间的录音室专辑,带搜索的从维基百科找对了 3 张,不带搜索的猜了 4 张。
对照组还有一层讲究,参照必须固定住。强化学习把这个教训讲得最透,零和博弈里两个智能体一起训练,两条学习曲线摆在一起比,比不出任何东西。谁都压不过谁,可谁都打得赢未经训练的对手。所以要先固定参照再评。要么放一个预训练或启发式的固定对手,每次评估都对着它;要么把历史版本存下来,攒成一个对手池,确认新版本通常赢得过池中对手,AlphaStar 用的就是这条路。落到智能体评测上,两版系统都在改的时候,直接互比一样没意义,总得有一方冻成锚点。调优预算还得对等,一边搜了几十组超参,一边拿默认值顶上,这样的比较不公平。
对手池这条线还有三条提醒。头一条,池子是各个团队私有的,彼此不可比,两个团队各自赢遍自己的历史版本池,两份成绩放不到一张表上,池子的难度、对手的构成都不一样,跨团队的比较得回到同一套任务集。第二条,固定任务、换背景群体,DeepMind 的 Melting Pot 评测套件就是这个设计,场景不动,把一起参与的角色换掉,专测策略对陌生搭档的零样本泛化,换到工程上,就是那句把协作方模型换成别家、系统还转不转的追问。第三条,当心预处理悄悄改了目标,把奖励或分数做标准化、归一化,动的不只是量纲,还有优化目标的语义,量出来的可能已经不是原来想量的东西。
到这一步,评测的各个环节接成了一个循环,任务集喂给系统跑出分数,跑出的失败回流成新案例,任务集跟着长大。
跑出来的结果要跟元数据一起落库,模型版本、配置、时间戳都陪着分数存下来,分数一跌破阈值就报警。这套回归体系再接上第 14 章的运维,从度量到改进的闭环就完整了。
分数跌破阈值会报警,这是被动防守;一套持续在改的系统,还值得配主动的断路器。盯四类数,整体通过率的退化幅度,跟上一版比跌了多少;旧任务复发率,上一版修好的这版还挂不挂;修复保留率,早先的改进这轮还保不保得住;新失败数,这版引入了几个从没见过的错。任何一类越线,就自动停下合并,回到上一个好版本,先把回归查清楚再往前走。持续改进最怕的不是不涨分,是涨一分、暗亏两分还不自知。
四类数写成代码,本版逐案结果配一份历史失败登记,一对照就都出来了。
python
"""示意代码:回归断路器四类数的最小计算,python3 可直接运行。"""
# 本版任务集逐案结果,外加一份历史失败登记(数据为示意)
NEW = {"c-01": True, "c-02": False, "c-03": True, "c-04": True, "c-05": False}
OLD_PASS_RATE = 0.8 # 上一版的通过率
EVER_FAILED = {"c-02", "c-03"} # 历史上挂过、后来修好的案例
def circuit_breaker(new: dict) -> dict:
"""四类数各数各的,任何一类越线就停下合并、回到上一个好版本。"""
relapsed = [c for c in EVER_FAILED if not new[c]] # 旧任务复发
kept = [c for c in EVER_FAILED if new[c]] # 修复保留
fresh = [c for c, ok in new.items() # 新失败
if not ok and c not in EVER_FAILED]
drop = OLD_PASS_RATE - sum(new.values()) / len(new) # 整体退化
return {"整体退化": f"{drop:.0%}", "旧任务复发": relapsed,
"修复保留": kept, "新失败": fresh}
if __name__ == "__main__":
for name, value in circuit_breaker(NEW).items():
print(f"{name}:{value}")把案例造得跟真事一样,做法是写成完整的交互场景,而不是一条孤零零的输入。一个场景写四件事,成功长什么样,边界在哪里,用户是什么人,对话怎么展开。第一件对着案例卡的期望行为,第二件做进输入设计里,后两件才是这套做法的增量。
用户画像要写具体。知识水平、情绪状态和对系统的预期各是什么,案例就随着画像变化。再往画像上加压力维度。紧迫性,用户立刻要答案;模糊性,关键信息缺失,看智能体追不追问;情绪挫败,用户带着指责来;知识错位,用户误解了系统的能力。每加一个维度,同一个任务就变出一族变体。
探偏见也有一族变体维度。做法是把案例里的姓名换成另一个群体常见的姓名,别的地方一字不动,成对跑一遍,两份产出只要有差异,就是信号。第 13 章讲偏见检测时,要把指标按客群拆开比,这类成对样本正是那边要用的数据。
对话流也不只是一条提示词。追问、澄清、上报和失败后的恢复,都跨着轮次展开,写进去才贴近真实交互。
生成案例,还可以让模型自己上手。按画像与维度把场景变体批量生成出来,领域专家只管审阅,一个人一天审过的量,比逐条手写高一个数量级。变体暴露出来的问题,常常不是模型的错,而是团队内部还没对齐的预期。同一条变体,两位专家各给各的判定,没对齐的地方当场现形。
批量生成本身也有门道,别一句造二十条就撒手。成熟些的流程分两步,先让模型出蓝图,这个场景该覆盖哪些用户类型、哪些边界、哪些对话走向,蓝图审过了再批量出样本;出样本时用多专家的路数,一次让模型扮几个角色,客服主管、合规和老用户,各出各的视角。直接生成的样本彼此雷同,蓝图先立、角色再分,多样性才起得来。
真实案例要等上线慢慢攒,公开基准又不贴自己的业务,任务集不够用时还有一条补量的路,合成数据生成。做法是成对地造数据,拿一道已知正确答案的题,配一份好答案和一份差答案,在好答案里注入常见的错误类型,就得到那份差答案,比如编造一个数字、漏掉一个要点,然后把这对答案喂给评分器,它从两份的对照里学“什么叫好”。这条路有边界,只适合有客观判据的任务,开放式任务的好与差没有共识,造不出有效的对子。生成后仍要人工抽检,抽检时给每条标上失败类别,对齐 12.1 那套失败三分法,回流改进时才知道往哪儿派工。
评测系统自己也是智能体的攻击面,伯克利的一个研究团队扫了一遍广泛使用的基准,八个里个个有评分类漏洞。有的把标准答案放在任务配置文件里,智能体让浏览器开一个本地文件地址就把答案读了去,812 道题一道没解,分数却接近满分;有的靠测试跑通判分,智能体往测试目录塞十行钩子代码,测试结果在汇报前全改成通过。一个零解题能力的智能体,光凭这类洞在多个基准上拿到接近满分。
这些洞不用人教,模型自己会找上去。METR 给 o3 做评估时数过,评分函数全程可见的难任务上,128 次运行里 39 次出现自发的奖励作弊,改掉判分与计时函数、顺着调用栈抄评分程序已算好的答案都算在内,占三成;换到评分不可见的常规任务集,1,087 次运行只出 8 次。METR 的解释是评分函数看得见才绕得动,也不排除难任务本身的因素。第 2 章讲过奖励作弊这个词,落到评测设施上,它就是要防的具体攻击。
防御方法全在隔离。判分进程与智能体各跑各的沙箱,评分代码放在模型摸不着的地方,标准答案存到它够不到的路径;凡是设计上允许智能体 import 评分模块的评测框架,设计上就带着这个洞。
评测基座搭稳,还能干一件超出打分的事,当搜索的试验台。配置怎么调、策略怎么选,放进评测里批量试,分数当裁判,谁高谁留,评测从给人看的报表,变成自动挑优的依据。有条健康检查顺带能用,同一个智能体,第一千个任务的表现该比第一个好,经验的沉淀该看得见;看不出长进,说明学习压根没发生,跑得再多也是原地重复。这一章给的度量、轨迹、裁判,是信任的必要条件,不是充分条件:信一个智能体,还得它能说清自己干了什么,轨迹和第 14 章的 trace,正是那份举证材料。
本章小结
- 12.1 评测驱动开发:写代码前答完五问(成功标准、任务集、指标、基线和迭代节奏),产出维度表、任务集目录、打分脚本、对照组和定时任务,计划进版本库过评审;结论是统计性的,分数带置信区间报,几十条案例配并发跑批(分道限流、指数退避和单题失败不连坐),评测环境与生产隔离;改动按从小到大的阶梯一次进一处;指标单放会遭钻空子(古德哈特定律),配一组互相牵制的;失败分上下文性、知识性和推理性三类,各配各的修复方法,分类学本身定期翻新;指标底层立混淆矩阵四格,假阳性是误报、假阴性是漏报,精确率查准、召回率查全,错改代价大看精确率、漏改代价大看召回率,F1 取两者的调和平均兼顾两头。
- 12.2 轨迹:评测的统一对象,消息、动作、结果和元数据四要素,多智能体轨迹长成树,子轨迹挂在派发节点下;答案抽取要定成显式策略(最后一条助手消息还是拼接);过程指标量工具选择、参数和顺序(STEPScore:步骤集合 F1 加每错序步扣 0.1);工具先过单元测试,评测五步流程从工具单元测试到运营指标;轨迹落盘带运行 ID,入库前脱敏,长结果放对象存储只留引用。
- 12.3 LLM 裁判:能上确定性规则的绝不交给裁判;裁判提示四条(维度可判定、分档有定义、先理由后分数和结构化输出);三种典型偏差(位置、冗长和自我增强),成对比较换序取均值、跨家族配裁判;串通的防御方法三条(换厂商、分立场提示和定期人工复审);省钱三层漏斗(规则筛两端、嵌入定灰区和裁判终审);置信度校准用温度缩放或保形预测(温度缩放拿带真值样本找温度系数,把自报的把握校到实际命中率,保形预测交候选清单,保证正确答案以指定概率在清单里,置信度直接参与业务决策时才值得上),事实精度用 FActScore,量化断言用会计算的裁判(TIR);裁判上岗前过校准(分层抽样、人机一致率和换模型重做)。
- 12.4 公开基准:GAIA 量通用助理(466 题,人类 92% 对 GPT-4 带插件 15%),SWE-bench Verified 量代码工程(500 例人工校验),τ²-bench 量对话与稳定(pass^k 量次次都对,pass@k 量能力上限,报分注明口径);METR 时间视界双口径(五成是头条数,八成是生产数,八成只有五成的四分之一到六分之一,换代涨幅自带折扣);榜单分是模型加脚手架的组合成绩,脚手架工程该单立项;防数据污染(私有任务集、改写重测);基准当选型参考,不当验收依据。
- 12.5 自建任务集:案例三路来(真实输入采样脱敏、bad case 当天转案例、手工边界与恶意),编码智能体加注障一路(SWE-smith 三种办法,仓库测试当验证器);案例卡记输入、期望行为和来源日期,期望行为按可判定程度排档;规模克制(mini 两分钟日常迭代、full 约八分钟阶段验收),配置留变化防过拟合;基线集与探索集分开;反复用来改系统的题已参与调优、分数系统性偏高,最终验收另留从没参与优化的留出集(holdout),用过就算污染、要补新题顶替;对照从直连模型起步,参照冻成锚点,反事实基线算子智能体净值;断路器盯四类数(整体退化、旧任务复发、修复保留和新失败);评测系统自身是攻击面,判分进程与智能体各跑各的沙箱、标准答案不可达,允许智能体 import 评分模块的框架,设计上就带着这个洞;合成数据生成补冷启动的量,成对构造好差答案喂评分器,要有客观判据,生成后人工抽检并标注失败类别。
参考资料
- Mialon 等《GAIA: A Benchmark for General AI Assistants》(2023,466 题、人类 92% 对 GPT-4 带插件 15%),https://arxiv.org/abs/2311.12983 ,核实于 2026-08。
- Meta《ARE/Gaia2: Agents Research Environments and Gaia2》(2025,ARE 平台、800 动态场景、10 个 universe),https://arxiv.org/abs/2509.17158 ;仓库 https://github.com/facebookresearch/meta-agents-research-environments ,核实于 2026-08。
- SWE-bench 官网 Verified 页(500 例人工校验、与 OpenAI 合作完成),https://www.swebench.com/verified.html ;Epoch AI 基准页与镜像 https://epoch.ai/benchmarks/swe-bench-verified ,核实于 2026-08。
- Scale AI《SWE-Bench Pro: Evaluating Software Engineering Agents on Real-World Enterprise Problems》(1,865 任务、41 仓库、公开/保留/商业三分),https://arxiv.org/abs/2509.16941 ,核实于 2026-08。
- Sierra《τ-bench: A Benchmark for Tool-Agent-User Interaction in Real-World Domains》(2024,pass^k 指标、retail 域 pass^8 低于 25%),https://arxiv.org/abs/2406.12045 ,核实于 2026-08。
- Sierra《τ²-bench: Evaluating Conversational Agents in a Dual-Control Environment》(2025,双控环境、telecom 域、任务定义 user_scenario 的 known_info 栏与模拟用户渐进透露守则),https://arxiv.org/abs/2506.07982 ;仓库 https://github.com/sierra-research/tau2-bench ,核实于 2026-08;known_info 栏与守则核自仓库 src/tau2/data_model/tasks.py 与 data/tau2/user_simulator/simulation_guidelines.md,核实于 2026-09-16。
- METR《Measuring AI Ability to Complete Long Software Tasks》(2025,时间视界指标、50% 与 80% 双口径,80% 视界恒为 50% 视界的四分之一到六分之一),https://arxiv.org/abs/2503.14499 ,核实于 2026-10-07。
- Zheng 等《Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena》(NeurIPS 2023,位置偏差、冗长偏差、自我增强偏差,GPT-4 裁判与人类一致率超八成),https://arxiv.org/abs/2306.05685 ,核实于 2026-08。
- LangSmith 官方文档(轨迹采集、筛选、导出与看板),https://docs.langchain.com/langsmith ,核实于 2026-08。
- Arize Phoenix 官方文档(开源、基于 OpenTelemetry 与 OpenInference 的轨迹与评测),https://arize.com/docs/phoenix ,核实于 2026-08。
- DeepSeek 官方定价页(V4-Flash 峰时价,成本例算基准),https://api-docs.deepseek.com/quick_start/pricing ,核实于 2026-08。
- Victor Dibia《Designing Multi-Agent Systems》(2025)第 10 章(评测驱动开发五问、轨迹四要素、答案抽取策略、专家检查清单到评测方法的翻译配方、Eugene Yan 评测设施观察、裁判冗长惩罚与维度归一两个教训、四配置对比实验、基准与数据污染、SWE-bench 原版数字转引)。见 txt-ref-zh/designing-multi-agent-systems/。
- 《AI Agents in Action》第 10 章(自洽性评估流的嵌入均值选答、“最一致答案仍错”的诚实负例),见 txt-ref-zh/ai-agents-in-action/。
- Heiko Hotz、Sokratis Kartakis《Multimodal, Real-Time AI Agent Systems》(O'Reilly)第 5 章(五步评测流程,工具单元测试、函数调用数据集、工具选择评测、端到端评测、运营指标)。见 txt-ref-zh/multimodal-realtime-agents/。
- 《AI Agents: The Definitive Guide》第 1、8、9 章(第 8 章行为压力测试:场景四要素、用户画像与压力维度、LLM 批量生成变体加专家审阅;第 1 章 AI Scientist v2 投 ICLR workshop 的完整口径;第 9 章 SWE-smith 三种注障法与仓库测试当验证器)。见 txt-ref-zh/ai-agents-definitive-guide/。
- Sam Bhagwat、Michelle Gienow《Patterns for Building AI Agents》(O'Reilly 2025)第 10、11、12、13 章(医疗险复核案例:三层指标与北极星“错误批准数”、失败三分类与按类分桶改进、95% 到 99% 的单项目周期口径、PM 定目标的对话版)。见 txt-ref-zh/patterns-for-building-ai-agents/。
- 《AI Agents in Action》第二版 第 7 章(测试驱动的智能体开发:最小改动六档阶梯、只加不删的反模式、基准冲突三问、智能体串通与复核层治理)。见 txt-ref-zh/ai-agents-in-action-2e/。
- 《Claude Code: The Definitive Guide to Agentic Development》第 1、8、10 章(三分之一现实与“拿到正确产出的总时间”口径、先试一把过再转协作、验证基础设施投资与自动验证背压的杠杆)。见 txt-ref-zh/claude-code-definitive/。
- Ben O'Mahony、Fabian Nonnenmacher《Building AI Agent Platforms》(O'Reilly 2027 Early Release)第 1 章(评测瘫痪与小范围用户组先行、内部摘要工具的指标口径错位例)。见 txt-ref-zh/building-agent-platforms/。
- Ali Arsanjani、Juan Pablo Bustos《Agentic Architectural Patterns for Building Multi-Agent Systems》(Packt 2026)第 11 章(STEPScore:步骤集合 F1 加每错序步扣 0.1、BLEU/ROUGE/BERTScore 量不出步骤顺序)。见 txt-ref-zh/agentic-architectural-patterns/。
- 《Building Reliable AI Systems》(Manning MEAP)第 9 章(FActScore 原子事实分解与 0.67 算例、通用集镜像生产分布加对抗集的双测试集纪律)。见 txt-ref-zh/building-reliable-ai-systems/。
- Min 等《FActScore: Fine-grained Atomic Evaluation of Factual Precision in Long Form Text Generation》(EMNLP 2023,长文本拆原子事实、逐条对照知识源算支持率),https://arxiv.org/abs/2305.14251 ,核实于 2026-08-31。
- Younghee Song、Jungjun Hur《Build an AI Agent (From Scratch)》(Manning MEAP)第 2、4 章(裸模型 20 题子集四模型成绩与 25% 可解上限、带搜索 7/10 花 1.89 美元对不带 2/10 花 0.26 美元的十题对照)。见 txt-ref-zh/build-ai-agent-from-scratch/。
- Stefano V. Albrecht、Filippos Christianos、Lukas Schäfer《Multi-Agent Reinforcement Learning: Foundations and Modern Approaches》(MIT Press 2024)第 10、11 章(零和博弈共同训练的学习曲线无信息量与锚定对手/历史版本池、超参搜索预算不对等则比较不公平、SMAC 固定配置过拟合与 SMACv2 随机化)。见 txt-ref-zh/multi-agent-rl/。
- Julian Soh、John Tidwell、Priyanshi Singh《Building and Distributing Agentic AI Solutions》(2026)第 3 章(基线集与探索集分离、预期结果三形式、三层注入测试)。见 txt-ref-zh/building-distributing-agentic-ai/。
- 《AI Agent Handbook》(企业级智能体落地开源白皮书)第 17 章(锁定留出集仅用于候选版本冻结后的发布验收、与训练数据隔离;长期依据同一留出集的通过结果选择版本会产生间接过拟合,须定期补新题轮换),见 参考资料/ai-agent-handbook/05-optimization/ ,核实于 2026-10-01。
- Sakana AI《The AI Scientist-v2: Workshop-Level Automated Scientific Discovery via Agentic Tree Search》(Yamada 等,2025,三篇论文投 ICLR workshop、一篇过同行评审被正式接收),https://arxiv.org/abs/2504.08066 ,核实于 2026-08-31。
- Dhivya Nagasubramanian《Agentic AI for Engineers》(Springer/Apress 2026)第 11 章(反馈回路元度量:错误复发率、纠正对改进的比值、覆盖率与延迟、来源集中度,“反馈在流进来,却没有东西流出去”的回路失血判断;阈值系作者经验示意,未入正文),见 txt/agentic-ai-for-engineers.txt(英文原文,第 11 章,行 13395-13624)。
- Addy Osmani《Agentic Engineering》(2026 Early Release)第 3 章(同一模型换两套 harness 跑 Terminal-Bench 排名差出几十位的对比;LangChain 自报口径,名次与分数未入正文),见 txt/agentic-engineering.txt(英文原文,第 3 章,行 1064-1168、1443-1459)。
- 《Agentic GraphRAG》(Anthony Alcaraz、Sam Julien,O'Reilly 2026 中译)(失败分类学与干预路由:上下文性、知识性、推理性三类各配修法;会计算的裁判:生成验证代码对照数据源再裁决;回归断路器指标;失败类别的开放式编码翻新),见 txt-ref-zh/agentic-graphrag/。
- 《Build an AI Agent (From Scratch)》(Younghee Song、Jungjun Hur,Manning MEAP)(批量评测的并发工程:分提供商信号量、指数退避、return_exceptions 单题失败不连坐;模型安全拒绝 finish_reason 为 refusal 的跨提供商差异与后备处理),见 txt-ref-zh/build-ai-agent-from-scratch/。
- 《AI Agents: The Definitive Guide》(Nicole Koenigstein)(GUI 与截屏任务的轨迹断点审查;用户隐式反馈信号:重提、改口、放弃、绕回人工;评审看动作不只看言辞),见 txt-ref-zh/ai-agents-definitive-guide/。
- 《Multimodal, Real-Time AI Agent Systems》(Heiko Hotz、Sokratis Kartakis,O'Reilly 抢先版)(企业评测三段式演进:人工起步、半自动裁判、全自动回归;另一模型按历史评测成绩自动打磨提示词;模型情报源入口),见 txt-ref-zh/multimodal-realtime-agents/。
- 《Patterns for Building AI Agents》(Sam Bhagwat、Michelle Gienow,O'Reilly 2025)(仿真调参:拿评测基座当搜索试验台、任务序列上的学习信号;SME 复核界面:产出按真实形态呈现、完整轨迹可回放),见 txt-ref-zh/patterns-for-building-ai-agents/。
- 《Agentic Mesh》(O'Reilly 2026)(信任以可解释性为前提、轨迹与 trace 作为举证材料的衔接视角),见 txt-ref-zh/agentic-mesh/。
- 《Becoming an Agent-Based Modeller》(Jennifer Badham、Corinna Elsenbroich,Routledge 2026)(验证对确认的术语对:代码做的是不是我想做的、建的是不是对的模型;故事即规范;模拟用户只测设计的行为不测真实分布的警告;第 13 章实验纪律:同一组参数多跑、看波动幅度何时不再收窄来定轮数,显著性辨的是随机波动还是真实差异),见 txt/agent-based-modeller.txt(英文原文)。
- Shirley Wu《Collaborative AI Agents》(Stanford 博士论文 2026)(过分配合的模拟用户把真实用户会纠正的失败藏起来:跨轮一致约束、维持用户偏好状态、真实交互定期校准三向对策),见 txt/collaborative-agents-diss.txt(英文原文)。
- 郑天民《AI Agent 开发实战》(2025)(数字画像与刻板印象偏差的警告),见 txt/ai-agent开发实战.txt。
- 《Agentic AI For Dummies》(Pam Baker,Wiley 2026)(奖励作弊与指标博弈两例、古德哈特定律的智能体版;Apple 推理极限论文转述;最大值对平均值的报分纪律),见 txt/agentic-ai-for-dummies.txt(英文原文)。
- 《GenAI on Google Cloud》(Ayo Adedeji 等,O'Reilly 2026)(模型坍缩:拿模型自产输出当真值逐代退化、用户偏好经反馈回路放大),见 txt/genai-google-cloud.txt(英文原文)。
- 《Agentic AI for Healthcare》(Sairohith Thummarakoti 编,Routledge 2026)(置信度校准:自报置信度天生未校准、温度缩放与保形预测、自洽一致率当工程替代),见 txt/agentic-ai-healthcare.txt(英文原文)。
- 《Building Agent-Powered Applications》(Vasyl Zvarydchuk,Packt 2026)(类别不平衡的 accuracy 陷阱与宏微平均;Likert 分档与评分者分歧标准差筛除;在线评测的异步指标与小号裁判;合成数据先蓝图后样本、多专家元提示),见 txt/building-agent-powered-apps.txt(英文原文)。
- Shojaee 等《The Illusion of Thinking: Understanding the Strengths and Limitations of Reasoning Models via the Lens of Problem Complexity》(Apple,2025-06,四类可控复杂度谜题、复杂度过临界点后大推理模型准确率不升反降、思考量收缩),https://arxiv.org/abs/2506.06941 ,核实于 2026-09。
- Leibo 等《Scalable Evaluation of Multi-Agent Reinforcement Learning with the Melting Pot Test Suite》(DeepMind,2021,固定场景换背景群体、测对陌生搭档的零样本泛化),https://arxiv.org/abs/2107.06857 ,核实于 2026-09。
- UC Berkeley RDI《How We Broke Top AI Agent Benchmarks: And What Comes Next》(Hao Wang、Qiuyang Mang 等,2026,八个广泛使用的智能体基准均存在评分类漏洞,WebArena 经 file:// 本地地址读走任务配置中的标准答案、812 题拿到约满分,SWE-bench 判分遭 pytest 钩子文件改写,零解题能力智能体在多个基准拿到接近满分),https://rdi.berkeley.edu/blog/trustworthy-benchmarks-cont/ ,核实于 2026-10-07。
- METR《Recent Frontier Models Are Reward Hacking》(2025,o3 在评分函数可见的 RE-Bench 难任务上 39/128 次运行自发奖励作弊、占 30.4%,评分不可见的 HCAST 任务集 8/1087 占 0.7%,评分可见性为主因的解释),https://metr.org/blog/2025-06-05-recent-reward-hacking/ ,核实于 2026-10-07。
- 《Multi-Agent Reinforcement Learning: Foundations and Modern Approaches》(Stefano V. Albrecht、Filippos Christianos、Lukas Schäfer,MIT Press 2024)(最大值答是否解决过、均值答学得多快多稳;对手池跨算法不可比;奖励预处理改变优化目标语义;COMA 式反事实基线:改选默认动作的差值记功),见 txt-ref-zh/multi-agent-rl/。