Skip to content
文章目录
GitHub Star

Agent 测评的身份难题:一次任务换了模型,历史成绩还能算数吗? ​

假设一轮研究原定使用模型 A。它完成入口判断后,主研究请求遭遇可切换的供应商失败;系统重新核验请求,换由模型 B 继续,最终留下了回答。运行状态可能是完成的,但这份回答到底应该计入谁的成绩?

最直觉的修复是:别记配置里的模型 A,改记实际模型 B。这句话没有错,却只解决了最后一次请求的名字。实际 Agent 可能同时出现入口判断、Main 研究、Child 调查、请求失败后的备用路线,以及进程重启后的继续执行。一个 Run 不一定对应一个模型,甚至不一定对应一份完整可观察的请求清单。

更困难的问题发生在第二天:昨天那份结果,今天能不能免跑一次、继续当作可比的评测? 如果回答这个问题只依赖模型名或 Git SHA,看似节约成本,实际上可能把不同的实验当成同一次实验。

本文依据 ETF Agent 对真实 SDK 接缝、隔离 PostgreSQL 和本地评测入口的受控验证,解释这条判断链。下文的 A/B 是教学化称谓;验证使用合成响应和受控故障,不是一次已经发生的生产误归因事故,也不证明 A 或 B 的语义质量。

一、先分清:评测单元、请求和 Run 不是同一个身份 ​

一次评测先固定题目、被测配置、评审方法及选出的案例单元;一次运行再根据该配置执行多个具体模型请求。不同身份要回答不同问题。

身份回答的问题不该承担什么
计划身份打算用哪个模型、哪些案例和评测条件?不能证明物理请求确实发给了它
实际请求身份哪个 Provider、模型和协议真正被派发?请求结果是完成、失败还是未知?一次请求不能代表整次 Run
生效行为身份最终请求受哪些可信指令、工具契约和推理/生成配置控制?不能用一次 Prompt 的字节哈希代替所有授权和语义判断
评测单元身份哪个案例、轮次、配置、评审规则与执行证据形成这份结果?不能因为 Run 完成,就自动获得历史结果复用资格

还有一个容易混淆的标识:请求的 attempt ID 用于把诊断和原请求关联起来,并不是跨两轮实验比较“行为是否相同”的稳定键。一次重试有新的请求身份,但也可能沿用相同的被批准配置;反过来,即使业务 Run ID 不变,真正发送的模型或参数也可能改变。

因此,合适的思路不是再造一个“万能身份表”,而是让原请求负责人提供实际派发事实,原指令/工具负责人提供生效控制事实,评测负责人组合这些事实后决定可比性。各方仍保留原来的授权与结果归属。

二、为什么知道备用模型 B,还不足以修正评测? ​

仍用开头的研究任务,假设发生以下受控请求序列:

请求角色计划/实际已知结果
入口请求EntryA/A已完成
第一次主研究MainA/A供应商失败
第二次主研究MainA/BB 完成请求
调查请求Child可独立选择只观察到部分诊断

如果评测适配器把上述记录压缩为一个“本次模型=A”的标签,就会把 B 的结果错归给 A;如果改成“本次模型=B”,又抹掉入口和第一次 Main 请求。更糟的是,Child 的请求可能被混入 Main 的比较,改变模型调用次数、成本和实验条件。

修复涉及的不只是显示名称。原诊断需要保留已知请求的角色(Main 或 Child)、用途(Entry 或执行)、实际 Provider/Model/Protocol 和请求结局;本地评测再分别保存 Main、Entry、Child 的可识别观察。属于哪次请求,必须沿原请求标识关联,不能靠结果字符串反推。

还有一个不直观的细节:诊断的总体覆盖可能是不完整的。例如有个模型事件缺少有效身份,整条时间线不能被认证为完全覆盖;但其中两条已经验证的 Main 请求仍然可以提供可靠的反例。已知 B 与计划 A 不符,就足以拒绝把结果归为 A。反过来,只看到一条与 A 相同的请求,不能证明没有遗漏的 B 请求。

这体现了一条不对称原则:一条可信矛盾可以否定可比性;少量一致观察不能证明完整相等。 代码在读取诊断时既保留合格的单条请求事实,也保留覆盖未知,避免两种误判。

三、比对的是生效行为,不是请求时的配置表 ​

即使实际调用都显示为模型 A,结果也未必属于同一个实验。模型看到的可信系统指令、参与的 Skill、按顺序暴露的逻辑工具、推理强度、输出限制、协议及其他行为控制参数,都可能改变结果。

需要把两类变化分开:

  • 行为控制输入:可信指令、真正参与的工具契约、有效推理/生成参数等。它们决定某个配置下模型被怎样驱动。
  • 任务和动态材料:用户问题、检索返回、历史消息、经授权的上下文压缩。这些当然影响回答,但不能简单把每个动态字节变化当作“系统行为配置版本升级”;案例与资料本身由评测计划另行固定。

这也是为什么只计算完整 Prompt 的哈希并不合适:既会把本来不同但合法的用户输入混入配置身份,也无法保证哈希来自最终真正派发的那次请求。原实现从指令生产、Tool Surface 准入、上下文拟合,到 Gateway 编码之间有多个变化时点。评测需要在正确接缝拿到生效事实,而不是从启动参数或事后编辑的报告猜测。

本次工程验证还检查了脏工作区下的代码来源。仅仅 HEAD 相同不能证明执行代码相同:已经跟踪但未提交的源文件可能变化。于是本地验证会在适当范围观察运行源码的摘要,并区分“前后已知不同”“能够观察到相同”和“这部分根本没观察到”。摘要相等只说明受限源范围相符,不是依赖、实际请求和模型版本全都一致。

四、结果不能只有 pass/fail:还有「不可比」与「带假设复用」 ​

把身份放到评测层以后,核心判断至少分三种:

已知条件对历史结果的处理
相关实际身份和必要比较条件均满足原评测资格可以按照原评价规则考虑复用,并保留原始结果
已知 Main 线路、配置、源码、计划或案例出现矛盾不复用这项历史归因,标明不一致
缺少必要的请求观察或不可变版本信息保留未知,除非存在明确获准的有限近似政策

这里“未知”和“不同”不能互换:观察缺失不是没有执行,已知不一致也不能因为其他字段未知就被忽略。

工程上还有一个实用但不那么纯粹的选择。本地评测恢复并非总能获得 Provider 的不可变模型版本,也未必能重新证明每一份实际请求输入。因此在一项明确限定于本地评测恢复的政策下,可以考虑复用原执行开始后 48 小时内的历史单元,条件是原计划、注册表、配置、路线和当前可观察的代码来源等检查没有发现已知差异,并且保留原审核记录。

这不是“48 小时内一定相同”。返回结果要显式记录行为输入兼容性属于 assumed-not-verified,状态可以是 passed_with_warnings;它没有重新进行模型质量测试,也没有给其他评测消费者颁发精确复用资格。原执行时间不能被恢复时间刷新;时间缺失、过期或位于未来时不能使用这项近似。

相反,一旦观察到原 Main 实际走了与计划不同的路线、Entry 输出限制变化、源码在评测期间变化,或适配器计划/配置摘要冲突,就要保留 unverified,而不是用近似政策覆盖。已知差异应当在启动下一个需要付费的评测检查点之前发现,而不是先发请求,最后再说旧成绩不可比。

五、如何在代码里定位这种问题? ​

排查时最容易走偏的地方,是把所有错误都归咎于模型选择器。事实上,这条证据链有多处不同的观察接缝:

  1. 请求前:配置和可信控制输入怎样最终进入一次合法模型请求?中间是否还有合法但改变行为的拟合?
  2. 派发时:原模型有没有真正发送?备用 Provider 是否重新准入?每次尝试实际使用什么协议和模型?
  3. 诊断投影时:Main、Entry、Child 标签和失败状态有没有在转换成评测单元时丢失?部分诊断会不会误删仍然有效的单条证据?
  4. 历史读取时:跨进程之后,持久记录保留的是原请求身份,还是由当前默认配置重新填的标签?
  5. 复用决策前:已知配置和源码漂移是否在下一批请求派发前被发现?历史时间窗口是否来自原运行?

这些都能通过确定性测试发现,而不需要让 LLM Judge 猜测。受控验证沿实际配置的 SDK 适配器注入合成 Provider 失败,检查失败的 A 与成功的 B 在原诊断、原请求记录和本地 Evaluation 中仍能分别定位;其他测试覆盖 Child 冷唤醒、跨进程回读与复用前的漂移阻断。测试能说明身份传递及拒绝条件在受控路径生效,不能用来宣称模型质量、公平性或所有生产请求都已被完整记录。

六、什么时候值得实现这套机制? ​

如果产品只有单次模型调用、不做历史复用,也没有实验比较,把“预期模型”和“实际响应”记清楚可能已经足够。进一步维护多个身份、受限摘要和不确定状态,会增加状态解释、报告阅读与测试成本。

当系统开始支持故障切换、多角色 Agent、冷恢复和长期评测时,问题才升级为:能否证明今天的结果和昨天在相同、可复核的条件下形成? 若证明不了,工程系统应该有勇气留下“不知道”,或把获准采用的近似写在结果旁边。低成本复用与精确可比性之间存在取舍,不能通过改一个字段名抹平。

本文讨论的是评测事实如何归属。关于任务为什么允许切换模型,见模型故障切换;关于题库、Judge、金融正确性和发布判断的整体分工,见Agent 测评全景。

与个人博客并行:这里按问题连续阅读,博客保留时间线。 · 联系邮箱:hpoenixf@foxmail.com · 微信:hpoenixf0510