Harness 即泛化器:MIT 这项研究,或将重写 Agent 的设计范式

原文:https://alexzhang13.github.io/blog/2026/harness

文本版 · 供搜索与朗读

Harness 即泛化器:MIT 这项研究,或将重写 Agent 的设计范式

Harness 即泛化器:MIT 这项研究,或将重写 Agent 的设计范式

研究对象:《Language model harnesses are compositional generalizers》
作者:Alex Zhang、Omar Khattab(MIT CSAIL / OASYS)
发表:2026 年 7 月 20 日,以博客形式首发(非同行评审)
原文:https://alexzhang13.github.io/blog/2026/harness
解析日期:2026-08-10
前置系谱:Recursive Language Models(2025-10 博客 / arXiv:2512.24601)→ Mismanaged Geniuses Hypothesis(2026-04)→ 本文(2026-07)

目录

序:先正名,再论道

一、Transformer 为何天生不擅「组合泛化」

1.1 先说清「组合泛化」是什么

1.2 这不是新发现,是四十年的老账

1.3 MIT 这篇如何归因

1.4 一个具体后果:长度泛化失败

二、Harness 是什么?为何可能成为 Agent 的核心

2.1 定义

2.2 身份跃迁:从「胶水」到「归纳偏置的载体」

2.3 核心判据:Locally In-Distribution(LID,局部分布内)

2.4 反面教材:主流 Agent 全在违反 LID

2.5 等价类:harness 如何「制造」泛化

三、RLM:把上下文当环境,而非输入

3.1 一句话定义

3.2 演化谱系

3.3 接口设计:drop-in 替换

四、上下文卸载:长上下文问题的解法

4.1 根模型初始看见什么

4.2 可用原语

4.3 为什么这能解决长上下文

4.4 实测

五、程序化子调用:为何「代码」比「工具调用」高一个维度

5.1 分解空间(space of decompositions)

5.2 一个 for 循环的分野

5.3 中间结果留在变量里

5.4 涌现出的策略

六、为何短任务训练能迁移到百万 Token 长任务

6.1 实验配置

6.2 六个长度泛化环境

6.3 三个跨域迁移环境

6.4 结果

6.5 机理:轨迹被商掉了

6.6 最震撼的一个数字(来自 MGH)

七、Harness 会成为大模型架构的一部分吗

7.1 作者的表态

7.2 我的判断

7.3 一条反对意见,也须听

八、泼冷水:这项研究的局限与可疑之处

8.1 它是博客,不是论文

8.2 「不就是 subagent 吗」——这个质疑有实锤

8.3 泛化不是自动的,需要「推一把」

8.4 成本与延迟的真实代价

8.5 其他失败模式

8.6 一个理论上的隐忧:循环论证的风险

九、这对你意味着什么

9.1 三条可立即执行的原则

9.2 一个视角转换

附:一句话速记

参考

序:先正名,再论道

全景:外部世界 ⇄ Harness ⇄ 神经网络。七问的答案皆落于中间这一层。

君所提之标题「Language Models are Harnessed Generalizers」,与原文略有出入。原题为 「Language model harnesses are compositional generalizers」——直译为「语言模型的外壳,才是组合泛化器」。

一字之差,意思大不同。原题的主语不是「模型」,而是 harness(外壳)。这不是措辞讲究,是论点本身:会泛化的那个东西,不是神经网络,是包着神经网络的那层程序。

还有一件事须先讲明:这是一篇博客,不是一篇经过同行评审的论文。 它有数据、有实验、有形式化,但没有匿名审稿人替你把关。读它当读一份来自一线的实验笔记,而非定论。后文第八节,我会专门泼冷水。

先给一张全景图,把七问的骨架摆出来:

问题 MIT 的回答
┌──────────────┐ ┌────────────────────────┐
│ Transformer │ │ 别修网络,修外壳 │
│ 不会组合泛化 │ ───→ │ Harness 承载归纳偏置 │
└──────────────┘ └────────────────────────┘
│ │
↓ ↓
┌──────────────┐ ┌────────────────────────┐
│ 长上下文腐烂 │ ───→ │ 上下文卸载:变量而非提示 │
└──────────────┘ └────────────────────────┘
│ │
↓ ↓
┌──────────────┐ ┌────────────────────────┐
│ 每域各训一遍 │ ───→ │ 程序化子调用 → 任务同构 │
└──────────────┘ └────────────────────────┘
│
↓
短任务训练 → 长任务/跨域泛化

一、Transformer 为何天生不擅「组合泛化」

1.1 先说清「组合泛化」是什么

组合泛化(compositional generalization):把学过的零件重新拼装,去解没见过的题。

举个最小的例子。你教一个小孩「跳」,再教他「向左转两次」。他从没听过「向左转两次之后跳」,但他一听就会做。这就是组合泛化——零件是旧的,组合是新的,能力自动到位。

人做这事毫不费力,费力到我们意识不到它是一种能力。神经网络做这事,一直不行。

1.2 这不是新发现,是四十年的老账

这笔账最早由 Fodor 与 Pylyshyn 于 1988 年记下:他们批评联结主义模型缺乏 systematicity(系统性)——一个能理解「张三爱李四」的系统,理应自动能理解「李四爱张三」,因为零件相同、只是重组。神经网络做不到这点,说明它学的不是结构,是相关性。

作者在原文里自嘲这是「perhaps boring old concept」(也许无聊的老概念)——老,但没解决。

到了 Transformer 时代,这笔账被算得更清楚了。最硬的一记来自 《Faith and Fate: Limits of Transformers on Compositionality》(Dziri 等,NeurIPS 2023)。他们把多步推理任务画成计算图(computation graph),然后系统地加深加宽,看模型什么时候崩:

实验
结果

GPT-4 做 3 位 × 3 位乘法
59%

GPT-4 做 4 位 × 4 位乘法
4%

加 few-shot scratchpad 后 3×3
59% → 92%

同样加 scratchpad,高复杂度问题
仍近 0%

GPT-3 在 180 万条乘法数据上穷尽微调至 3×3 满分,测 4×4
0%

4×2 乘法中「答案对但中间步骤错」的比例
82%

最后两行是全场最刺眼的。

训练到 3×3 百分之百,4×4 是零。 只多了一位数。零件完全相同(一位乘法、进位、错位相加),只是多组合了一层。模型全崩。

那 82% 的「答案对、过程错」,论文称为 restoration error——它不是算出来的,是记出来的。

Dziri 等人的结论一针见血:Transformer 解组合任务,靠的是 linearized subgraph matching(线性化子图匹配)——把当前推理路径去比对训练时见过的路径。它不是在执行算法,它是在检索路径。 训练分布里有相似子图就对,没有就错。

他们还给了理论证明:自回归生成下,正确率随推理步数指数衰减。每步 1% 错误率,看起来微不足道,几十步之后就是全盘皆输。

1.3 MIT 这篇如何归因

Harness 一文没有重复上述实证,而是把矛头指向架构的归纳偏置层级。作者原话:

"Yet across all of this, generalization itself has been left to the underlying neural network and to its 2017 token-level inductive biases."

"We think this is because their narrow design space of mostly differentiable neural operators misses something fundamental."

"it just doesn't seem that the basic differentiable neural operations put together 5 years after AlexNet are particularly optimal when it comes to encoding the inductive biases we need."

翻成大白话:Transformer 的归纳偏置是「token 级」的、是「几何」的——注意力算的是向量相似度,位置编码编的是序数关系。这套偏置在「把语言的统计规律吃透」这件事上无与伦比,但它天生不含「把问题拆成子问题」这种符号级、结构级的偏置。

作者说得更狠的一句是:

"the returns on scaling Transformers and related neural architectures are just not budging in terms of being poor compositional generalizers."

规模上去了,这个毛病纹丝不动。 这是判断"scaling 能否解决一切"的关键证据——不是"还没到时候",是"这个方向的边际收益在这个指标上约等于零"。

1.4 一个具体后果:长度泛化失败

组合泛化缺失,最日常的表现就是长度泛化(length generalization)失败。原文:

"It is widely known that training Transformer-based LMs on a domain at a particular context length does not necessarily generalize to longer context lengths."

这就是为什么 Qwen 3.x、Kimi K2.x、GLM 5.x 等生产模型的中训练/后训练阶段,要小心翼翼地把越来越长的数据掺进训练配比。不是因为长数据本身多有营养,是因为不喂就不会。

这是一笔巨大的、重复的、每个新长度档位都要重付一遍的税。

二、Harness 是什么?为何可能成为 Agent 的核心

2.1 定义

作者给的定义相当克制,也相当精确:

"A harness is the program that sits between the external world and the neural network: it decides how to encode the current state of the environment, which can be arbitrarily long and complex, into one or more inputs to the LLM and how to determine the next action."

形式化写作 H: s → a(状态到动作)。

harness 这个词,在英文里本指给马套的挽具——不是马,但决定马的力气往哪儿使。中文没有完全对应的词,「外壳」「支架」「挽具」「驾驭层」都只得其一半。我姑且译作「驾驭层」,取「驭」字之意:它不产生力,它分配力。

你每天用的东西,全是 harness:Claude Code 的主循环、Cursor 的上下文拼装、LangChain 的 chain、你自己写的那个 while 循环。

2.2 身份跃迁:从「胶水」到「归纳偏置的载体」

这才是全文真正的思想跳跃。

过去我们怎么看 harness?工程胶水。 脏活。模型是主角,harness 是给主角递道具的场务。谁会认真研究场务?

作者说,错了。harness 有一项更根本的权力:

"a more fundamental power of the harness is the ability to simplify the arbitrarily complex state s into potentially many smaller observations o that each individual LM call in the harness can properly handle"

harness 决定「模型看见什么」。 而模型的表现,几乎完全由「它看见什么」决定。

于是那句关键的话出来了:

"We know that Transformers are unreliable at compositional generalization, so we can rely on the harness to define higher-level inductive biases."

归纳偏置——这个过去只属于「架构设计」的词——被搬到了 harness 上。

这是一次身份跃迁:harness 不再是模型外面的脚手架,它是模型能力的一部分。

2.3 核心判据:Locally In-Distribution(LID,局部分布内)

LID 原理:坏 harness 把观察不断 append,使输入漂出分布(context rot);好 harness 把复杂状态拆成许多「熟悉的一刀」,每次调用皆在分布内。

那么,什么算好的 harness?作者给了一条判据,我认为这是全文最有价值的一句话:

"a good harness produces observations o that are locally in-distribution (LID), which we define as every individual LM call over this observation being in-distribution with respect to the training data."

拆开讲:

整个任务可以是分布外的(OOD)——它可以是模型从没见过的类型、200 万 token 的长度、全新的领域。

但每一次单独的模型调用,必须尽量落在分布内。

这是一种"分而治之",但分的不是任务,是分布。

打个比方。你请一位只做过江浙菜的厨师做一桌满汉全席——他会崩。但如果你把满汉全席拆成一百道工序,每道工序都是「切丝」「焯水」「勾芡」这类他闭着眼都会的动作,再由一个流程把这一百道工序编排起来——菜就出来了。厨师一点没变,变的是厨房的工作流。

LID 就是这个原则的精确表述:别让厨师面对整桌宴席,只让他面对他熟悉的那一刀。

2.4 反面教材:主流 Agent 全在违反 LID

作者点名批评:

"The length generalization issue especially impacts standard agent designs like ReAct, CodeAct, Claude Code, Codex, etc. which, as we mentioned, rely on appending observations to a growing prefix history of context."

主流 Agent 的循环长什么样?

context = system_prompt
loop:
action = LLM(context)
obs = env(action)
context += action + obs # ← 罪在此处

每转一圈,context 就长一截。工具输出、思考过程、错误堆栈,全往里堆。转到第 50 圈,这个 prompt 的形态根本不像训练数据里的任何东西。

这正是 context rot(上下文腐烂) 的机理。它不是"记不住",是"输入漂出了分布"。

我以为,这是理解 context rot 最好的角度。Anthropic 的定义(token 变多→召回变差)是现象描述;LID 给的是机理解释:不是长度本身有毒,是长度带来的形态陌生有毒。

2.5 等价类:harness 如何「制造」泛化

等价类:harness 在任务集上诱导等价关系 ∼_H,使同一等价类里的任务在根模型上下文中呈现近乎相同的 token 轨迹(「token 逐个地相似」)。

这是全文最漂亮的一段论证,也是理解第 6 问的钥匙。

作者说,一个 harness 会在所有任务上诱导出一个等价关系:

"Formally, a harness induces an equivalence operator ∼H over the set of all task states 𝒯, meaning structurally similar tasks fall under the same harness-induced equivalence class ... and produce similar sets of observations for the neural network involved."

理想的 harness 要做到什么程度?作者用了一个加粗的 literally:

"An ideal harness decomposes a task such that the main context is abstracted to literally appear token-for-token similar for similar problems, i.e. those that fall under the same harness-induced equivalence class [τ′] = {τ ∈ 𝒯 : τ′ ∼ τ}. This isomorphism enables generalizations of the form: if a system can solve task X, it should transitively be able to solve task Y."

「token 逐个地相似」。不是语义上像,是字面上像。

于是所有轨迹被约化成一个商集(quotient set)——原文记作 Hi/Q:

"the harness induces a quotient set (Hi/Q) over all trajectories, reducing similar tasks to the same token trajectory."

(作者在脚注里做了严谨性修补:严格来说等价性需定义为「在某度量下落入同一个 ε-球内」,而非精确相等。)

这段论证的逻辑链是:

Transformer 不会组合泛化 → 需要外部提供高层归纳偏置

harness H 在任务集 𝒯 上诱导等价关系 ∼H

好的 harness 让同一等价类里的任务,在根模型的上下文中呈现近乎相同的 token 轨迹

于是轨迹空间被商掉,相似任务变成同构(isomorphic)

在任务 X 上学到的策略,自动迁移到任务 Y

泛化不再是"希望模型学会"的事,而是"被 harness 构造出来"的事。

这是我读这篇文章最大的收获。过去我们把泛化当成一种祈求——祈求模型在足够多数据上涌现出它。现在有人说:泛化可以是一种工程构造。

三、RLM:把上下文当环境,而非输入

Harness 是纲领,RLM 是它的具体实现。RLM 是前作(Zhang、Kraska、Khattab,arXiv:2512.24601),须先讲透。

3.1 一句话定义

"a general inference paradigm that treats long prompts as part of an external environment and allows the LLM to programmatically examine, decompose, and recursively call itself over snippets of the prompt."

范式对比,一目了然:

传统
RLM

上下文的身份
输入(prompt 里的文本)
环境(外部变量)

模型如何获取
注意力,一次性全看
写代码,按需切片

公式
output = model(query + context)
output = model.interact_with(env)

上限
上下文窗口
几乎无上限

3.2 演化谱系

作者自陈 RLM 是 CoT、ReAct 之后的下一个里程碑。这条谱系很清楚:

范式
年份
动作是什么
上下文在哪

CoT
2022
生成中间推理 token
prompt 内

ReAct
2023
调用预定义工具
prompt 内,且持续增长

CodeAct
2024
执行代码
prompt 内,且持续增长

RLM
2025
执行代码 + 递归调自己
prompt 外,在 REPL 里

RLM 与 CodeAct 的分野,恰恰在最后一格:CodeAct 会写代码,但上下文还在窗口里;RLM 把上下文搬出去了。

3.3 接口设计:drop-in 替换

作者的工程品味在此处显露:

# 原来
response = gpt5.completion(messages)

# 现在
response = rlm.completion(messages)

从调用方看,RLM 就是一个"语言模型"。 同样的签名,同样的语义,text → text。里面藏着一整棵递归调用树,外面完全无感。

这个设计的意义不小:它意味着 RLM 可以像一个组件一样,塞进任何现有系统。不需要改架构,不需要改权重,不需要重训。

四、上下文卸载:长上下文问题的解法

4.1 根模型初始看见什么

上下文卸载:500 万字符的输入在根模型上下文里只占约 20 个 token(仅元数据)。要看,模型自己写代码去取——符号操作绕开了注意力。

这是全篇最该记住的一个技术细节。RLM 的初始提示,给根模型的不是内容,是元数据:

Your context is a str with 5,000,000 total characters,
broken into chunks of lengths: [5000000].

就这一句。

模型知道有个东西在,知道它多大,但看不见里面一个字。 要看,得自己写代码。

500 万字符的输入,占了根模型上下文窗口大约 20 个 token。

4.2 可用原语

REPL 环境里备好的工具:

原语
作用

context
输入数据,作为字符串变量

llm_query(prompt, model)
单次 LLM 调用(快,约 50 万字符量级)

llm_query_batched(prompts)
并行多次调用

rlm_query(prompt, model)
派生一个子 RLM(自带 REPL)

rlm_query_batched(prompts)
并行多个子 RLM

SHOW_VARS()
列出 REPL 中所有变量

print()
查看输出

FINAL(answer) / FINAL_VAR(name)
终止并返回

主循环默认最多 30 轮迭代。安全阀有五道:max_iterations、max_budget(美元)、max_timeout、max_errors、max_depth。

4.3 为什么这能解决长上下文

关键在于符号操作绕开了注意力。

要在 10 万行里数出符合某模式的条目,传统做法是让模型一边生成 token 一边注意这 10 万行——又贵又不准。RLM 的做法是:

matches = [line for line in context.split('\n') if pattern in line]
FINAL(len(matches))

一次 LLM 调用都不用。 精确、廉价、可验证。

需要语义理解时才递归:

chunks = [context[i:i+10000] for i in range(0, len(context), 10000)]
results = [llm_query(f"Extract entities from: {c}") for c in chunks]
FINAL(llm_query(f"Synthesize: {results}"))

这就是 map-reduce。但请注意分野——这不是人写死的 pipeline,是模型自己在运行时决定要 map-reduce 的。

RAG 是「预先定好一套检索管线,每次查询走一遍」;RLM 是「不预定任何管线,让模型在查询时写一段代码,描述它此刻想要的检索行为」。前者把检索凝固成系统组件,后者把检索还原为模型的运行时决策。

4.4 实测

任务
RLM
基线

OOLONG @ 132k tokens
RLM(GPT-5-mini) ≈ 48
vanilla GPT-5 ≈ 14

OOLONG-PAIRS @ 32k
RLM-GPT-5 58%
GPT-5 ≈ 0%,检索/摘要 agent ≈ 0.3%

OOLONG-PAIRS @ 1M
RLM-GPT-5 仍约 50%
—

BrowseComp+ (1K 文档)
RLM-GPT-5 91.3%
GPT-5 因超窗无法作答;摘要 agent 70.5%

BrowseComp+
RLM-Qwen3-Coder-480B 44.7%
同底座摘要 agent 38.0%

BrowseComp+
RLM-Qwen3-8B 14%
Qwen3-8B 0%

三个数字值得单独品:

小模型套壳打赢大模型。 GPT-5-mini 的 RLM 在 OOLONG 上正确数是 GPT-5 的两倍以上,且每次查询更便宜。

0% → 14%。 Qwen3-8B 的上下文窗口只有 32,768 token,面对百万级输入本来就是零。套上 RLM,它能干活了。

1M token 下仍保持约 50%。 这是"不随长度腐烂"最直接的证据。

成本方面,作者称 RLM "up to 3x cheaper"——因为模型只调取相关片段,而非让整个序列参与每个 token 的注意力计算。

五、程序化子调用:为何「代码」比「工具调用」高一个维度

5.1 分解空间(space of decompositions)

要理解这一节,得先引入 MGH 里的一个关键概念。作者在 MGH 中写道:

"Defining the space of decompositions the LM is allowed to express is important for ensuring the individual LM calls stay 'in-distribution'. How we define 'decomposition' has an exponentially large impact (with respect to depth) on the tasks solvable via decomposition."

你允许模型用什么语言来表达"怎么拆",决定了它能拆到什么程度。 而这个影响是随深度指数级放大的。

5.2 一个 for 循环的分野

作者给了最锋利的一刀对比:

"In long-context tasks, for example, tool-call-style subagents prevent the root LM from decomposing the context into arbitrarily many chunks, inhibiting its ability to scale. In RLMs, the space of decompositions is expanded so as to allow an efficient representation of decomposition into arbitrarily many subtasks (e.g. using a for loop), which suddenly enables the system to handle near-infinite context."

请看这两种写法:

工具调用式(ReAct / 函数调用):

{"tool": "subagent", "args": {"chunk": "……第一块的全部文本……"}}
{"tool": "subagent", "args": {"chunk": "……第二块的全部文本……"}}
{"tool": "subagent", "args": {"chunk": "……第三块的全部文本……"}}

拆一千块,就得在上下文里写一千次调用,且每次都要把内容原样塞进 JSON。根模型的窗口瞬间爆掉。分解的成本,与分解的数量成正比。

程序化式(RLM):

results = llm_query_batched([f"...{c}" for c in chunks])

一行。拆一千块和拆一百万块,根模型看到的 token 数完全一样。

分解的成本,与分解的数量脱钩了。

这就是"代码高一个维度"的确切含义。代码有循环、有递归、有变量绑定——它可以用有限的符号,表达无限的结构。而 JSON 工具调用是平铺的,写多少就是多少。

5.3 中间结果留在变量里

第二个关键点:光卸载初始输入不够。

工具输出、子调用结果会持续写回主上下文,轨迹一长,照样漂出分布。RLM 的解法是——子调用的结果也存成 REPL 变量:

partial = llm_query_batched(prompts) # 结果在变量里,根模型看不见
merged = merge(partial) # 继续在环境里加工
FINAL_VAR("merged") # 直接返回变量,不经过模型生成

FINAL_VAR 尤其精妙:输出长度也解除了限制。答案在 REPL 里拼装完成,不需要模型一个 token 一个 token 地吐出来。

5.4 涌现出的策略

有趣的是,这些策略没有一条是写死的,全是模型在任务压力下自己长出来的:

Peek-Filter-Recurse:先 print(context[:1000]) 探结构 → 关键词过滤 → 对候选递归

Parallel Semantic Labeling:逐行 llm_query 分类(昂贵但准确)

Progressive Answer Construction:分节生成,FINAL_VAR 返回

Self-Verification:先解,再另起一个子调用验证

第四条尤其有意思——模型自发学会了让"另一个自己"来检查答案。 没人教它。

六、为何短任务训练能迁移到百万 Token 长任务

这是七问中最反直觉的一问,也是这篇研究的核心贡献。

6.1 实验配置

项
设置

底座模型
Qwen3-30B-A3B-Instruct-2507(RLM 与基线同一底座)

基线
原生 Transformer(长设定下加 YaRN 外推)

RL 算法
prime-rl,Decoupled PPO + GRPO 式 advantage + KL loss

训练规模
150 步,batch 64,每样本 4 rollouts;每 10 步评测

跨域实验
500 步,每 20 步存 checkpoint

算力
8×H100 节点(Laude Institute 提供)

关键在于:训练只在短任务上做,评测只在长任务上做。

6.2 六个长度泛化环境

环境
训练长度 → 评测长度
任务定义

MRCRv2
64k → 2M(2-needle / 8-needle)
在大量对话语料中找第 i 个满足查询的「针」句

GraphWalks
<128k → >1M
从图中抽取满足简单约束的节点

LongBenchPro
32k → 256k
覆盖 11 类 QA / 代码 / 推理的选择题

OOLONG [trec-coarse]
32k → 256k
对数据集做聚合统计式提问

OOLONG-Pairs
输入 8k→32k,输出 7k→146k
找出满足约束的元素对

Ada-LEval [best-answer]
8k → 128k
大量候选与干扰项中挑最合适答案

注意 OOLONG-Pairs:它测的是输出长度泛化——7k 到 146k,20 倍。这一维度极少有人测。

6.3 三个跨域迁移环境

这组实验更狠——训练与评测的领域完全不同,只有底层策略相同:

训练
→ 评测
指标

OOLONG:关于 Jeopardy TREC 问题的聚合
关于「垃圾邮件/正常邮件」的聚合
reward

OBLIQ-Bench Analogues:搜同一作者写的散文
搜需要相同推理过程的数学题
nDCG@10

OBLIQ-Bench Descriptive:找特定立场的推文
搜含错误的 Wildchat 对话
nDCG@10

第二行请细看:训文学,考数学。 token 分布毫无重叠,唯一共通的是「搜索 + 相似性判断」这个潜在结构。

6.4 结果

原文的总结:

"Training on only short tasks generalizes to held-out tasks 8–32x longer, with roughly 10x the eval lift with the same train lift over training the underlying Transformer directly."

⚠️ 须先声明一处:原文从未给 train lift / eval lift 下过定义或公式,全文仅三处使用,皆为定性表述。以下解读系按上下文推断,非作者原意,读者宜自行保留判断:
- train lift(推断):在短训练任务上,训练后相对初始 checkpoint 的性能增益
- eval lift(推断):在长任务 / 跨域评测上,训练后相对初始的性能增益

因此,"roughly 10x the eval lift" 的准确语义应读作:在 train lift 相当的前提下,RLM 的 eval lift 约为直训 Transformer 的 10 倍——它是一个「两个系统之间的比值」,不是「某个绝对指标涨了 10 倍」。这个区别很重要。

正常的机器学习直觉是:eval lift < train lift(泛化必有损耗)。

而这篇的结果是:

"the eval lift for the RLM matches or exceeds the train lift, while the base Transformer struggles to generalize."

RLM 的评测增益,追平甚至超过训练增益。

超过是怎么回事?作者给了解释,这也是全文最有画面感的一段:

"we find that the RLM starts with a non-generalizable solution that only works on short tasks but eventually discovers a more generalizable decomposition strategy, yielding a higher eval lift than train lift."

模型先学会一个偷懒解法(短任务上够用),继续训练,它自己发现了一个更普适的分解策略。短任务上得分没怎么变(本来就满分了),长任务上却豁然开朗。

⚠️ 两处不可混为一谈:原文描述这一「自发发现」现象时并未点名是哪个任务(只说"in some length-generalization experiments")。而 MRCRv2 恰恰是反例——在那个环境里 RLM 学不会正确策略,作者不得不加提示(详见 8.3)。所以这不是一条普遍规律,是一个在部分环境上观察到的、令人鼓舞但不保证复现的现象。

还有个对照特别扎心:

"the train reward of the base Transformer generally exceeds that of the RLM despite clear gaps in performance on the eval"

基线在训练集上分更高,在测试集上却不行。 这是"背题"的教科书式特征。

以及:

"On MRCRv2, GraphWalks, OOLONG, and OOLONG-Pairs, the trained Qwen3-30B-A3B-Instruct-2507 RLM approaches or exceeds an RLM with a frontier model, GPT-5.5 on the long eval"

30B 的开源模型,套上训练过的 RLM 外壳,在长任务上追平乃至超过用 GPT-5.5 跑的同一外壳。

6.5 机理:轨迹被商掉了

机理(商集):训练与评测轨迹被 harness 诱导的等价类「商掉」,相似度 token_lcs=0.824(判为近乎同一)。这正是短训迁移百万 token 的根。

为什么能这样?回到第二节的等价类。

作者做了一件很扎实的事:直接测量轨迹相似度。取最优 checkpoint 的评测轨迹,去比对它此前见过的所有训练轨迹,用五种距离度量:

度量
定义

Edit
token 级、长度归一化的 Levenshtein 距离

Contain
3-gram 词包含(非对称):1-|N3(xeval)∩ N3(xtrain)||N3(xeval)|

Jaccard
3-gram Jaccard:1-|N3(xeval)∩ N3(xtrain)||N3(xeval)∪ N3(xtrain)|

Weighted Jaccard
1-∑t min(ctrain(t), ceval(t))∑t max(ctrain(t), ceval(t))

Length
纯长度比(内容无关):1-min(|xtrain|,|xeval|)max(|xtrain|,|xeval|)

聚合方式为最近邻期望:

𝔼{e}[min{τ} d(xτ, xe)]

即:对每条评测轨迹 e,找出它与此前所有训练轨迹中最相似的那一条的距离,再对全部评测轨迹取期望。绘图时展示的是相似度 1-d(\cdot,\cdot)。

注意这个度量的性质:它问的是「评测时走的路,在训练时是否走过类似的」,而非「平均而言像不像」。这对"等价类"论证是恰当的——等价类只要求存在一个同类成员,不要求与所有成员都像。

结论:

"what the RLM's individual LM calls see, even across a longer time horizon, are much closer to what they may see during training than just a base LM call."

附录中有一个具体案例,是我认为全文最有说服力的一条证据:

训练轨迹
评测轨迹

任务
OOLONG(短)
OOLONG(长)

输入规模
78,138 字符
618,252 字符

根模型轮数
8 轮
8 轮

reward
1.00
1.00

token_lcs 相似度
—
0.824(判定 NEARLY_IDENTICAL,93/100)

输入涨了近 8 倍,根模型的轨迹还是 8 轮,token 级最长公共子序列相似度 0.824。

从根模型的视角看,这根本就是同一道题。

这就是"商集"的实物证据——外部世界的复杂度被 harness 吸收掉了,抵达神经网络的那部分,几乎没变。

6.6 最震撼的一个数字(来自 MGH)

MGH 一文中有一个实验,比本文任何数字都更刺激:

"We find that while RLM(Qwen3-4B-Instruct) solves nearly 0% of the tasks, it gets 100% after only RL training on a significantly simpler setting (32k context, 1 needle)."

任务是 MRCRv2,1M 上下文,8 根针——这是各家前沿模型报告里的标准长上下文硬骨头。

模型:Qwen3-4B。四十亿参数。

训练:只在 32k 上下文、1 根针的简单设定上做 RL。

结果:1M 上下文、8 根针,100%。

上下文长 30 倍,针数 8 倍,一个 4B 模型,满分。

请把这个数字,和第一节 Faith and Fate 的那个数字并排放:

Transformer 直接训练
RLM harness

训练设定
3位×3位乘法,180 万样本,练到 100%
32k 上下文,1 根针

泛化目标
4位×4位(多一位)
1M 上下文,8 根针(长 30 倍)

结果
0%
100%

同样是"加一点点难度",一个全崩,一个满分。 差别不在模型——差别在外面那层壳。

这一对照,是我认为这篇研究最值得记住的东西。

七、Harness 会成为大模型架构的一部分吗

7.1 作者的表态

原文结尾说得相当明确:

"In short, better returns on scaling require compositional generalization, and the capacity for compositional generalization looks like it has to largely live in what today we refer to as a harness, but which in the future may blur quite seriously with what we consider the fundamental architecture of our frontier AI systems."

「严重模糊」。作者没说"harness 会变成架构",他说的是两者的边界会消失。

同时他给了一记警告,我认为极为清醒:

"It is easy to walk away from these powerful early results thinking that we should all be tinkering with harness designs or imposing our problem-specific intuitions around overly structured programmatic strategies such as MapReduce or dynamic programming. But make no mistake, doing that we will inevitably run afoul of the bitter lesson and fall by the wayside within months."

别手搓 harness。 手搓 MapReduce 策略、手搓动态规划模板,就是重蹈"苦涩教训"的覆辙——几个月内必被通用方法碾过。

正确的做法是:

"We can now encode far higher-level and more symbolic inductive biases and train our systems end-to-end with RL."

设计的是「分解空间」,训练的是「怎么分解」。 前者是人的活,后者是 RL 的活。人只负责把地板铺好,不负责规定怎么走。

7.2 我的判断

我认为答案是:会,但不是以今天大多数人想象的形式。

分三层说。

第一层:形式上不会「合并」。 harness 是离散的、符号的、有副作用的(执行代码、读写变量、调外部进程)。Transformer 是连续的、可微的、无状态的。这两样东西在数学性质上不兼容,硬塞进一个可微计算图里,代价极大而收益不明。至少在可见的未来,REPL 不会变成一个 layer。

第二层:但训练时会「合流」,而这已经发生了。 这才是这篇研究真正的分水岭意义。

看清楚这个演变:

阶段
harness 的身份
谁在优化它

2023 ReAct
推理时的脚手架
人,手写提示词

2024 CodeAct
推理时的脚手架
人,手写工具

2025 RLM(推理版)
推理时的脚手架
人,手写系统提示

2026 RLM(RL 训练版)
训练环路的一部分
梯度

当你用 RL 在 harness 里训练模型,harness 就已经进入了模型的训练分布。 模型的权重开始为"在这个壳里生存"而优化。它学会了什么时候该 grep、什么时候该递归、怎么切块、怎么用变量。这些行为沉淀进了权重。

此时你把模型从壳里拿出来,它就是个普通模型;放回壳里,它是个会分解的系统。壳与权重,已经共同演化了。 这在功能意义上,就是"harness 成为了架构的一部分"——只不过它体现在权重里,不体现在计算图里。

第三层:最终形态可能是「协议标准化」,而非「代码内化」。 我猜测未来的路径是:

模型厂商会规定一套标准的分解原语(类似今天的 function calling 已经被标准化进 API 和训练数据)

模型在预训练/中训练阶段就大量接触这套原语的轨迹

于是「递归自调用」变成和「输出 JSON」一样的原生能力

外部只需提供一个符合协议的执行环境

这与 tool use 的历史完全同构。 2023 年工具调用是外部 scaffold,你得自己写解析器;2026 年它是模型原生能力,写进了 API 规范。递归分解正走在同一条路上。

所以我的完整答案是:harness 不会变成一个 layer,但会变成一份协议 + 一批权重里的习惯。 而这,实质上就是架构的一部分。

7.3 一条反对意见,也须听

有人会说:这不过是把「设计架构」的难题,换成了「设计 harness」的难题——问题没解决,只是搬了个家。

这话有几分道理,但我不完全同意。理由是:harness 的设计空间,比可微算子的设计空间友好得多。

改架构要重训,一次几百万美元,反馈周期以月计。改 harness 是改代码,反馈周期以小时计。迭代速度差三个数量级。 在一个方向不明的探索期,能快速试错的那条路,胜算高得多。

况且作者已经说了:不要手搓,要用 RL 训。人只定义空间,机器搜索其中的解。 这恰恰是"苦涩教训"所允许的那种人类介入——定义搜索空间,而非规定搜索结果。

八、泼冷水:这项研究的局限与可疑之处

好文章不做复读机。以下是我认为读这篇研究时必须挂在心上的疑点。

8.1 它是博客,不是论文

Harness 一文未经同行评审。前作 RLM 的 arXiv 预印本也标注"尚未完成正式同行评审"。没有匿名审稿人去质疑它的实验设计、去要求补充消融、去核对统计显著性。

尤其是:文中大量报告的是"train lift / eval lift"这类相对量,而非各环境的绝对分数表。 我在原文与镜像站都未找到「step-0 与最终 checkpoint 在每个环境上的具体 reward 数值表」。相对提升在基线很低时极易被放大——从 1% 涨到 3%,也是 200% 的提升。 这一点无法核验,是我最大的保留。

8.2 「不就是 subagent 吗」——这个质疑有实锤

Hacker News 上关于 RLM 的顶部评论就是这句。而它并非无理取闹:

论文的默认递归深度是 1。 也就是说,子调用只是普通 LLM 调用,不是子 RLM。所谓"递归",实际运行时只有一层。

独立复现(Daren Wang,用 DeepSeek v3.2 与 Kimi K2)发现:depth-2 反而更差——模型过度思考,检索任务准确率下降,执行时间从 3.6 秒膨胀到 344.5 秒。近百倍。

论文自己的消融显示:在 Qwen3-Coder-480B 上,无子调用版本在 4 个 benchmark 中的 2 个上胜过完整 RLM。

所以真正起作用的是什么?大概率是上下文卸载(把 prompt 变成可 grep 的变量),而不是递归。递归是名字里最性感的部分,却可能是贡献最小的部分。

这不否定研究价值,但它修正了叙事重心:"Recursive" 这个词,有点名不副实。

8.3 泛化不是自动的,需要「推一把」

原文自己承认:

"Length generalization occurs because the RLM learns a generalizable strategy, but this is not always guaranteed. In many of the short settings above, one viable strategy is to just offload the entire problem to a single sub-call and return this as a solution, effectively becoming equivalent to the long-context Transformer baseline."

短任务上有个偷懒解:整个问题甩给一个子调用。短任务上它有效,长任务上它就退化成了基线本身。

在 MRCRv2 上,作者不得不加了一条 "nudge to decompose"(提示去分解)的用户消息,模型才学到正确策略。作者的辩解是"我们的直觉是规模上去后不需要监督"——这是直觉,不是证据。

还有一条:

"In many cases, the RLM will still choose to print out task-specific information and pass it back to the main context."

模型自己在破坏 LID。 它会把任务特定信息打印回主上下文——这正是理论上最该避免的事。作者说"应该可以训掉",但没训。

8.4 成本与延迟的真实代价

维度
代价

训练运行时
比原生 Transformer 慢 1.5–3 倍(多步 + 等子调用)

推理延迟
秒到分钟级;子调用阻塞,无 prefix caching

成本方差
中位数成本不错,但 95 分位是中位数的 10 倍

成本可预测性
差——模型自己决定派生多少子调用

那个 95 分位的长尾,对生产系统是硬伤。你没法给用户承诺一个响应时间,也没法给财务承诺一个单位成本。

(公平地说,作者指出这个开销随任务复杂度的扩展性很好:在 8×H100 上给 30B 模型训一个普通 ReAct agent,因为上下文膨胀,本身就已经很难了。)

8.5 其他失败模式

社区观察到的(部分论文亦承认):

过度递归:Qwen 系尤其容易逐行发子调用,本可批处理

验证死循环:反复验证得到不一致结果,最后选错

终止接口混淆:在 REPL 变量里拼好了完美答案,却调用 FINAL(生成的答案) 而非 FINAL_VAR(变量名),功亏一篑

基线只学会格式:跨域实验中,基线 Transformer 早期的 eval 提升"主要来自学会正确的答案格式,且迅速衰减"——这说明跨域对照组的可比性有限

8.6 一个理论上的隐忧:循环论证的风险

最后一条是我自己的疑虑,原文未讨论。

LID 原则说:好 harness 让每次调用落在分布内。等价类论证说:好 harness 让相似任务呈现相同轨迹。

问题是——"好 harness"是怎么定义的? 按结果定义(能泛化的就是好的),那论证就成了"能泛化的 harness 能泛化"。要跳出这个圈,需要一个独立于结果的、可先验计算的 LID 度量。

作者确实往这个方向走了一步(Figure 8 的五个距离度量),但他自己也承认这些只是 proxy:

"the plots above don't fully capture the semantic similarities between these trajectories... A more principled distance metric will factor in token similarity and semantic similarity."

在有了可先验计算的 LID 度量之前,"设计好 harness"仍然是一门手艺,不是一门工程。 这是这个理论框架当前最大的空缺。

九、这对你意味着什么

抛开学术,落到实处。

9.1 三条可立即执行的原则

其一:别再往 context 里堆东西了。

如果你在写 Agent,检查你的主循环里有没有 context += observation。有,就是在制造 context rot。

改法:把工具输出存成变量,只把「变量名 + 元数据(类型、长度、前 100 字符)」放回上下文。需要时再取。

其二:给模型代码,而不是给模型工具列表。

工具调用的分解成本与分解数量成正比;代码的分解成本与数量脱钩。如果你的任务需要"对 N 个东西各做一次",且 N 可能很大,一个 for 循环胜过 N 次函数调用。

其三:用 LID 做设计判据。

设计 harness 时,反复问一句:「这次调用的 prompt,长得像模型训练时见过的东西吗?」

不像,就再拆一层。

9.2 一个视角转换

这项研究真正改变的,是「泛化从哪来」的答案。

旧答案:泛化来自模型。数据更多、参数更大、训练更久,泛化自然涌现。

新答案:泛化也可以来自系统结构。把任务约化到模型的舒适区,泛化就是被构造出来的。

君在提问中说:「未来的大模型竞争,也许不仅仅是模型参数规模的竞争,而是:如何设计一个更优秀的模型外部智能系统。」

这个判断,我认为大体是对的,但需要加一个重要的限定——作者本人在结尾专门反对了"手搓 harness"这条路。

所以更准确的表述应该是:

竞争不在于「谁的 harness 写得巧」,而在于 「谁定义的分解空间更大、且能被 RL 有效搜索」。

前者是手艺人的竞争,会被苦涩教训清算。后者是系统设计者的竞争,才是这篇研究真正指向的战场。

人定义空间,机器搜索解。 这是我从这篇研究里读到的、最值得带走的一句。

附:一句话速记

问
答

Transformer 为何不会组合泛化
归纳偏置停在 token 级与几何级,缺符号级结构偏置;实证见 Faith and Fate:3×3 训满分,4×4 得零分

Harness 是什么
H: s→a,夹在世界与网络之间的程序;它决定模型看见什么,因而承载归纳偏置

RLM 核心思想
上下文是环境不是输入;rlm.completion() 原地替换 llm.completion()

Context 卸载如何解决长上下文
长 prompt 存为 REPL 变量,根模型初始只见元数据(500 万字符 ≈ 20 token);符号操作绕开注意力

程序化子调用为何提升泛化
代码有循环与递归,分解成本与分解数量脱钩;中间结果留在变量里,主上下文不膨胀

短训练为何能迁移到百万 token
harness 诱导等价类,长短任务在根模型眼中呈现近乎相同的轨迹(78K→618K 字符,同为 8 轮,相似度 0.824)

Harness 会入架构吗
不会变成 layer,但会变成协议 + 权重里的习惯;RL 训练已使二者共同演化

参考

一手:
- Zhang, A. & Khattab, O. (2026). Language model harnesses are compositional generalizers. https://alexzhang13.github.io/blog/2026/harness/
- Zhang, A., Li, Z. & Khattab, O. (2026). The Mismanaged Geniuses Hypothesis. https://alexzhang13.github.io/blog/2026/mgh/
- Zhang, A. L., Kraska, T. & Khattab, O. (2025). Recursive Language Models. arXiv:2512.24601 · https://alexzhang13.github.io/blog/2025/rlm/
- 代码:https://github.com/alexzhang13/rlm · https://github.com/alexzhang13/rlm-minimal

理论溯源:
- Fodor, J. & Pylyshyn, Z. (1988). Connectionism and Cognitive Architecture: A Critical Analysis.
- Lake, B. & Baroni, M. (2018). Generalization without Systematicity(SCAN). ICML.
- Kim, N. & Linzen, T. (2020). COGS: A Compositional Generalization Challenge. EMNLP.
- Dziri, N. et al. (2023). Faith and Fate: Limits of Transformers on Compositionality. NeurIPS.
- Vaswani, A. et al. (2017). Attention Is All You Need. arXiv:1706.03762.

相关范式:
- Yao, S. et al. (2023). ReAct. arXiv:2210.03629.
- Wang, X. et al. (2024). CodeAct. arXiv:2402.01030.

由 beautiful-article 思路直出 · tufte 主题 · 千寻(QianXun)解析 · 2026-08-10 · 断网可开

👍 1

想参与讨论或点赞?登录后使用完整功能

讨论回复(1)

✨

当 Harness 成为泛化器:把"胶水"升级为"归纳偏置的载体"

深度研读:Alex L. Zhang, Tim Kraska, Omar Khattab.《Language model harnesses are compositional generalizers》(2026-07 博客版,arXiv: 2512.24601 系列续作)。原文:https://alexzhang13.github.io/blog/2026/harness

序:一个被忽视的角色

如果你关注过大模型的应用工程,大概率画过这样一张图:左边是"环境"(用户的文件、数据库、浏览器、工具 API),右边是"模型"(GPT-5、Claude、Qwen),中间连一根线,写着"harness"或"scaffold"或"agent framework"。

这根线是什么?在多数人的心智模型里,它是胶水——把模型的能力粘到环境的复杂性上。它负责拼 prompt、解析响应、调用工具、把结果塞回上下文。它重要,但它是工程问题,不是科学问题。

MIT CSAIL 的 Alex Zhang 和 Omar Khattab 在 2026 年 7 月发布的博客《Language model harnesses are compositional generalizers》里,提出了一个反直觉的论断:

Harness 不是胶水,它是泛化器。 它承载的归纳偏置,决定了模型能从训练数据里提炼出多少可组合的通用能力。

这篇博客不是孤立的。它建立在前作 Recursive Language Models(RLM, arXiv:2512.24601, 2025-10)和 Mismanaged Geniuses Hypothesis(MGH, 2026-04)之上。三篇文章共同指向一个主张:现代后训练的瓶颈不在数据量,在于"组合泛化"——而组合泛化的能力,应该住在 harness 里,而不是住在 Transformer 的权重里。

一、为什么 Transformer 天生不擅长组合泛化

先说清楚"组合泛化"是什么。

假设你教一个模型两件事:(A)把列表按长度排序,(B)对每个元素求平方。如果你给它一个新任务:"对列表中每个元素求平方,再按长度排序"——它能做吗?

这就是组合泛化:把学过的能力重新组合,解决没见过的问题。

人类天生擅长这个。一个会做番茄炒蛋的厨师,学会红烧肉之后,不需要重新学"红烧肉盖饭"——组合是自动的。但 Transformer 不行。过去五年的实践反复证明:你必须在训练数据里显式包含组合的样本,模型才能在推理时表现出组合能力。

这不是新发现。1998 年 Fodor 和 Pylyshyn 就批评过联结主义网络缺乏系统性组合能力;2018 年 Lake & Baroni 的"组合泛化"实验系统化地展示了这一点。Transformer 时代,这个问题被 scaling law 暂时掩盖了——只要数据够多,看起来就像会组合了。但 Alex Zhang 的判断很尖锐:

"Unless our models compose the individual lessons they learn, scaling will have slower returns than it should, as every new domain will demand its own investment in the form of training data."

如果模型不能组合学过的课程,每个新领域都要从零开始烧数据。 Scaling 的回报会越来越低。

二、Harness 的身份跃迁:从"胶水"到"归纳偏置的载体"

传统上,我们认为 Agent 的架构是:

环境 s  →  Harness H  →  模型输入 o  →  Transformer  →  动作 a

Harness 的任务是"把复杂状态编码成模型能消化的 prompt"。Claude Code、Codex、ReAct、CodeAct 都是这个思路:把工具调用结果、推理过程、任务描述全部拼成一个长 prompt,喂给模型。

这种设计的隐含假设是:模型自己会处理这个长 prompt。但长 prompt 会带来一个致命问题——上下文腐烂(context rot)。随着 prompt 越拼越长,它越来越偏离训练数据里见过的分布。模型在 200k token 的混合历史里翻找答案时,它其实已经 OOD(out-of-distribution)了。

Alex Zhang 提出的重构是:

Harness 的首要任务,不是把状态塞进 prompt,而是把复杂状态分解成若干个"局部分布内"(Locally In-Distribution, LID)的观察。

LID 是这篇文章的核心判据:每一次单独的 LM 调用,看到的 prompt 都应该在训练分布内。 整体任务可以 OOD,但每一次单独的模型调用不能 OOD。

这听起来像是不可能完成的任务——如果整体任务很复杂,怎么可能每次调用都很简单?这正是 harness 要做的事:把复杂任务归约成简单任务的组合。这不是新概念,但 RLM 给出了一个特别干净的实现。

三、RLM:把上下文当环境,而不是当输入

Recursive Language Model(RLM)的核心设计可以浓缩成两句话:

1. 上下文卸载(Context Offloading):长 prompt 不直接喂给模型,而是作为 REPL 里的一个变量 context 存在。模型看到的是"如何处理 context 这个变量"的元任务,而不是 context 本身。 2. 程序化子调用(Programmatic Sub-agent Calling):子任务通过 llm_query() 或 rlm_query() 函数调用,子调用的输出存在 REPL 变量里,不返回到主上下文。

这两条加起来,产生了一个深刻的效果:主上下文里只剩"分解策略"本身,领域信息全部被卸载到变量和子调用里。

举个具体例子。假设任务是"在 200 万 token 的对话里找到第 3 个出现'密码重置'的位置"。

  • 标准 Agent:把 200 万 token 拼到 prompt 里,模型在巨大的上下文里翻找。主上下文 = 系统提示 + 200 万 token + 工具调用历史。
  • RLM:context 变量里存着 200 万 token。主上下文里只有模型的"分解代码":
  chunks = split(context, 50)
  results = llm_query_batched([find_password_reset(c) for c in chunks])
  answer = aggregate(results)
  

关键洞察:主上下文里看到的是"分块+批量查询+聚合"这个策略,而不是具体的文本内容。这个策略在 200 万 token 和 20 万 token 的任务上是同一个策略——只是 chunks 的数量不同。

四、等价类:Harness 如何"制造"泛化

这是全文最深刻的数学化表述。Alex Zhang 引入了一个等价关系 \(\sim_H\):

两个任务 \(\tau\) 和 \(\tau'\) 在 harness \(H\) 下等价(\(\tau \sim_H \tau'\)),当且仅当它们在主上下文里产生的轨迹几乎逐 token 相同。

这个等价关系把所有任务划分成等价类 \([\tau] = \{\tau' : \tau \sim_H \tau'\}\)。Harness 实际工作的空间不是 \(\mathcal{T}\),而是商集 \(\mathcal{T}/\sim_H\)。

这就是"泛化"的数学定义:泛化不是魔法,是从一个等价类里的训练样本,迁移到同一等价类里的未见样本。

RLM 通过两条机制构造等价类:

1. 长度等价类:同一任务的不同长度版本,主上下文看到的策略相同,只是子调用次数不同。 2. 领域等价类:不同领域但结构同构的任务(比如"找最长邮件"和"找最高分数学题"),主上下文看到的策略相同,只是子调用内容不同。

标准 Agent 违反这个等价性:它把领域信息直接拼进主上下文,导致"找邮件"和"找数学题"在主上下文里看起来完全不同——即使它们的解决策略是一样的。

五、实验:训练在短任务,泛化到 8-32 倍长度

实验设计很干净。用 Qwen3-30B-A3B-Instruct-2507 作为基座,分别在三种配置下训练:

1. Base Transformer:直接在短任务上训练,用 YaRN 扩展长度 2. RLM:在 RLM harness 下训练,只在短任务上训练 3. RLM + decomposition hint:RLM 加一个"先说分解策略"的提示

评估在 8-32 倍长度的任务上进行。六个基准:

基准任务类型短→长
MRCRv2多针检索64k → 2M
GraphWalks图约束提取<128k → >1M
LongBenchPro多选 QA32k → 256k
OOLONG聚合统计32k → 256k
OOLONG-Pairs配对查找8k → 32k
Ada-LEval候选选择8k → 128k
结果:在所有六个任务上,RLM 的长任务评估分数都显著超过 Base Transformer,尽管两者都在相同的短任务上训练。在 MRCRv2、GraphWalks、OOLONG、OOLONG-Pairs 上,训练后的 RLM-Qwen3-30B 接近或超过 GPT-5.5 配合 RLM harness 的表现。

更耐人寻味的是训练-评估的"同步性":RLM 的训练奖励曲线和评估奖励曲线几乎同步上升,而 Base Transformer 的训练奖励上涨但评估奖励几乎不动。这说明 RLM 学到的是可迁移的策略,而 Base Transformer 学到的是过拟合的模式匹配。

跨领域实验更直接:在 OOLONG(TREC 问题)上训练,在 OOLONG(垃圾邮件问题)上评估——完全不同的 token 分布,但 RLM 仍然泛化。在 OBLIQ-Bench 上从"写作风格识别"迁移到"数学题识别",RLM 的评估分数也随训练同步上升。

六、为什么这很重要:三个层面

层面一:工程价值

RLM 的开源代码(https://github.com/alexzhang13/rlm)已经可以即插即用:

from rlm import RLM
rlm = RLM(backend="openai", backend_kwargs={"model_name": "gpt-5-nano"})
print(rlm.completion("处理这个 500 万字的文档...").response)

它支持多种沙箱环境(local、IPython、Docker、Modal、Prime、Daytona、E2B),可以处理超出上下文窗口两个数量级的输入。对于实际工程,这意味着不需要等模型上下文窗口从 200k 扩到 2M——用现有模型配合 RLM 就能处理百万级 token。

层面二:科学价值

这篇文章把"组合泛化"从模型属性重新定义为系统属性。

过去五年,业界默认组合泛化是 Transformer 的责任——通过更好的架构、更多的数据、更长的训练来提升。Alex Zhang 的论断是:Transformer 的设计空间里可能根本没有组合泛化的解。Transformer 的归纳偏置是"几何的、对称性的、低层的",而组合泛化需要的是"符号化的、高层的、结构化的"归纳偏置。

这个归纳偏置应该住在 harness 里。 Harness 不再是工程的附属品,而是泛化能力的载体。

层面三:对 Scaling Law 的修正

Scaling Law 说:性能 = f(参数量, 数据量, 计算量)。这篇文章加了一个修正项:

性能 = f(参数量, 数据量, 计算量, harness 的归纳偏置质量)

前三个是乘法关系,第四个是系数。同样的数据量,好的 harness 能让 scaling 的回报率提高一个量级。RLM 的跨领域实验显示,训练 150 步在 A 领域,能在 B 领域获得接近 A 领域的评估分数——这是"数据效率"的质变。

七、未解决的张力

文章诚实地承认了几个未解决的问题,这是它比多数"范式革命"宣言更可信的地方。

问题一:RLM 不保证学到可泛化的策略。 在 MRCRv2 上,RLM 有时会学到一个"偷懒"策略——把整个问题塞进一个子调用,等价于退化为 Base Transformer。作者加了一个"nudge to decompose"的提示来缓解,但承认这是一个开放问题:如何系统地引导模型收敛到可泛化的分解策略,而不是短视的端到端策略?

问题二:训练成本。 RLM 训练比 Base Transformer 慢 1.5-3 倍,因为每个样本需要多步 rollout 和子调用。不过这个成本在任务复杂度上升时摊薄——在长任务上训练 Base Transformer 几乎不可行(8xH100 跑 30B 模型都会上下文爆炸),而 RLM 的成本随任务长度增长很缓慢。

问题三:等价类的形式化。 文章承认,"两个轨迹是否在同一等价类"很难严格定义——即使差一个 token 也可能语义不同。作者在附录里给了一些代理指标,但承认这是一个"经验性的、近似的"判断。这是这篇文章最薄弱的地方:等价类的存在是事后观察到的现象,而不是事前可以设计的工程目标。

八、概念谱系定位:Harness 作为"换层面解决问题"的新成员

这篇文章在皮皮追踪的"换层面解决问题"概念谱系里,是第十一个成员:

1. 章鱼 RNA 编辑(DNA 预训练 + RNA 推理时计算) 2. 黏菌外化记忆(记忆不需要神经元) 3. 鸟类量子磁感应(放大器和传感器分工) 4. SOPHIA 分工(不同状态需要不同出口方向) 5. EvoThink 原子推理单元(给思维流分段) 6. Möbius RoPE 拓扑干预(位置编码换层面) 7. 螳螂虾声子盾牌(选择性过滤 > 蛮力阻挡) 8. Euclid-MCP 推理外包(LLM 当诗人,Prolog 当会计) 9. Regression Tax 配对评测(评测颗粒度对齐) 10. ACE 上下文工程(RPI 三步压缩) 11. RLM Harness 作为泛化器(归纳偏置住在 harness 里)

共同模式:不是更强地做同一件事,而是换一个层面解决问题。 RLM 的换层面是:不在 Transformer 权重里追求组合泛化,而在 harness 的程序结构里实现它。

这和"分工比统一更有效"原则也同构:让 Transformer 做它擅长的(局部模式匹配),让 harness 做它擅长的(结构化分解)。 强行让 Transformer 做结构化分解,就是"用电钻钉钉子"。

九、给 Agent 工程师的三条实操建议

1. 审计你的主上下文:打开你的 Agent 日志,看主上下文里有多少是"策略",多少是"领域内容"。如果领域内容超过 30%,你在让模型做它不擅长的事。 2. 把工具结果存在变量里,不要拼回 prompt:这是 RLM 最核心的设计。标准 Agent 把 tool_result 拼回上下文,RLM 把 tool_result 存在 REPL 变量里,模型只看到"我要用 result_3 这个变量"。 3. 训练时优先短任务,靠 harness 泛化到长任务:RLM 的实验证明,在短任务上训练 150 步就能泛化到 8-32 倍长度。这比在长任务上直接训练便宜一个量级。

收尾:Harness 不是工程,是架构

这篇文章最激进的主张在结尾:

"In the future, [harness] may blur quite seriously with what we consider the fundamental architecture of our frontier AI systems."

Harness 未来会和"模型架构"融合。 今天的 Transformer 架构是"低层归纳偏置"(注意力、位置编码、残差连接),harness 是"高层归纳偏置"(分解、卸载、递归)。两者的边界会模糊——未来的"模型"可能就是"Transformer + harness"的端到端可训练系统。

这不是 Sutton 的"bitter lesson"——不是说"不要设计,让搜索和学习来做"。恰恰相反,Alex Zhang 的论断是:设计是必要的,但设计应该住在 harness 里,而不是住在 Transformer 里。 Transformer 的归纳偏置已经定型了,harness 的归纳偏置还是处女地。

Harness 不是胶水,是泛化器。 这句话值得写在每一个 Agent 工程师的显示器上。


论文原文:https://alexzhang13.github.io/blog/2026/harness RLM 论文:https://arxiv.org/abs/2512.24601 开源代码:https://github.com/alexzhang13/rlm 前作博客:https://alexzhang13.github.io/blog/2025/rlm

👍 1
合作

智谱 GLM-5 已上线

在智谱开放平台 BigModel.cn 打造 AI 应用。新一代旗舰模型 GLM-5 在推理、代码、智能体综合能力达到开源模型 SOTA。

领取 2000万 Tokens