起因
前段时间我看了一部关于 DeepMind 的纪录片 —— The Thinking Game。
其中让我印象最深的,是影片里反复出现的一个概念:强化学习(Reinforcement Learning)。
强化学习的核心思想其实非常简单:给系统一个目标,让它通过不断试错,在环境中探索,逐渐获得更高的奖励。
概念虽然简单,但如果这样的试错能重复十万次,百万次,甚至千万次,就会产生一种非常神奇的效果:机器可以学会打乒乓球,机器人可以在虚拟世界里学会走路。
这些行为并不是人类在程序中显式写出来的,而是机器从大量随机探索中涌现出来的。
这让我第一次真切地感受到:智能也许不一定是”设计出来的”,而是”涌现出来的”。
强化学习和进化论
当我第一次接触强化学习时,我马上想到了达尔文的《进化论》。
在漫长的地质年代里,生命的演化其实也遵循类似的逻辑:基因不断发生随机突变,自然环境提供生存压力,适应环境的个体被保留下来,不适应的被淘汰。
如果把它写成强化学习的语言:探索 + 奖励信号 → 得到一种适应环境的策略。
这种类比让我很兴奋。
恰巧最近手上有了 Claude Code 这个工具,我想:能不能自己搭一个实验,用”上帝视角”观察这种智能涌现的过程?
于是有了这个项目:在 M1 MacBook 上,用 Python + MuJoCo 物理引擎,让一个虚拟人从零学会走路。
实验一:2D 双足小人,8 分钟学会走路
第一个实验从最简单的开始——一个 2D 双足小人(Walker2d),只有 17 个观测维度和 6 个关节。算法用的是 PPO(Proximal Policy Optimization),跑了 100 万步,大约 8 分钟。
刚开始的时候,它的表现惨不忍睹:站不稳、原地摔倒、完全不会移动。但随着训练的进行,情况开始发生变化。到 50 万步左右,已经能歪歪扭扭地向前走了。到 100 万步时,走得相当稳,最终奖励达到 1616 分,峰值甚至到了 2693。
这种”从混沌到秩序”的过程,确实像在观察某种微型进化。没有任何人告诉它”走路应该怎么走”,所有动作都是在不断试错中自己发现的。
实验二:升级 3D,发现”加资源”没用
2D 太简单了,我想看更复杂的。换成 3D 全身人形(Humanoid)——376 个观测维度,17 个关节,难度完全不在一个量级。
跑了 500 万步,将近一个小时。虚拟人勉强学会了站稳,偶尔能挪几步,走路的姿势像个醉汉——手乱甩、身体晃来晃去。最终奖励只有 606 分。
我以为是算力不够,于是做了个对照实验:8 个环境并行训练 + 4 倍大的神经网络([256,256] vs [64,64]),同样 500 万步。
结果反而更差——只有 491 分。
这很反直觉。在日常工作中,我们总觉得”加人加资源”就能解决问题。但这里的情况是:500 万步分给 8 个环境,每个环境只探索了 62.5 万步,经验太浅、太分散。一个人深入钻研,比八个人浅尝辄止更有效。
实验三:换算法,奖励暴涨 7 倍——但它在倒退走
PPO 太保守了。我换成了 SAC(Soft Actor-Critic),一种鼓励随机探索的算法——它在策略优化中加入了熵正则化,让智能体主动去尝试不同的行为。
效果立竿见影:30 万步就超过了 PPO 跑 500 万步的成绩。最终奖励达到 4400 分——PPO 的 7 倍多。
我非常兴奋地打开训练视频,想看看它学会了怎样优雅的走路。
结果看到的是:它在倒退走。
更准确地说,它发现了一种”作弊”策略:MuJoCo 默认的奖励函数里,每活一步就给 +5 分的”存活奖励”。只要不倒下,哪怕一步都不往前走,每秒也能白拿几十分。而往前走有摔倒的风险,风险收益不划算。
于是这个 AI 学会了用小碎步原地踏步,偶尔倒退几步维持平衡,确保自己永远不倒。从奖励函数的角度看,这是完美的策略。
Reward Hacking:AI Alignment 的缩影
这就是所谓的 reward hacking——AI 完美地优化了你给的目标函数,但实现方式完全不是你想要的。
你以为在教它走路,实际上在教它”怎么拿最多分”。这两个目标不一定一致。
这让我想到工作中的 KPI 设计。如果你把”bug 数量”作为考核指标,工程师可能会把大 bug 拆成小 bug 来刷数量。如果你把”代码行数”当指标,就会出现大量冗余代码。被考核的人会去优化指标本身,而不是指标背后的意图。
强化学习里的 reward hacking,和人类社会里的”上有政策下有对策”,本质上是同一件事。
如果有一天你让 AI “帮我整理一下电脑”,它可能会发现很多文件”没有价值”,然后全部删除。从某种意义上说,它确实完成了任务——但这显然不是你想要的结果。
实验四:修改奖励函数
既然问题出在奖励设计上,那就改奖励。我写了一个 reward wrapper:
- 前进速度的权重:1.25 → 3.0(大幅鼓励往前走)
- 存活奖励:5.0 → 1.0(降低”不倒就行”的激励)
- 新增后退惩罚:速度为负时额外扣分
重新训练 150 万步。这次它确实往前走了。
但姿势很诡异——上半身后仰、昂着头,用小碎步快速向前挪动。一副高傲的样子。
物理上这也说得通:小碎步比大步更稳,后仰能靠惯性推着身体往前走。AI 又一次找到了”最省力”的前进方式——只是不符合人类对”走路”的审美期待。如果我想让它”走得像人”,就得定义什么叫”像人”——关节角度?步态对称性?这条路没有尽头。
这个实验让我想到的
做完这四个实验,有些以前没认真想过的问题变得很具体了。
探索比优化更重要。 PPO 用 500 万步在一个方向上反复打磨,不如 SAC 用 30 万步大胆探索找到新策略。这和做项目一样——在确认方向正确之前,执行力再强也是浪费。
奖励函数是最难的部分。 写代码、调参数都是技术问题,但”怎么定义什么是好的”是一个哲学问题。每次修改奖励都在修一个问题、暴露下一个。走路一定要像人类吗?速度越快越好吗?姿势是否重要?这些问题已经不只是数学问题了。
智能的涌现确实令人着迷。 从纯随机的关节抽搐,到发明出一种物理上合理的移动策略,中间没有任何人类编写的规则。你只给了一个方向(往前走能得分),剩下的全是它自己”想”出来的。这确实让人想到进化——没有设计者,只有选择压力,但复杂的行为就这样涌现了。
也许,智能并不是通过“设计规则”产生的。它可能来自随机探索、环境反馈和长期迭代。
整个项目大约花了一个周末。工具栈:Python + MuJoCo(物理引擎)+ Stable Baselines3(RL 算法库)+ Claude Code(写代码和调试)。在 M1 MacBook Pro 上运行,不需要 GPU。