让 Agent 给自己打分,评测集就开始变成作弊集
自进化闭环一旦转起来,分数的含义就变了:题变窄、判据泄漏、模型给自己答案打高分,都能让曲线向上而能力不动。这篇写怎么给闭环装一根模型碰不到的尺子,也写闸门不装时分数往哪走。
给 Agent 装自进化闭环的人,最后大多会撞上同一件事:分数还在往上走,走上去的那个东西越来越不像能力。题是模型自己出的,答案是模型自己答的,「这次为什么成功」还是模型自己总结的——三件事同一个来源,分数就不再是别人手里的尺子,变成它给自己记的分。被测系统一旦自己改写评测集,评测集就变成作弊集。这篇要拆的就是分数上变化的来路,以及怎么在闭环里留一根模型碰不到的尺子。
自进化闭环是我见过最容易让人产生错觉的东西:评测找出缺陷,缺陷转成经验,经验写进记忆,下一轮再跑起来。曲线往上走本身就让我警觉。自进化这条线我认同,只是要在每一段上补一件事:给每段装一把它碰不到的尺子。
分数涨了,涨的不一定是能力#
自进化这两年跑出来的可对照量级,主要落在两条路线上:一条从失败里复盘出 Skill 再用,另一条把经验写进权重。第一条路线上,开放问答的准确率从 60.6% 推到 67.9%,涨 7.3 个百分点。第二条路线上,三个环境分别到 89.9%、72.7%、47.1%,同一条基线在 77.6%、66.1%、约 38.5%。相对基线分别涨 +12.3、+6.6、+8.6 个百分点,经验库同期从 55 条涨到 100 条。
这两组数只报了涨了多少,没报涨在哪一环,这正好是要拆开的东西。涨出来的那部分里,多少是能力、多少只是把尺子挪近了,不看结构永远分不出来。
自进化的主张本身是对的:让系统在日常任务里积累经验,比人一条条总结出得快得多。闭环有个结构性缺陷:它优化的信号,来自一个它自己参与构造的评价过程。出题是模型做的,解题是模型做的,总结「这次为什么成功」的还是模型。三者同源,分数就不再是一把独立的尺子。
分数涨了有几种常见的假象,共同点是都能让曲线向上。光看曲线认不出是哪一种,得靠几道独立的读数把出题、答题、判分这三者拆开。
| 现象 | 看起来像 | 实际可能是什么 | 怎么确认 |
|---|---|---|---|
| 通过率持续上升 | 能力在长 | 题集被换成模型擅长做的那些 | 留一批它没见过的新题,只看这一批 |
| Judge 分数变高 | 输出质量变好 | 评委偏爱被测模型的表达风格 | 换一档模型当 Judge,看分数是否回落 |
| 加了 Skill 之后做对了 | Skill 有增量 | 任务本来就简单,模型本来就会 | 拿掉 Skill 再跑一遍,做消融 |
| 上线之后表现平稳 | 这次优化没有副作用 | 输出变长、工具变多、拒答率在漂 | 盯方向性指标的分布,不只盯通过率 |
「加了 Skill 之后做对」这个结论我验证过:某个 Skill 加上之后,通过率很好看。我把这个 Skill 删掉再跑同一批 40 条用例,通过率只掉 1.7 个百分点,插进来的 token 却是实打实的。归因没有对照,成功就记错了账。
一致率和冲突率必须一起报,才看得出这次是真对得准、还是把冲突挪了个地方。更隐蔽的是藏在一次成功优化后面的「上线之后表现平稳」,答案风格悄悄变了——更长、更啰嗦、工具调用更多——这些压根不在指标里。这类漂移从不让任何一条用例失败,它只让成本和体验慢慢变差。自进化里每次「分数变好了」的报告,都该长成这个样子。
闸门不装,分数会往哪走#
要拆的第一件事是「不装闸门会怎样」。先拆第一条路线。同一批开放问答复盘出 Skill 之后涨了 7.3 个百分点,把同一套 Skill 挪到另一个检索任务上、不重新训练,只剩 +5.3 个百分点。
7.3 减 5.3,差的这 2 个点就是同源数据在题集内部自循环换来的。经验库也在同步长,通用和任务专属两类条目都翻了近一倍。库翻一倍,同期三个环境最好的一个也就换来 12.3 个百分点。经验库不是能力,库变长本身说明不了涨分是从哪来的。
另一组数指向的是别的资产。让模型自己用自己总结的 Skill 跑同一批任务,两档强模型分别把成功率从 30.6% 推到 71.1%、从 29.6% 推到 69.8%,都在 +40 个百分点上下。
这两个 +40 的对照口径是同一批任务上的自进化。把其中一档总结的 Skill 直接搬给四个弱模型,提升落在 +35.4 到 +44.1 之间,可绝对值都低于让弱模型自己自进化,最差的那个只到 43.1%。同一份经验换个执行载体就掉一档,掉了这一档照样当成有效经验写进库,这是记忆污染最安静的一条路:不报错、不回滚,只是越用越不划算。
脏的是记忆,不是分数。一条错误经验写进去之后,在有人查到它之前,可能已经影响数百次后续任务,而错误蔓延的速度远快于修复速度。环境抖动的失败一旦当成「能力缺口」写进长期记忆,后面好几轮都会在这条错误上继续长。等到看清,能做的往往只有把记忆模块整个关掉退回无状态,积累下来的经验一起清零。
这一路能一路涨上去,根因是一致率门槛没卡住。评测信号无意中奖励了啰嗦:写得更长的答案更容易撞上正确内容,于是每一轮分数都在涨,每一轮的技术门控也都通过,方向却已经偏了。
等回头看已经偏了十几个版本,连该回滚到哪一版都定不下来。这条路等回头看才发现,已经偏出去十几个版本,连该回滚到哪一版都定不下来。门槛具体卡在一致率上。同一批样本上,两边结论完全一致才算一条,Judge 与人工的一致率到不了 85%,这个数以下的分数就定不了结论,只能退回半自动抽检。
出题、答题、裁判必须是三方#
对策的结构很清楚:闭环里至少要有一样东西是模型碰不到的,先动验证资产。一份固定版本的隐藏题集,平时读不到,只在验收的时候跑一次。这份题集的题谁也顺手优化不了,因为没有任何一条通道改得到它——这条听起来朴素,却是整套设计里唯一不可替代的一件。
数据三分是这个思路的标准形态,三个集合的分工和可见范围各不相同。具体怎么切,看下面这张表。
| 集合 | 谁能看 | 用它做什么 |
|---|---|---|
| 训练集 | 可以暴露给修复生成器 | 让它据此改自己 |
| 验证集 | 不暴露,只在调参时读 | 判断这次改动有没有用 |
| 测试集 | 完全独立 | 只在验收时跑一次 |
切的时候按问题类型分层,不能随机撒。随机撒的结果是三类题在三个集合里分布不一致,测出来的差别其实是分布差别。起步比例我按训练集六成、验证集两成、测试集两成来分,实际由样本量和风险定——高风险场景宁可把测试集比例往上抬。
角色分离同理:出题、执行、总结、判定,能分开就分开,判定这一环至少要跟被测对象不同源。自进化那条线上的角色划分我照做,并且额外要求总结者不参与出题。总结者一旦参与出题,经验就会朝它自己擅长的方向长。
自生成的题目还得守住一条:答案不能由模型自己给。凡是能构造出确定性答案的题,就用执行结果或者规则来判定;只有真正开放的题才让模型判,并且这批题要单独标记、单独监控它们的通过率变化。
外部刻度还要再补两样。先是版本化的外部基准,它不参与任何调参,只用来回答「这一版比上一版强在哪」。课程分布监控跟在后面,记录题集在知识点、难度、动作类型上的分布。分布莫名其妙变窄,就是课程坍缩的信号,这时候分数涨了也要停下来看。
冷启动这一环必须有人先推一程,它最容易被漏掉。没有这一圈,闭环连往哪个方向转都是它自己定的。题集的构造方式也得写死——比例、分层、题源每次现想,前后两次的分数就不可比。
让 Judge 看证据,别让它看答案#
裁判是最容易坏的一环,因为它是唯一有权给分的地方,坏了没人反对。它一坏,整套读数就跟着歪。
我的做法是把事实提取和语义裁决分开。凡是能用确定性断言判的——某个值有没有取到、某次调用有没有发生、结果等不等于预期——全部在进 Judge 之前判完。剩下「不同但可能合理」那一小撮才交给 Judge。我把它给分的范围压到最小,出错的面也跟着变小。
Judge 本身还要校准。我自己卡的经验门槛是:跟人工复核的一致率到 85% 左右,口径是同一批样本上两边判定结论完全一致才算一条,到这个数才允许它进日常自动化。每次 Judge 版本升级,就把与人工的一致率、高风险样本的漏判率、边界样本的重复波动这几样重测一遍。哪一样不对,就退回半自动。
评审规则只留在内部,这条同样容易被忘。把评分细则暴露给被测对象,等于教它怎么迎合裁判:我见过答案为迎合评分表变冗余——每一条都对得上标签,没一条真正解决问题。
金标校准集怎么建也有讲究。样本得覆盖边界和高风险两类,随机抽一百条达不到——抽出来的几乎全是简单样本,测不出 Judge 在哪里会错。校准集还要跟 Judge 版本一起归档,换版本就重跑,不然「一致率 85%」这句话会一直沿用下去,直到它早就不是真的。
Judge 和被测模型如果同源,风险还要再加一层:它会偏好自己的表达风格。解法是换一档模型当裁判重新跑一遍。分数明显回落,量到的是相似度;分数不回落,量到的才是质量。
把事实提取前置,在这条线上有现成的例子。一次调用失败,返回体里往往已经写清楚了是排队、限频还是参数错,只是系统没把它结构化提取出来。把这几类做成可读字段再交给判定环节,绝大部分样本在进 Judge 之前就已经有了确定答案,需要它发表意见的只剩真正开放的那几题。Judge 的判断面越小,它坏掉时能造成的损失也越小——这是这一环唯一的原则。
每一段都要有外部刻度#
把自进化拆开看:评测产出信号,记忆承接沉淀,落地把改动变成生效的东西,控制保证方向不偏。都通了,飞轮才转得起来。
| 环 | 做什么 | 这一环的外部刻度 |
|---|---|---|
| 评测 | 发现缺陷、判断更新是否更好 | 隐藏集与人工抽检 |
| 记忆 | 决定什么值得沉淀 | 写入门槛与预算上限 |
| 落地 | 从候选改动到生效 | 独立评测与发布门禁 |
| 控制 | 保证长期方向不偏 | 方向性指标与周期审计 |
自进化要区分两种信号:能力信号看同类题在隐藏集上有没有做得更好,知识信号看原本不知道的事实后来有没有派上用场。两种信号的验证方式不同,把能力信号和知识信号混在总分里看,就分不清这次进化是长了本事还是长了笔记。
闭环会放大评测的误差,不会把它平均掉。评测这一环的价值不止是打分,它还决定哪些经验值得沉淀。弱 Judge、过时的题集、不公平的预算,会把错误写进记忆和 Skill,形成错误加速。
落地这一环是工程量最大的一环,本质上是给 Prompt、Skill、记忆做一套持续交付。诊断、汇聚信号、生成候选改动、独立评测、安全门控、灰度、回流、沉淀,这一整圈走完才算一次进化。跳过其中任何一步,省下的是今天的工时,付出的是下个月的返工。
控制这一环最容易被当成「出事再说」,它的作用其实相反:分级自主、不可逆红线、人工节点、方向性审计、自动降级,这几样决定了评测、记忆、落地三段闯祸时的上限。回归全绿不等于方向没偏,这是这一环存在的全部理由。
进化出来的东西分三层,成本和风险差得很远:产物层是单次任务的输出,任务结束即失效;装配层包含记忆、Skill、Prompt、工具与工作流,可回滚,是主战场。模型层改的是权重,成本最高、风险最大。绝大多数自进化该发生在装配层,它便宜、可回滚、可审计。动模型层之前,先问装配层是不是已经做到头了。
经验进记忆要过两道门#
评测侧的防线之外,更持久的污染来自记忆。闭环里最贵的后果是它把错误经验固化下来反复用,一次打分不准还排不到它前面。所以一条经验要进长期记忆,得先过两道门。
诊断门先回答:这次失败是真能力缺口,还是题目本身坏了,还是环境抖了一下。后两类——题目坏了和环境抖——不该产生任何经验,它们只会把记忆搞脏。过了诊断门才是验证门:先在隔离样本上确认有效,再确认它在真实任务里没有引发新的破坏。没有这两道门,系统会把错误的归因固化成长期记忆,越用越差。
写入门槛得先定:只有正信号和明确的反例才值得沉淀,含糊的中间态不写。中间态写进去,记忆里就会堆满「大概是这样」的条目,而这类条目在后续检索里会和真正的规则抢注意力。
时间这一维也得单独守。经验按「在前序任务里学到、在后序相关任务里验证」的逻辑积累,切分必须严格按时间走。否则未来信息会漏进今天的评测,制造出一种预测能力很强的假象——这类假象在回测里特别好看,上线当天就消失。
能力回归得跟代码回归一视同仁。每次改动能力或提示词,都要带上它自己的用例、负例和相邻能力的边界用例一起跑。只跑它自己的用例,会漏掉「这次改动把旁边那个能力带坏了」,而这类退化在平均分上几乎看不出来。
把运气和方向分开读#
同一个 Agent 跑同一道题,两次结果可以不一样。这种方差如果不当回事,很容易把一次运气好当成优化有效。
我自己做过一轮重复实验:8 道长题,同一版本每道连跑 5 次,合计 40 次完整执行,单次约 20 分钟,机时约 13 小时(40 × 20 分钟 = 800 分钟)。波动全部集中在 3 道需要跨文件比对的题上,区间分别是 60%–100%、40%–80%、20%–100%,全批极差 80 个百分点;其余 5 道基本不动。
判据因此要分两层。稳定那 5 道自身就有 0 到 20 个百分点的摆幅,噪声会盖住比这更小的提升,这种提升算不上结论;波动那 3 道要先跑够次数才敢比。重复次数得按跑数定:跑满 40 次之后,这 8 道题的通过率才敢拿去跟下一轮比。只跑一遍的数字,涨了也是噪声。
配套的判据是 champion-challenger。它要求新版本按单条用例粒度看清赢在哪、输在哪。在平均分上赢一点点不算赢,还得设一条下限——涨不到 20 个点不算数,这 20 个点就来自稳定那 5 道题自身的摆幅。它也不能在相邻能力的边界用例上退化——不少改动就退在这里,平均分看不出来。
读记忆的顺序同样要设限。我按高层背景、关键词检索、按需回溯原文这三层走,越往下越贵也越少走到。没有这个顺序,记忆层会退化成「每次都全文塞进上下文」,那跟没有记忆治理是等价的。版本同样容易漏:模型版本、Prompt 版本、记忆版本都要跟分数一起落盘,否则两个月后回看那条突然变好的曲线,没人说得清是哪一次改动带来的。
除了通过率,我还一直盯一组方向性指标:输出长度的分布、工具调用轮次的分布、拒答率的变化趋势。任何一项发生系统性漂移都值得去看一眼,哪怕当时分数很好看。这组指标的成本极低,它只需要把已有的日志做一次分布统计。
归因要能落到具体环节。我按现象层看到的是什么、过程层哪一步开始偏离、责任层该改哪个模块来记。Trace 证据汇总之后先缩圈再定责。省掉过程层,归因会退化成「大概是 Prompt 的问题」,而这类结论没法变成行动。
周期人工审计也是这一环的一部分。自动化盯住的是你事先想到的那几项,人看的是「有没有出现我没想到的东西」。频率不必高,但要有固定节奏,并且每次都要留下结论,写进审计记录。
评估器本身也得评一遍。我维护一份元评测集,专门盯「机器判的和人判的差多少」,不一致率一旦抬头,就得停下来校准评估器,别继续信它输出的分数。评估器失准却无人知道,是闭环里最难被发现的一类失效——因为所有报表看起来都正常。
再往外是两道硬约束,它们保住「随时能停下来」的主动权:自动产生的变更进入发布流程前过人工门禁,高风险能力退化触发自动回滚。冷启动、价值判断、领域取舍、合规与安全红线这几件事得由人定,Agent 自己定不了。
自进化闭环值得跑,它的复利是真的。但在跑之前要先回答一个问题:这条闭环里,有没有一样东西是模型碰不到的?
没有的话,闭环只是把偏见一圈圈放大,分数会涨得很漂亮,走得也越来越远。有了——一份它读不到的题集、一个不同源的裁判、一道能回滚的门——这条闭环才立得住:每一圈都由外部刻度校准,涨上来的分数才敢当成能力去兑现。闭环跑起来之后,判断哪一层还是空的同样需要一个基准,八层验收总表补的就是这一块。