Heuristic Learning:后梯度时代的下一个范式
本文是 Jiayi Weng(EnvPool 作者)于 2026 年 5 月发表的一篇深度博客。核心命题是:当 LLM coding agent 足够强大时,一种全新的学习范式正在浮现——Heuristic Learning(启发式学习)。它不训练神经网络、不更新权重,而是通过 coding agent 持续维护一个纯代码的策略系统,使其在环境中不断迭代进化。
作者在维护 EnvPool 时,想寻找一种便宜的方法来测试游戏环境是否正确运行。每次运行神经网络对 CI 来说太昂贵了。于是他问了一个问题:
他用 Codex 写了一个纯规则版本,完全不用神经网络。几轮迭代后,结果远超预期:
经过多次与 Codex 的迭代后,作者将这个过程命名为 Heuristic Learning (HL),被维护的对象称为 Heuristic System (HS)。
一个 HS 绝不只是孤立的 policy.py。它至少包含:
单条规则不够。规则、反馈、历史和下一条更新路径必须全部连接起来,才构成一个 HS。
| 维度 | Deep RL | Heuristic Learning |
|---|---|---|
| 策略 | 神经网络参数 | 代码:规则、状态机、控制器、MPC、宏动作 |
| 状态 | 通常是显式观测 | 通常是显式变量、检测器、缓存等可读表示 |
| 动作 | 神经网络前向传播产生 | 执行代码逻辑产生 |
| 反馈 | 主要是固定奖励 | 通过 coding agent 上下文提供:测试、环境反馈、日志、回放都算 |
| 更新 | 基于梯度的参数更新 | coding agent 直接编辑代码 |
| 记忆 | on-policy 基本没有;off-policy 有回放缓冲区 | 可显式存储试验、摘要、失败原因、回放和版本差异 |
如果 HL 有祖先,那就是专家系统和规则系统。在 coding agent 出现之前,它们的维护成本高得可怕。
问题不是启发式无用,而是人类负担不起持续维护的成本。手动维护专家系统有点像工业革命前的纺纱:一个人可以做,但一旦规模增长,稳定性和维护成本就会压垮一切。
当模型能力提升后,人类的干预应该缩小。在边界清晰的系统中,反馈循环可以开始自动闭合:
神经网络中的灾难性遗忘发生在新数据将参数推向新任务时,旧能力被覆盖。HL 也会遗忘,只是以更具工程感的形式:
所以 HL 并不自动解决 Continual Learning。它将"避免遗忘"转化为一个更工程导向的问题。
在 HL 中,旧能力可以被固定为:
这将 Continual Learning 从"如何更新参数?"转变为"如何维护一个持续吸收反馈的软件系统?"
作者定义了耦合复杂度:coding agent 为支持 HL 所能维持的策略复杂度水平。更具体地说,是一次更新必须同时考虑的相互依赖的状态、规则、测试、反馈信号和历史约束的数量。
耦合复杂度受模块边界、接口稳定性、测试覆盖率、可观测性、回滚成本和状态可复现性限制。良好的模块化将全局耦合切割为局部耦合,减少 agent 必须同时在脑中维护的复杂度。
取决于模型能力、上下文长度、记忆质量、工具质量和迭代速度。更强的模型能同时处理更多交互。更长的上下文意味着更少的丢失线程。记忆保留跨轮经验。搜索、定位、执行和回放工具将部分认知负荷移出模型。
Breakout 达到满分 864,部分因为规则简单,但也因为失败可以在视频上回放、本地复现和回归测试。Ant 复杂得多,但它分解为节律、姿态、接触和残差 MPC 模块。Montezuma 则是一个有用的反例:一条无人看管的运行达到 400 分,但路径由 86 个宏动作组成,基本上是开环执行。这说明某些环境需要更强的程序形式:可组合的宏动作、可恢复的搜索状态和长期记忆。Plain if-else 不能解决一切。
Breakout 看似几何问题:球在哪、挡板在哪、球撞墙后会落在哪里?难点在后面。策略可以持续回球,但不再打到新砖块,分数陷入稳定循环。
| 版本 | 分数 | 关键机制 |
|---|---|---|
| baseline_v0 | 99 | 初始 RAM 截距 |
| tunnel0_v1 | 387 | 无 tunnel 偏移 |
| stuckbreaker | 507 | 卡死循环破解器:长期无奖励时给落点加偏移 |
| fastlead | 839 | 快速低球提前量 |
| final | 864 | 残局释放偏移 + 挡板漂移补偿 |
387 是一种会迷惑人的局部高分。策略已经擅长回球,但它把球送入了周期性路径:不会死,但也不会清除更多砖块。Codex 检查视频和轨迹后,定位到问题:球轨迹缺乏扰动。第一个有效机制是循环破解:如果长时间无奖励,周期性地给预测落点加偏移,把球打出局部循环。
然后出现了另一种失败模式。对于快速低球,追逐普通截距会让挡板过度领先并漂移。Codex 添加了 fast_low_ball_lead_steps=3。
从 839 到 864 更像是维护一个已经复杂的系统。Codex 尝试了死区、发球偏移、砖块平衡偏置和前瞻步数。大多数方向无效。最终有用的改变是残局条件:第一面砖墙后,只有当球还远离挡板时才应用卡死偏移;当球靠近时逐渐释放偏移。还添加了微小的挡板漂移补偿。
最终的 RAM 配置在三局验证中均为 864/864/864。之后 Codex 将同一几何控制器迁移回纯图像输入:无 RAM,仅用 RGB 分割检测挡板、球和砖块平衡。图像版先得分 310,然后 428,最终在七次本地策略 episode 后达到 864,对应 14,504 个本地策略环境步。
作者一开始没有指定"用 CPG"或"用 MPC"。约束很简单:不训练神经网络、本地可复现、每轮留记录、持续推高分数。Codex 首先读取 EnvPool/Gymnasium Ant 的观测和奖励,确认动作顺序、根速度、躯干朝向、关节位置和速度,然后自己提出了第一个节律步态。
第一个版本是四腿相位振荡器:左右腿反相,髋和踝关节跟踪正弦目标角度,动作由 PD 控制器产生。五随机种子均值 2291,已经远超随机。
| 版本 | 分数 | 关键改进 |
|---|---|---|
| ant_lr_cpgpd_v1 | 2291.9 | 左右反相 CPG + PD |
| ant_yawaxis_grid_v2 | 2857.9 | 偏航反馈 + 重调参数 |
| ant_h3_428_v1 | 3162.0 | 二/三次谐波 |
| ant_mpc_residual_v1 | 3635.5 | horizon=6, candidates=32 |
| ant_mpc_residual_cfg4 | 3964.7 | horizon=8, candidates=48 |
| ant_mpc_residual_cand07 | 4647.1 | MPC 配置局部搜索 |
| ant_mpc_residual_warm02 | 5165.2 | warm-start 残差计划 |
| ant_mpc_fast065x060 | 5759.4 | 更快步态 + 更大残差 |
| ant_mpc_term001 | 6054.5 | 终端速度代价 |
| ant_mpc_default_adaptive | 6146.2 | 速度自适应相位 + 姿态 |
跳跃来自残差 MPC。粗略地说,MPC 就是"边走边想一小段未来"。保持节律步态作为基础反射;在每个真实环境步,在本地 MuJoCo 模型中采样几十个小的残差动作序列,评分它们,只执行第一个残差动作,然后在下一步重新观测和重规划,用未完成的先前计划作为热启动。
同一家族的另一个证据。五轮评估 mpc-staged-tree-asym-pd-cpg,seeds 100..104,均值 11836.7,min=11735.0,max=12041.2。策略使用可解释的步态/姿态规则和在线 staged-tree MPC:先通过 CPG/PD 形成高分步态,然后用短视界模型评分和分段摆动幅度调度来调整动作。
VizDoom 是第一人称视觉控制任务,进一步证明 HL 不依赖神经网络也能处理视觉输入。
检验在正确时间收集医疗包是否能接近奖励上限。先用更强的 object/info 策略验证行为上限(10 seeds 约 1.01);然后移除不可复现信息,只保留 pip EnvPool、render() 的屏幕像素和公共 HEALTH 变量。最终纯 CV 版本用亮度阈值、形态学 close/dilate 和连通分量找到医疗包,用边界框中心决定转向或前进。如果健康仍高且医疗包已接近,则原地等待直到健康衰减后再收集。10 seeds 达到 mean=0.9441,min=0.2900。
更接近 FPS 烟雾策略。它不是记忆化的地图路线;行为分解为三个循环:可见时击杀怪物、健康或弹药低时寻找补给、无目标时快速探索。屏幕侧使用 cv2/NumPy 颜色阈值和连通分量提取敌人候选、弹药/健康物品候选、以及墙壁和门口的暗区比例。从 EnvPool info 只使用公共游戏变量如 HEALTH、AMMO2、HITCOUNT、DAMAGECOUNT、KILLCOUNT。迭代循环是并行运行 10 seeds,通过 render() 直接录制 35fps 10 网格视频,检查失败模式。最终版本保留屏幕 CV 加公共变量作为闭环控制器。10 seeds 达到 mean=557.0,min=440.0。
Breakout 和 Ant 是单点故事。Atari57 问的是:当工作流离开几个漂亮例子后,还剩下什么?
直接在整个 Atari57 套件上运行相同的 Codex 工作流,每个环境两种观测模式,每种模式三个独立重复:
无人给出逐步提示。每个 agent 收到相同模板和不同的 ENV_ID / OBS_MODE / REPEAT_INDEX,然后运行直到停止。每个运行必须输出 policy.py、trials.jsonl、summary.csv、sample_efficiency.png 和 README.md。
传统神经网络 Atari 学习必须在每个环境中从高维输入重新学习表示、信用分配和动作含义。Codex 反而将每个环境分解为小型可维护的程序系统:射击游戏中的瞄准和躲避、接球游戏中的弹跳预测、躲避游戏中的位置规则、包装器细节,以及每个环境自己的失败实验记录。
有些环境不适合普通的反应式启发策略。Montezuma's Revenge 就是典型例子。
在 Atari57 原生图像批量中,一条无人看管的 Codex 运行达到了 400.0 分:seed 10001,1769 环境步。它本质上是由 86 个宏动作 组成的开环路线。
Montezuma 暴露了一个表达力问题。普通的 policy.py 状态机难以表示这种路线:动作必须与时机对齐,失败需要恢复,中间状态需要重新进入计划的方式。有些环境需要可组合的宏动作、可恢复的搜索状态和长期记忆。Plain if-else 不能解决一切。
当前的范式迁移已经从预训练到 RLHF,再到大规模 RL / RLVR。任何可以被验证的东西都开始变得可解。
在线学习和持续学习可以部分地通过 RLVR 产生的 agent,经由 Heuristic Learning 来解决。从这个角度,作者称之为下一个范式的候选:任何可以被持续迭代的东西都开始变得可解。
因为 Heuristic Learning 不能做神经网络能做的一切。它受代码能表达的内容限制,尤其在复杂感知和长视界泛化方面。用作者今天所知,无法想象一个 agent 不用神经网络、只用纯 Python 代码解决 ImageNet。
最有希望的方向似乎是:用 HL 快速处理在线数据,将在线经验转化为可训练、可回归测试、可过滤的数据,然后定期更新神经网络。
层次结构:关节级 HL → 肢体级 HL → 全身平衡 HL → 任务级 HL
Welcome to the next paradigm.