Test-Time Harness:推理阶段用强模型辅助弱模型的能力迁移框架
最近在梳理大模型应用落地时我发现一个很有意思的现象很多团队其实已经不缺“好模型”了顶级模型的 API 随时可以调推理能力也很强但真正到了生产环境大家反而会纠结一个问题——能不能用更小的模型跑出接近大模型的效果如果只靠微调小模型在复杂推理任务上往往学不进去而且高质量训练数据的获取成本非常高。于是有一类思路开始被更多人关注不改弱模型的权重而是在推理阶段给弱模型“搭一个架子”让强模型在这个架子里扮演规划者、评审者、纠偏者的角色把能力以受控的方式迁移过去。这正是标题 “AI4AI at Test-Time: Strong-to-Weak Capability Transfer via Harnesses” 想表达的核心思想。这篇文章不打算翻译论文而是希望站在工程视角把这套思路拆开讲清楚它到底解决什么问题Harness 是什么跟微调和蒸馏有什么区别适合哪些场景又有哪些坑。无论你是做算法研究、大模型应用开发还是正在给团队设计 Agent 推理链路这篇文章都会给你一些可落地的参考。1. 背景与核心概念1.1 大模型能力分层带来的现实问题现在的大模型能力分布很不均匀。同一个模型可能写代码很强但数学推理一般可能日常对话很流畅但面对长文档结构化抽取时输出总是不稳定。更明显的是不同规模模型之间的差距。以 7B、13B 这种中小规模模型和百亿、千亿级模型对比差距往往不在“知识量”上而在于推理深度和复杂任务的过程控制能力。中小模型能记住很多知识但遇到需要多步推理的任务时容易在中途走偏而且没有自我纠错意识。这就带来一个非常现实的工程问题直接调大模型 API效果好但成本高、延迟不可控、数据出域风险大。本地部署小模型便宜可控但复杂任务效果不达标。微调小模型又需要高质量数据、训练算力和反复迭代周期很长。于是如何在不重训模型的前提下把强模型的能力“借用”给弱模型就成了一个很有吸引力的方向。1.2 从“AI4AI”说起“AI4AI” 可以简单理解为用 AI 来服务 AI。这不是一个新概念过去几年我们看到的几种典型形态包括用一个大模型生成训练数据去微调另一个小模型这是 “AI for AI” 在训练期的典型应用。用一个模型做另一个模型的输出评估器这是 “AI for AI” 在评测期的应用。而在标题里AI4AI 被放在了Test-Time也就是推理阶段。用强模型在推理时“伴随”弱模型帮助它完成原本完成不了的任务。这里的关键不再是“训练时教会弱模型”而是“推理时辅助弱模型”。1.3 什么是 Strong-to-Weak Capability TransferStrong-to-Weak Capability Transfer直译是“从强到弱的能力迁移”。传统的能力迁移比如知识蒸馏做法是让强模型先输出一批答案再把这些答案当作训练数据去训练弱模型让弱模型逼近强模型的输出分布。这种方式的问题在于能力迁移发生在训练阶段弱模型需要真正“学会”某种能力但学习效果受模型容量、数据质量和训练成本的限制。Test-Time 的能力迁移则换了一个思路不是在权重层面让模型变强而是在推理流程层面让模型的表现变强。比如弱模型单独做一道数学题可能直接输出一个错误答案。但如果给弱模型一个流程先让强模型把题目拆成几个小步骤。弱模型依次完成每个小步骤。强模型审查中间结果发现问题就让弱模型重做。最后强模型再做一次整体校验。那么弱模型最终输出的正确率很可能显著提升。这就是一种能力迁移只是迁移的载体不是参数而是推理过程中的结构和监督信号。1.4 为什么叫“Harness”Harness 在英文里有“马具、挽具、束缚装置”的意思翻译成“约束框架”或者“脚手架”都比较贴切。在 AI 领域Harness 通常指包裹在模型外部的一套控制逻辑。它不改变模型内部参数但会改变模型接收什么输入、分几步输出、如何被校验、出错后如何重试。你可以把 Harness 理解成一个“导师”角色它给弱模型布置任务。它拆解任务给弱模型分配它能力范围内能完成的子任务。它检查弱模型的阶段性产出。它决定是继续往下走还是打回去重做。强模型不一定需要亲自完成每一步但它通过控制流程和校验输出来“托管”整个任务的质量。这就是 Strong-to-Weak Capability Transfer 的核心机制。2. 为什么 Test-Time 能力迁移值得关注2.1 训练期迁移的瓶颈先来看传统的两种迁移方式。微调Fine-tuning在特定任务数据上继续训练模型让模型适应该任务。优点是效果直接缺点是成本高且小模型容量有限很难学会超出其表达能力的推理能力。你可以用小模型微调出“看起来很懂业务”的模型但遇到真正的复杂推理它依然会暴露能力上限。知识蒸馏Distillation用强模型输出作为弱模型的训练目标核心假设是“弱模型能够从强模型的输出中学到能力”。这个假设在很多任务上成立但在复杂推理任务上往往打折扣。因为蒸馏通常只传递了“结果”而复杂推理真正关键的是“过程”。一个数学题的最终答案可能就是“42”但中间那几十步推理才是能力的真正载体。如果只是结果蒸馏弱模型本质上还是在“背答案”而不是“学推理”。2.2 Test-Time 迁移的思路转变Test-Time 迁移把目光从权重转移到了流程。它的核心观点是与其让弱模型自己学会复杂推理不如在推理时给弱模型提供一个受约束的、有监督的环境让它在每一步都得到正确的引导。这样有几个明显的好处不用改模型权重不担心灾难性遗忘也不需要训练算力。迁移的是过程不只是结果对推理类任务更友好。适应性强模型换了一个Harness 可以继续用只要接口不变。效果可解释每一步怎么推理、为什么重试都记录在案方便排查。2.3 三种方式的对比维度微调知识蒸馏Test-Time Harness变更对象模型权重模型权重推理流程是否需要训练是是否迁移内容任务偏好输出分布推理过程与监督信号成本高中中低主要是推理成本部署灵活性低低高对推理类任务效果依赖模型容量通常有限有潜力需验证可解释性差差好从这个表格可以看出Test-Time Harness 的定位非常特殊它不追求“让弱模型变聪明”而是追求“让弱模型在正确的工作流里表现得聪明”。3. Harness 到底长什么样3.1 抽象结构拆解一个典型的 Harness 通常包含四个核心组件1. Planner规划器负责将一个复杂任务分解成多个子任务。这个角色通常由强模型担任因为任务拆解本身需要较强的语义理解和逻辑能力。2. Executor执行器负责按顺序执行子任务。这个角色通常由弱模型担任因为拆分后的子任务复杂度降低了弱模型能力足以应对。3. Verifier验证器负责检查执行器的中间输出和最终输出。验证器需要判断“当前结果是否正确”或者“当前结果是否离正确方向更近了一步”。4. Feedback反馈器当验证器发现执行器出错时反馈器负责生成纠错指令。比如告诉弱模型“你这一步的数学计算有问题注意第二行到第三行的除法”或者直接给一个更正后的中间提示。整个 Harness 的工作流可以用下面这段有序列表说明接收原始任务。强模型Planner对任务进行拆解生成一个步骤列表。弱模型Executor依次执行每一个步骤。强模型Verifier对每个步骤的产出进行校验。如果校验通过继续执行下一步。如果校验不通过强模型Feedback生成纠错指令弱模型重新执行当前步骤。所有步骤完成后强模型对最终结果做一次整体检查。输出最终结果。3.2 一个可理解的伪代码为了让这个流程更具体我用 Python 伪代码写一个最小 Harness 框架。注意这不是某个论文中的官方实现而是为了帮助理解机制设计的示意代码。# 文件minimal_harness.py # 说明一个最小化的 Test-Time Harness 示意框架 def run_task_with_harness(task, weak_model, strong_model, max_retries2): # 第 1 步强模型拆解任务 plan strong_model.plan(task) # 初始化上下文保存中间状态 context {task: task, steps: plan.steps, history: []} # 第 2 步按步骤交给弱模型执行 for step in plan.steps: attempt 0 while attempt max_retries: # 弱模型生成当前步骤的输出 output weak_model.generate(promptstep.prompt, contextcontext) context[history].append({step: step.name, output: output, attempt: attempt}) # 第 3 步强模型校验当前输出 verdict strong_model.verify(stepstep, outputoutput) if verdict.passed: # 校验通过进入下一步 context[step_outputs][step.name] output break else: # 校验失败生成纠错指令并重试 feedback strong_model.feedback(stepstep, outputoutput, errorverdict.reason) step.prompt step.prompt \n[纠错指令] feedback attempt 1 # 如果重试次数耗尽仍未通过可以选择跳过或终止任务 if attempt max_retries: context[failed_steps].append(step.name) # 第 4 步强模型做最终整体校验 final_result strong_model.final_check(context) return { result: final_result.output, context: context }这个伪代码里的weak_model和strong_model可以理解为两个不同的 LLM 实例plan、verify、feedback等方法在真实实现中通常是经过精心设计的 Prompt 模板。3.3 Harness 配置的工程化表达如果想把 Harness 工程化我们可以把规则和模板做成配置文件。下面是一个 YAML 风格的示意配置描述一个用于“代码修复”场景的 Harness。# 文件harness_code_fix.yaml # 说明代码修复场景的 Harness 配置示意 harness: name: code_fix_harness planner: model: strong-model-name prompt_template: 请将下面的编程任务拆解为不超过 5 个步骤\n{task} executor: model: weak-model-name prompt_template: 当前任务步骤{step_name}\n请完成该步骤并给出对应代码片段。 verifier: model: strong-model-name prompt_template: | 请检查下面的步骤输出是否正确。 步骤{step_name} 输出{output} 如果正确请输出 PASS否则请输出 FAIL 并说明原因。 feedback: model: strong-model-name prompt_template: | 下面这个步骤输出存在错误{error} 请生成一条纠错指令帮助执行者修正输出。 注意纠错指令需要指明具体问题而不是直接给出完整答案。 max_retries: 2 enable_final_check: true注意这里面的模型名和 Prompt 只是示意实际使用时需要根据你自己的模型和任务来做适配。但这个结构已经能表达 Harness 的核心思想把强模型的能力分解成规划、校验、反馈三个接口在推理过程中反复使用。4. 设计一个 Harness四个关键维度上面看的是一个最小 Harness 结构。如果要在真实场景中设计一套 Harness有四个关键维度需要想清楚。4.1 信息瓶颈要不要让弱模型拿到完整问题在没有任何 Harness 的情况下弱模型拿到完整问题直接输出答案。这个过程信息量极大弱模型很容易被无关信息干扰或者在长链路推理中迷失。Harness 的第一个作用就是设置信息瓶颈。通过任务拆解弱模型每次只看到一个小步骤而不是整个复杂问题。这可以显著降低弱模型的工作负担。但这里有一个权衡拆得太细调用强模型的次数增加成本和延迟上升拆得太粗弱模型依然要处理超出能力范围的子任务Harness 形同虚设。在实际设计中建议这样把握如果弱模型在某个子任务上的成功率已经很高不需要拆得更细。如果弱模型频繁在某个环节出错就要把该环节再细分一级。拆解粒度应该随着任务难度动态调整而不是所有任务都用同一套模板。4.2 监督信号过程监督而不是结果监督Harness 里强模型扮演的 Verifier 非常关键。很多人在初始设计时会犯一个错误只看最终输出对不对。这样问题很大因为弱模型在中间步骤出错时没有及时被纠正等到了最后一步再来检验已经无法定位问题出在哪里了。更好的做法是过程监督每个子步骤完成后立即校验。校验不只要给出 PASS / FAIL还要给出失败原因。反馈信息需要具体到“哪一步、哪个逻辑、哪个数值可能出错”。过程监督会让强模型的调用次数变多但对复杂推理任务的效果提升非常明显。它本质上是把“事后纠错”变成了“事中纠错”。4.3 自适应程度固定模板还是动态生成按照 Harness 的生成方式可以分成两类。固定模板 Harness强模型不参与动态规划所有的步骤、校验规则都预先写好。优点是稳定、成本低、可预测缺点是泛化能力差换一个任务类型可能就不适用了。动态生成 Harness强模型根据每一种新任务动态生成步骤、校验规则和反馈指令。优点是适应性强能应对开放域任务缺点是强模型调用次数更多且 Prompt 设计不好时强模型拆解出来的步骤可能不合理。在实践中比较合适的做法是“半动态”用任务分类器判断当前任务类型。每种任务类型有一套基础 Harness 模板。强模型在模板基础上做局部调整而不是从零生成。4.4 成本控制强模型是稀缺资源在这个方案里强模型虽然不需要每次都完整推理整个任务但它的调用次数直接决定成本。一个任务如果被拆成 5 步每步还有重试一次任务可能要调用 8~10 次强模型成本并不低。所以成本控制是 Harness 设计里非常现实的问题。几种常见的控制手段分层校验简单步骤用规则校验复杂步骤才调用强模型校验。置信度阈值弱模型输出时如果能返回置信度只有低置信度才让强模型介入。重试限制每个步骤设置最大重试次数超过次数就跳过或终止。批量规划一次调用强模型拆解多个任务降低规划器的调用频率。5. 如何理解这类工作的实验价值如果你去查阅相关论文或技术报告会发现这类工作的实验设计和传统微调研究有很大区别。这里提供一个阅读和评估的框架。5.1 关注任务难度分布判断 Test-Time Harness 是否有效不能只看平均正确率。要关注测试集中任务难度的分布简单任务上弱模型本来就能做对Harness 的增益很小。中等难度任务上Harness 很可能带来显著提升。极难任务上即使有 Harness弱模型也可能无法完成因为它的基础表达能力确实有限。所以看实验结果时要把正确率按难度分桶来看不能只看一个整体数字。5.2 关注“弱模型Harness”是否接近强模型Strong-to-Weak 迁移的终极目标是让弱模型在 Harness 的辅助下逼近强模型的能力。因此实验中最值得关注的一个比值是(弱模型 Harness 的效果 - 弱模型的效果) / (强模型的效果 - 弱模型的效果)这个比值可以理解为“能力迁移效率”。如果 Harness 只能让弱模型提升一点点那说明 Harness 的设计有问题如果能接近强模型基线那说明迁移是有效的。5.3 关注成本增益比任何工程方案都不能只看效果还要看成本。建议在评估时记录以下几个指标指标说明弱模型单独运行成本基线成本强模型单独运行成本上限成本弱模型 Harness 成本目标方案成本效果提升幅度与基线对比单任务平均强模型调用次数衡量成本的关键只有“效果提升明显且总成本明显低于直接用强模型”的方案才真正具备工程落地价值。如果 Harness 调用强模型太频繁那还不如直接让强模型来做。6. 工程落地哪些场景最适合用 Harness6.1 适合 Harness 的场景特征根据前面的分析Harness 在以下场景中最有优势任务可以拆解。如果任务本身是单步生成、无法拆解Harness 能发挥的空间有限。中间过程可校验。比如代码运行结果、数学题的中间步骤、SQL 查询结果都可以通过规则或模型校验。弱模型基础能力尚可。弱模型不是完全不会而是容易出错、容易走偏需要外部监督来兜底。强模型调用成本可接受。业务对成本有一定容忍度或者强模型部署在自建 GPU 集群上。6.2 典型场景一代码修复与代码生成代码是 Harness 最天然的应用场景。弱模型生成的代码可能有 bug但传统方法只能靠测试用例来判断对错。有了 Harness 之后强模型将任务拆成“写函数签名、写核心逻辑、写边界处理、写测试”等步骤。弱模型生成代码片段。验证器执行单元测试如果测试失败反馈器把报错信息返回给弱模型。弱模型针对报错信息做修复。这里验证器可以不是强模型而是真实的代码执行环境成本更低、结果更可靠。混合使用规则验证器和模型验证器往往是最优解。6.3 典型场景二数据抽取与结构化输出在处理长文档、非结构化文本时弱模型经常犯“漏字段”“格式错误”这类问题。Harness 可以这样设计强模型先根据业务需求拆解抽取字段清单。弱模型逐字段抽取而不是一次输出完整 JSON。强模型校验每个字段的抽取结果发现缺失或格式错误时反馈。最后强模型把字段结果组装成目标结构。这个做法的好处是即使弱模型整体能力一般但逐字段抽取的每个步骤都比较简单成功率会明显提升。6.4 典型场景三Agent 工具调用很多 Agent 系统里主模型需要决定“调用哪个工具、传什么参数、如何处理工具返回结果”。如果主模型是弱模型经常会出现工具选错、参数格式错误、不理解返回结果等问题。用 Harness 改造后强模型在推理链路中担任“工具调用检查员”。弱模型提出工具调用意图后强模型先校验工具选择是否正确、参数是否合规。校验通过才真正执行工具调用。工具返回后强模型再协助弱模型理解返回结果生成下一步动作。这种设计能在不替换主模型的前提下明显提升 Agent 的稳定性。7. 局限性与风险别把脚手架当成治疗Harness 是一个很实用的工程思路但它不是万能的。在工程实践中有几个风险需要认清。7.1 成本与延迟可能失控一个 5 步任务如果每步都调用强模型校验再加上重试单任务延迟可能从 2 秒涨到 10 秒以上。这在 To C 交互场景中是不可接受的。所以生产落地时一定要设计降级策略强模型繁忙或超时时Harness 直接退化为基础模式让弱模型独立输出。7.2 弱模型能力上限仍然存在Harness 是“脚手架”不是“新大脑”。如果弱模型的基础理解能力很差连拆分后的子任务也完不成那再好的 Harness 也无法让效果发生质变。一个不太严谨但有效的判断方法是如果弱模型在简单子任务上的成功率低于 60%那说明问题不在推理链路上而在模型基础能力上这时候应该优先换模型或做微调而不是继续优化 Harness。7.3 反馈器可能给出错误指导强模型也不是不会犯错。当强模型在验证和反馈环节出现幻觉时它可能把正确的输出判错或者给出错误的纠错指令把弱模型带偏。这类问题在跨领域任务中更容易出现。降低风险的办法包括使用规则验证器兜底模型验证器只处理规则无法判断的部分。对强模型的验证结果做二次抽查尤其是在高风险场景。在 Harness 中加入“放弃重试”策略当弱模型连续重试结果出现反复波动时停止重试保留当前最佳结果并告警。7.4 安全与合规边界Test-Time Harness 通常需要在推理链路中引入两个模型如果强模型是云端 API那么业务数据会被发送到外部服务这会带来数据安全问题。在金融、医疗、政务等强合规场景下需要优先考虑将强模型部署在私有化环境或者在数据出域前做脱敏处理。另外Harness 的 Prompt 中注入了任务描述、中间结果和反馈信息这些内容是提示注入攻击的潜在目标。尤其是在 Agent 场景中如果工具返回内容包含恶意指令弱模型可能在反馈生成阶段把恶意指令当作真实需求。必要的时候需要对工具返回内容做隔离和清洗。7.5 别把“评测通过”当成“能力提升”还有一个容易被忽视的问题Harness 可能让弱模型在特定评测集上表现出色但这不代表弱模型真的变强了。它更像是在一个精心设计的赛道上跑出了好成绩。如果后续任务的 Harness 结构发生改变弱模型的优势可能瞬间消失。因此在做技术选型时一定要确认你的核心诉求是“提升一个持续运行系统的稳定性”还是“提升模型本身的通用能力”。前者适合用 Harness后者需要回到训练路线。8. 动手实践一个最小验证方案如果你现在就想验证这个思路在你自己业务上是否有效可以参考下面的最小验证方案。它不需要重新训练模型也不需要写复杂的框架一个周末就能跑通。8.1 选择一个任务优先选择一个结果可量化的任务。比如数学应用题解答答案是否正确有标准答案。代码修复修复后的代码能否通过测试用例。结构化抽取抽取结果与标注字段是否一致。不推荐一开始就在开放域问答或纯生成类任务上做因为评估标准不明确很难判断 Harness 是否真的有效。8.2 准备两个模型弱模型选择你当前部署的、效果不太理想但成本可控的模型。强模型选择调用外部 API 的模型或者你的 GPU 集群里最大的模型。关键是两个模型能够通过统一的接口调用方便写代码。8.3 实现三个 Prompt根据 Harness 结构你至少需要三个 Prompt 模板规划 Prompt输入任务输出步骤列表。校验 Prompt输入步骤、弱模型输出输出 PASS 或 FAIL。反馈 Prompt输入错误原因输出纠错指令。这三个 Prompt 可以先手工编写运行多轮后根据效果迭代优化。8.4 运行对比实验分别跑三个配置弱模型单独运行。强模型单独运行。弱模型 Harness。记录每组的效果指标和成本指标对比提升幅度。8.5 一个最小验证代码骨架最后给一个最小验证的 Python 代码骨架供你参考。# 文件quick_harness_test.py # 说明快速验证 Test-Time Harness 是否有效的最小脚本 from typing import List, Dict class LLMClient: 统一的模型调用客户端实际使用时替换为你的模型接口。 def __init__(self, model_name: str): self.model_name model_name def generate(self, prompt: str) - str: # 这里替换为真实的模型调用逻辑 # return call_model(prompt, modelself.model_name) return f[{self.model_name} output for: {prompt[:30]}...] def split_task(planner: LLMClient, task: str) - List[str]: prompt f请将下面的任务拆解为多个可独立完成的步骤\n{task}\n每个步骤一行。 response planner.generate(prompt) steps [line.strip(- ) for line in response.strip().splitlines() if line.strip()] return steps def verify_step(verifier: LLMClient, step: str, output: str) - tuple[bool, str]: prompt f 步骤{step} 模型输出{output} 请判断这个输出是否正确。 如果正确仅输出PASS 如果错误输出FAIL 原因。 response verifier.generate(prompt) passed response.strip().upper().startswith(PASS) return passed, response def run_harness(weak: LLMClient, strong: LLMClient, task: str, max_retries: int 2) - str: steps split_task(strong, task) final_outputs [] for step in steps: step_output weak.generate(step) for _ in range(max_retries): passed, reason verify_step(strong, step, step_output) if passed: break # 纠错让强模型生成改进后的指令 fix_prompt f下面是错误原因{reason}\n请生成一条改进指令帮助完成步骤{step} fix_instruction strong.generate(fix_prompt) step_output weak.generate(f{step}\n改进指令{fix_instruction}) final_outputs.append(step_output) # 汇总结果 combined \n.join(final_outputs) return combined if __name__ __main__: weak LLMClient(weak-model) strong LLMClient(strong-model) task 计算 23 * 17 48 / 6 的结果并解释计算过程。 result run_harness(weak, strong, task) print(Harness 结果) print(result)跑通这个骨架后你可以逐步加入更复杂的验证规则、动态任务拆解、成本统计和日志追踪让它变成一个真正的生产级 Harness 模块。9. 写在最后最近一年我看了不少关于 Agent 流程、模型编排和推理优化的资料一个很深的体会是大模型应用落地时模型能力的重要性往往低于推理链路设计的重要性。同样一个弱模型直接调用是一种效果放进精心设计的 Harness 之后可能是另一种效果。Test-Time Capability Transfer 这个方向本质上就是想把“强模型的能力”变成一种可以在推理阶段按需取用的服务而不是只能通过昂贵训练才能获得的东西。这种方式当然不能完全替代微调和蒸馏但它给了工程师一个新的杠杆当模型能力不足时先别急着换模型或投训练资源可以先想想能不能在推理阶段给模型搭一个更好的环境。如果你正在做大模型应用我建议你挑一个最常见的业务任务用我上面给的最小方案花一个周末验证一下。也许你会发现手里的弱模型比想象中要强得多。