智能体评测分数背后:harness 如何左右排行榜与模型选型 如果你最近在选 Agent 模型多半做过这样一件事打开某个智能体排行榜把靠前的几个模型记下来然后申请 API跑到自己那几条业务任务里试一遍。结果经常很尴尬——排行榜上领先好几个点的模型在真实场景里表现平平反而是排名略靠后的某个模型在某些任务上更顺手。问题不一定出在模型身上更可能出在评测本身。业内越来越多人意识到一个判断智能体评测分数反映的是“模型 评测 harness”这个组合的表现上限而不只是模型本身的能力。评分框架、工具定义、环境搭建、判定规则这些评测侧的变量对最终分数的影响有时比模型参数还大。这篇文章不打算教你怎么刷榜而是想讲清楚三件事评测 harness 到底是什么它从哪些环节影响分数以及我们该如何理性使用智能体排行榜。如果你正在做 Agent 选型或者想复现某个榜单结果却总是对不上这篇文章应该能帮你少走不少弯路。1. 为什么排行榜分数越来越“对不上号”几年前的大模型评测大多是“静态考题”模式。MMLU、GPQA、HumanEval 这一类基准本质上是给模型一道题模型输出一个答案评分器把它和标准答案比对完事。评测变量很少模型权重、温度参数、提示词。只要这三点固定分数基本可复现横向对比也相对公平。智能体评测完全不是这样。Agent 任务里模型面对的是一个“动态环境”它要先理解用户指令再决定调用哪个工具、传什么参数然后观察工具返回结果决定下一步动作直到任务完成。整个过程通常持续好几轮模型还要处理环境反馈中的异常、半结构化数据、甚至前后矛盾的信息。正是因为这种动态性评测条件本身变成了评测的一部分。同一个模型在不同评测框架下走完全程最后可能得到完全不同的分数。这不是“有人作弊”而是智能体评测的基础特性你测的是模型在某个环境中的行为而不是模型在真空中的“智力”。于是出现了人们常说的“对不上号”模型在某个榜单排第一但你自己的任务上表现一般。两个榜单都评测 Agent 能力同一个模型的名次却差很多。社区有人用开源框架复现了官方分数也有人复现不出来双方都觉得对方环境有问题。这些问题几乎都可以从 harness 的差异上找到解释。甚至可以说智能体评测目前最不透明、也最值得关注的部分不是模型而是 harness。2. 评测 harness 到底是什么先统一概念在智能体评测语境里harness 可以理解为让模型接入任务环境并完成打分的一整套“脚手架”。它不是一个单一组件而是所有评测侧逻辑的集合。平时大家说的“评测框架”“跑评测的代码”“Agent 环境”大多数时候指的就是 harness。一个完整的智能体评测 harness至少包含以下几层组成作用典型问题输入组装把任务转成模型请求包括 system prompt、few-shot 示例、用户指令prompt 写法不同模型行为会明显变化工具接入定义模型可调用的工具、API 集合、参数 schema工具数量、命名、描述都会影响决策执行环境运行代码隔离环境、网络策略、依赖包、mock 服务环境缺依赖或网络受限会导致动作失败观测循环管理多轮对话、步数上限、重试机制、日志记录步数不够、无重试会直接拉低任务完成率评分器判断任务是否成功可能是关键词匹配、执行结果校验或 LLM 裁判判定标准不统一会让结果不可比用一个类比来理解智能体评测像“考驾照”。模型是考生harness 是考试车、考场路线和考官。考生本身技术过硬但如果考试车离合不好使、考场路线坑洼不平、考官判定又严格结果可能很不理想。反过来一个普通水平的考生在性能稳定的考试车、熟悉的路线上也可能拿到不错的成绩。排行榜公布的是“考生综合成绩”但很少有人告诉你考试车是什么、考官怎么打分。所以当你看到两个模型之间相差几个点时先别急着得出“A 模型比 B 模型强”的结论因为这个差距很可能来自 harness 的选择。那么harness 具体是怎么把分数推高或拉低的下面拆开看。3. harness 在哪里“偷分”与“赠分”3.1 输入组装prompt 写法改变能力表现同一个模型系统提示词写得是否清晰执行效果可以差很远。好的评测 prompt 会明确告诉模型你要按步骤来、不要编造工具返回、遇到错误要修正参数重试。粗糙的 prompt 则可能只有一句“你是智能助手”。这不算什么秘密但它直接影响基准分数的“水分”。我们经常看到某些公开榜单只给出“我们用了某个 prompt 模板”却不公布模板细节。一旦模板变更模型名次可能重排。所以在判断一个榜单是否可信时第一个应该看的就是 prompt 是否完整公开。3.2 工具定义数量和粒度的双重影响模型需要从工具列表里选出正确的那个。工具数量越少选择越容易工具说明越清晰误调用越少。这里的变量包括工具数量给模型 10 个工具和 500 个工具决策难度完全不同。工具命名与描述get_weather和get_weather_by_city_and_date的语义清晰度不同。参数 schema是否强制校验是否自动补全。工具返回格式结构化 JSON 还是冗长文本截断策略如何。一个很常见的现象是某个模型在官方榜单上工具调用准确率很高换到第三方框架后因为工具 schema 格式不兼容或描述不一致准确率明显下降。此时模型权重并没有变变的是 harness 对工具层的组织方式。3.3 执行环境依赖和网络决定任务能不能跑通对于 SWE-bench 这类代码修复评测模型需要修改仓库代码然后让测试通过。测试能否跑起来取决于环境里有没有正确的依赖版本、网络是否可以下载包、测试命令是否和仓库结构匹配。一个真正正确的代码补丁可能因为环境缺依赖而失败一个补丁本身质量一般但在宽松环境下也可能侥幸通过。对不同智能体任务执行环境还包含 mock 服务的真实性。如果 mocked 工具返回的数据结构和真实系统不一致模型会被“带偏”。评测环境离真实系统越远榜单分数的参考价值就越低。3.4 观测与容错步数上限和重试机制这是最容易被忽略的变量也是对分数影响非常大的变量。最大步数设成 3 步和 10 步完成率差异巨大。有的智能体任务天然需要 5 次以上工具调用步数上限设小了能力再强也跑不完。是否允许重试工具调用偶发失败、模型传参偶发错误在真实系统里很常见。如果评测框架不重试这些偶发问题会被直接计入失败。工具结果截断长结果被截断后模型可能丢失关键字段从而做出错误判断。上下文管理多轮对话塞满历史后是否压缩、是否丢弃旧消息都影响后续决策。这些“工程细节”并不属于模型能力但它们叠加起来可以轻松制造出 10 个点以上的分数差距。3.5 评分器判定标准决定“成功”定义同一段 Agent 执行记录用不同评分器可能得出完全相反的结论。字符串匹配类评分器要求输出里包含某些关键词如果模型表达正确但措辞不同就会被判失败。执行结果校验类评分器则看数据库或文件系统里是否留下正确状态相对客观但对环境一致性要求极高。LLM 裁判类评分器能理解自然语言但它本身又是一个带偏见的模型judge 的 prompt、温度、甚至模型版本都会影响打分。更隐蔽的是 LLM 裁判的随机性。同一个 judge 模型跑两遍可能给出不同的分数。如果榜单不做多轮采样取均值这个随机性就会被当成模型能力的差异。3.6 算力与并发资源评测要跑大量任务需要 GPU 或 API 额度。如果资源不够评测方可能会降低并发、缩短上下文、限制最大生成长度。而 Agent 任务往往需要长输出一旦最大 token 被截断最后一步动作可能没输出完任务直接失败。这种问题是资源约束导致的而不是模型能力导致的但它照样进入分数统计。一句话总结harness 的每个环节都在影响分数而这些变量全部折叠进了一个看似简单的数字里。只要榜单没有完整公开 harness 配置我们就不可能从分数上准确推断模型能力。4. 从 SWE-bench 与 Codex 看 harness 的行业风向“评测 harness”这个词在 Agent 圈子流行起来和几件公开事件有关。SWE-bench 是很典型的例子。它要求模型阅读真实 GitHub issue修改仓库代码最后通过单元测试。这个基准刚出来时很多团队发现模型在 SWE-bench 上的分数严重依赖“测试环境搭建”这一步。仓库历史依赖版本、测试命令、甚至基准代码库的 commit 版本都会影响结果。官方后来也不得不持续更新环境修复脚本社区里也经常出现“换一台机器分数就变了”的讨论。另一个被广泛讨论的事件是 OpenAI 在 Codex 系列中公开了评测执行的代码和配置。从公开资料看要在 SWE-bench Verified 上复现官方分数需要相当精细的环境控制包括安装测试依赖、设置 CI 脚本、处理仓库特定命令。官方把这些配置打包进评测框架并开放出来后社区第一次直观感受到原来一个高分成绩背后有这么多的“非模型”环节在起作用。也是从那个时候开始“harness engineering”这个词慢慢出现。很多 Agent 团队开始设立专门的评测工程角色负责设计评测任务、维护执行环境、制定打分规则。换句话说评测已经从“跑个 benchmark 算个准确率”进化成了正经的工程体系。在中文社区最近也出现不少类似“DeepSeek harness 官网”“DeepSeek harness 安装”的搜索。这个词目前并没有一个统一的官方指向更多人把它理解为“用某个评测任务框架去跑 DeepSeek 系列模型”。大家搜索这些关键词往往是想复现某个榜单成绩或者想用统一框架对比手头模型。这恰好说明可复现评测已经成了 Agent 开发者的刚需而 harness 是绕不开的入口。如果你所在团队正在做 Agent 应用现在就应该把 harness 当成一等公民对待。它不是选型之后才考虑的“评测工具”而是决定你能否真正比较模型能力的底层基础设施。5. 最小 harness 代码拆解模型只是输出框架决定成败为了看清 harness 到底做了什么我们写一个最小可运行的智能体评测骨架。这个示例不依赖复杂的评测平台只演示最核心的循环逻辑。5.1 工具定义与执行函数# minimal_harness.py 一个最小可运行的智能体评测骨架。 思路模型只能通过工具观察和改变环境harness 负责执行工具、 管理对话、控制步数并最终把结果交给评分器。 import json from openai import OpenAI client OpenAI( base_urlhttps://your-model-endpoint.example.com/v1, api_keyyour-api-key ) SYSTEM_PROMPT ( 你是智能体评测任务中的助手。 你必须使用提供的工具完成任务不要编造工具返回结果。 如果任务已完成用自然语言总结最终答案。 ) TOOLS [ { type: function, function: { name: get_weather, description: 查询指定城市的当前天气, parameters: { type: object, properties: { city: {type: string, description: 城市名如 北京} }, required: [city] } } }, { type: function, function: { name: book_ticket, description: 预订机票返回订单号, parameters: { type: object, properties: { flight_no: {type: string}, date: {type: string} }, required: [flight_no, date] } } } ] def execute_tool(name: str, arguments: str): 真实评测中这里会调用业务系统或 mock 服务。 底线要求返回结构稳定不抛异常。 args json.loads(arguments) if name get_weather: return json.dumps( {city: args[city], weather: 晴, temperature: 25}, ensure_asciiFalse ) if name book_ticket: return json.dumps( {order_id: TKT20250001, status: confirmed}, ensure_asciiFalse ) return json.dumps({error: funknown tool: {name}}) def run_episode(task: str, max_steps: int 5) - str: messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: task} ] for step in range(max_steps): resp client.chat.completions.create( modelyour-agent-model, messagesmessages, toolsTOOLS, temperature0.0 ) msg resp.choices[0].message if msg.tool_calls: # 模型只是声明“我想调用工具”真正执行工具的是 harness messages.append(msg) for tc in msg.tool_calls: tool_result execute_tool(tc.function.name, tc.function.arguments) messages.append({ role: tool, tool_call_id: tc.id, name: tc.function.name, content: tool_result }) else: # 模型认为任务已完成输出最终答案 return msg.content or return FAIL_MAX_STEPS if __name__ __main__: task 想明天从北京飞上海请帮我订一张机票并告诉我是否需要带伞。 print(run_episode(task, max_steps5))这段代码里模型做的工作只有一件事根据当前对话历史输出“下一步动作”。至于工具调用是否真的执行、返回结果如何进入模型上下文、步数限制是多少、任务何时结束全部由 harness 控制。这也解释了为什么同一个模型会产生不同结果只要更换SYSTEM_PROMPT、TOOLS定义、max_steps或execute_tool里的 mock 返回模型后续决策就会改变。分数自然跟着变。5.2 评测入口脚本# eval_runner.py from minimal_harness import run_episode TASKS [ { id: task_001, task: 查询北京的天气并预订明天北京到上海的机票, expected: [TKT, 晴] }, { id: task_002, task: 帮我订一张后天上海到深圳的机票, expected: [TKT] }, ] def evaluate(): passed 0 for item in TASKS: raw_output run_episode(item[task], max_steps5) hit all(key in raw_output for key in item[expected]) print(f{item[id]}: {PASS if hit else FAIL} - {raw_output}) passed int(hit) print(fpass1: {passed / len(TASKS):.2%}) if __name__ __main__: evaluate()这里的评分方式非常简单检查模型最终输出是否包含expected里的关键词。只要模型换一种措辞比如把“TKT20250001”写成“订单号 TKT20250001”只要包含关键词就算通过但如果它说“已为您预订成功订单号是 TK2025 开头的 8 位数字”就可能命中失败。一个看似简单的评分器差异就已经足以让结果不可比。真实的评测系统只会更复杂不会有更简单。6. 同一模型两种配置看看 harness 变量有多大在真实评测中harness 不是一段代码而是一组配置组合。我们继续沿用上面的例子给出两种配置分别代表“粗糙评测”和“精细评测”。模型权重完全不变只看 harness 变量带来的影响。6.1 粗糙配置{ system_prompt: 你是一个智能助手。, tools: [get_weather, book_ticket], max_steps: 3, enable_retry: false, observation_truncate: 2000, judge: { type: exact_match, reference_keys: [order_id] } }这个配置里模型只拿到一句极简的系统提示最多执行 3 步工具调用失败不重试工具返回超过 2000 字会被截断最后使用关键词匹配判定结果。6.2 精细配置{ system_prompt: 你是智能体任务执行器。每次只输出一个工具调用。若工具返回错误根据错误信息修正参数并重试。工具结果必须按原始字段完整保留不要截断。任务完成后用简洁列表输出最终结果。, tools: [ { name: get_weather, description: 根据城市精确查询实时天气参数 city 必须为中文全称。, parameters: [city] }, { name: book_ticket, description: 预订机票。调用前必须先用 search_flight 确认航班存在。, parameters: [flight_no, date] } ], max_steps: 10, enable_retry: true, retry_times: 2, observation_truncate: 8000, judge: { type: llm_as_judge, judge_model: judge-model-name, rubric: 任务成功需要满足订单号真实存在、日期正确、回答中包含关键信息。 } }精细配置给了模型更长的执行空间、更明确的行为约束、更充足的工具结果窗口并且把最终的“一句一判”改成了 LLM 裁判。6.3 同一个模型在两种配置下的预期差异维度粗糙配置精细配置对分数的影响max_steps310任务没跑完就强制结束直接拉低完成率retry关闭开启一次工具偶发失败就会导致整轮失败observation_truncate20008000长工具结果被截断模型缺失关键字段judge关键词匹配LLM 裁判模型表达正确但措辞不同时被判失败核心结论是如果你在粗糙配置上跑一个模型在精细配置上跑另一个模型然后把两个分数放在同一个榜单里排大小那你得到的“榜单”本质上没有任何可比性。这不是模型能力排序而是 harness 配置排序。所以在做任何模型对比之前先固定 harness再谈模型。7. 如何正确看待智能体排行榜既然 harness 影响这么大是不是说明排行榜完全没有用当然不是。排行榜仍然有参考价值关键是你得知道怎么看。第一看榜单先看 harness 是否完整公开。一个负责任的评测方至少应该公开任务集合、系统提示词模板、工具定义、环境构建脚本、评分器代码。如果这些都不公开那个数字只能当作“宣传指标”不能当作“技术结论”。第二把排行榜当初筛而不是终判。排行榜可以帮你快速圈出几个候选模型但最终选型必须用你自己的任务、自己的工具定义、自己的评分标准跑一遍。只有这样才能知道模型在你的业务环境里到底行不行。第三关注任务分布不要只看总分。有的榜单偏重网页浏览操作有的偏重 API 工具调用有的偏重代码仓库修改。如果你的业务是日常客服类工具调用那么一个全是网页操作任务的榜单参考价值就有限。拆开看分项分数比看排名更有用。第四警惕“评测集污染”与“过度拟合榜单”。如果一个模型专门针对某个公开榜单的题型做了训练它的分数高于其他模型并不代表通用能力强。这种情况在静态基准上已经出现过在智能体基准上同样存在。第五理解分数的不可复现性。即使榜单环境完整公开你在自己机器上复现时也可能因为 GPU 版本、依赖库、API 服务波动等因素拿到不同结果。差几分不代表别人造假更可能只是环境细节不同。一句话看待智能体排行榜的正确姿势是“审慎”。你可以从中获得选型灵感但不能把排名当成模型能力的绝对度量。8. 建立自己的评测基线团队工程建议如果你所在团队正在做 Agent 应用与其纠结第三方排行榜不如尽早建立自己的评测基线。这是我认为目前 Agent 工程落地里最值得投入的一环。8.1 把 harness 代码和配置纳入版本管理不要把评测脚本放在某个人的本地目录里。harness 代码、prompt 模板、工具 schema、环境镜像、评分器全部纳入 Git 管理并打上版本号。每次模型升级或评测逻辑调整都要能回溯到当时用的是哪套配置。agent-eval/ ├── configs/ │ ├── harness_v1.json │ └── harness_v2.json ├── tasks/ │ ├── task_001.json │ └── task_002.json ├── src/ │ ├── harness.py │ ├── tools.py │ └── judge.py └── logs/ └── episodes/8.2 自建 50 到 100 条内部评测样本第三方榜单覆盖场景有限自建样本才能贴近业务。样本来源可以是真实用户问题、客服对话、工单描述等。每条样本要包含任务描述、预期结果、允许的工具范围、评分标准。与其追求数量不如先保证 50 条高质量样本覆盖典型场景。之后再逐步扩充。8.3 评分标准分层设计我建议按三层设计评分器不要只用一种确定性校验例如数据库表里是否生成了正确订单、文件系统里是否出现预期文件。这种判断最客观。约束校验例如输出是否包含关键字段、工具调用是否使用了合法参数。比纯关键词匹配稍灵活。LLM 裁判用于开放式任务判断但要固定 judge 模型和温度允许“通过/失败/存疑”三态。存疑案例人工复核。8.4 记录完整执行轨迹而不仅仅是分数评分前必须保存每个 episode 的完整消息日志、工具调用参数、工具返回结果、步数消耗。一旦分数不符合预期第一件事不是重跑而是回放轨迹。没有轨迹的评测分数等于没有证据的结论。8.5 把评测接入 CI但注意成本和稳定性评测可以作为 CI 阶段的一部分在模型候选版本更新时自动运行。但 Agent 评测耗时较长且依赖外部 API稳定性可能不足。更务实的做法是白天跑人工干预的详细评测晚上跑自动化冒烟评测两者分开。冒烟评测只覆盖最核心的 10 条任务保证主流程不回归。8.6 把“评测工程”当成正式岗位或专项职责Harness engineering 正在成为 Agent 团队的必要能力。它不是临时找个人“跑跑测试”而是需要有专人维护任务集、环境、评分逻辑和回归报告。如果团队没有专职评测岗位至少应指定一人作为评测基线负责人防止“人人都能改评测改了没人知道”的局面。9. 常见误区与排查思路在实际操作中大家最常遇到的问题就是“复现分数对不上”。下面整理几个高频问题及排查思路。问题现象可能原因排查方式解决方案官方高分但本地复现分数低harness 配置不同或环境不一致对比官方公布的评测配置与本地配置统一 prompt、工具集、重试策略、评分器任务在 max_steps 内没完成步数上限太小或工具调用链过长查看 episode 日志中的工具调用轨迹增大步数或优化 prompt 让模型减少无用调用工具结果被截断导致后续失败observation_truncate 设置太小检查消息长度和截断位置增大截断长度或让工具返回更精简的字段同一份输出在不同评分器下结果不同judge 标准不统一或 LLM 裁判有随机性固定 judge 模型与温度多次采样使用确定性评分流程必要时人工复核API 调用频繁失败导致任务失败评测环境网络限制或限流检查错误日志中的 HTTP 状态码增加重试与退避机制多次运行分数波动大评测样本量太小或样本难度不均匀按样本维度查看通过率分布扩充数据集按场景分层采样换一台机器分数就变环境依赖或随机种子不一致固定 Python 版本、依赖版本、随机种子使用相同容器镜像跑评测除了表格里的问题还有几个容易踩的认知误区一个是“排行榜分数差 3 个百分点就说明模型 A 强于模型 B”。在很多智能体榜单上3 个百分点可能只是评测样本量不足带来的统计噪声或者 judge 模型的一次随机波动。要下这个结论至少需要看多轮评测均值和置信区间。另一个是“模型官方发布的分数一定能在任何框架下复现”。官方分数通常伴随官方指定的环境。脱离官方 harness直接在第三方框架里跑分数变化是正常的并不代表模型或框架有问题。还有一个是“换一个 harness 跑出更低分就说明模型不行”。更准确的说法是这个模型当前适配的调用方式在另一套 harness 里没有发挥出来。真正优秀的模型应该具备一定的跨 harness 鲁棒性但任何模型在显著不同的工具 schema 和 prompt 风格下表现都会波动。关键是你要找到适合自己业务的那一套固定配置去横向比较。10. 总结与下一步智能体排行榜上的分数本质上是一个三元组合的结果模型权重、评测 harness、任务数据集。三者共同决定最终数字。作为开发者最需要建立的认知是不要脱离 harness 去比较模型能力也不要面对不一致的复现结果就急着归因于模型。如果你正准备开始 Agent 选型建议按这个顺序行动先完整阅读目标榜单的评测说明确认 harness 是否公开。如果公开下载或复现官方配置在自己的环境里跑通一份基线。然后从业务中整理出 50 条左右内部评测样本固定一套 harness 配置把你关心的两三个模型放进去横向对比。最后把评测代码、配置、日志纳入版本管理让评测成为团队工程的一部分而不是一次性的“看榜选型”。真正值得信任的不是排名而是你能完全复现和理解的评测过程。下一次你再看到某个智能体排行榜时可以先问一句这个分数背后的 harness我看到完整的了吗如果答案是不确定那这个数字就先别当作决策依据。