ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

LLM Agent对比评测:不披露Harness,结果可信吗?

LLM Agent对比评测:不披露Harness,结果可信吗? 最近有一篇论文标题直白得有点不留情面《Stop Comparing LLM Agents Without Disclosing the Harness》。它的核心立场是当你拿两个 LLM Agent 做对比评测并得出“A 比 B 强”的结论时如果论文或报告没有完整交代背后的 harness评测脚手架/智能体运行框架这个结论很可能不是模型能力的真实排序而是两套工程系统之间的差异。更直接的说法是在长程智能体评测里harness 对结果的影响可能超过模型本身。这个观点是不是危言耸听要看你怎么定义 Agent 评测。传统 LLM 评测是输入 prompt、输出答案、比对分数变量相对可控。Agent 评测不是这样模型需要在任务环境里持续决策、调用工具、观察返回结果、修正策略最终完成一个长流程目标。在这个过程里每一步都可能出错工具调用格式解析失败、参数类型不对、上下文超长被截断、任务中途状态丢失、找不到可用工具。而这些环节大多不是模型决定的是 harness 决定的。换句话说你以为在测模型实际上有很大一部分是在测 harness。这篇文章我会先拆解什么叫 Agent Harness再解释为什么它会影响 LLM 对比结果接着分析长程智能体评测中误差为什么会被放大最后给出一个可落地的负责任评测清单评测时到底要披露什么、怎么设计对比实验、怎么避免把 harness 的差异误归因成模型的差异。1. 核心观点速览维度内容论文立场对比 LLM Agent 时如果不披露 harness 配置结果可能失真问题的本质Agent 评测结果 模型能力 × Harness 工程质量 × 任务环境harness 范围提示词模板、工具定义、解析器、执行循环、重试机制、状态管理、上下文压缩、预算控制最容易被误读的点不同 Agent 框架的对比结果常常被当成模型能力对比长程任务影响步骤越多单步差异叠加越明显harness 影响被放大对开发者的要求记录并公开完整 harness 配置不止报告模型名称和分数实操建议用模型 × harness 交叉矩阵做实验给结果附带方差和完整日志2. 为什么 Agent 评测比传统 LLM 评测更依赖工程实现先回到一个基本问题评测一个 LLM Agent 到底在评测什么如果你只用单轮问答测模型那问题很简单输入一句 prompt模型输出答案看匹配度或人工打分。此时影响结果的变量主要是模型自身能力、提示词、解码参数。评测者不需要额外写太多工程代码一个 requests 请求加一个评分函数就够了。但 Agent 评测完全不同。以常见的工具调用任务为例模型先根据用户目标生成一个工具调用意图这个意图经过 harness 的解析之后变成具体的 API 请求环境执行请求后把结果返回给模型模型再根据结果决定下一步动作直到任务结束。这里可以拆出几个典型的失败点模型输出的工具调用格式是否正确被解析。不同模型习惯的输出格式不一样有的偏好 JSON有的偏好 XML有的直接输出纯文本。如果 harness 只针对某一种格式做了严格解析另一个模型的正确输出反而可能被丢弃。模型是否能收到完整、准确的环境反馈。工具执行结果可能很长比如终端输出几百行harness 需要决定截断长度、保留哪些字段、按什么格式回填给模型。模型失败后有没有重试机会。调用工具时参数类型写错harness 是把错误信息返回给模型让它自己修正还是直接判定任务失败。模型能不能在长流程中维护任务状态。很多 Agent 任务不是一步完成的模型需要知道“我已经做到了哪一步”如果 harness 不维护状态或没有提供足够的履历信息模型很快就会丢失上下文。传统评测里这些环节要么不存在要么被简单封装在评测框架中影响很小。但 Agent 评测里这些环节会直接决定任务成功还是失败。更关键的是不同团队在研究同一个 Agent 任务时往往会用不同的 harness。有些团队会自己实现一套工具调用循环有些团队直接用现成框架有些团队会在框架上做大量二次开发。大家最后报告的都是“XX 模型在 XX benchmark 上得分 XX”但背后的实现差异可能非常大。这就是论文标题里那句 “Without Disclosing the Harness” 想点破的问题对比结果却没有披露跑出这个结果的完整工程上下文。3. 拆解 Agent Harness它到底包含什么Harness 不是一个独立的新概念。把它理解为“把 LLM 接到任务环境上的所有工程代码”会更容易看清楚边界。一个完整的 Agent Harness 至少包含下面这些组件。3.1 任务提示词与状态管理模型第一次进入任务时会收到一段系统提示词和任务描述。这段文本是否清晰、是否提供了足够的任务背景、是否包含工具使用说明直接影响模型后续行为。同一个模型系统提示词写得好一点和差一点任务成功率可能拉开很大差距。状态管理则更进一步。长程任务里模型通常无法一次性看到全部历史harness 需要用消息列表、摘要、结构化记忆等方式把任务当前进度反馈给模型。有的 harness 只是简单拼接历史消息有的则会定期让模型总结再控制上下文列表长度。这两种策略会导致模型在任务后半段的“记忆力”完全不一样。3.2 工具调用循环与解析器工具调用是 Agent 任务的核心动作。模型输出一段文本后harness 要判断这段文本是不是一个工具调用如果是就解析出工具名、参数、目标然后把请求发到执行环境。这个环节看起来不复杂但细节极多。比如模型输出内容中混有解释性文本和工具调用标记harness 能否正确提取工具调用部分。参数值是字符串、数字、数组还是嵌套对象类型不匹配时是否需要强制转换。工具不存在时是直接报错还是提示模型从可用工具列表里重新选择。模型一次输出多个工具调用时是顺序执行、并行执行还是只执行第一个。如果 harness 的解析器只针对一个模型的常见输出格式做过优化那评测另一个模型时极有可能出现误判。这个误判会被记录为“模型调用工具失败”但真实原因其实是 harness 解析不够鲁棒。3.3 重试与错误恢复策略Agent 在执行任务过程中一定会出错。模型给出的参数不对、工具超时、API 返回异常、环境状态与预期不符这些错误有的是模型导致的有的是环境导致的有的是 harness 导致的。不同 harness 的错误处理逻辑差异很大出现一次错误后直接终止任务算失败。出现错误后把错误信息返回给模型让它重新尝试。设置最大重试次数超过次数才终止。对不同类型的错误做分级处理例如参数错误自动重写环境超时直接跳过。如果一个评测任务错误率较高那么重试策略的不同会直接影响最终成功率。评测结果差异可能不是模型能力差异而是“允许模型犯多少次错”的差异。3.4 上下文与预算控制Agent 任务里模型需要调用工具才能完成目标但模型可利用的上下文窗口是有限的。随着任务推进历史消息会越来越长直到触达上下文上限。Harness 的上下文管理策略包括直接裁剪最早的消息保留最近消息。把历史消息交给模型生成摘要。用向量检索方式提取与当前目标最相关的历史片段。允许模型主动结束任务并输出最终答案。同一个模型在上下文管理策略不同的 harness 里可能表现截然不同。长程任务尤其明显因为任务越长模型越需要依赖 harness 对重要信息的保留能力。3.5 Harness 核心组件小结组件主要作用对评测结果的影响系统提示词与任务描述定义任务目标和行为约束影响任务理解、工具使用倾向工具定义与 Schema告诉模型有哪些工具可用、参数要求是什么影响工具选择准确率、参数生成正确率工具调用解析器从模型输出中提取并解析工具调用不同模型适应度可能完全不同执行循环与错误处理决定失败后是否重试、如何反馈错误直接影响最终成功率状态维护与上下文管理决定模型能否感知任务进度和历史长程任务影响尤其明显上下文预算与成本控制限制总调用次数、总 token 消耗影响任务可执行范围和评测成本4. Harness 如何左右对比结果理解 Harness 对对比结果的影响可以先看一个简单的误差累积模型。Agent 任务是多步决策过程每一步都可能失败。假设一个任务需要执行 100 步每一步的成功率是 p那么最终整体成功率大约等于 p 的 100 次方。# 用简单概率模型演示误差累积 # 注意这只是理解误差累积的直觉模型不是论文实验数据 for p in [0.99, 0.98, 0.95, 0.90]: total_success_rate p ** 100 print(f单步可靠率 {p:.2f}100 步后整体成功率约 {total_success_rate:.4f})输出结果单步可靠率 0.99100 步后整体成功率约 0.3660 单步可靠率 0.98100 步后整体成功率约 0.1326 单步可靠率 0.95100 步后整体成功率约 0.0059 单步可靠率 0.90100 步后整体成功率约 0.0000如果两个 harness 的单步可靠率分别是 0.99 和 0.95那么跑同一个 100 步任务整体成功率会从 36.6% 掉到 0.59%差距接近两个数量级。而这个单步可靠率的差异很可能来自工具调用解析器对不同模型输出格式的适配程度来自错误重试策略来自返回结果截断逻辑。它们都算 harness 的一部分。这就解释了论文标题强调的问题当你在两个不同 harness 上跑同一个 Agent benchmark得到的分数差异可能非常大。如果直接把 A 模型在 harness X 上的分数拿去和 B 模型在 harness Y 上的分数比你无法判断结果是模型能力差异还是 harness 工程差异。实际开源社区里也常有类似的讨论同一批模型在不同 Agent 框架里跑同一个任务集排名经常不一致。这不是模型本身不稳定而是每个框架都带了一套自己的 harness它们对提示词组织、工具调用格式、上下文管理、错误恢复都有各自实现。框架不统一评测结果很难直接横向对比。5. 长程智能体评测放大效应更明显论文标题特意强调“长程智能体评测”。为什么长程任务会让 harness 的影响更突出因为短任务里harness 的差异可能被任务随机性掩盖长任务里harness 的差异会通过逐步累积变得不可忽视。长程任务的典型特征有四个。第一步骤数量大。任务目标往往需要通过几十次甚至上百次工具调用才能完成。按上面的误差累积模型单步可靠率差 1% 都可能造成最终成功率的巨大差别。第二上下文长期处于高压状态。模型不可能把所有历史都装进上下文harness 必须决定如何压缩、摘要、检索信息。一个任务进行到后半段模型还记不记得任务最初的目标、已经完成哪些步骤、还有哪些约束条件直接决定了最终能否完成。第三错误恢复更复杂。短任务出错后重试一次往往就能解决。长任务里错误会叠加某一步拿到错误数据后续步骤基于错误数据继续推理并做出决策harness 如果不提供回滚机制错误会被不断放大。第四评测成本更高导致很多实验只跑一次或少数几次。长程任务的 token 消耗大、运行时间长研究团队往往不会做大量重复实验一次成功率的随机波动也可能被误读为模型能力差异。此时如果 harness 本身不稳定结果方差会非常大。因此在长程智能体评测中一个鲁棒的 harness 应该做到帮助模型精确定位当前任务阶段、保留关键历史信息、在错误发生后提供可恢复路径、控制上下文长度不失控、对每次运行保留完整轨迹以便复盘。这些都不是模型能力但会深刻影响模型能力能否被真实地体现出来。6. 负责任评测一组必须披露的 Harness 信息论文的核心诉求不是“不要对比”而是“对比之前先披露 harness”。把这句话转成工程行动就是任何 Agent 评测结果都应该附带一份 harness 配置说明。这样其他团队才能判断分数是否可比、是否需要在相同条件下复现。一份负责任的 Agent 评测报告至少需要披露下面这些信息。6.1 模型侧配置模型名称和具体版本例如某个模型的具体 checkpoint 或 API 版本。解码参数temperature、top_p、max_tokens、seed 是否固定。是否有特殊系统提示词或角色设定。是否启用了结构化输出、JSON 输出约束等功能。6.2 Harness 核心实现工具 Schema 由谁编写人工编写还是使用模型生成。工具调用解析方式基于正则、基于 JSON 解析、基于特殊 token 解析。模型输出中夹杂普通文本时如何提取工具调用。一次输出多个工具调用时的处理策略。工具调用出错时的反馈格式和重试次数上限。是否允许任务失败后整体重跑重跑多少次。6.3 上下文与状态管理系统提示词的完整内容。是否使用摘要机制摘要由谁生成、多久生成一次。历史记录如何处理裁剪、摘要、向量检索还是三者结合。最大上下文长度设置。任务状态是否被持久化保存中途崩溃能否恢复。6.4 统计口径同一任务集跑了多少遍。报告的是平均值、中位数还是最佳值。是否报告了方差或置信区间。任务成功判定的标准由谁定义是否有自动评分脚本。是否有失败任务的人工复核。一个简单的方式是在每次评测前先写好一份类似下面的 JSON 配置记录。它既是你实验的复现依据也是你和其他团队沟通的基础。{ experiment: demo-agent-benchmark, model_config: { model_name: your-model-name, temperature: 0.0, max_tokens: 4096 }, harness_config: { system_prompt: 请复现实验记录中的完整系统提示词或附文件路径, tool_schema_source: manual-or-generated, tool_call_parser: json-mode-or-regex-or-special-token, max_retry_per_step: 3, enable_summary: true, summary_interval_steps: 10, history_strategy: truncate-or-summary-or-vector-retrieval, max_context_tokens: 128000 }, eval_config: { task_count: 100, repeats_per_task: 5, timeout_seconds: 60, success_metric: task-completion-rate } }注意上面这个 JSON 只是记录模板模型名称、任务名和具体数值需要按实际实验填写。真正的问题不在于你是否用了这个格式而在于你是否能够完整回答模板里每一个字段。7. 从论文到实践设计你自己的 Agent 对比实验如果你正在做 Agent 评测接下来这段是作业级别的参考。无论是写技术报告还是要给自己的项目选型建议按下面的方法设计实验。7.1 先建立模型 × Harness 的交叉矩阵不要只在同一个模型上换 harness也不要在同一个 harness 上换模型。要一次把两个维度同时变起来至少是“2 个模型 × 2 个 harness”的 4 组实验。这样才能看到模型差异和 harness 差异分别在多大程度上影响结果。# 伪代码设计一个模型 × Harness 的交叉评测 # 真实项目中需要替换成你自己的任务加载和评分逻辑 models [model-a, model-b] harnesses [harness-x, harness-y] tasks load_task_set(benchmark_tasks.jsonl) results {} for model in models: for harness in harnesses: key f{model}{harness} all_scores [] for repeat in range(5): # 每个组合跑 5 次 runner create_runner(modelmodel, harnessharness) scores runner.run(tasks) all_scores.append(scores) results[key] summarize(all_scores) # 计算均值、方差 print(f{key}: {results[key]})跑完后的结果分析应该重点关注两个问题。第一固定 harness、换模型时模型排名是否稳定。如果稳定说明这个 harness 有能力区分模型能力差异如果不稳定说明你需要检查任务集是否太短或方差太大。第二固定模型、换 harness 时分数是否出现明显跳变。如果同一个模型在两个 harness 下分数差距过大说明这个模型对 harness 的敏感度很高。此时单点跑出来的分数没有代表性。7.2 保留完整的轨迹日志只看一个最终成功率是不够的。Agent 评测失败后的排查高度依赖过程日志。建议每次运行都保存一份 JSONL 格式轨迹文件记录每一轮的系统提示词、模型输出、解析结果、工具调用、工具返回值、错误信息和最终判定。推荐使用下面这种目录结构组织评测项目agent-eval/ ├── configs/ # 每个实验的 JSON 配置 │ ├── exp-model-a-harness-x.json │ └── exp-model-b-harness-x.json ├── harnesses/ # 各版本 harness 实现 ├── tasks/ # 任务集文件 ├── logs/ # 每次运行留下的 JSONL 完整轨迹 │ └── 2025-01-01_model-a_harness-x_run-1.jsonl ├── results/ # 汇总分数表 └── scripts/ # 评测启动与评分脚本目录结构本身不限制用哪种语言或框架核心目标是任何一次评测结果都可以追溯到完整的运行配置和执行轨迹。这样如果某一天结果被质疑你可以快速定位是模型输出问题还是 harness 解析问题还是任务集本身有歧义。7.3 先跑小任务集验证稳定性在正式烧钱跑长程评测之前先抽 10 到 20 个任务组成小集合把程序跑通看重复实验结果是否稳定。如果小集合上同一个配置跑 3 次分数方差都大得离谱那么换大集合只会更不稳定先调 harness 比先换模型更迫切。8. 评测结果归因分清楚是模型差还是 Harness 差跨框架对比 Agent 时最常见的错误是把结果差异直接归因到模型。如果严格按交叉矩阵实验做归因可以按下面几条规则梳理。第一如果模型 A 在 harness X 和 harness Y 上都稳定优于模型 B才能说模型 A 的综合能力强。此时结论对 harness 不敏感可信度较高。第二如果模型 A 在 harness X 上优于模型 B但在 harness Y 上相反说明结论对 harness 高度敏感。这种情况很难说谁更强只能描述为“在特定 harness 配置下A 的表现如何”。第三如果同一模型在同一 harness 上重复跑多次分数波动本身就很大那先别急着比较模型。任何差异都可能落在噪声区间内。解决方法是增加重复次数或者修改评测指标让任务判定标准更稳定。第四如果某个模型的失败日志集中在工具调用解析错误上不要急着给模型下结论。去检查 harness 的解析器是否对该模型的输出格式适配良好把正常的工具调用误判成失败也是常见原因。第五如果某个模型的任务中途失败集中在同一类型步骤那就要区分是模型规划问题还是 harness 缺失某项提示。可以把该步骤的工具返回结果、错误信息和模型下一步输出单独抽出来复盘。真实原因往往藏在日志里而不是藏在分数表里。为了帮组复盘可以考虑把一次完整的失败轨迹记录下来格式可以简化为下面的 CSV 结构step,type,content,success 1,user,任务目标...,true 2,assistant,我需要先查询库存,true 3,tool_call,search_inventory({sku: A123}),true 4,tool_result,{status: ok, count: 0},true 5,assistant,库存不足需要换一个供应商,true 6,tool_call,list_suppliers({region: east}),true 7,tool_result,{status: error, message: region field required},false ...这样每一帧都能单独查看哪些步骤是模型规划导致哪些是 harness 解析导致一目了然。9. 需要避免的评测误区常见做法潜在风险正确姿势仅报告模型名和最终分数无法复现无法判断差异来源附完整 harness 配置和任务集版本用不同框架跑不同模型直接对比结果把 harness 差异误当成模型差异用交叉矩阵多个 harness 上相互验证只跑一次分数出现随机波动偶然性被误读为能力差异多次运行报告均值和方差失败后反复重试直到成功只记录最终结果掩盖了模型真实单次成功率把重试策略写进配置不要默认“无限重试”只报告成功率不保存轨迹无法定位失败原因保存完整 JSONL 轨迹支持事后复盘任务集不固定中途随意修改不同版本任务集之间不可比给任务集加版本号改动就换版本忽略模型输出格式差异某些模型因为格式不匹配被误判检查解析器对不同模型的适配程度10. 总结与建议这篇论文最值得记住的一点不是“harness 越复杂越好”而是Agent 评测的结果必须放在工程上下文中解释。Agent 框架、提示词、解析器、上下文管理、重试策略、错误恢复这些 harness 组件和模型本身一样都会对最终分数产生决定性影响。尤其是在长程智能体评测中harness 的差异会随着任务步骤增加而逐步放大。对普通开发者来说这意味着几件事第一不要只看一张 leaderboard 就去评判模型。先看这份榜单背后用的是什么任务集、什么 agent 框架、什么工具定义。评测框架不同结果含义可能完全不同。第二用 Agent 框架时需要意识到所有现成框架本身就自带一套 harness。你在框架上改一行系统提示词或者在设置里调整最大重试次数本质上都在改变评测条件。第三如果要发布模型对比结果请把论文标题当成一份格式规范披露 harness 配置、报告重复运行统计、附上完整运行轨迹。否则别人很难判断你的结论到底是模型能力的体现还是 harness 实现细节的体现。建议收藏这份披露清单在你下一次跑 Agent benchmark 或写技术报告时逐项对比检查。只要能在评测结论前多写一段“本次实测的 harness 配置如下”这篇论文提出的大部分问题就已经避开了。
返回列表