ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

LLM Agent评测中Harness的影响:为何需要披露评测框架

LLM Agent评测中Harness的影响:为何需要披露评测框架 如果你最近在关注 LLM Agent 的评测榜单可能会产生一个很直接的观感同一个模型有的团队测出来“表现很强”换一个团队测出来“也就那样”。一开始大家习惯把差距归因于提示词写得不够好但后来陆续有工程经验表明问题往往出在评测链路本身。最近一篇论文把这个话题放到了明面上标题非常直接《Stop Comparing LLM Agents Without Disclosing the Harness》。它的核心观点是在长程智能体评测中“评测框架/驱动层”Harness对结果的影响可能比模型本身更大。这篇论文提醒我们一个容易忽略的事实大家在榜单上比较的并不是“模型能力”本身而是一整套由数据、工具、流程和评价规则组成的系统。本文会从工程视角拆解为什么 Harness 会影响评测结论同一个模型在不同 Harness 下为什么会出现结果差异以及我们在设计自己的评测平台时可以从论文的批评中借鉴哪些规范。1. 榜单上的“模型能力”往往是一个系统能力1.1 智能体评测到底在测什么大语言模型 Agent 与传统问答模型最大的区别在于它需要与环境交互。一次任务通常不是“输入一段文字、输出一段文字”就结束而是包含多轮推理、工具调用、中间结果读取、错误修正、最终答案生成等步骤。也就是说模型的行为不仅取决于权重还取决于它“看见什么消息”“能用什么工具”“失败后能否重试”。我们可以把评测结果写成这个粗粒度公式评测成绩 ≈ 模型能力 × Harness 能力 × 任务环境匹配度在单轮问答中模型能力占主导但在长程智能体任务中Harness 的工程实现会把模型能力放大或抑制。这也是论文主张“不要在不披露 Harness 的情况下比较 Agent”的根本原因。1.2 隐藏变量远不止“提示词”很多人以为 Harness 只是提示词模板其实它覆盖了从任务下发到结果打分的全过程。我整理过自己在评测中踩过的隐藏变量至少包括以下这些任务描述是直接发给模型还是被拆成了 system/user/assistant 多段历史消息模型输出是自由文本还是强制走 JSON 或 Function Calling 结构工具调用结果是否回填到对话历史以什么格式回填智能体在中间步骤失败后是否允许重试重试次数是多少是否给模型设置了最大步数、超时时间、最大 Token 限制环境状态是否被错误复用到其他评测任务打分模型是哪个版本打分提示词是否稳定数据集的文件读取顺序和并发线程数是否变化。上面任意一点变化都可能导致一个任务从“能完成”变成“不能完成”。论文批评的正是这种比较如果评测双方使用的 Harness 不同最后得出的能力排名更多反映的是评测系统差异而不是模型真实差异。1.3 长程任务尤其容易受 Harness 影响长程智能体任务通常包含数十步甚至数百步动作步骤越多中间出错的位置就越多。Harness 在每一步里都扮演“裁判员和后勤人员”的双重角色一方面它决定模型能否获得必要的动作空间另一方面它也决定错误发生后任务是否可以恢复。举个具体例子一个网页自动化任务需要完成登录、搜索、对比、下单四个动作。如果 Harness 不允许模型在元素定位失败后重新读取页面模型很可能卡在登录步骤但同样的模型在另一个允许读取页面快照并重试的 Harness 中或许能顺利完成整单。论文提到 Harness 的影响可能超过模型本身在长程任务中并不夸张因为每一步的失败概率都会累加最终的差距会非常明显。2. 什么是智能体评测中的 Harness2.1 从“比赛调校”理解 Harness“Harness”这个词来自英文原意“马具”后来被引申成测试工具中的“测试夹具/驱动框架”。放在 LLM Agent 场景里我比较喜欢用一个类比比赛评价一辆车时不能只看发动机纸面马力还要看变速箱、悬挂、轮胎、赛道条件和车手策略。发动机是模型Harness 则是那套让发动机在赛道上真正跑出成绩的工程系统。Harness 至少承担三件事第一把任务描述转换为模型可以处理的对话或动作指令第二在模型产生动作后负责调用工具、读取环境状态并把结果回传第三在多个回合之后把模型的执行过程转换成可打分的结果。简单说它连接了模型和任务环境并定义了智能体如何思考、行动、观察和终止。2.2 Harness 中常见的模块一个工程完整的智能体评测 Harness通常会包含这些模块任务加载器读取评测集并将原始任务实例化到目标环境里对话管理维护多轮 messages 列表保证模型看到的上下文状态正确动作解析器从模型自由文本中抽出 action或直接消费 Function Calling 参数工具执行器实际去调用搜索、数据库、网页、代码执行等工具反馈回填器把工具返回结果拼装成模型能理解的消息状态检查器判断任务是否已经完成、是否达到最大步数结果记录器存储每个步骤的输入输出便于后续复现指标计算器按任务规则计算最终分数或者调用评估模型打分。如果你在调一个 Agent却只关注模型权重版本而忽略这些模块的实现那么测评结果很容易失真。因为修改任何一个模块都会直接决定模型能不能拿到有效信息。2.3 Harness 与 Agent 框架的关系有人会问LangChain、LlamaIndex 这类框架算不算 Harness更准确地说Agent 框架是构建 Agent 的“开发库”Harness 是把某个确定版本的 Agent 放进评测流程中的“运行驱动层”。你可以用 LangChain 写模型调用逻辑但评测时还需要把 prompt、工具注册表、对话组装方式固定下来这就是 Harness 的职责。最近社区里越来越多人谈到“Harness Engineering”也会出现类似“DeepSeek Harness”“Codex Harness”的说法。这些词并不是在说模型本身而是在说围绕某个模型调优出的整套执行与评测环境。它们能成为热词本身说明一个趋势Agent 能力的比较不再只是“模型参数和推理能力”的比较还包括整个工程系统的设计质量。3. 论文的核心命题与实验思路3.1 “请停止比较”到底在反对什么论文《Stop Comparing LLM Agents Without Disclosing the Harness》的核心主张是如果研究论文、技术报告或产品发布只想把分数列出来并宣称自己比某个竞品好却没有披露评测用的 Harness这种比较缺少科学价值。这里的“没有披露”包含两层问题。第一层是好坏问题Harness 本身存在大量自由度不同实现会显著改变结果所以不披露就无法让读者判断分数是否可靠。第二层是复现问题即使其他团队想复现实验没有 Harness 的细节也无从知道任务是怎么跑出来的。论文并不是全盘否定比较而是要求比较必须建立在可审计的评测环境上。3.2 实验设计上的启示模型因素与 Harness 因素分开看虽然我无法在这篇文章里完整复述论文里的每张实验表格但它提出的实验设计思路是值得借鉴的在团队内部做模型选型时尤其有用。第一种做法是“固定 Harness只换模型”。这种方式能比较出在相同条件约束下模型本身的相对优势。第二种做法是“固定模型只换 Harness”。这种做法更容易暴露出 Harness 是放大器还是限制器。假如同一个模型在 A Harness 下只能完成 30% 的任务在 B Harness 下能完成 70%而另一个模型在同样两组 Harness 下的表现却是反过来的那就说明我们看到的结果很可能是“模型 × Harness”的交互效应而不是单纯的模型能力差异。论文标题用“不要比较”其实是一种提醒当 Harness 属于系统的一部分时我们得在报告里把“模型贡献”和“Harness 贡献”分开处理。否则一个调得更好的 Prompt 模板或结果解析器很容易被误报成模型能力的大幅提升。3.3 “披露 Harness”的实际含义“披露 Harness”不一定是要求把所有代码都公开更合理的理解是至少要公开一组可审计的评测配置。比如用哪个模型版本、哪个客户端的采样参数、构造了什么消息模板、工具如何执行、任务结束后如何判定成败、由哪个模型打分等。这些信息的作用是让读者能判断评测是否公正也让后续研究者可以在同一套条件下继续比较。用工程术语来说这是给评测过程加上“版本管理”。你可以有自己的私有评测环境但对外给出结论时必须说明你的环境配置是什么。论文把“披露 Harness”当成比较 Agent 的必要前提本质上是在推动评测透明化。那些只讲分数、不提供实验配置的对比在科学严谨性上是不够的。4. 用一个小 Demo 观测 Harness 的影响为了把原理讲得更具体我设计了一个最小可运行示例。它的思路是固定同一个“模型后端”分别用两种不同 Harness 跑同一任务观察评测结果差异。示例采用模拟后端不需要 API Key可以直接运行。4.1 示例场景与文件结构假设业务里有一个订单结算智能体任务是某个订单包含 100 件电子产品单价 399 元请计算订单的总税额。这里的关键前提是税率不能由模型凭记忆猜测必须通过工具 lookup_tax_rate 查询业务系统系统返回税率为 0.12。我先创建下面文件结构agent-harness-demo/ ├── run_demo.py └── README.md可选所有代码都写在 run_demo.py 中完全可复制运行。运行环境方面只要 Python 3.9 以上都可以不需要安装第三方依赖。4.2 先搭建一个可替换的模型后端真实项目中我们会调用 OpenAI 兼容接口或各家模型 SDK。我这里先用一个 MockBackend 模拟模型它模拟的是“模型不知道业务系统里的真实税率需要使用工具后才能正确计算”的合理行为。真实使用时可以把 chat 方法内部替换成模型客户端。# 文件路径agent-harness-demo/run_demo.py import re TOOLS { lookup_tax_rate: { description: 查询商品分类对应的税率输入电子产品等品类名称, run: lambda category: 0.12 if category.strip() 电子产品 else 0.06 } } class MockBackend: 演示用模型后端。 真实项目可把 chat() 内部替换成 OpenAI 兼容 API response client.chat.completions.create( modelyour-agent-model, messagesmessages, temperature0.2, ) def chat(self, messages): last messages[-1][content] if 【工具结果】lookup_tax_rate - 0.12 in last: return 最终答案总税额 100 * 399 * 0.12 4788.00 元。 if 请直接给出最终答案 in last: return 无法直接给出可靠答案因为我不清楚该业务系统内的真实税率需要先查询税率。 return 调用工具查询税率lookup_tax_rate(电子产品)这个模型后端的策略是没有工具结果时它不愿意编造税率拿到工具结果后它能完成乘法并给出最终答案。业务系统税率为 0.12 只是一个演示设定不代表现实中的法定税率。4.3 实现两种 Harness 并对比下面这段代码分别实现了 FlatHarness 和 StepHarness。FlatHarness 只是把工具描述写进提示词希望模型一步到位直接回答但不会真正执行工具。StepHarness 则会解析模型输出中的工具调用执行工具并把结果回填给模型形成多一步的反馈闭环。# 文件路径agent-harness-demo/run_demo.py继续追加 def flat_harness(model, question): FlatHarness不提供真正的工具执行能力 只把工具描述写进提示词要求模型直接回答。 tool_doc 可用工具lookup_tax_rate(category)查询品类税率。 messages [ {role: system, content: 你是订单结算助手。}, {role: user, content: f{question}\n{tool_doc}\n请直接给出最终答案不要假设税率。}, ] response model.chat(messages) success False m re.search(r总税额 [\d.] \* [\d.] \* [\d.] ([\d.]) 元, response) if m: success True return { response: response, success: success, score: 1.0 if success else 0.0, } def step_harness(model, question): StepHarness支持工具调用。解析模型行动 - 执行工具 - 回填结果 让模型拿到真实税率后再计算。 tool_doc 可用工具lookup_tax_rate(category)查询品类税率。 messages [ {role: system, content: 你是订单结算助手必须通过工具获取税率后计算。}, {role: user, content: f{question}\n{tool_doc}}, ] max_steps 3 for _ in range(max_steps): response model.chat(messages) messages.append({role: assistant, content: response}) action re.search(rlookup_tax_rate\(([^)])\), response) if not action: if 最终答案 in response: m re.search(r总税额 [\d.] \* [\d.] \* [\d.] ([\d.]) 元, response) return { response: response, success: bool(m), score: 1.0 if m else 0.0, } return { response: response, success: False, score: 0.0, } tool_input action.group(1).strip( \) result TOOLS[lookup_tax_rate][run](tool_input) messages.append({ role: user, content: f【工具结果】lookup_tax_rate - {result}, }) return { response: messages[-1][content], success: False, score: 0.0, }在 StepHarness 中循环次数被限制为 3 次。实际长程评测系统里这个 max_steps 通常允许模型调用几十次工具但实现思路是一致的解析动作、执行动作、回填观察、进入下一轮决策。4.4 运行主函数查看结果# 文件路径agent-harness-demo/run_demo.py继续追加 def main(): question 某订单包含 100 件电子产品单价 399 元请计算该订单的总税额。 model MockBackend() flat_result flat_harness(model, question) step_result step_harness(model, question) print(FlatHarness 结果, flat_result) print(StepHarness 结果, step_result) if __name__ __main__: main()在终端里执行cd agent-harness-demo python run_demo.py预期输出大致是FlatHarness 结果 {response: 无法直接给出可靠答案因为我不清楚该业务系统内的真实税率需要先查询税率。, success: False, score: 0.0} StepHarness 结果 {response: 最终答案总税额 100 * 399 * 0.12 4788.00 元。, success: True, score: 1.0}注意这里的 MockBackend 行为是刻意设计的所以运行结果非常干净。真实模型的行为不会这样二元化但它足以帮助我们理解同一个模型在两种 Harness 下的“有效表现”差异FlatHarness 根本不给模型拿到真实税率的机会StepHarness 则把环境中的关键信息交给了模型。4.5 从一步工具调用看长程评测这个 Demo 只用了一个工具调用步骤严格来说并不能算“长程任务”。但它的价值在于展示 Harness 影响模型的机制模型的能力需要借助 Harness 提供的信息通道才能发挥。长程任务会把这种机制放大许多倍模型每走一步都要依赖 Harness 正确处理状态、动作和反馈任何一环做得不好后续步骤就会连锁失败。我在实际评测项目里经常看到类似现象两个团队评测同一个开源模型A 团队的 Harness 支持完整的工具结果回填和失败重试B 团队的 Harness 却只是简单解析模型文本。最后 A 团队报告的成功率远高于 B 团队但这不一定说明 A 团队调模型调得更好只能说 A 团队把“评测环境”建得更完整。论文批评的正是这种不能被当作模型能力差异的系统差异。5. 落地评测平台时如何减少 Harness 带来的干扰5.1 锁定 Harness 版本像锁代码一样锁评测配置生产项目里的依赖会升级评测代码也一样会改动。为了得到可互相比较的结论任何一次 agent 评测都应该使用确定的 Harness 版本。可以在评测入口处用一个 JSON/YAML 配置记录模型名、提示词版本、工具注册表版本、最大步数、温度等这样每次评测报告都能追溯到具体环境。# 文件路径demo-eval-config.yaml eval_meta: project: order-agent-eval model_name: your-model-name model_version: commit-hash harness_version: v1.2.0 prompt_version: v3 task_set: long_horizon_seed_001 max_steps: 30 run_count: 5 temperature: 0.2 judge_model: your-judge-model-name judge_prompt_version: v1这份配置的价值不在格式而在“版本化”。当评测结果发生变化时先查看是模型版本变了还是 Harness 版本变了能省去大量排查时间。5.2 让每一次任务记录都可完整回放评测平台不能只保存最终分数最好把每一步的完整日志都保存下来。比如模型发了什么动作、工具返回了什么结果、Harness 是否重试过、任务在哪一步失败。这样一旦分数异常就能回到具体步骤观察是模型判断错误还是 Harness 解析错误。记录日志时我会按一次评测任务一个目录来存内容包括原始任务文本、完整 messages 序列、工具执行时间、错误堆栈、打分结果等。虽然存储成本会比单轮问答高不少但对于定位长程智能体问题来说这一步是必要的。5.3 先做 Harness 自检再测模型评测前可以准备一批“确定性任务”任务的标准答案和流程步骤都是人工定义好的甚至不需要真实模型参与用一个规则脚本就能跑通。先用这批任务验证 Harness 本身是否正确再让模型进场。如果规则脚本都跑不通那就说明问题出在 Harness测试大模型只会得到无效分数。我在团队里通常把 Harness 自检拆成三块工具调用是否能正确执行、工具结果是否能正确回填、结果抽取和打分规则是否稳定。这三块都通过后模型的评测结果才具备解读价值。5.4 控制并行、随机性和采样参数长程智能体评测存在明显的不确定性。温度太高会让同一个任务跑两次结果不一致并行过度可能让环境状态互相污染评测集顺序变化也可能影响带缓存或有状态的环境。尽量固定随机种子、降低温度、串联运行有状态任务或者至少多次运行并报告均值和失败样例。论文强调 Harness 对评测影响重大也包含这层意思当我们没有控制好随机性时模型之间的微小差异会被随机噪声淹没而 Harness 中的细节则可能变成“稳定的噪声源”。想让结论可信就得把可能影响结果的条件尽量固定下来。6. 常见问题与误区6.1 常见误区表格下面整理几个我在评测中经常遇到的问题可供快速对照。问题现象常见原因解决思路同一模型两个团队评测结果差异很大两边的 Harness 在工具调用和提示词构造上不一致统一评测框架对比时必须披露 Harness 配置加了 Function Calling 后分数大幅提升模型原本无法获得结构化工具参数区分“模型能力变化”和“Harness 能力变化”长任务做到一半就超时或崩掉最大步数、超时时间设置不合理调整 Harness 参数并记录在评测报告中重跑评测时结果不稳定温度、并行度、环境状态控制不足固定随机种子多次运行并取置信区间打分模型认为正确但人工认为错误判分规则未覆盖步骤过程使用过程型指标不只依赖最终答案6.2 不要简单迷信“Agent 榜单”看到任何 Agent 排行时先不要急着得出“模型 A 比模型 B 强”的结论。可以问几个问题榜单的评测任务是什么类型每个任务的执行环境是否一致工具调用失败是否有重试最终结果由谁判定如果这些信息不完整那么榜单更适合作为参考而不是直接指导选型。论文标题里用了“Stop Comparing”并不是要求我们完全不做对比而是希望对比前先解决评测环境的可比性。这也是工程师视角下最理性的做法把模型能力从系统能力中剥离出来能剥多少算多少。7. 建设可复现评测体系的最佳实践7.1 评测报告至少披露这些字段如果要在内部报告或对外技术文章中给出 Agent 评测结论建议至少记录以下字段模型名称与版本基础提示词模板及版本Harness/Agent 框架版本工具函数列表与实现版本最大步数、超时、重试策略评测数据集版本与筛选规则评分方式规则匹配还是 Judge 模型运行次数与随机种子失败任务的日志链接。披露这些内容并不难却能让读者快速判断你的评测结论在什么范围内成立。论文标题中的 Disclosing the Harness落到日常工作中就是这张清单。7.2 将评测代码纳入版本管理和 CI现实中很容易出现“为了修一个临时 Bug 改了评测脚本结果整个历史分数不可比”的尴尬。评测代码应纳入 Git 仓库任何改动都走合并请求并在改动后重新跑基线任务。可以用一组回归任务充当评测系统的“单元测试”每次 Harness 变更都检查是否有异常分数波动。当评测环境像业务代码一样被认真管理模型升级或 Harness 升级带来的影响才可能被识别出来。否则所谓能力提升只是环境漂移的幻影。7.3 区分模型的失败与 Harness 的失败长程智能体任务失败时先做归因。如果模型输出了错误动作但动作本身可以被 Harness 正确执行这是模型问题如果模型输出了正确动作但 Harness 没有调用到工具或没有把结果正确回传这是 Harness 问题。把这两类失败分别计数比只看一个总体成功率有价值得多。一个实用的归因方式是记录失败点的快照失败时模型看到了什么消息、上一个动作是什么、工具返回了什么。如果错误始终集中在某个工具解析环节就去修 Harness如果错误集中在模型对工具结果理解不足再去换更大的模型或改 Prompt。8. 结语与后续关注方向这篇来自“Stop Comparing LLM Agents Without Disclosing the Harness”的核心批评本质上是把智能体评测从“比模型”拉回到“比系统”的层面。对开发者而言它带来的启发非常实际模型很重要但不能脱离评测环境谈模型。后续关注方向可以有两条一是 Harness Engineering 是否会进一步标准化形成类似“评测驱动层协议”的东西二是评测平台如何更好地把过程日志、动作空间、反馈机制纳入可审计范围让不同团队之间能够做更有意义的对比。对普通项目团队来说与其着急追逐新模型不如先把评测环境版本化、透明化让每一次“模型变强了”都建立在可信证据上。下一次团队准备升级模型之前可以先问一句我们上次评测用的 Harness 还完整保留着吗提示词、工具、判分脚本的版本都锁定了吗如果这两个问题都回答不了那结果里看起来几个点的提升很可能只是噪声。
返回列表