先说一个很常见的现象:你的团队最近在对比两个模型做 Agent 选型,任务集相同、prompt 写得也差不多,结果 A 模型在甲团队评测里胜出,B 模型在乙团队评测里又反超。两边都觉得自己测得很严谨,但拿出来的报告互相没法说服对方。问题往往不在模型,也不在 prompt,而在于评测 Agent 时,大家默认把“模型能力”当成了唯一变量,却忽略了藏在模型外面的整套运行环境——论文里把它叫作 Harness。
这也是《Stop Comparing LLM Agents Without Disclosing the Harness》这篇论文最有冲击力的地方。它选择了一个很强硬的立场:当你在比较两个 Agent 时,如果不披露各自的 harness,那么你比较的可能根本不是模型本身,而是两套评测环境之间的差异。文章更进一步判断,在长程智能体评测这类多步、交互式任务上,harness 的影响甚至可能超过模型本身。
这篇论文对做 Agent 应用和基础设施的工程师、做模型评测的技术同学、以及需要给团队做模型选型决策的人,都值得认真读一遍。它没有停留在“评测得加小心”这种层面,而是直接把评测拆成一组可披露、可比较的工程参数。读完这篇文章,你会明白 harness 到底由哪些组件构成、为什么长程任务会放大它的影响、怎样设计一个能区分“模型贡献”和“harness 贡献”的评测流程,以及你在复现别人结果失败时应该先检查哪些环节。
1. 为什么一篇“批评评测方法”的论文值得认真读
1.1 Agent 评测本质上是一项基础设施工程
过去做 NLP 模型对比,事情简单得多:给一段输入,让模型生成输出,然后算指标。即使需要考虑 prompt、解码参数、few-shot 示例,变量也相对可控。到了 LLM Agent 阶段,一个评测单元不再是一问一答,而是一整段“感知-决策-行动-观察”的循环:
- 模型需要读取任务;
- 根据环境状态决定调用哪个工具;
- 工具返回结果后再次决策;
- 如果出错,可能需要自我纠正;
- 一直持续到任务结束或者步数耗尽。
在这样的流程里,模型权重只是决策者,真正决定任务能不能完成的,还有工具是否好用、反馈是否及时、错误能否被容忍、上下文是否会被截断、环境是否提供了足够信息。评测 Agent,本质上是在评测一套“模型 + 外围系统”的组合体。如果只报模型名,信息损失非常大。
1.2 论文的核心判断:没有披露 harness 的对比没有意义
论文标题直接用 Stop Comparing 这个词,属于很明确的学术表态。它的核心主张可以概括为三句话:
- Agent 评测成绩是“模型 + harness”共同作用的结果;
- 现有大量 Agent 对比只报告模型名和基准名,不报告 harness 细节;
- 在没有披露 harness 的情况下,模型之间的分数差异无法被正确归因。
论文进一步强调,长程智能体评测中 harness 的影响会被放大。原因是任务越长,模型需要与环境交互的次数越多,外围系统每多引入一点偏差,最终结果就会被累积放大。这个判断和很多人的工程体感是一致的:有时候换一个更好的模型,不如把工具调用失败后的重试策略改一版。
1.3 谁最需要关注这个问题
如果你属于下面几类人,这篇论文对你不是纯学术讨论:
- 做 Agent 应用开发的工程师:你在评测 prompt 模板、工具 schema、重试策略时,其实就是在调 harness;
- 做大模型评测的同学:你的榜单分数如果不能复现,大概率不是模型变化,而是 harness 没有对齐;
- 负责技术选型的技术 Leader:你看到的“模型 A 比模型 B 强 X%”,可能只是某一个 harness 下的结论。
认清这一点不是让你不信任评测,而是让你学会在阅读报告时多问一句:它是在比模型,还是在比模型外面那层壳?
2. Harness 到底是什么:模型外面的那层“运行外壳”
2.1 从赛车类比理解 harness
Harness 这个词在英文里有“马具、掌控装置”的意思,在软件工程中常被译为“测试夹具”或“运行外壳”。在 Agent 评测语境里,它可以理解为一套完整评测所需的全部配件。
一个更贴近工程师直觉的类比是赛车。不同赛车评测如果只公布发动机型号,却不公布轮胎、悬挂、空气动力学套件、电子控制系统和赛道天气,那评测结果基本没法解释。模型权重相当于发动机,harness 就是发动机之外的一切:底盘怎么调、进站策略是什么、车手对轮胎温度的管理方式是什么。同一个发动机,放进不同的车架里,圈速可能完全不一样。
换成 Agent 领域:同一个模型,配上不同的工具调用解析器、不同的最大步数、不同的错误重试策略、不同的回退机制,最终能否完成任务会有肉眼可见的差别。
2.2 Harness 与 Agent 框架不是同一个概念
这里需要澄清一个常见的混淆:很多人会把 Agent 框架(如 LangChain、AutoGPT 这类系统)等同于 harness。实际上二者不完全相同。
Agent 框架更偏重“如何组装 Agent 系统”:模型怎么被调用、工具怎么被注册、记忆怎么管理。而评测 harness 在框架之上增加了“如何运行一次评测、如何限制实验变量、如何判定成功、如何记录过程”的约束。换句话说,评测 harness 是包围在 Agent 系统外面的可控实验装置。
容易混淆的还有提示词。很多人把提示词当成“模型的一部分”,但从论文视角看,提示词其实是 harness 的组成部分。同一个模型,换一套系统提示词,表现可能判若两人。因此,当你调整了系统提示词后说“这个模型更强了”,严格来说你是在说“这个模型在某 harness 版本下更强了”。
2.3 Harness 分层拆解:一张表看清全部构件
一套典型的长程智能体评测 harness 可以拆成以下几层:
| 层级 | 典型组件 | 说明 |
|---|---|---|
| 环境层 | 工具服务、沙箱、任务仿真器、浏览器/代码执行环境 | 决定 Agent 能“看到”和“操作”什么 |
| 动作层 | 工具 schema、JSON 解析器、动作空间约束 | 决定模型输出能不能被正确转成可执行动作 |
| 策略层 | 最大步数、重试策略、回退机制、反思触发条件 | 决定 Agent 容错和纠错能力 |
| 反馈层 | 观察结果截断、中间奖励、人类反馈或程序化反馈 | 决定模型从环境中获得多少信息 |
| 评测层 | 成功判定函数、指标聚合方式、终止条件 | 决定任务“是否算成功”的判断标准 |
| 资源层 | 随机种子、并发数、超时时间、模型调用参数 | 决定实验是否可复现 |
这些组件里,任何一个发生改变,都会直接影响最终分数。很多评测报告只会写“模型 A 在 XX 基准上达到 XX%”,但完全不提解析器用的是宽松模式还是严格模式、任务允许几次重试、环境里是否有 oracle 反馈。这些都是被测对象的一部分,不是可以忽略的实现细节。
2.4 从“某某模型 + harness”的热搜看行业需求
最近在技术社区里,“某某模型用什么 harness”“harness 怎么安装”这类检索明显多了。很多开发者已经开始把某个 LLM 和它的 harness 放在一起搜索,潜意识里已经意识到:模型只是一个零件,想让它完成真实任务,还需要给它配备一套能发挥能力的运行外壳。
这种检索行为本身值得玩味。它未必代表某个官方产品已经出现了稳定的“harness 插件”或“桌面版”,而是说明需求侧正在把“评测运行环境”当成一个可以被版本化管理、可以被安装配置的工程产物来对待。从这个角度看,论文讨论的不只是评测规范,也在精准踩中 Agent 工程化落地过程中正在发生的真实变化。
3. 长程智能体评测:为什么 harness 的影响会被放大
3.1 长程任务是什么
长程智能体评测,指的是评测那些需要模型在多个时间步里持续决策、反复与环境交互才能完成的任务。典型场景包括:
- 让 Agent 读取仓库代码、定位 bug、修改并运行测试;
- 让 Agent 在网页上完成多步信息检索和表单操作;
- 让 Agent 操作真实系统环境完成数据整理与配置文件修改。
长程的“程”可以理解为任务必须跨越多少步。单轮问答没有“程”,短工具调用可能只有一两步,长程任务往往需要几十步甚至上百步。随着步数增加,评测结果的方差来源也会从“模型本身懂不懂”扩散到“外围系统是否把它每一步的决策都顺利执行了下去”。
3.2 四个放大机制
长程任务会放大 harness 影响,背后有四个机制:
第一是误差累积。单步成功率即使很高,经过多步连乘后整体成功率也会明显下降。如果 harness 对单步失败没有有效的纠错机制,模型再聪明也很难走到终点。
第二是随机性扩散。长程任务中,模型每一步都可能受采样随机性、环境状态扰动和工具返回噪声的影响。同一个模型在同一个任务上跑两次,路径可能完全不同。没有固定种子和足够次数的重复实验,一次的评测结果不具备代表性。
第三是环境反馈的敏感度。短任务可以从最终文本直接判断内容是否相关;长程任务每一步的工具返回是否准确、反馈是否足够,决定了模型能不能及时调整后续行为。
第四是工具链强耦合。长程 Agent 几乎必然依赖具体工具,工具异常、schema 不匹配、执行超时等外围问题都会被记入 Agent 的失败原因。很多“模型失败”实际是“环境失败”或“工具接口设计失败”。
3.3 传统评测与长程评测的对比
| 维度 | 传统静态评测 | 长程智能体评测 |
|---|---|---|
| 交互方式 | 单次输入输出 | 多轮“动作-观察”循环 |
| 主要能力 | 知识、推理、文本生成 | 规划、工具使用、纠错、记忆管理 |
| 环境影响 | 很低 | 很高 |
| 变量数量 | 较少 | 很多,且互相耦合 |
| 一次评测耗时 | 秒级 | 可能分钟到小时级 |
| 对 harness 的敏感度 | 低 | 高 |
| 结果可复现性 | 相对容易 | 较难,取决于 harness 是否固定 |
这也是论文强调“长程智能体评测”的原因。静态基准里,harness 更接近一个简单的“评分包装”;而在长程任务中,harness 已经成为 Agent 系统中不可分割的一部分。把 harness 从“实验工具”升级为“被评测对象的核心变量”,是这篇论文最关键的视角转换。
4. “模型对比”为什么需要控制变量:一场实验设计问题
4.1 评测本质上是一场受控实验
任何严谨的对比都应该有一个明确的实验设计。理想情况下:
- 独立变量:你想比较的东西,比如模型权重;
- 控制变量:所有其他条件保持一致;
- 结果:因为独立变量改变而产生的可观测差异。
但现实中,很多 Agent 评测根本没有完成这一步。模型 A 用的是严格 JSON 解析器,模型 B 用的是宽松解析器;模型 A 给了 20 步,模型 B 只给 10 步;模型 A 失败可以重试三次,模型 B 一次都不允许重试。最后结果出来后,整理报告的人把差异归因于“模型能力”,这在方法论上不成立。
4.2 最容易混入“模型对比”的混淆变量
从工程经验看,评测结果里至少隐藏着以下几类容易被忽略的变量:
- 工具调用解析器:模型输出只要稍微不规范,严格模式直接判失败,宽松模式会先清洗再转成动作;
- 最大步数与超时:步数上限直接影响长任务的完成率;
- 失败重试与自我纠正机制:允许重试的效果等同于给模型叠加了一层额外的鲁棒性;
- 系统提示词的详细程度:有的评测会给模型极其详细的指导,这本质上是 harness 在“帮”模型解题;
- 工具返回的观测是否被截断:很多模型并不是能力不够,而是上下文里根本没拿到关键信息;
- 成功判定的粒度:一个任务是否成功,是要求完全正确,还是只要部分完成就算成功;
- 随机种子与温度:Agent 评测路径高度随机,不用固定种子和不做多次重复实验,结果不可比。
4.3 什么时候才能说“模型 A 强于模型 B”
要得到“模型 A 强于模型 B”这个结论,最稳妥的方式是在固定同一套 harness 的前提下比较多个模型。换句话说,所有被测模型必须使用完全一致的工具 schema、解析策略、最大步数、反馈格式和成功判定函数。
同样重要的是反向控制:如果你想验证“这版 harness 改动是否让 Agent 更强”,那就应该固定模型不变,只修改 harness 中的一个变量。这和软件工程里做性能优化一样,一次只能改一个因素,否则出了问题你很难定位是谁引起的。
论文的观点比这更严格一点:即使模型和 harness 都固定,报告中还必须披露 harness 的具体版本和配置。否则别人无法复现你的实验,也就无法判断你的结论是否可靠。评测结果的可复现性,不是评测完成后的附加项,而是结论有效性的前提。
5. 用一个最小示例看:同一模型在不同 harness 下的差异
5.1 实验目标与场景
为了把“harness 的影响超过模型”这个抽象观点落到可操作的层面,我们设计一个最小实验:
- 任务:Agent 读取一个 JSON 配置文件,端口不合法时修改为合法端口,最后运行校验;
- 模型:用一个能力完全一致的“脚本式 Agent”来替代真实模型,排除模型差异;
- harness 变量:只改变一个参数——模型输出是否会被解析器清洗后重试;
- 对比:在同种子、同任务、同模型行为下,跑 200 次评测,统计两种 harness 的通过率。
这个实验刻意做得简单,目的是让你在本地就能跑通,并且直观看到:模型行为完全没变,只改 harness 的一个容错参数,最终评测通过率就可能从三成变成接近满分的水平。
5.2 最小评测 Runner 代码
这里用 Python 标准库实现,不需要安装任何第三方依赖:
# 文件路径:examples/mini_harness_demo.py """ 同一个"模型行为",在不同 harness 策略下,最终评测通过率会出现明显差异。 本示例用可控模拟说明机制:模型被替换为脚本式 Agent,只改变 harness 对 模型输出格式的容忍度,观察评测结果变化。 """ import json import random class TaskEnv: """内存版迷你环境,模拟读取配置、修改配置、运行校验三个工具。""" def __init__(self, init_config): self.config = init_config self.edited = False def read_config(self): return {"role": "observe", "content": self.config} def write_config(self, new_config): self.config = new_config self.edited = True return {"role": "observe", "content": "write_ok"} def check_config(self): try: cfg = json.loads(self.config) except Exception: return {"role": "observe", "content": "invalid_json"} port = cfg.get("port") if isinstance(port, int) and 1024 <= port <= 65535: return {"role": "observe", "content": "check_ok"} return {"role": "observe", "content": "check_fail"} def build_plan(): """一个固定的任务计划,代表模型内部已经知道该怎么做。""" return [ {"action": "call_tool", "tool": "read_config"}, { "action": "call_tool", "tool": "write_config", "args": {"new_config": '{"port": 6080}'}, }, {"action": "call_tool", "tool": "check_config"}, ] class DeterministicAgentWithNoise: """模拟能力完全一致的模型:按计划输出动作,但有概率输出格式噪声。 noise_rate 表示模型输出不规范的频率。这里统一模拟成把工具调用 包在 markdown 代码块里,这是真实 Agent 评测里常见的不规范输出。 """ def __init__(self, plan, noise_rate=0.3): self.plan = plan self.noise_rate = noise_rate def next_action(self, history): step = len(history) if step >= len(self.plan): return "" action_str = json.dumps(self.plan[step]) if random.random() < self.noise_rate: action_str = "```json\n" + action_str + "\n```" return action_str def parse_action(raw_text, strip_markdown=False): """把模型输出解析成结构化 action。 strip_markdown=True 表示 harness 宽容处理模型输出,会自动剥离 外层 markdown 代码块;False 表示严格要求 clean JSON。 """ text = raw_text.strip() if strip_markdown and text.startswith("```"): lines = text.splitlines() if lines and lines[0].startswith("```"): lines = lines[1:] if lines and lines[-1].strip() == "```": lines = lines[:-1] text = "\n".join(lines) try: action = json.loads(text) return True, action except Exception: return False, None def execute_action(env, action): """执行一个工具调用并返回观测结果。""" if action.get("action") != "call_tool": return {"role": "observe", "content": "unknown_action"} tool = action.get("tool") args = action.get("args", {}) if tool == "read_config": return env.read_config() if tool == "write_config": return env.write_config(args.get("new_config")) if tool == "check_config": return env.check_config() return {"role": "observe", "content": "tool_not_found"} def run_episode(agent, max_steps, strip_markdown): """运行一次完整任务,返回最终状态与交互历史。""" env = TaskEnv('{"port": 99999}') history = [] for _ in range(max_steps): raw = agent.next_action(history) if raw == "": return "fail_no_action", history ok, action = parse_action(raw, strip_markdown=strip_markdown) if not ok: return "fail_parse_error", history obs = execute_action(env, action) history.append({"action": action, "observation": obs}) # 成功条件:执行过 check_config 且结果为 check_ok if action.get("tool") == "check_config" and obs.get("content") == "check_ok": return "success", history return "fail_max_steps", history def run_experiment(repeat=200, seed=42): """固定种子运行多次评测,统计不同 harness 下的成功率。""" random.seed(seed) stats = {} for name, max_steps, strip in [ ("strict_no_retry", 3, False), ("lenient_markdown_strip", 3, True), ]: success = 0 fail_reasons = {} for _ in range(repeat): agent = DeterministicAgentWithNoise(build_plan(), noise_rate=0.3) status, _ = run_episode( agent, max_steps=max_steps, strip_markdown=strip, ) if status == "success": success += 1 else: fail_reasons[status] = fail_reasons.get(status, 0) + 1 stats[name] = { "success_rate": success / repeat, "fail_reasons": fail_reasons, } return stats if __name__ == "__main__": result = run_experiment(repeat=200, seed=42) print(json.dumps(result, indent=2, ensure_ascii=False))这段代码的关键设计是:DeterministicAgentWithNoise的内部计划完全一致,代表“模型能力”没有变化;唯一变化的是 harness 对模型输出的容错策略。strict_no_retry要求每一次parse_action都成功,一旦模型输出带了 markdown 包裹就立刻终止;lenient_markdown_strip会在解析前剥离外层代码块,让同样的输出可以被正确执行。
5.3 运行与预期输出
在项目根目录执行:
python examples/mini_harness_demo.py运行后会看到类似下面的输出(不同随机种子会有波动,但趋势是稳定的):
{ "strict_no_retry": { "success_rate": 0.34, "fail_reasons": { "fail_parse_error": 132 } }, "lenient_markdown_strip": { "success_rate": 1.0, "fail_reasons": {} } }在这个模拟里,模型的行为完全一样,任务完全一样,唯一的差别只是 harness 是否对模型输出做一次无害的格式清洗。结果显示,严格策略下成功率只有三成左右,宽松策略下基本可以做到百分之百。
这个实验虽然不涉及真实 LLM 调用,但它准确复现了论文要表达的机制:模型输出的不规范不是小概率事件,尤其是在长程任务中,几十次工具调用里出现一两次格式错误非常正常。一个具备基本容错能力的 harness,可以直接把“模型能用”和“模型评价为不可用”区分开。这也是为什么在讨论 Agent 评测结果时,必须把 harness 写清楚。
6. 输出一份可复现评测的披露清单
6.1 Agent 评测报告应披露哪些字段
论文强调的重点之一是“Disclosing the Harness”。结合工程实践,一份可复现评测至少应该披露以下内容:
| 类别 | 必填字段 | 说明 |
|---|---|---|
| 模型 | 模型名、权重版本、量化方式 | 不能只写“某模型”,要有可精确定位的版本 |
| 采样参数 | temperature、top_p、max_tokens | 解码策略直接影响输出质量和随机性 |
| 任务集 | 数据集版本、任务数量、任务拆分方式 | 长程任务尤其要写清楚筛选规则 |
| 工具环境 | 工具 schema、沙箱版本、浏览器/系统环境 | 环境不同,Agent 可操作性完全不同 |
| 行为策略 | 最大步数、超时、重试规则、反思策略 | 这是最容易改变评测结论的区块 |
| 解析方式 | 输出解析器、是否清洗 markdown、失败处理 | 同样是模型输出,不同解析器结果不同 |
| 反馈机制 | 中间反馈来源、是否包含 oracle 信息 | 是否有额外提示会显著影响复杂度 |
| 成功判定 | 判定函数、部分完成计分方式 | 不同判定标准可以制造完全不同的指标 |
| 实验配置 | 随机种子、重复次数、并发数 | 保证结果可以被重复实验验证 |
| 运行日志 | 完整交互轨迹、报错信息 | 便于其他人定位失败原因 |
6.2 Harness 配置即代码
这些配置不应该是散落在 README 里的自然语言,而应该是随评测代码一起提交的结构化文件。下面是一份参考 YAML:
# 文件路径:eval-configs/agent-eval-v1.yaml experiment: name: "agent-eval-demo-v1" task_set: "config-fix-mini" task_count: 200 seed: 42 model: name: "your-model-id" version: "your-model-version" temperature: 0.0 max_output_tokens: 2048 harness: framework: "custom-runner" version: "git-commit-hash" max_steps: 3 parse_policy: strip_markdown: true retry_on_parse_error: false tool_schema: "strict-json" stop_condition: "check_config returns check_ok"配置中强调version: "git-commit-hash",是因为 harness 代码和配置一样需要版本控制。任何一次评测结果,都应该能通过experiment.name + model.version + harness.version + seed唯一定位到一次可复现实验。
6.3 评测记录的结构化输出
每次评测结束,应当把结果连同关键配置一起落盘。下面是一份最小 JSON 记录,既包括成功率,也包括产生该结果时使用的最小配置集合:
{ "experiment": "agent-eval-demo-v1", "model": { "name": "your-model-id", "version": "your-model-version", "temperature": 0.0 }, "harness": { "framework": "custom-runner", "version": "1.0.0", "strip_markdown": true, "retry_policy": "none", "max_steps": 3 }, "runtime": { "total_episodes": 200, "seed": 42, "success_rate": 0.34 } }把这类 JSON 写入评测仓库的results/目录,和代码、配置一起进入版本管理,可以让整个团队在任何时候回溯“某个分数是由哪些条件产生的”。这是让评测从“一次性研究”变成“可积累工程资产”的最有效手段。
7. 常见问题与排查:为什么别人评测结果复现不出来
以下清单比较贴近真实团队场景,适合直接用于排查:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 同一个模型,两个团队分数差异巨大 | 工具解析器或输出清洗策略不同 | 对比两边的 parse 前后日志 | 统一解析策略,写入 harness 配置 |
| 模型在评测中频繁失败,但单独调工具没问题 | 最大步数太小或超时设置不合理 | 查看失败任务的步数分布 | 拉大 max_steps,或为长任务单独设超时 |
| 复现别人报告分数时偏低 | 提示词里包含额外的任务指导或 oracle 信息 | 检查系统提示词中是否有隐含答案 | 发布评测时提交完整提示词文本 |
| 多次运行同一评测分数波动大 | 随机种子未固定,重复实验次数不足 | 查看多次运行的标准差 | 固定 seed,并至少重复 10 次以上 |
| 模型因为一次格式错误就整局失败 | 解析器缺少容错机制 | 查看失败原因统计里的 parse_error | 增加格式清洗和有限次重试 |
| 同一任务在本地通过,在评测环境失败 | 工具环境或沙箱不一致 | 对比本地和评测环境依赖 | 把评测环境容器化,纳入配置管理 |
这组问题背后有一个统一规律:绝大多数“分数复现不出来”的情况,都不是模型变了,而是模型外面的 harness 配置变了。找到差异的第一步,不是重新调 prompt,而是先让两边的评测环境对齐。
8. 工程建议:把 Harness Engineering 纳入 Agent 开发流程
8.1 Harness 应当被当作一等工程资产
论文标题里没有直接使用“Harness Engineering”这个说法,但这个概念已经在 Agent 工程社区里快速升温。它的含义可以概括为:用工程化手段管理评测中的 harness,把它从“每次实验临时拼凑的脚本”升级为“可版本化、可复现、可比较的系统组件”。
这要求团队至少做到三件事:
- harness 代码入库,配置入版本管理;
- 每次评测都必须记录模型版本、harness 版本、seed 和完整交互日志;
- harness 的每一次改动都当作一次产品变更来 review,不能随手改完就重新跑分。
把 harness 当作“一等公民”之后,评测结果才有长期积累的价值。否则今天跑出来的高分,下个月可能因为某个脚本被顺手改掉而彻底不可复现。
8.2 建立评测矩阵而不是单点对比
做模型或 Agent 版本对比时,不要只跑一个成功率的数字。推荐建立一个“模型 × harness”的矩阵:
- 固定模型,对比多个 harness 配置,找出当前模型最需要的运行条件;
- 固定 harness,对比多个模型,得到相对公平的模型能力排名;
- 把两个维度同时呈现,例如“这些分数是在宽容型 harness 下的结果,如果换成严格型,所有模型的分数都会下降,但下降幅度不同”。
这种矩阵的价值在于:它能告诉你模型之间的差距是稳定的,还是会在某类 harness 下被放大或缩小。如果模型 A 只有在极其宽容的解析策略下才超过模型 B,那 A 的“优势”就不是特别强的信号。