开源Agent框架刷榜ARC-AGI-3背后:RLM Harness的工程真相与自我改进争议 最近有一个现象值得所有做大模型应用的人注意一个开源 Agent 框架在 ARC-AGI-3 上拿到了非常亮眼的成绩直接引爆了社区讨论。紧接着“自我改进的 RLM harness”这个说法开始刷屏有人把它当作开源模型追平闭源标杆的信号也有人泼冷水说这只是把测试时计算和验证循环做得更精致离真正的“自我改进”还很远。这场争论的双方看似在争一个结果实际上是在用同一句话描述两件不同的事。要判断谁更有道理必须先搞清楚 ARC-AGI-3 为什么难、RLM 是什么、harness 在工程上到底做了什么以及“自我改进”这四个字在技术语境里能不能被严格定义。这篇文章会把概念、争议和一个最小可运行的评测 harness 示例放在一起讲最后给出我对这场争论的判断。1. 先把这场争论的背景说清楚ARC-AGI 是一系列专门用来测试“抽象推理与泛化能力”的评测基准最初由 François Chollet 提出。和常见的问答、代码或数学基准不同ARC 的任务只有少量输入输出网格示例模型需要从几个例子中推断出变换规则再把它应用到新的测试输入上。这个设计从一开始就针对“记忆型模型”题目足够新颖训练数据里几乎没有现成答案可以背。ARC-AGI-2 已经把难度拉高了一大截而这次的 ARC-AGI-3 在公开信息中被称为“目前最难的一代”在防记忆、防暴力搜索上做了更严格的设计。正因如此当一个开源 Agent 框架在上面拿到高分时社区的反应才会这么强烈。大家好奇的不是“分数高不高”而是“它到底是怎么做到的”。真正引起争议的是这个方案背后的“自我改进 RLM harness”。从技术拆解看它并不是让模型在训练阶段更新权重而是在推理阶段让模型反复生成候选程序、执行、验证、再修正直到程序能在训练样例上完全正确。这种“递归式自我修正”能不能叫“自我改进”是整场争论的焦点。我的判断很明确这件事对工程界的真实价值不是“开源模型突然变聪明了”而是 harness 工程Harness Engineering第一次被推到台前——通过给模型配置执行器、验证器、记忆和预算控制一套可控的外壳就可以显著改变模型在复杂推理任务上的表现。这篇文章会从四个核心概念讲起再给出可落地的 harness 示例最后把争议拆成技术问题逐个分析。2. 四个关键概念ARC-AGI-3、Agent框架、RLM、harness在进入代码之前必须先把概念对齐。这组词在讨论里经常被混用而它们之间的边界恰恰是理解争议的关键。2.1 ARC-AGI-3专门用来“防背题”的评测集ARC 的全称是 Abstraction and Reasoning Corpus中文一般译为“抽象推理语料库”。每个任务包含几组“输入网格-输出网格”对网格是带颜色的二维矩阵颜色用数字表示。模型要做的不是记忆某个领域知识而是看懂“把红色块移动到黄色块旁边”“按规律旋转整个图形”这类抽象变换然后对测试输入生成正确输出。ARC-AGI-1 发布于 2019 年当时的模型得分很低人类却很容易完成。ARC-AGI-2 在 2025 年发布后把绝大多数模型打回原形随后 ARC-AGI-3 又进一步提高了题目难度和防记忆强度。这个基准的核心理念是智能不是“知道多少”而是“在少量样本下能多快地学会新技能”。所以它天然不欢迎背题也不欢迎针对旧题反复调参的刷榜策略。对工程师来说ARC 类任务的最大特点不是花哨而是“验证明确”输出要么和标准答案逐格相等要么错误。这种二值化验证恰好为 harness 自动化提供了条件。2.2 Agent 框架让模型能写、能跑、能改Agent 框架指的是以 LLM 为核心加上规划、工具调用、记忆、执行和反馈等模块的自动化系统。一个典型的 Agent 不是一个模型单打独斗而是模型负责思考框架负责让模型调用 Python、读取文件、操作接口再根据执行结果决定下一步。在 ARC-AGI-3 这类任务里Agent 框架的价值在于它允许模型不直接“说出答案”而是“写一段程序来生成答案”。程序能不能跑、输出对不对由执行器和验证器判断。模型根据报错信息和验证结果反复修改程序直到通过全部训练样例。这种“生成-执行-验证-再生成”的循环是本次刷榜方案最核心的工程结构。2.3 RLM递归语言模型还是推理语言模型“RLM”在社区里有两种常见解读。一种是 Recursive Language Model递归语言模型模型生成一个候选解决方案后观察执行结果再基于结果递归地调整自己的方案。这里的“递归”指的是同一个模型在一条闭环里反复作用于自己的输出正是这种结构让“自我改进”这个说法有了来源。另一种是 Reasoning Language Model推理语言模型泛指那些在输出之前会进行多步推理、或者输出推理轨迹的语言模型。这个理解更宽泛几乎涵盖了所有带思考链的模型。在 ARC-AGI-3 的刷榜语境里大家讨论的“RLM harness”更接近第一种模型在任务内部对自己生成的程序做迭代修正。需要注意这种迭代发生在测试时test time并不是训练时更新权重。理解这一点是看懂后面所有争议的前提。2.4 Harness模型外面的那一圈工程Harness 这个词原意是“马具”在 AI 工程里指模型外壳prompt 模板、API 适配、工具执行沙箱、验证器、记忆管理、预算控制、日志记录全部属于 harness 的范畴。模型是引擎harness 是方向盘、仪表盘和安全带。“Harness Engineering”最近之所以频繁出现在讨论里是因为同样一个模型装进不同的 harness推理效果可能天差地别。近期的搜索热词里deepseek harness、codex harness 频繁出现大量开发者其实在搜索同一个问题怎么把一个开源模型包进一个可控的评测或执行外壳里。把 DeepSeek 这类模型接入自定义 harness用验证回路的思路解决具体推理任务已经成了一类非常典型的工程需求。下面用表格区分 Agent 框架与 Harness这两个概念在争议中经常被混用。维度Agent 框架Harness核心目标完成业务目标如写文档、查数据、操作软件约束、引导、验证模型输出保证过程可控关注问题任务拆解、工具协作、长程规划输入封装、执行沙箱、结果校验、预算控制典型组成Planner、Tools、Memory、ExecutionPrompt 模板、Verifier、Budget、Logging在评测中的角色被测对象测量与控制装置与对方的关系一个好的 Agent 通常内置 harnessHarness 可以独立于 Agent 存在简单说Agent 是“干活的系统”harness 是“驾驭模型的装置”。一个刷榜方案里的 harness决定了模型能看到什么、能做什么、能被验证什么以及最多花多少成本。3. 为什么 ARC-AGI-3 这么难刷榜的难点在哪先看一个 ARC 任务对模型意味着什么。模型拿到的通常只有两到三组网格对比如输入是一个 3x3 网格输出是一个 3x3 网格。再给一组不同尺寸的网格对。模型需要猜出规律比如“把网格中所有黄色块变成绿色”“把蓝色区域顺时针旋转 90 度”。这里的难点有三个。第一规则空间极大。ARC 任务的变换可以涉及颜色映射、几何变换、对象计数、递归填充、条件分支甚至多种规则的组合。理论上能解释两三组样例的规则可能有成千上万条模型必须选出“最符合人类先验”的那条而不是随便一条能解释样例的规则。第二纯文本推理很难做空间抽象。LLM 在自然语言和代码任务上很强但把二维网格的形态变化用一段文字描述清楚再直接推出答案成功率很低。这也是为什么只靠“想”很难拿高分。第三验证结果是二值的。输出网格必须和标准答案逐格相等差一个数字就是零分。这种严格性意味着模型不能靠“差不多对”拿分必须精确。那么开源 Agent 框架是怎么突破的核心思路是“把推理转化为程序合成”模型不为每个任务直接输出答案而是编写一个 Python 函数该函数接收输入网格返回输出网格。harness 用训练样例执行这个程序如果程序能在所有训练输入上得到与训练输出一致的结果就认为它大概率是正确的再用它预测测试输出。这个思路的关键在于ARC 任务的规则本质上是一段可计算程序。只要规则可以被代码表达验证器就能用训练样例把大量错误候选筛掉。刷榜的难点也从“一次猜对”变成了“如何在有限尝试次数里写出一个能通过全部训练样例的程序”后者恰恰是 harness 最擅长解决的问题。4. harness 在工程上到底做了什么看一个最小 ARC harness通常由六个部分组成。第一任务适配器Task Adapter。负责把 ARC 的 JSON 数据转换成模型能理解的文本描述把网格的二维数组渲染成带坐标的字符串并把训练样例组织成结构化的 few-shot 提示。第二模型调用层Model Provider。统一不同模型的 API处理重试、超时、限流保证模型接口对上层 harness 透明。第三求解器Solver。决定模型采用什么策略生成候选程序可以是直接生成 Python 函数也可以是先生成思路再翻译成代码还可以在失败后让模型阅读执行报错并修正。第四执行器Executor。在沙箱环境里运行模型生成的程序。这一步必须隔离禁止网络访问设置超时防止模型写出死循环或危险操作。第五验证器Verifier。用训练样例判断候选程序是否正确。ARC 任务适合用“网格逐格相等”的严格验证这种方式客观且无歧义。第六预算与记忆Budget Memory。记录每个任务已经尝试的次数、消耗的 token、执行时间把历史和失败原因回传给模型避免重复犯同样的错误。把这些组件用配置表达出来就是一个典型的 harness 配置。下面是一个参考示例# configs/harness_agent.yaml harness: model: provider: openai-compatible base_url: ${API_BASE} api_key_env: API_KEY name: deepseek-chat temperature: 0.4 solver: mode: program-synthesis max_attempts: 8 include_history: true executor: sandbox: docker image: python:3.11-slim network: disabled timeout_seconds: 10 verifier: mode: train-exact-match compare: grid-equality logging: save_history: true trace_tokens: true这份配置值得注意的几点max_attempts限制单任务最多尝试 8 次防止无限重试executor.network设为 disabled避免模型生成的代码访问外部网络verifier.mode使用训练集严格比对而不是让模型自己判断对错logging.trace_tokens用于记录每次调用的 token 消耗因为成本透明度是争议中的核心问题。之所以说“harness 工程正在成为第一道方法论门槛”是因为同样的底座模型在这种配置下和裸提示词下的得分差距可能是数量级的。这也解释了为什么“harness 和 agent 区别”会成为热门搜索很多人想弄清楚自己搭的 agent 不聪明到底是模型不行还是外壳不行。5. 一个最小可用的开源评测 harness 示例附代码下面给出一个最小可运行的 ARC 评测 harness。假设你有一个可通过 OpenAI 兼容接口调用的模型并且把 ARC-AGI-3 任务数据放在./arc-agi-3目录下。5.1 加载任务# arc_harness/load_task.py import json from pathlib import Path def load_task(task_id: str, data_dir: Path) - dict: 从 ARC-AGI-3 的 JSON 文件加载单个任务。 path data_dir / f{task_id}.json with open(path, r, encodingutf-8) as f: task json.load(f) return task def describe(task: dict) - str: 把任务的关键结构打印出来便于调试。 lines [] for i, pair in enumerate(task[train]): inp pair[input] out pair[output] lines.append( fTrain[{i}] input{len(inp)}x{len(inp[0])} foutput{len(out)}x{len(out[0])} ) for i, pair in enumerate(task[test]): inp pair[input] lines.append(fTest[{i}] input{len(inp)}x{len(inp[0])}) return \n.join(lines)5.2 核心求解循环这个循环是 harness 的引擎反复调用模型生成程序在训练样例上验证通过后再预测测试输出。# arc_harness/harness.py from dataclasses import dataclass dataclass class Budget: max_attempts: int 8 max_total_tokens: int 32000 timeout_seconds: int 10 class ModelAPI: 对模型的封装需要实现两个方法。 def generate_program(self, task: dict, history: list) - str: 调用模型生成一个 Python 函数 solve(grid) - grid。 raise NotImplementedError def safe_exec(self, program: str, grid: list): 在沙箱中执行程序返回输出网格失败返回 None。 raise NotImplementedError class ARCHarness: def __init__(self, model_api: ModelAPI, budget: Budget): self.model_api model_api self.budget budget def solve(self, task: dict): history [] for i in range(self.budget.max_attempts): program self.model_api.generate_program(task, history) ok True for pair in task[train]: pred self.model_api.safe_exec(program, pair[input]) if pred is None or pred ! pair[output]: ok False break if ok: predictions [ self.model_api.safe_exec(program, pair[input]) for pair in task[test] ] return { program: program, predictions: predictions, attempts: i 1, } history.append({attempt: i, program: program, ok: ok}) return None这段代码的逻辑很直白只有候选程序能在所有训练样例上都得到与标准答案一致的输出才被接受然后用于预测测试集。history会把前几次失败的程序返回给模型让模型看到错误后再修正。5.3 运行评测假设评测脚本已经写好命令行运行方式如下python -m arc_harness.eval \ --data-dir ./arc-agi-3 \ --config configs/harness_agent.yaml \ --task-list sample_tasks.txt \ --output results/run_1.json预期输出类似task 0001: PASS (attempt 2, exec 0.9s, tokens 6240) task 0002: FAIL (max_attempts exceeded) ... accuracy: 0.36 (9/25), total_tokens: 298120, avg_attempts: 4.8这个示例告诉我们刷榜方案的工程本质并不神秘就是“程序合成 训练集验证 测试集推理”。真正拉开差距的是每次尝试的质量、历史信息的利用方式、代码沙箱的效率和预算控制策略。6. 手把手验证结果判断“自我改进”是否成立面对“自我改进”这类说法第一步不是争论词义而是检查评测过程是否规范。ARC 任务的结果是严格的网格相等所以不需要模糊评分但恰恰因为验证严格评测中的“信息泄漏”会非常隐蔽。需要检查以下几个方面。第一测试真值有没有泄漏给求解器。正确的 harness 只把训练样例给求解器测试输出的标准答案只存在于独立评测脚本里。如果在 prompt 里混入了测试答案验证器再严格也没有意义。第二尝试次数和 token 预算是否透明。所谓的高分可能是每道题尝试几百次换来的。ARC-AGI 本身的哲学是“少量样本下快速学会”如果每道题消耗几十万 token就算分数再高也偏离了基准的设计初衷。第三验证器是否独立。如果让模型自己判断“我这次的结果对不对”很容易出现自我确认偏差。ARC 场景下应该用程序化验证也就是逐格比较如果必须用模型验证也应该用独立的评判模型。第四结果是否可复现。固定模型版本、temperature、随机种子、prompt 模板和评测脚本后两次运行应得到一致的分数。可复现是科学结论的底线也是判断“改进”是否真实存在的前提。下面是一个自检清单检查项方法通过标准测试集未泄漏审计评测脚本求解器只能访问 train 字段尝试次数受限记录 max_attempts报告贴出真实尝试次数Token 预算一致记录每次调用 usagetotal_tokens 有公开记录结果可复现固定 seed 与模型版本两次运行准确率一致验证器独立使用网格严格比对验证代码与模型输出无耦合做完这套检查再回头看“自我改进”你会发现大多数情况下它描述的不是模型能力的永久变化而是在一次任务内通过多次尝试与反馈提升了单次任务的成功率。这个提升是真实的但它发生在“搜索空间”里而不是“模型权重”里。7. 争议的本质测试时搜索 vs 真正的学习7.1 学习发生在权重里还是搜索里机器学习意义上的“改进”通常指模型权重更新后在多数任务上能力永久提升。但 RLM harness 的“自我改进”一般不涉及权重更新它是在推理阶段让模型根据执行反馈反复修正候选程序。严格来说这是“测试时搜索”不是训练期学习。不过也不能完全否定测试时改进的价值。人类解题时也经常反复试错搜索本身就是智能的一部分。真正的分歧在于这种收益能不能迁移到下一个任务。如果模型解决完