🧠 Learning Beyond Gradients

Heuristic Learning:后梯度时代的下一个范式

✍️ Jiayi Weng 📅 2026-05 🔗 trinkle23897.github.io

📑 目录导航

📌 内容总览

本文是 Jiayi Weng(EnvPool 作者)于 2026 年 5 月发表的一篇深度博客。核心命题是:当 LLM coding agent 足够强大时,一种全新的学习范式正在浮现——Heuristic Learning(启发式学习)。它不训练神经网络、不更新权重,而是通过 coding agent 持续维护一个纯代码的策略系统,使其在环境中不断迭代进化。

864
Breakout 理论最高分
6146
Ant 纯代码策略
11837
HalfCheetah 均值
557
VizDoom D3 Battle
342
Atari57 搜索轨迹
0
神经网络参数更新
💡 核心洞察:关键转折不是 coding agent 让写代码更快,而是它改变了哪些代码值得长期维护的经济学。过去手动维护启发式规则的成本高到不可接受,现在 coding agent 可以持续迭代一个软件系统,让启发式规则从一次性补丁变成可持续演化的资产。

🎯 The Anomaly:异常实验结果

作者在维护 EnvPool 时,想寻找一种便宜的方法来测试游戏环境是否正确运行。每次运行神经网络对 CI 来说太昂贵了。于是他问了一个问题:

Can we write cheap, reproducible heuristics that are much stronger than a random policy, and use them to drive environments into informative states?

他用 Codex 写了一个纯规则版本,完全不用神经网络。几轮迭代后,结果远超预期:

✅ 真正令人惊讶的不是分数,而是 Codex 并没有在训练神经网络。它在维护一个可以不断成长的软件系统。Breakout 策略早已超越了"球在左边就往左走"的简单规则,它演化出了动作探针、状态读取器、球和挡板检测器、落点预测、卡死循环检测、回归测试、视频回放和实验日志。

💡 Heuristic Learning 核心概念

经过多次与 Codex 的迭代后,作者将这个过程命名为 Heuristic Learning (HL),被维护的对象称为 Heuristic System (HS)

HL 的定义

HS 的组成

一个 HS 绝不只是孤立的 policy.py。它至少包含:

单条规则不够。规则、反馈、历史和下一条更新路径必须全部连接起来,才构成一个 HS。

HL 相比 Deep RL 的优势

⚖️ HL vs Deep RL:全面对比

维度Deep RLHeuristic Learning
策略神经网络参数代码:规则、状态机、控制器、MPC、宏动作
状态通常是显式观测通常是显式变量、检测器、缓存等可读表示
动作神经网络前向传播产生执行代码逻辑产生
反馈主要是固定奖励通过 coding agent 上下文提供:测试、环境反馈、日志、回放都算
更新基于梯度的参数更新coding agent 直接编辑代码
记忆on-policy 基本没有;off-policy 有回放缓冲区可显式存储试验、摘要、失败原因、回放和版本差异

⏳ 为什么 Heuristic Learning 以前没有起飞

如果 HL 有祖先,那就是专家系统和规则系统。在 coding agent 出现之前,它们的维护成本高得可怕。

Add one rule today to fix case A.
Tomorrow, case B breaks.
Add another if-statement the day after.
The day after that, nobody dares delete anything.

问题不是启发式无用,而是人类负担不起持续维护的成本。手动维护专家系统有点像工业革命前的纺纱:一个人可以做,但一旦规模增长,稳定性和维护成本就会压垮一切

💡 核心类比:纺纱机改变了生产曲线;coding agent 改变了启发式规则的维护曲线。它们像一个通道,可以持续向 Heuristic System 输送智能,让它不断进化。

当模型能力提升后,人类的干预应该缩小。在边界清晰的系统中,反馈循环可以开始自动闭合:

environment feedback / test failure / log anomaly
-> coding agent reads context
-> edits policy / test / memory
-> reruns
-> writes results back into trials and summaries
-> continues to the next round

🔄 HL 如何做 Continual Learning

神经网络中的灾难性遗忘发生在新数据将参数推向新任务时,旧能力被覆盖。HL 也会遗忘,只是以更具工程感的形式:

所以 HL 并不自动解决 Continual Learning。它将"避免遗忘"转化为一个更工程导向的问题。

旧能力如何固化

在 HL 中,旧能力可以被固定为:

🔑 这与压缩经验到神经网络权重中完全不同。HL 的历史是显式的、可读的、可删除的、可重构的。它负责记忆,但也负责将一堆本地补丁压缩成更简单的表示。
⚠️ 大泥球风险:一个只增长从不压缩的 HS 最终会变成大泥球。它可能"记住"了很多东西,但记忆形式如此糟糕,以至于没人敢碰它,系统 decay。

健康 HS 的两个必要操作

  1. 吸收反馈:将新失败、日志和奖励写回系统
  2. 压缩历史:将本地补丁折叠回更简单、更可维护的表示

这将 Continual Learning 从"如何更新参数?"转变为"如何维护一个持续吸收反馈的软件系统?"

🔗 耦合复杂度(Coupling Complexity)

作者定义了耦合复杂度:coding agent 为支持 HL 所能维持的策略复杂度水平。更具体地说,是一次更新必须同时考虑的相互依赖的状态、规则、测试、反馈信号和历史约束的数量。

💡 关键判断:这不能用代码行数衡量。一个 500 行、模块边界清晰、测试良好、状态可复现、日志清晰的策略可能很容易维护。一个 80 行、每行都影响其他行、没有日志或回放的策略可能是定时炸弹。

代码侧的边界

耦合复杂度受模块边界、接口稳定性、测试覆盖率、可观测性、回滚成本和状态可复现性限制。良好的模块化将全局耦合切割为局部耦合,减少 agent 必须同时在脑中维护的复杂度。

Coding Agent 侧的边界

取决于模型能力、上下文长度、记忆质量、工具质量和迭代速度。更强的模型能同时处理更多交互。更长的上下文意味着更少的丢失线程。记忆保留跨轮经验。搜索、定位、执行和回放工具将部分认知负荷移出模型。

工作假设

Breakout 达到满分 864,部分因为规则简单,但也因为失败可以在视频上回放、本地复现和回归测试。Ant 复杂得多,但它分解为节律、姿态、接触和残差 MPC 模块。Montezuma 则是一个有用的反例:一条无人看管的运行达到 400 分,但路径由 86 个宏动作组成,基本上是开环执行。这说明某些环境需要更强的程序形式:可组合的宏动作、可恢复的搜索状态和长期记忆。Plain if-else 不能解决一切。

🎮 Breakout 实验详解

Breakout 看似几何问题:球在哪、挡板在哪、球撞墙后会落在哪里?难点在后面。策略可以持续回球,但不再打到新砖块,分数陷入稳定循环。

实验轨迹

版本分数关键机制
baseline_v099初始 RAM 截距
tunnel0_v1387无 tunnel 偏移
stuckbreaker507卡死循环破解器:长期无奖励时给落点加偏移
fastlead839快速低球提前量
final864残局释放偏移 + 挡板漂移补偿

387 → 507:卡死循环破解

387 是一种会迷惑人的局部高分。策略已经擅长回球,但它把球送入了周期性路径:不会死,但也不会清除更多砖块。Codex 检查视频和轨迹后,定位到问题:球轨迹缺乏扰动。第一个有效机制是循环破解:如果长时间无奖励,周期性地给预测落点加偏移,把球打出局部循环。

507 → 839:快速低球提前量

然后出现了另一种失败模式。对于快速低球,追逐普通截距会让挡板过度领先并漂移。Codex 添加了 fast_low_ball_lead_steps=3

839 → 864:系统维护

从 839 到 864 更像是维护一个已经复杂的系统。Codex 尝试了死区、发球偏移、砖块平衡偏置和前瞻步数。大多数方向无效。最终有用的改变是残局条件:第一面砖墙后,只有当球还远离挡板时才应用卡死偏移;当球靠近时逐渐释放偏移。还添加了微小的挡板漂移补偿。

纯图像版本

最终的 RAM 配置在三局验证中均为 864/864/864。之后 Codex 将同一几何控制器迁移回纯图像输入:无 RAM,仅用 RGB 分割检测挡板、球和砖块平衡。图像版先得分 310,然后 428,最终在七次本地策略 episode 后达到 864,对应 14,504 个本地策略环境步。

🔑 注意:14.5K 步不应被描述为"纯图像从零到满分"。真实过程是 Codex 先在 RAM 版本中发现了几何控制器、循环破解器和残局偏移释放。结构稳定后,才将状态读取层从 RAM 换为 RGB 检测器。14.5K 是图像版本的迁移预算。

🐜 Ant / HalfCheetah 实验详解

Ant:从节律步态到残差 MPC

作者一开始没有指定"用 CPG"或"用 MPC"。约束很简单:不训练神经网络、本地可复现、每轮留记录、持续推高分数。Codex 首先读取 EnvPool/Gymnasium Ant 的观测和奖励,确认动作顺序、根速度、躯干朝向、关节位置和速度,然后自己提出了第一个节律步态。

第一个版本是四腿相位振荡器:左右腿反相,髋和踝关节跟踪正弦目标角度,动作由 PD 控制器产生。五随机种子均值 2291,已经远超随机。

Ant 迭代轨迹

版本分数关键改进
ant_lr_cpgpd_v12291.9左右反相 CPG + PD
ant_yawaxis_grid_v22857.9偏航反馈 + 重调参数
ant_h3_428_v13162.0二/三次谐波
ant_mpc_residual_v13635.5horizon=6, candidates=32
ant_mpc_residual_cfg43964.7horizon=8, candidates=48
ant_mpc_residual_cand074647.1MPC 配置局部搜索
ant_mpc_residual_warm025165.2warm-start 残差计划
ant_mpc_fast065x0605759.4更快步态 + 更大残差
ant_mpc_term0016054.5终端速度代价
ant_mpc_default_adaptive6146.2速度自适应相位 + 姿态

残差 MPC 的核心思想

跳跃来自残差 MPC。粗略地说,MPC 就是"边走边想一小段未来"。保持节律步态作为基础反射;在每个真实环境步,在本地 MuJoCo 模型中采样几十个小的残差动作序列,评分它们,只执行第一个残差动作,然后在下一步重新观测和重规划,用未完成的先前计划作为热启动。

base = cpg_action(phase, q, dq, roll, pitch, yaw, rates, contacts, vx)

best_plan = previous_plan.copy()
best_obj = rollout_objective(obs, best_plan)
for _ in range(CANDIDATES - 1):
    residuals = clip(best_plan + rng.normal(0.0, MPC_SIGMA, size=(HORIZON, 8)), -MPC_CLIP, MPC_CLIP)
    residuals[1:] = 0.6 * residuals[1:] + 0.4 * residuals[:-1]
    obj = rollout_objective(obs, residuals)
    if obj > best_obj:
        best_obj = obj; best_plan = residuals

plan[:-1] = PLAN_DECAY * best_plan[1:]
return clip(base + best_plan[0], -1.0, 1.0)

HalfCheetah

同一家族的另一个证据。五轮评估 mpc-staged-tree-asym-pd-cpg,seeds 100..104,均值 11836.7,min=11735.0,max=12041.2。策略使用可解释的步态/姿态规则和在线 staged-tree MPC:先通过 CPG/PD 形成高分步态,然后用短视界模型评分和分段摆动幅度调度来调整动作。

🔫 VizDoom 实验

VizDoom 是第一人称视觉控制任务,进一步证明 HL 不依赖神经网络也能处理视觉输入。

D1 Basic

检验在正确时间收集医疗包是否能接近奖励上限。先用更强的 object/info 策略验证行为上限(10 seeds 约 1.01);然后移除不可复现信息,只保留 pip EnvPool、render() 的屏幕像素和公共 HEALTH 变量。最终纯 CV 版本用亮度阈值、形态学 close/dilate 和连通分量找到医疗包,用边界框中心决定转向或前进。如果健康仍高且医疗包已接近,则原地等待直到健康衰减后再收集。10 seeds 达到 mean=0.9441,min=0.2900。

D3 Battle

更接近 FPS 烟雾策略。它不是记忆化的地图路线;行为分解为三个循环:可见时击杀怪物、健康或弹药低时寻找补给、无目标时快速探索。屏幕侧使用 cv2/NumPy 颜色阈值和连通分量提取敌人候选、弹药/健康物品候选、以及墙壁和门口的暗区比例。从 EnvPool info 只使用公共游戏变量如 HEALTH、AMMO2、HITCOUNT、DAMAGECOUNT、KILLCOUNT。迭代循环是并行运行 10 seeds,通过 render() 直接录制 35fps 10 网格视频,检查失败模式。最终版本保留屏幕 CV 加公共变量作为闭环控制器。10 seeds 达到 mean=557.0,min=440.0。

🕹️ Atari57 批量实验

Breakout 和 Ant 是单点故事。Atari57 问的是:当工作流离开几个漂亮例子后,还剩下什么?

实验设置

直接在整个 Atari57 套件上运行相同的 Codex 工作流,每个环境两种观测模式,每种模式三个独立重复:

57 games x 2 observation modes x 3 repeats = 342 coding-agent search trajectories

无人给出逐步提示。每个 agent 收到相同模板和不同的 ENV_ID / OBS_MODE / REPEAT_INDEX,然后运行直到停止。每个运行必须输出 policy.py、trials.jsonl、summary.csv、sample_efficiency.png 和 README.md。

核心结果

💡 信号解读:这个比较是关于环境交互效率的,没有把 coding agent 读取日志、写代码、看视频的代价转换成总计算预算。但信号仍然具体:一个非常粗糙的 coding agent 批量工作流,无人检查中间结果,就已经把 Atari57 中位数推到了这些基线的附近。

按游戏分析

传统神经网络 Atari 学习必须在每个环境中从高维输入重新学习表示、信用分配和动作含义。Codex 反而将每个环境分解为小型可维护的程序系统:射击游戏中的瞄准和躲避、接球游戏中的弹跳预测、躲避游戏中的位置规则、包装器细节,以及每个环境自己的失败实验记录。

🏛️ Montezuma:表达力边界

有些环境不适合普通的反应式启发策略。Montezuma's Revenge 就是典型例子。

在 Atari57 原生图像批量中,一条无人看管的 Codex 运行达到了 400.0 分:seed 10001,1769 环境步。它本质上是由 86 个宏动作 组成的开环路线。

Montezuma 暴露了一个表达力问题。普通的 policy.py 状态机难以表示这种路线:动作必须与时机对齐,失败需要恢复,中间状态需要重新进入计划的方式。有些环境需要可组合的宏动作、可恢复的搜索状态和长期记忆。Plain if-else 不能解决一切。

✅ 这种失败对 HL 很有价值。它告诉我们边界在哪里,并暗示下一层抽象。有些反馈需要新的表示和新的程序形式才能进入系统。对于 Montezuma,下一个接口可能需要宏动作、可恢复状态、搜索和长期记忆。

🔮 The Next Paradigm?

当前的范式迁移已经从预训练到 RLHF,再到大规模 RL / RLVR。任何可以被验证的东西都开始变得可解

在线学习和持续学习可以部分地通过 RLVR 产生的 agent,经由 Heuristic Learning 来解决。从这个角度,作者称之为下一个范式的候选任何可以被持续迭代的东西都开始变得可解

为什么是"部分地"?

因为 Heuristic Learning 不能做神经网络能做的一切。它受代码能表达的内容限制,尤其在复杂感知和长视界泛化方面。用作者今天所知,无法想象一个 agent 不用神经网络、只用纯 Python 代码解决 ImageNet。

真正的方向:HL + NN 的融合

最有希望的方向似乎是:用 HL 快速处理在线数据,将在线经验转化为可训练、可回归测试、可过滤的数据,然后定期更新神经网络。

机器人学的 System 1 / System 2 分工

层次结构:关节级 HL → 肢体级 HL → 全身平衡 HL → 任务级 HL

🎯 结语:Coding agent 改变了写代码的速度。它也改变了哪些代码值得长期维护。许多启发式看起来无望,真正的问题其实是维护成本。它们不一定太弱。Coding agent 改变了这条维护曲线。规则、测试、日志、记忆和补丁过去是散落的工程材料。现在它们可以成为一个持续更新的 Heuristic System,一个真正能解决在线学习和持续学习长期挣扎的问题的系统。

Welcome to the next paradigm.

🎓 关键收获

  • Heuristic Learning 是一个新范式:用 coding agent 维护纯代码策略系统,不训练神经网络、不更新权重
  • 关键转折是维护成本曲线:coding agent 让过去负担不起的启发式规则维护变得经济可行
  • Heuristic System 不是 policy.py:它是一个包含策略、检测器、反馈通道、记录、回放、测试和记忆的完整软件系统
  • HL 将 Continual Learning 工程化:旧能力固化为回归测试、黄金轨迹和失败视频;核心是吸收反馈 + 压缩历史
  • 耦合复杂度是核心瓶颈:受模块边界、测试覆盖、可观测性和 agent 能力共同限制
  • 实验结果令人震惊:Breakout 864(满分)、Ant 6146、HalfCheetah 11837、VizDoom 557、Atari57 中位数 HNS 1.18(最佳单次运行)
  • Montezuma 暴露了边界:纯 if-else 不够,需要宏动作、可恢复搜索状态和长期记忆
  • HL 不是 NN 的替代品:它受代码表达力限制,真正的未来是 HL + NN 的融合架构
  • System 1 / System 2 分工:浅层 NN 负责感知,HL 负责规则和局部恢复,LLM 负责高层次反馈和周期更新

📚 参考资料

  1. 1
    Learning Beyond Gradients(原文,中英双语)
    https://trinkle23897.github.io/learning-beyond-gradients/
  2. 2
    Artifact 仓库(代码、视频、CSV、复现脚本)
    https://github.com/Trinkle23897/learning-beyond-gradients
  3. 3
    EnvPool(作者的并行环境库)
    https://github.com/sail-sg/envpool
  4. 4
    Codex (gpt-5.4) 实验使用的模型