LLM Agent评测离不开Harness:不披露则模型对比不可信 在一篇讨论 LLM Agent 评测方法的论文中作者给出的判断非常直接Stop Comparing LLM Agents Without Disclosing the Harness。翻译成大白话就是如果不在报告或代码中完整公开用来驱动、约束、反馈和评估 Agent 的那套 harness就不应该轻易发布不同模型之间的性能对比结论。这个观点击中了当前 LLM Agent 评测的一大痛点大家把注意力放在模型权重、prompt 技巧、benchmark 分数上却很少认真追问——当某个 Agent 拿到高分时分数里有多少来自模型本身又有多少来自外部评测管线。理解这一点需要跳出“模型是主角评测只是背景”的惯性。对普通单轮问答来说评测大致只在给定输入后比较输出外部环节很少。但 LLM Agent 评测完全不同模型要在多轮、长上下文中持续决策、调用工具、观察反馈、修正错误。每一步都可能经过 harness 解析动作、执行工具、拼装历史、截断消息、决定是否重试再继续下一个循环。模型只是整个环路中的一环而环路上每个细节都会影响最终得分。这也是为什么很多团队开始重视 harness engineering当有人觉得“另一个实现跑分更高”时往往不是模型被换掉了而是 harness 的行为变化了。下文会从概念、原理、披露规范、最小案例到工程实践把这个容易被忽略的变量拆开讲清楚。1. 先弄清楚LLM Agent 评测中的 harness 到底是哪一层1.1 一句话定义和容易混淆的地方如果用一句话概括harness 是“把 Agent 固定住并让它能在环境中完成任务的整套外部装置”。它既包含代码也包含配置、提示词模板、交互规则、工具边界和评分逻辑。在软件测试语境里test harness 指驱动被测对象并收集结果的程序在 LLM Agent 评测里harness 的范围更大。它至少决定以下内容评测任务如何描述给模型。模型输出如何被解析成结构化动作。动作如何调用真实或模拟环境。环境反馈如何回传给模型。模型可以执行多少步什么条件算结束。最终轨迹如何判分部分完成是否给分。需要强调harness 并不等于“Agent 框架”。可以说 LangChain、LlamaIndex 是 Agent 框架但 harness 是更具体的实验设置。同一个框架下把max_steps从 10 改成 3把解析逻辑从正则匹配改成 JSON Schema 校验把工具报错信息截断到 200 字符都属于更换 harness。只有把版本、配置、prompt、错误恢复策略全部记录下来才算真正披露了 harness。1.2 harness 的关键组成做 Agent 评测时建议把 harness 拆成六个子模块逐项记录子模块常见配置项影响面任务提示system prompt、user prompt、few-shot 示例、格式约束影响模型对目标和输出格式的理解动作解析输出解析器、JSON Schema、函数调用校验、容错规则一次解析失败会消耗步骤预算情况严重时直接判失败工具执行真实 API 或模拟器、超时时间、返回内容长度、并发度决定反馈是否足够支撑模型下一步决策上下文管理历史轮数、摘要策略、消息截断、重排序长程任务中记忆丢失会造成重复错误动作循环控制max_steps、早停条件、重试次数、随机种子决定模型有多少机会纠正错误效果评估最终答案匹配、过程得分、LLM 评审、成本约束直接决定最终分数与排名很多团队觉得已经“披露了实验设置”因为他们在论文或 README 里写了“基于 ReAct 框架”“使用 function calling”“温度设为 0”。这些信息太粗。真正导致结果分歧的往往是更下一层的默认行为。例如框架是否自动对工具返回结果做摘要模型输出中的“思考过程”是否会被当作工具参数一次 JSON 解析失败会不会自动重发。这些默认行为没有被写出来实验结果就失去了可比性。1.3 应该把 harness 当成实验条件而不是实现细节论文特意用 harness 而不是 evaluation framework 来指代这套运行环境背后的潜台词是实验比较必须控制变量。模型权重是一类自变量harness 是另一类自变量。如果不同模型跑在不同 harness 上你测出来的差异其实是“模型差异 harness 差异”的混合物。更麻烦的是不同模型对 harness 的敏感度不同。有的模型擅长严格按照 JSON 输出有的模型更习惯自然语言加代码块有的模型在工具反馈被截断后容易陷入反复猜测。同一个 harness 对模型 X 很友好对模型 Y 却可能造成系统性劣势。结论自然是不披露 harness 的模型对比既无法复现也难以解释。因此合理的实验姿势是把 harness 当成一个“变量”而不是“暗盒”。跑模型之前先写 harness 描述文件跑完之后连同轨迹一起归档。就像做化学实验要写明温度、浓度、催化剂一样Agent 评测也要写明这套外部装置。2. 为什么长程智能体评测最容易受 harness 影响2.1 从单步能力到多轮轨迹短任务里模型的单步输出质量基本能代表最终结果长程任务则不同。代码库修改、网页操作、数据分析这类任务通常需要模型连续执行很多动作每走一步都会产生新的状态。下一步的输入依赖上一步的工具返回结果和之前的全部上下文。长链路意味着误差会累积。如果 harness 在第 3 步截断了工具返回内容模型第 4 步就无法看到关键数据如果模型在第 4 步输出了解析失败的动作harness 又没有给出足够的错误提示第 5 步可能是重复动作。当任务长度达到几十步任何一个中间环节的不透明处理都会被放大成最终结果的显著差异。单轮问答评测很难发现这种问题因为模型只输出一次外部装置没有介入空间。评测长程智能体时外部装置几乎每一步都在介入模型能力就不等于最终成绩。2.2 反馈质量比提示词更隐蔽常见误区是把 harness 影响理解为“提示词写法不同”。其实影响最大的是 post-action feedback也就是模型采取动作之后harness 返回给它的信息。一次典型的 Agent 循环可以写作task_prompt - model_generate - parse_action - execute_tool - build_observation - append_to_context - model_generate - ...这个链路中任何环节的信息丢失都会改变模型后续决策。例如工具返回了一个 8000 字符的 CSV两套 harness 分别执行下面的策略harness A完整保留 CSV并允许模型调用文件读取工具分段查看。harness B只保留前 500 字符超过部分直接丢弃。如果任务要求模型找到表格最后几行的问题同一模型在 harness A 下可能成功在 harness B 下只能靠猜测。这种差异与模型本身的逻辑能力无关是 harness 的反馈通道设计不同。2.3 对比实验结论翻转的三个信号团队内部做 Agent 评测时如果发现下面几个现象应该先怀疑 harness而不是急着换模型同一个模型在内部评测环境上表现不错在某个公开评测工具的默认配置下排名明显下降。只是升级了评测框架版本没有修改模型和任务各模型相对排名却发生了改变。某个模型非常擅长产生结构化输出某个模型输出格式不够稳定当你改变解析容错策略时排序发生逆转。这些现象都说明评测结果已经被 harness 干扰。论文标题用“stop comparing”这种强表达正是希望社区停止在一个不透明、不完整、不可复现的评测条件下继续输出模型对比结论。3. 比较 Agent 必须披露的四类 harness 信息3.1 行动空间与工具层实现第一类必须披露的信息是模型能调用什么工具、工具定义怎么描述、工具层如何执行。具体要写清楚工具名称、功能描述、输入参数 Schema、是否允许并行调用。工具调用是真的访问外部系统还是在模拟器中运行。工具返回结果是否会被截断、摘要、重排。工具调用超时时间和异常类型如何返回给模型。例如工具描述中的一句 “Args: expr: str”看起来不起眼却能影响模型构造参数的格式。如果工具层要求 JSON 类型而工具描述里没有给出例子模型可能猜测传字符串还是传对象。这些猜测在几十次调用后会显著影响结果。3.2 上下文管理和循环控制长程评测最容易忽略的是上下文管理策略。必须记录max_steps是多少允许模型最多执行多少轮。每轮生成的最大 token 数会不会导致 JSON 输出被截断。历史上下文达到阈值后采用“丢弃最早消息”“滚动摘要”“完整保留”中的哪一种。动作解析失败时是否把错误信息重新发给模型最多重试几次。任务在什么条件下算结束模型输出结束标记、工具成功、步骤耗尽还是时间超时。这些参数中任何一个变化都意味着模型试错机会不同。尤其要注意“自动重试”这类隐性机制。有的框架会默认在解析失败后重新请求一次模型表面上是提高鲁棒性实际上等于悄悄放宽了任务难度。对比实验必须把这种机制写明确。3.3 评估指标与判定边界第三类信息是分数如何产生。长程智能体评测不只是“成功 or 失败”很多实现包含部分得分、过程奖励、成本惩罚等。需要披露最终答案如何提取是取最后一次输出、第一个 JSON 代码块还是人工审核。字符串匹配规则是精确相等、包含关系还是使用归一化字符串。部分完成时如何给分是否按步骤数、工具调用数或中间产出打分。是否用 LLM judge如果使用提供 judge 的 prompt 和模型版本。是否统计 token 成本、执行时间和重试次数。判分细节直接决定排名。一个轨迹在“只允许最终答案完全正确”的规则下得 0 分在“允许中间结果部分给分”的规则下可能是 0.8 分。如果不同论文使用不同判分规则比较分数就毫无意义。3.4 harness 披露模板下面是一个适合写在实验报告附录里的模板benchmark_name: multi_tool_decision_task_v2 harness_version: v2025.06.01 repository: https://example.invalid/agent-harness runtime: model_provider: internal-endpoint generation_temperature: 0.0 max_tokens_per_response: 1024 prompt: system_prompt_digest: sha256:xxxxxx user_prompt_template: templates/task.md few_shot_examples: - examples/task_007.json tools: definitions_file: tools/tools.json simulate_real_env: false tool_timeout_ms: 10000 truncate_observation_chars: 12000 loop: max_steps: 8 parse_error_policy: return_error_to_model parse_retry_times: 1 stop_token: FINAL_ANSWER context: max_history_rounds: 20 overflow_strategy: drop_oldest_observation evaluation: answer_extractor: last_json_block score_policy: partial_credit_by_tool_success judge_model_name: internal-judge-v2 judge_prompt_digest: sha256:yyyyyy这段 YAML 本身并不复杂但它把实验条件固定下来了。其他人拿到这份描述可以判断你的评测结果是在什么环境里产生的也可以按相同配置重跑。4. 一个最小示例同一模型为什么会在不同 harness 下得到不同结论4.1 设定一个稳定的对比场景为了直观展示 harness 的影响这里不依赖某个特定模型而是构造一个可理解的最小任务模型需要通过多次工具调用来完成一个“逐列统计 CSV 并排除异常值”的任务。任务链路中包含一次错误解析、一次超长工具返回、一次早期上下文丢失。我们需要验证的是同一个模型在这套任务中能在多少步内完成任务并得到正确结果。假设两套 harness 都使用同一个模型权重和同一个任务描述唯一差别集中在工具反馈、历史保留和步骤预算上。4.2 两套 harness 配置第一套配置尽量保留完整信息也给模型更多纠错机会# harness_a.yaml max_steps: 8 max_observation_chars: 12000 tool_result_truncation: none parse_error_policy: return_error_to_model parse_retry_times: 1 context_history: full_history stop_condition: final_answer_valid score_policy: partial_credit_by_tool_success第二套配置使用更严格的预算和更弱的反馈# harness_b.yaml max_steps: 4 max_observation_chars: 500 tool_result_truncation: head_and_tail_500 parse_error_policy: fail_current_step parse_retry_times: 0 context_history: last_3_rounds stop_condition: final_answer_or_step_limit score_policy: exact_final_match从代码上看两套配置都称得上“reasonable”但它们产生的结果会明显不同。4.3 分歧产生路径假设模型在第 1 步生成了包含解释文字和 JSON 动作的输出{ thought: 先查看任务文件再计算平均值, action: {tool: read_file, args: {path: data.csv}} }harness A 的解析器会从代码块中提取 JSON解析成功并把错误判定留给后续校验harness B 如果要求整段输出必须是严格 JSON第一步就可能解析失败。接着csv 文件内容超过 10000 字符。harness A 完整返回模型可以看到所有列名harness B 只返回前 500 字符和末 500 字符中间列名被截断。模型后续要选择正确列时只能靠猜。任务还没进入核心计算模型已经因为 harness 差异失去了关键信息。如果任务原本需要 6 步完成harness A 的max_steps: 8留有纠错余地harness B 的max_steps: 4很可能在第 3 步时步数耗尽。最终评分规则进一步加剧差异harness A 允许部分工具成功得部分分harness B 只按最终答案精确匹配给分。所以同一模型可能在一套 harness 下看起来“基本能解决任务”在另一套 harness 下“完全不会任务”。实际评测里很少有人会同时公布这种成对配置只公布模型分数不公布 harness读者就无法判断问题出在模型还是实验装置。5. 工程落地如何把 harness 固化进 Agent 评测流程5.1 建议的目录结构一套可维护的 Agent 评测工程建议把 harness 配置、环境代码、轨迹记录和评估器分开agent-harness/ ├── configs/ │ ├── harness_a.yaml │ └── harness_b.yaml ├── environment/ │ ├── tools/ │ ├── simulator/ │ └── real_env_adapter/ ├── prompts/ │ ├── system.md │ └── task_template.md ├── trajectory/ │ └── 2025-06-01_run_001.jsonl ├── evaluator/ │ ├── extract_answer.py │ └── scoring_rules.yaml ├── runner.py └── results/ └── summary.csv把 harness 配置从主代码里拆出来是为了让实验参数能跟着任务一起切换。runner.py只负责加载配置、初始化环境、运行循环、写轨迹不在代码里硬编码max_steps或工具描述。5.2 用描述文件绑定一次运行一份完整运行记录至少应该包含三个信息模型标识、harness 配置、评测任务集合。可以在启动脚本时同时传入python runner.py \ --model model_x \ --task task_set_v1 \ --harness configs/harness_a.yaml \ --output-dir results/model_x_harnes_a启动脚本可以读取 harness YAML把哈希值写入结果文件头部。这样即使将来配置文件被修改旧结果仍然知道当时使用的是哪个版本。5.3 记录轨迹而不是只记录分数只记分数无法复盘。建议每次评测输出 JSON Lines 格式的运行轨迹每个事件保留一个对象{type: state, step: 0, task: task_001, ts: 2025-06-01T10:00:00Z} {type: model_call, step: 1, prompt_tokens: 2210, response: 调用 read_file...} {type: parse, step: 1, parsed: {tool: read_file, args: {path: data.csv}}} {type: tool, step: 1, tool: read_file, ok: true, chars: 10240} {type: context_update, step: 1, dropped_rounds: 0} {type: score, task: task_001, policy: partial_credit_by_tool_success, score: 0.4}每条事件对应模型环路上的一次关键节点。如果最终分数异常可以通过轨迹找到是哪一步信息丢失或解析失败导致的。5.4 做模型与 harness 的交叉矩阵更严谨的做法是做二维交叉实验。不要只比较“模型 A 在默认 harness 下的分数”和“模型 B 在默认 harness 下的分数”而是固定同一个任务集分别跑多套 harness。configs [harness_a.yaml, harness_b.yaml] models [model_x, model_y] for model in models: for config in configs: result run_benchmark(modelmodel, harnessconfig, taskstask_ids) results.append(result)这样得到的结果会呈现出一个矩阵模型性能在每个 harness 下是否一致排序是否随 harness 变化。如果模型 A 在 harness A 下领先在 harness B 下落后说明当前结论不稳定。此时要优先分析 harness 差异而不是直接发布“A 比 B 强”的结论。6. 常见误区与排查方法先把结果失真当成 harness 问题6.1 现象与排查表团队在对比 LLM Agent 时经常遇到以下情况问题现象常见根因排查方式处理建议同一个模型在不同电脑上结果不一致依赖版本或随机种子不一致对比生成模型版本、环境锁文件、随机种子复跑两次固定依赖版本记录所有可复现参数模型明明很强换了一套工具描述后分数大跌工具描述缺失关键使用示例检查工具 Schema 是否清晰查看失败轨迹中的解析错误更新描述后重新跑交叉矩阵观察排序稳定性模型在本地评测中成功在评测工具默认配置下失败本地 harness 悄悄做了 retry 或上下文摘要比较本地循环代码和默认评测工具循环逻辑统一使用同一 harness不要靠额外机制“保送”模型分数提高但无法解释从哪个环节改进只记录 final score没有记录轨迹回看 JSONL 轨迹找到问题步骤强制记录 model_call、parse、tool 事件A/B 对比结论在增加 seed 后不再成立任务只有 1 条或 seed 太少方差大对每条任务多 seed 重跑并计算置信区间至少使用多 seed、多条任务再下结论6.2 三个高频坑第一个高频坑是把 prompt 修改排除在 harness 之外。很多团队在对比模型时会为某个模型补充几行 few-shot 或格式提示然后说“模型更强了”。从评测视角看这同时改变了两个变量模型权重和 harness。如果要比较模型prompt 必须保持同一套模板所有为特定模型优化的 prompt 都应该记录为 harness 变更。第二个高频坑是过度依赖框架默认策略。读源码不仔细框架默认做什么都不知道。比如某个框架可能默认在解析失败后重试一次你会以为“成功率 90% 是模型能力强”实际上重试机制贡献了大量修正机会。框架升级还可能改变默认截断逻辑导致同一个评测脚本的输出排序出现跳变。第三个高频坑是只用最终答案判分不记录过程结果。最终答案判定本身也是一种 harness 行为。模型如果在第 8 步输出了正确结果第 3 步因为解析失败被扣分你会不会注意到它的纠错能力如果只记录最终答案可能会忽略 harness 是否在错误路径上提供了足够信息。只有完整轨迹能区分“模型本来就对”和“harness 通过反复重试让模型碰巧最终输出正确”。排查顺序建议按这种优先级进行检查任务输入文件是否一致。检查生成模型、版本和随机种子是否一致。检查 prompt 模板是否完全一致。检查工具执行环境是否真实超时与返回长度是否一致。检查上下文截断和步数限制是否一致。检查解析器与自动重试逻辑是否一致。检查判分规则和答案提取器是否一致。最后才考虑模型权重本身或任务难度问题。7. 最佳实践让 harness 成为 Agent 评测的一等公民7.1 实验阶段的分工建议在研究或工程团队中可以给评测结果强制附带三样内容一份 harness 配置清单使用 YAML 或 JSON 描述别写小作文。一个 git commit 号锁定评测代码和 prompt 模板的准确版本。一条不带隐私问题的轨迹示例方便复盘和判断错误阶段。团队内部可以约定任何模型对比结论只有在至少两套 harness 下排序一致才允许写入周报或发布文档。如果两套 harness 给出不同排序先解释 harness 差异再讨论模型优劣。这能有效降低“用自己的 harness 证明新模型很香换一个评测环境就翻车”的风险。7.2 发布和复现前的检查清单发布实验或上线评测系统前可以参考下面的清单[ ] 是否写明模型版本、量化方式和推理服务版本。[ ] 是否写明max_steps、temperature、max_tokens_per_response。[ ] 是否给出 system prompt 和 few-shot 的完整内容或摘要哈希。[ ] 是否给出工具定义文件和工具执行方式。[ ] 是否说明工具返回结果的截断和摘要策略。[ ] 是否说明 context 超出限制时的处理策略。[ ] 是否说明解析失败后的重试策略。[ ] 是否说明答案提取器和评分规则。[ ] 是否记录多 seed 标准差和置信区间。[ ] 是否把评测代码和配置文件提交到可访问的仓库。对学术论文来说即使投稿页数有限也可以把完整 harness 放入附录或开源仓库。缺少这些信息模型对比就无法被他人在同等条件下验证。7.3 可以继续深挖的方向从实践向前的角度有四个方向值得继续关注harness 对模型行为的影响机制研究工具描述格式、输出解析方式、错误反馈长度会如何改变模型动作分布。harness 自动优化能否通过搜索更好的工具描述、few-shot 选择和评分策略来评估 Agent 的真实能力上限。多 seed 与长任务成本评估长程评测成本高很多实验只跑一次未来需要更多重复实验和方差报告。跨任务稳定性一个模型在某类任务上的高分能否在另一个相似但不同领域的任务上保持稳定。这些方向本质上都要求把 harness 从“评测工具的默认配置”提升为“实验设计的重要变量”。研究者和工程师越早意识到这一点得到的模型对比结论就越可靠。回到论文标题里的建议Stop Comparing LLM Agents Without Disclosing the Harness。它并不是说以后不要比较模型而是说比较前必须承认 harness 与模型同等重要。对研究者而言发布模型数据时要同时发布运行装置对工程师而言每次 A/B 评估都要以完整环境可复现为底线。真正值得追求的不是把模型放到一个对自己最友好的 harness 上证明它更强而是让评测结论在换一个诚实披露的 harness 后依然稳定。

相关新闻

最新新闻

156页供应链与智能制造战略规划项目建议书【附全文阅读】

156页供应链与智能制造战略规划项目建议书【附全文阅读】

本文档为《供应链与智能制造战略规划项目建议书》,适配健康保健品等制造型企业的供应链部门(规划 / 运营岗)、生产部门(精益制造 / 工厂管理岗)、IT 部门(数字化转型 / 系统运维岗)、战略规划部…

2026/9/3 7:30:03
【Java+AI零花钱项目实战五M4~GA】AI交互集成(IDEA+ClaudeCode+ccSwitch+DeepSeek-V4-Pro+doubao-seed-evolving+SpringAI)

【Java+AI零花钱项目实战五M4~GA】AI交互集成(IDEA+ClaudeCode+ccSwitch+DeepSeek-V4-Pro+doubao-seed-evolving+SpringAI)

一、前言: 1、经过前面四个姐妹篇的实战摸索,探察出了VibeCoding的最佳实践方案是:不降级ClaudeCode的能力 便宜的DeepSeek大模型 Spec-Driven开发模式。本章将记录完整的M5~GA的过程。 二、M4~GA实现 2.1、开发质量影响点 在使用过程中…

2026/9/3 7:30:03
GPT-5.6-Sol与Cerebras硬件组合实现20倍推理加速的技术解析

GPT-5.6-Sol与Cerebras硬件组合实现20倍推理加速的技术解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 7:30:03
从PID控制到双闭环设计:滚球控制系统实战解析

从PID控制到双闭环设计:滚球控制系统实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 7:30:03
MATLAB与Coppeliasim联合仿真:UR5机械臂运动控制与轨迹规划实战

MATLAB与Coppeliasim联合仿真:UR5机械臂运动控制与轨迹规划实战

简介:本资源是一套面向计算机、电子信息工程及数学等专业本科生的UR5机械臂运动控制实践套件,聚焦MATLAB与Coppeliasim协同仿真的核心技能训练,解决课程设计、期末大作业及毕业设计中机械臂建模、运动学求解与闭环控制实现等典型问题。压缩包…

2026/9/3 7:30:03
HCIA认证自学指南:从网络基础到实验拓扑的完整备考方案

HCIA认证自学指南:从网络基础到实验拓扑的完整备考方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 7:25:03