
如果你也在跑智能体评测或者正在写“哪个模型更强”的对比报告我建议先停下看看评测里那层看不见的“脚手架”。最近有一篇论文标题非常直接《Stop Comparing LLM Agents Without Disclosing the Harness》。它提醒我们当我们需要回答“哪个 LLM Agent 更好”时许多人比较的是模型真正决定结果的往往是模型外面那层 harness。尤其是在长程智能体评测里harness 的工程差异对最终跑分的影响可能超过模型本身的差异。这个判断不是否认模型的重要性而是在提醒两件事第一单次评测结果很难直接归因给模型第二不披露 harness 的 Agent 对比结论基本不可复现。下面我会拆开讲清楚 harness 是什么、为什么长程评测里它影响这么大、做 Agent 对比时要披露哪些配置、以及怎么设计一套不容易误导自己也不容易误导别人的实验。1. 为什么这个话题值得单独写一篇很多人对“模型评测”的理解还停留在静态题库阶段给模型一批问题算正确率得到排行榜。这种评测里哪怕是不同厂商的 API只要输入相同结果差异主要来自模型推理能力、知识覆盖和指令遵循质量比较容易归因。但 LLM Agent 不是这么工作的。Agent 要在多步交互里调用工具、观察结果、修正计划、记忆关键信息直到完成一个长程目标。于是问题出现了同一个模型在 A 作者的代码里表现很差在 B 作者的代码里可能表现很好。论文作者把它归功于模型B 作者在博客里也把它归功于模型但真正拉开差距的是各自写的那套 Agent 循环、工具描述、上下文裁剪策略和终止条件。这套东西就是论文标题里的 harness。harness 在英文软件开发里本来就有“测试脚手架”的意思。LLM Agent 领域沿用这个概念指的不是模型权重而是模型外面那层完整系统怎么把任务包装成给模型看的提示词每一步模型输出之后怎么解析工具调用结果如何反馈给模型上下文超长后怎么截断或压缩同一错误重试多少次跑多少步必须结束结果怎么判分、失败怎么归类。如果你只比较模型不比较这层系统评测准确性就要打问号。更麻烦的是很多公开对比都没有把这些细节写清楚。读者看到的是“模型 A 比模型 B 高 10 分”但实际可能只是“模型 A 跑的 harness 比模型 B 跑的 harness 多了一个记忆压缩模块”。这也是为什么这篇论文值得关注它把我们过去习以为常但很少说破的问题直接放在标题里要求 Agent 评测必须披露 harness。2. Harness 到底在指什么2.1 从软件测试的 test harness 说起软件工程里的 test harness 通常包含三部分测试执行环境、测试脚本与被测对象的桩模块、结果收集与断言工具。一句话概括它是“为了让被测代码能跑起来并且在可控条件下验证”而搭的周边机制。LLM Agent 的 harness 和它有相似之处但也有不同。Agent 的“被测对象”不只是模型而是由模型和环境交互形成的复杂系统。因此这里的 harness 经常要承担两类职责第一类是运行职责。它要提供一个循环让 Agent 能不断“思考 → 调用工具 → 获得观察 → 再思考”。第二类是约束职责。它要知道什么时候停止、怎么处理失败、如何避免 Agent 陷入无效循环。所以一些人会把 harness 翻译成“评测框架”或“脚手架”。在论文讨论里我更建议把它理解成“智能体外层系统”。它既服务于 Agent 运行也服务于 Agent 评测。2.2 harness 不是模型也不是工具集比较容易混淆的是 harness 和工具集。工具集是 Agent 可以调用的函数比如搜索、代码执行器、数据库查询。harness 决定的是“怎么调用这些工具”系统提示词里如何描述工具每次模型输出是否允许调用多个工具工具返回结果太大时怎么裁剪调用出错了是重试还是换个工具上一步结果是否要回填到下一步对话里。同样一个工具函数放在不同的 harness 里Agent 成功率会差很多。因此不能说“我的 Agent 使用了 WebSearch 工具所以环境很标准”。工具只是环境的一部分调用策略才是 harness 的核心。维度模型层Harness 层具体对象参数权重、大脑能力循环逻辑、提示词模板、上下文管理是否可下载是公开或闭源不一定经常藏在项目代码里是否影响跑分影响常常被低估是否被披露论文会写明论文往往不写清楚主要风险模型能力不足评测结果归因错误、不可复现从工程角度来看模型更像是“大脑”harness 更像是“神经系统、四肢和决策流程”。大脑很重要但没有神经系统和四肢长程任务根本跑不起来。2.3 三个容易理解错的点第一harness 不等于 LangChain 或某个具体框架。框架只是实现 harness 的一种方式。自己写的 Agent 循环也是 harness直接调用模型 API 后手写 while 循环同样存在大量 harness 设计。第二harness 不等于评测集。评测集是任务集合harness 是怎么执行这些任务并判定成功失败的程序。同一个评测集用不同 harness 跑结果差异可能非常大。第三harness 不是“越快越好”。有些项目为了让 Agent 看起来“效率高”会把最大步数设得很小结果模型还没充分执行就被截断。这类参数会直接改变任务成功率。效率要区分“模型主动提前终止”和“harness 强制截断”两者在评测里意义完全不同。3. 长程智能体评测与静态评测的本质差异3.1 静态评测是“单轮问答”Agent 评测是“多步决策”传统静态基准问题更像“问答题”或“选择题”模型回答完就结束。评测重点在知识是否覆盖、推理是否严谨、指令遵循是否到位。长程智能体评测完全不一样。一个典型任务是让 Agent 根据用户需求跨时间跨工具完成一套业务流程。过程中模型需要记住任务目标不被中间过程带偏调用外部工具处理返回的非结构化结果出错之后自我纠正在多次交互中保持一致策略决定什么时候已经完成不再浪费额外步骤。这些能力不只是“模型本身”的能力。模型能生成“我想调用 python 执行这段计算”这句话但 harness 得保证这句话能被正确解析成函数调用并且返回值能回到模型上下文里。3.2 同模运算不同的环境反馈长程 Agent 评测更适合被理解为“部分可观测环境下的序贯决策问题”。Agent 每一步只能观察到有限信息需要根据历史行动决定下一步动作。模型能力决定了单步决策质量的“基线”但长期执行结果还取决于初始信息和执行轨迹的累积。这个累积过程会产生几个重要后果第一小错误会被放大。模型某一步调用工具时输出格式不对harness 如果能智能重试或修复后面可以继续走harness 如果直接报错退出任务就失败了。这里扣的分很难说是模型能力不够还是 harness 容错不足。第二上下文状态随时间变化。第 2 步时的信息如果被第 10 步的上下文截断策略丢掉再聪明的模型也想不起来。长程任务特别考验上下文管理哪些历史要保留、哪些要压缩、哪些可以放到长期记忆里。第三终止条件影响最终分数。一个任务如果允许 Agent 跑 30 步成功路径可能在第 8 步就出现。但如果 harness 只允许 5 步模型可能刚刚查完前两个工具就被强制结束。这类失败完全不应该归因给模型。3.3 为什么说“模型横向对比”在这里很危险在静态题库里做横向对比控制变量相对容易同样的题目同样的提示词只替换模型。即使存在提示词敏感性整体结论也比较稳健。长程场景里要“只替换模型、保持其他变量完全一致”已经很难了更麻烦的是多数评测框架本身就是某种 harness。框架 A 的默认循环逻辑、JSON 解析方式、重试策略和框架 B 都不同。你说你在“比较模型”实际却在“比较框架”。这就是论文所指出的核心问题不披露 harness 的 Agent 横向对比结论容易失真。4. 论文核心主张的技术解释为什么 harness 可能比模型影响更大论文标题里的关键词是 “without disclosing the harness” 和 “may outrank the model itself”。这个判断可以从几个层面理解。4.1 Agent 评测得分 模型能力 × harness 执行质量 × 环境可解性先给一个不太严谨但很直观的理解公式Agent 最终得分 ≈ 模型策略质量 × harness 运行保真度 × 任务环境可完成度模型策略质量表示“给定完整信息模型有没有能力输出正确决策”。但 harness 运行保真度表示“模型输出的决策有没有被完整执行、正确解析、合理记忆”。如果 harness 运行质量低模型再强也无法体现。反过来说当 harness 运行质量已经足够高时模型之间的差距可能被放大也可能被缩小。如果任务主要卡在长程信息整合大模型优势明显如果任务主要卡在格式解析和状态管理那么模型差异反而不是决定项。4.2 一个常见案例模型“看起来变笨了”在 Agent 崩溃分析里有一种高频现象模型突然不再调用工具或者重复调用同一个工具。很多人拿到结果以后会认为模型推理能力不行。但如果打开 harness 日志常常会发现真正原因是工具调用出现 JSON 解析错误错误信息回灌到上下文模型越看越乱上下文接近上限历史轨迹被粗暴截断前面的任务目标被挤掉工具返回内容太大关键信息被截掉某一步出现了异常状态但 harness 没有给模型恢复的机会。换句话说模型是在一个“残缺反馈回路”里工作。把 Agent 看成运动员模型是肌肉爆发力harness 是神经系统、裁判规则和赛道环境。爆发力再强如果反馈回路断了比赛成绩照样很难看。4.3 长程评测的方差来源很多在模型之外单次长程 Agent 评测的方差很大。随机性来自多个方面模型采样温度工具返回的顺序中间一步失败后是否重试重试时提示词是否发生变化Agent 是否被早期终止判分器是否严格要求输出格式。其中许多变量都属于 harness 设计范围。如果不改动模型只改这些变量跑分上下波动几个点非常正常。论文的意思是如果你在这些变量没有固定的情况下比较模型最后得到的高下很可能只是“这次随机波动里谁更幸运”。所以“harness 影响超过模型本身”并不是说模型不重要而是说模型差异在评测系统里被严重噪声包裹。如果没有把 harness 固定并披露讨论模型高低没有明确意义。4.4 Harness 差异可能“淹没”模型差异举一个比较直接的例子。假设评测三个模型模型 X策略能力强但输出格式偶尔不稳定模型 Y策略能力中等但输出格式非常稳定评测任务要求第一步必须先调用工具每步最多 10 次格式错误直接判失败。在这种情况下模型 X 因为格式问题在早期失败率很高最终得分低于明确不如它的 Y。你能说 X 比 Y 差吗不能说应该说是“评测 harness 对格式失败过于严格影响了对核心策略能力的观测”。如果把 harness 改成“格式错误最多自动修复 3 次”模型 X 可能立刻反超。模型还是那两个模型因为 harness 不同结论顺序反转。论文真正想强调的是除非你在评估和报告时披露了这些设计否则论文中“模型 X 比模型 Y 强”这类结论读者无法判断到底是模型脑袋更强还是 harness 更适配这个模型。更严重的是同一套 harness 可能对某些模型的输出格式有隐性偏好从而造成系统性偏差。5. Harness 工程的关键变量哪些参数可能压过模型差异要真正理解论文的观点需要知道 harness 里到底有哪些变量。下面梳理几个最常见的“隐形选手”。5.1 最大步数与终止策略最大步数是长程评测里最直接的控制参数。它决定了 Agent 在任务上最多能进行多少次模型调用或工具调用。如果设得太小任务可能永远完不成如果设得太大失败模式又会表现为“无限循环”和“资源浪费”。比较理想的做法是记录两个指标任务成功率成功轨迹的步数分布。只看成功率很容易把“最大步数不够”误判成“模型能力不足”。5.2 工具描述与选择策略模型每一次决定调用哪个工具靠的是工具的名称、描述和参数说明。工具描述写得好不好很大程度决定模型能不能选对工具。这属于 harness 层却经常被当作“模型工具调用能力”。同样一个 search 工具如果在系统提示词里写“搜索互联网获取最新信息输入关键词输出结果列表。”“当且仅当用户问到实时信息且当前知识无法回答时才使用 search(query) 查询查询时优先使用简体中文关键词。”两种写法的触发率、错误率会明显不同。这部分差异会叠加到模型对比噪声里。5.3 上下文管理策略每个模型都有上下文窗口限制。长程 Agent 任务执行几十步之后不可能把所有内容都塞进上下文。Harness 必须决定怎么处理只保留最近 N 轮对历史内容做摘要把工具返回结果分块保存是否把重要任务目标固定在上下文开头。上下文截断策略几乎可以说是长程评测最大的差异来源。不同的摘要方法可能导致模型对任务目标的理解完全不同。同样两个模型在同一步数之下如果 harness 的上下文策略不同成功率差距可以非常明显。5.4 解析与重试机制模型输出不一定严格遵循 JSON 或函数调用格式。解析层是 harness 的重要组成部分。解析失败后是否把错误信息回传给模型让模型自行修复还是直接判定当前步骤失败好的 harness 会让模型自己纠错并在下一次生成时看到“刚才格式错误请重新输出”。差的 harness 可能遇到一次 JSON 解析失败就直接终止任务。这两种机制下模型表现会有很大差别。5.5 评测指标与判定方式最后还有一层是结果判定。同一个 Agent 完成任务后怎么判断它成功是否只依据最终答案字符串匹配是否要求 Agent 必须显式输出“任务完成”是否考虑中间过程的正确性判定方式也算广义 harness因为它直接影响分数统计。有些判定器对措辞极其敏感Agent 明明做对了但因为最终报告少写一个字段就被判失败。这类误差与模型能力无关。6. 新闻里的 deepseek harness / codex harness 到底在搜什么最近在社区里能看到类似 “deepseek harness”、“codex harness” 的搜索词。某种程度上这是“harness 工程”这个概念破圈的表现但也带来一些混淆。第一类搜索者可能是看到了某些评测 Agent 榜单想知道 DeepSeek 或 Codex 这类模型在跑 Agent 任务时用了什么外层框架他们想复现结果所以搜“deepseek harness 安装”、“deepseek harness 桌面版”。第二类搜索者是把“harness”当成了某个模型官方的工具产品以为它是 DeepSeek 或 Codex 推出的插件或桌面应用。这里要做一个边界澄清模型厂商可能会提供官方 CLI 或 Agent 调试工具底层也会包含某种 harness但“harness”这个词本身不是某一个模型的专有组件。它更像一种工程实践核心是“把模型能力封装成可运行、可评测的智能体”。所以当你在搜索 “deepseek harness” 时未必能找到某个官方统一命名的东西。更有效的方法是看清楚评测报告或论文里到底使用了什么 harness再看它是否开源。如果对方没有披露 harness那再去搜任何“官方 harness”意义都不大因为复现的关键信息已经缺失。7. 一套便于披露和复现的 Harness 配置模板这篇论文最直接的实践启发是以后做 Agent 评测除了报告模型名称更要报告一份完整的 harness 配置。下面给出一份可以参考的 YAML 模板。# 文件路径config/eval_harness_config.yaml # 用途记录一次长程智能体评测中 harness 相关配置 # 避免模型对比结果被脚手架变量污染。 eval: task_id: long_horizon_tool_benchmark model_name: your-model-name model_provider: openai_compatible temperature: 0.2 top_p: 0.9 harness: # Agent 循环总步数 max_steps: 25 # 是否允许模型连续调用多个工具 allow_parallel_tool_calls: false # 遇到可恢复异常时的最大重试次数 parse_retry_times: 3 # 解析失败时是否把错误信息回传给模型 return_error_to_model: true context: max_context_tokens: 16000 # 可选值: truncate_head / summarize_history / keep_recent_only overflow_strategy: summarize_history task_goal_position: head memory: memory_type: working_memory_and_summary summary_trigger_steps: 10 tool_layer: tool_names: [web_search, python_executor, file_reader] tool_description_language: zh include_usage_examples: true7.1 配置模板里哪些字段最影响跑分报告不要只贴一个模型名字。要尽量披露温度、系统提示词风格、工具描述语言、上下文超限策略和重试次数。因为这些变量可能比模型差异更能决定长程评测结果。如果论文篇幅有限最低限度也应该报告四个字段最大步数上下文溢出处理策略工具调用失败时的重试机制终止条件与失败分类标准。8. 最小实验示例同一模型两种 Harness为了直观感受“模型没变、结果却可能不同”可以用一个很小的 Python 骨架做演示。这里不调用真实 API而是用模拟模型来展示 harness 参数带来的差异。真实评测时把mock_llm_call替换成模型 API 调用即可。# 文件路径examples/harness_impact_demo.py 演示目的 - 同样一个“模型函数”在不同 harness 最大步数下 会得到不同的任务成败结果。 - 真实评测中并不建议只改 max_steps而是建议固定并记录。 运行方式 python examples/harness_impact_demo.py import json # ---------- 模拟一个真实模型调用 ---------- def mock_llm_call(history): 真实场景中这个函数内部会调用模型 API。 这里为了演示让模型“看起来像”要经过两轮工具调用才能给出答案。 text json.dumps(history, ensure_asciiFalse) if text.count(tool_result) 2: return {type: final_answer, content: 42} return {type: tool_call, tool_name: calculator, arguments: {expr: 6*7}} # ---------- Harness A只允许跑 2 步 ---------- class HarnessA: def __init__(self, max_steps2): self.max_steps max_steps def run(self, user_query): history [{role: user, content: user_query}] for step in range(self.max_steps): output mock_llm_call(history) if output[type] tool_call: # 模拟工具执行返回 history.append({ role: tool_result, content: 工具计算结果42 }) else: return {answer: output[content], steps: step 1} return {answer: None, steps: self.max_steps} # ---------- Harness B允许跑 5 步 ---------- class HarnessB: def __init__(self, max_steps5): self.max_steps max_steps def run(self, user_query): history [{role: user, content: user_query}] for step in range(self.max_steps): output mock_llm_call(history) if output[type] tool_call: history.append({ role: tool_result, content: 工具计算结果42 }) else: return {answer: output[content], steps: step 1} return {answer: None, steps: self.max_steps} if __name__ __main__: query 请计算 6 * 7并把结果返回给我 result_a HarnessA().run(query) result_b HarnessB().run(query) print(Harness A(max_steps2) 结果:, result_a) print(Harness B(max_steps5) 结果:, result_b)运行结果会是这样Harness A(max_steps2) 结果: {answer: None, steps: 2} Harness B(max_steps5) 结果: {answer: 42, steps: 3}这说明一个核心问题模型函数完全一样只是“最大允许步数”不同最终表现在评测指标上就可能是成功与失败的区别。真实评测会比这个复杂得多但原理一致。Harness 参数会中止 Agent 的探索过程而模型本身并不总是能在第一步就给出最终答案。这个演示不是让你把 max_steps 无限调大而是要建立一种敏感度意识修改任何 harness 参数后先看任务成功率是否变化再判断模型本身的优劣。如果没有做这种对照就直接说“A 模型比 B 模型更适合 Agent 任务”证据链是不完整的。9. 评测 Harness 报告清单与排障方法9.1 报告清单写 Agent 对比论文或技术报告时建议在方法部分增加一节 “Harness Configuration”。至少需要包含以下信息运行框架是自研 while 循环还是 LangChain、Codex CLI 等现成框架的哪个版本模型调用参数temperature、top_p、max_tokens、是否开启流式Agent 循环变量最大步数、重试次数、是否允许并行工具调用上下文策略最大上下文 token、溢出处理方案、历史压缩方法工具定义工具数量、工具描述语言、是否提供使用示例终止条件什么情况下算成功、什么情况下算失败、超时如何记录随机种子与多轮重复次数评测是否跑了多次并报告均值与方差。9.2 常见问题与排查思路问题现象可能原因排查方式解决方案同一个模型复现不出来别人的结果对方 harness 未披露或细节缺失查看评测报告中是否有 max_steps、上下文策略等配置先与原作者确认配置再重建 harness换成另一个模型后分数大跌工具描述或解析机制偏向原模型输出格式对比两种模型的原始输出日志查看解析失败率统一并记录工具描述确保系统对格式不过度敏感Agent 经常重复同一个工具调用工具结果没被正确写入上下文或状态没有更新查看每轮 history 拼接逻辑检查工具调用状态是否进入下一轮上下文上下文变长后性能下滑历史消息未被合理压缩关键目标被截断查看上下文溢出时的截断日志采用摘要式记忆或固定工作任务目标在头部JSON 解析失败导致任务中断重试机制设计不完善检查 parse_retry_times 和错误回传逻辑设置有限重试并将解析错误反馈给模型评测分数波动大环境随机性或采样随机性大固定 seed同一任务重复运行多次报告均值与方差不要只取单次最高值9.3 判分时注意三个边界第一不要把所有“没答对”都归为“模型理解错”。要先看是不是 harness 没给够信息比如工具结果没有成功返回。第二不要把所有“提前回答”都当成“模型聪明”。有些任务Agent 输出“我认为任务已完成”并不代表真的完成需要由评测器校验最终状态。第三不要忽略“因重试得到正确答案”的情况。如果模型第一次调用失败第二次靠 harness 返回错误信息才修正这类轨迹要单独统计否则会把 harness 的纠错能力误算成模型能力。10. Harness Engineering 对开发者的真正提醒从工程实践看harness engineering 大概率会成为 Agent 时代的核心技能。因为模型能力再强最终用户使用的是“模型 harness”的完整系统。评测也是一样Agent 评测本质上评测的是完整系统不只是模型。那么后续项目里可以给自己立三条规矩第一做 Agent 横向评测前先把 harness 冻结一个版本。冻结意味着代码、配置、提示词全部锁定任何修改都要记录并重新验证。第二同一组实验跑多次统计通过率的均值和方差。尤其是带工具调用和随机采样的大模型单次运行很容易让结论失真。第三报告结果时把“模型”与“harness”分开表述。可以写“在某个评测集、某套自定义 harness、某组工具描述条件下模型 X 的通过率为多少”。不要只写“模型 X 更强”这既是对读者负责也是对自己的结论负责。“Stop Comparing LLM Agents Without Disclosing the Harness”这个标题听起来尖锐但它真正指向的问题却很朴实评测报告需要具备可复现性。模型的参数是公开的模型内部的权重是确定的但 harness 的实现细节如果不说明Agent 评测就还停留在“黑盒比较”阶段。建议收藏这篇文章下次写 Agent 对比报告或者复现别人 Agent 结果时对照里面的配置清单过一遍。如果你也在搭建长程智能体评测体系欢迎在评论区分享你踩过的 harness 坑尤其那些“换了个模型结果大跌、最后发现是上下文截断策略不同”的典型经验。