当 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 | 多选 QA | 32k → 256k |
| OOLONG | 聚合统计 | 32k → 256k |
| OOLONG-Pairs | 配对查找 | 8k → 32k |
| Ada-LEval | 候选选择 | 8k → 128k |
更耐人寻味的是训练-评估的"同步性":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