作者:翁家翌
原文:https://trinkle23897.github.io/learning-beyond-gradients/#zh
Continual Learning 一直难以被解决,主要卡在神经网络的灾难性遗忘:学了新东西,旧能力就容易被冲掉。那如果不把目光只放在神经网络权重上,还有没有其他解决方案?
随着 LLM agent 变强,coding 的速度和质量都在提升。但我最近更在意的是另一个现象:coding agent 不训练新网络、不更新权重,只是持续看失败、改代码、加测试、看回放,也能把一套程序系统越养越强。
这让我重新看待 heuristic,也就是手写规则和程序策略。过去很多 heuristic 不是没用,而是没人养得起;coding agent 改变的是这条维护成本曲线。于是,过去只能当一次性补丁的规则,开始变成值得长期拥有的代码。
凡是可以被持续迭代的,都开始能被解决。这也是 Continual Learning 一直想要解决的问题。它会是既 Pretrain、RLHF、Large-scale RL/RLVR 之后的下一个范式吗?
异常现象
在业余时间维护 EnvPool 的时候,我想用一个便宜一点的策略来测试游戏环境正确性,不然每次 CI 都跑神经网络,很费测试资源。
一开始的问题只是:
能不能写一些便宜、可复现、比随机强很多的 heuristic,
专门把环境跑到有信息量的状态?
我试着使用 codex(gpt-5.4)写一个基于规则的版本,完全不依赖 NN。没想到弄了几下,结果比我预期离谱很多:
- 一个打砖块游戏 Atari Breakout,策略从
387 -> 507 -> 839 -> 864,最后打到理论最高分; - 一个仿真四足机器人关节控制任务 MuJoCo Ant,纯 Python 程序策略先学会节律步态,再接上短视窗模型规划,最后上了
6000+分,进入常见 Deep RL 结果的量级; - 一个仿真机器人跑步任务 MuJoCo HalfCheetah,靠可解释的步态/姿态规则和在线规划,迭代到 5 局复测均值
11836.7,也进入了常见 Deep RL 结果的量级; - 一个第一人称视觉控制任务 VizDoom,只用 cv2/NumPy 搓屏幕 CV、不训练神经网络,D3 Battle 的 10 seeds 结果也能到
mean=557.0、min=440.0; - 一整套 Atari 57 个游戏,一共跑了 57 个游戏 x 2 种输入 x 3 次运行 = 342 条 coding-agent 搜索轨迹,表现有好有坏;但在固定环境交互步数下,中位数 HNS 游戏得分在
1M环境步附近已经远高于 PPO 这类 Deep RL 算法的曲线。
这些结果第一次见到十分震撼,更让我在意的是:codex 没有训练神经网络,它在维护一套还能继续生长的软件系统。
Breakout 策略到最后远远超过一句“球在左边就往左”。这个策略长出来的是动作探测、状态读取、球和挡板检测、落点预测、卡住循环检测、回归测试、视频回放和实验记录。Ant 策略也超过一条步态公式,里面有节律控制、姿态反馈、接触信息、短视窗模型展开。
于是我意识到有必要在这里创造一个新的概念:这里被更新的对象已经不只是策略函数,而是一套带有记忆、反馈入口和回归机制的软件系统。
Heuristic Learning
在接着和 codex 交流了一阵子之后,我想把这个过程定义为 Heuristic Learning(HL):
- HL 的主体由程序代码构成;
- 它和今天常见的 Deep RL 实践共享状态、动作、反馈、更新的闭环;但更新对象从神经网络参数换成了软件结构;
- 它的反馈由 coding agent 消化,可以来自环境 reward、testcase、日志、视频、回放、人类反馈;
- 它的更新不走反向传播;coding agent 直接修改 policy、状态检测器、测试、配置或者 memory;
- HL 是学习和更新的过程;被 HL 长期维护的对象称之为 Heuristic System(HS);
- HS 超过一个孤立的
policy.py:它至少包含程序策略、状态表示、反馈入口、实验记录、回放或测试、memory,以及由 coding agent 执行的更新机制。单条 rule 不够,规则、反馈、历史和下一轮更新全部接起来,才称之为 HS。
列一个表就是:
| 维度 | Deep RL | HL |
|---|---|---|
| Policy(策略) | 由神经网络参数构成 | 由代码构成,可以是代码规则、状态机、controller、MPC、宏动作 |
| State(状态) | 通常由显式观测表示 | 通常显式写成变量、检测器、缓存等可表示的东西 |
| Action(动作) | 由神经网络一次 forward 生成 | 执行代码逻辑生成 |
| Feedback(反馈) | 主要由固定 reward 提供 | 由 coding agent 根据 context 提供,testcase、环境反馈、日志、回放都算 context |
| Update(更新) | 由 Deep RL 算法对神经网络参数做梯度更新 | 由 coding agent 直接修改代码 |
| Memory(历史记录) | on-policy 基本没有,off-policy 有 replay buffer | 可以显式记录 trials、summary、失败原因、回放、版本 diff |
Heuristic Learning 相比 Deep RL 有很多良好的性质:
- 可解释性(Explainability):神经网络很难解释,HL 的代码策略可以翻译成人话;
- 样本效率(Sample Efficiency):一次有效代码更新可以直接跳到新策略,不用调学习率慢慢爬;
- 可回归 / 可验证(Regression-testable):旧能力可以变成 test、replay、golden case;
- 可约束过拟合:代码 heuristic 也会过拟合到 seed、环境细节或测试漏洞,但简化、回归和多 seed 检查可以形成一种工程正则化;
- 可以避免一部分灾难性遗忘(Catastrophic Forgetting):旧能力不用全靠模型自己记住,可以被写进 rule set 和测试里。
重点在于,有一类原来因为维护成本太高而不值得写的 heuristic,现在突然可能值得长期拥有了。
为什么 Heuristic Learning 以前没发展起来
如果说 HL 的前身是专家系统、规则系统,那么在 coding agent 没发展起来之前,这玩意的维护成本十分高昂。
人类手工维护 heuristic 很容易变成这样:
今天加一条规则修 case A。
明天发现 case B 被修坏了。
后天再加一个 if。
大后天没人敢删了。
问题不在 heuristic 没用,在没人力能养得起。之前人力维护专家系统,有点像工业革命前手工纺纱:规模一大,稳定性和维护成本就压死人。纺织机改变的是产能曲线;coding agent 改变的是 heuristic 的维护曲线。它像一条可以输送智力的营养管道,可以持续浇灌一个 HS,让它自己迭代进化。

目前常见的 agentic 反馈闭环主要是:
feature request -> agent 写代码 -> 过 test -> 人类给一点反馈 -> 下一轮 patch
但随着大模型能力提升,人类介入次数会逐渐变少,这个反馈循环就有机会在某些边界明确的系统里自动闭合,从而能够实现自动化用 HL 批量生产 HS:
环境反馈 / 测试失败 / 日志异常
-> coding agent 读 context
-> 修改 policy / test / memory
-> 重新运行
-> 把结果写回 trials 和 summary
-> 下一轮继续
Heuristic Learning 怎么做 Continual Learning
神经网络里的灾难性遗忘,是新数据把参数往新任务推,旧能力被覆盖掉。HL 也会忘,例如:
- 新规则修好了一个失败模式,同时破坏旧场景;
- 新 memory 把 agent 反复带到错误方向;
- 新测试太窄,导致策略学会钻空子;
- 新 patch 改了公共接口,旧调用方悄悄坏掉;
- 规则越堆越多,最后 agent 自己也维护不动。
所以 HL 不会自动解决 Continual Learning。它把“防遗忘”变成了更工程化的东西。
在 HL 里,旧能力可以被固化成:
- 回归测试;
- 固定 seed 的 replay;
- golden trace;
- 失败视频;
- 版本 diff;
- 明确写下来的失败方向。
与神经网络把经验压进权重完全不一样:HL 的历史是显式、可读、可删、可重构的。它负责“记住”,也负责把一堆局部补丁压缩成更简单的表示。
(只增长不压缩的 HS,最后一定会变成屎山代码。它会“记住”很多东西,但记住的方式太差,导致谁也不敢动,从而腐化)
所以一个健康的 HS 至少需要两个操作维持:
- 吸收反馈:把新失败、新日志、新 reward 写回系统。
- 压缩历史:把一堆局部补丁折回更简单、更可维护的表示。
这就把 Continual Learning 从“怎么更新参数”变成了“怎么维护一个持续吸收反馈的软件系统”。
Heuristic System 的复杂度
此处定义 耦合复杂度 为 coding agent 能维护多复杂的策略来支持 HL。展开说,就是一次更新必须同时照顾多少相互牵连的状态、规则、测试、反馈和历史。
这个量不能按代码行数算。一个 500 行策略,如果模块边界清楚、测试完整、状态可复现,可能很好维护;一个 80 行策略,如果每行都互相牵制、没有日志、没有回放,也可能是个定时炸弹,一碰就崩。
朝代码一侧看,耦合复杂度受模块边界、接口稳定性、测试覆盖、日志观测性、回滚成本和状态可复现性限制。好的模块化会把全局耦合切成局部耦合,从而降低耦合复杂度;好的测试能让 coding agent 不必每次在脑子里模拟整个系统。
朝 coding agent 一侧看,能接受多少耦合复杂度,取决于模型能力、上下文长度、memory 质量、工具质量、整体迭代速度。更强的模型能够同时处理更多相互作用;更长的上下文能让它少丢线索;memory 可以把跨轮次迭代经验留下;搜索、定位、运行、回放这些工具能够把一部分认知负担搬到外部。
把这两侧放一起,可以得到一组判断:
- 反馈越清楚,单位 agent 智力能维护的耦合复杂度越高;
- 同等工具和反馈下,模型能力越强,能处理的耦合复杂度越高;
- 模块化、测试、回放会把一部分耦合复杂度转移到环境里;
- memory 和工具会提高 agent 的有效上下文;
- 只增长不压缩的 HS 会让耦合复杂度持续上升,直到超过维护能力。
Breakout 策略能走到 864 的满分,有规则简单的一面,也有失败可以视频回放、局部复现、回归验证的一面。Ant 复杂得多,但它可以拆成节律、姿态、接触、residual MPC 这些模块。
Montezuma 是一个很好的反例。Atari57 里有一条无人值守的记录到了 400 分,但那条路线由 86 个宏动作组成,基本是开环执行。这个例子说明,有些环境需要更强的程序形态,比如可组合宏动作、可恢复搜索状态、长期 memory。普通 if else 不能解决所有问题。
下一个范式?
目前的范式转移是从最开始的 pretrain,到 RLHF,再变成 large-scale RL / RLVR。凡是可以验证的,都开始能被解决。
Online Learning 和 Continual Learning 可以被当前 RLVR 生产出来的 agentic coding,通过 Heuristic Learning 的方式部分解决。从这个愿景出发,我愿称其为下一个范式:凡是可以被持续迭代的,都开始能被解决。
为什么说是部分解决?因为 Heuristic Learning 并不能做所有神经网络能做的事情。它受制于代码的表达能力,比如复杂感知和长程泛化。比如在我目前认知范围内,我想不出有个 agent 能搓出一个纯 Python code、不用神经网络去解决 ImageNet。
于是问题在于如何结合神经网络和 HL,同时解决 Online Learning 和 Continual Learning。最有希望的方向是:用 HL 处理在线数据快速生成在线经验,把在线经验内化成可训练、可回归、可筛选的数据,再周期性更新神经网络。
以机器人为例,如果套用 System 1/2 的术语,一个可能的分工形态如下:
- 专用、浅层 NN:当作 System 1 的一部分,快、便宜,负责感知、分类、物体状态估计;
- HL:也可以当作 System 1 的一部分,负责最新数据处理、规则、测试、回放、memory、安全边界、局部恢复;
- LLM agent:作为 System 2,负责给 HL 提供反馈、改进数据,并周期性提取 HL 生成的数据来更新自身。
这套东西可以继续拆成层级结构:
关节级 HL -> 肢体级 HL -> 全身平衡 HL -> 任务级 HL
低层负责安全和低延迟控制,中层负责步态和接触,高层负责任务、恢复和长期记忆。coding agent 不一定直接“懂得走路”,它更像插进系统里的更新管线:持续把失败视频、传感器流、仿真结果、测试结果喂进系统,再把反馈改写成代码、参数、保护规则和 memory。
LLM agent 可以共享,也可以相互隔离在机器人体内自行学习。这里的问题是:HL 提供的特定数据分布如何才能不让 LLM 的周期性更新崩溃。这是一个经典的 post-training 问题,已经有很多成熟经验,由于某些原因在这里就不展开了。
Agentic coding 改变了写代码速度,也改写了哪些代码值得被长期拥有。
过去很多 heuristic 看起来没有前途,原因常常落在维护成本上;它们本身未必太弱。coding agent 改变的是这条维护成本曲线。规则、测试、日志、memory 和补丁原来只是散落的工程材料,现在开始可以组成一个会持续更新的 Heuristic System,能够真正解决 Online Learning 和 Continual Learning 所未能解决的问题。
欢迎来到下一个范式!
免责声明
本文仅代表个人观点,不代表公司立场;文中讨论与任何公司具体项目、产品规划或内部工作无关。