启发式学习:用代码维护学习系统
在与 coding agent 合作一段时间后,我需要一个不完全是强化学习而不仅仅是手动编程的模式的名称。
我开始称之为启发式学习。
这个循环很熟悉:状态、操作、反馈、更新。区别在于更新目标。深度强化学习更新神经网络参数。启发式学习更新软件系统:代码、状态检测器、规则、测试、评估器、配置、内存和文档。
正在维护的对象
单一的启发式方法是不够的。当启发式属于一个可以吸收反馈并保留有效内容的系统时,它就会变得有用。
我将该对象称为启发式系统。
它通常包含:
- 纲领性政策;
- 明确的国家代表;
- 反馈渠道,例如测试、日志、奖励、视频或重播; ——实验记录;
- 故障记忆和修复;
- 更新机制,通常由 coding agent 执行。
重要的一点是连接性。规则、重播和测试必须满足。否则系统学习一次后就会忘记原因。
它与深度强化学习有何不同
这种比较很有用,因为表面环看起来很相似。
| 轴 | 深度强化学习 | 启发式学习 |
|---|---|---|
| 政策 | 神经网络参数 | 代码、规则、状态机、控制器、宏操作 |
| 状态 | 观察和学习表征 | 显式变量、检测器、缓存、类型化状态 |
| 行动 | 神经网络前向传播 | 可执行逻辑或工具调用 |
| 反馈 | 主要是奖励信号 | 测试、日志、重播、环境反馈、人类判断 |
| 更新 | 基于梯度的训练 | 由 coding agent 或人工直接编辑 |
| 内存 | 重播缓冲区或隐藏权重 | 试验、总结、失败、重播、版本差异 |
这并不能让启发式学习在每个领域都变得更好。当环境是可检查的并且验证足够便宜可以重复运行时,它就变得很有吸引力。
为什么现在值得做在对智能体进行编码之前,许多启发式系统太烦人而难以维护。他们积累了特殊情况、陈旧的评论、薄弱的测试和被遗忘的背景。
智能体改变了成本曲线。它们可以读取日志、编辑代码、添加测试、简化规则,并比较运行期间的行为。这样一类新的显式启发式系统值得拥有。
好处是实用的:
- 可解释性:政策通常可以翻译成普通语言。
- 样本效率:一次良好的代码编辑可以立即跳转到更好的策略。
- 回归测试:旧的胜利可以成为测试、重播或黄金案例。
- 约束过度拟合:多种子检查和简化充当工程正则化。
- 减少遗忘:能力可以存在于测试和规则中,而不仅仅是权重中。
风险也是现实的。启发式系统可能会过度适应种子、利用测试漏洞或成为一堆无法读取的补丁。这就是为什么压缩是学习的一部分。
最小健康循环
一个健康的启发式系统需要两次重复操作:
absorb feedback
-> write failures, rewards, logs, and replays back into the system
compress history
-> fold local patches into simpler rules, tests, and representations
没有吸收,系统就无法学习。如果没有压缩,它将变得难以维护。
一个小例子
想象一下一个智能体控制浏览器工作流程。当模式出现时,第一个版本失败。coding agent 添加一条规则:如果存在模态则关闭。后来,另一个失败表明模态有时是不应该关闭的登录提示。
较弱的系统会将这两个补丁保留为特殊情况。
更强大的启发式系统增加了:
- 模态类型的状态检测器;
- 每次失败的重播;
- 区分可忽略覆盖层和身份验证门的测试;
- 仅在分类后起作用的策略规则;
- 解释该规则存在原因的注释。
系统没有更新权重。它还是学会了。
我的收获
启发式学习将持续学习变成了软件维护问题:
What can be verified can often be improved.
What can be improved should be compressed.
What is compressed becomes reusable practice.
这是 coding agent 感觉强大的原因之一。他们不仅仅编写代码。它们可以帮助维护将重复的故障转变为可读、可测试的系统的循环。