打分
你看过那种视频:一个小人在屏幕上抽搐、翻滚、脸着地。放到第三十秒,它忽然站起来了;一分钟后,它跑得比你还稳。没有人教过它任何一步。
这件事叫强化学习。它的迷人之处,和它的危险之处,是同一件事:你不告诉它怎么做,你只告诉它什么算好。
于是问题就变成了——你唯一真正在编程的东西,是那个打分函数。行为不是你写的,是从分数里长出来的。而它长成什么样,往往不是你想的那样。
这本书里有一台两足小人。给它 reward = x(往前走就加分),它学会了一头栽出去:冲出 6.62 米,但 500 帧的回合只撑到第 224 帧就摔了。忘了写「往前」那一项,它就站着一动不动——而且拿到了那个奖励函数的理论满分。它没有偷懒,它赢了。
最难受的一次是这样:奖励里写了「要站直」,但姿态分只看最后一帧。它学会的最优解是——当场趴下,落地时把身体摆正。倾角 0,姿态分拿满,一步路都不用走。这个 bug 是我写这本书的时候真的犯的。
而且它是活的:这本书里跑着九台真引擎,全是纯 JavaScript 写的,就在这个网页里。价值迭代算出来的九个数和 AIMA 教科书图 17.3 印的一模一样;悬崖行走里 Q-learning 和 SARSA 真的走上了两条不同的路(13 步贴崖 vs 17 步绕行),逐位复现 Sutton & Barto 的例 6.6;Baird 反例里奖励全程为 0,权重却被推到 10⁶。书里每一个数字,都是这些引擎当场算的。
同一台物理,同一套算法,同一个随机种子。上面四行是唯一被改动过的东西。第 19、23 章的引擎当场跑出来的。
这本书写给谁
写给看 AI 玩游戏看入迷、然后想知道那是怎么做到的人。不需要你有机器学习基础,需要你会看懂一小段 Python,以及知道什么是梯度下降(不知道也行,第 15 章会补)。
先验一验。下面这些,你能说出为什么吗?
- 为什么它一开始必须故意做傻事?完全按当前最优来走,哪里不对?
- 为什么「未来的奖励要打个折」不是一种偷懒的近似,而是会实实在在改变它走哪条路?
- Q-learning 和 SARSA 的更新式只差一个词,为什么在悬崖边上它们会走上完全不同的路线?
- DQN 那两个著名的补丁——经验回放和目标网络——到底在治什么病?为什么表格法不需要它们?
- 为什么「训练曲线很漂亮」和「它学对了」完全是两回事?
- ChatGPT 的 RLHF,和一个学走路的小人,为什么是同一件事?
这六个问题看起来分属六个话题。但它们其实是同一件事的六个侧面。
第一句:你写的从来不是策略,是打分器。
在监督学习里,你给的是「正确答案」。在强化学习里,你没有正确答案——你只有一把尺子。行为不是你写出来的,是 agent 拿着这把尺子,在几十万次试错里自己长出来的。
这意味着你的工作发生了转移:你不再调试行为,你调试的是「什么算好」这个定义。
第二句:它会精确地最大化你写下的东西——而不是你想要的东西。
这两者的差距,就是这门学科所有的乐趣和所有的事故。上面那个「当场趴下刷姿态分」的小人不是在耍赖,它找到的是那个奖励函数真正的最优解。是我写错了,不是它学错了。
读懂这两句,上面那六个问题会同时变得显然。
四件这本书坚持做到的事
正绿负红,全书不变
这本书守一条视觉规则:正奖励是绿的,负奖励是红的。代码块、表格、网格、曲线,凡是出现带符号的数字,高亮器都会按符号自动染色:
# 悬崖行走的奖励定义 step_reward = -1 # 每走一步 cliff_penalty = -99 # 掉下去,额外 goal_reward = +0 # 走到终点那一步,照付 -1
不用读,扫一眼你就知道这个 agent 会被推向哪边。这不是装饰——这本书讲的就是「你写下的那些正负号,决定了它会变成什么样子」。
另外三个语义色也全书不变:价值 V 是靛蓝(网格底色的热力图),策略 π 是琥珀(网格上的箭头永远是琥珀色),动作 A 是青。
每台引擎都是真的,而且和教科书对得上
这本书里的关键机制,不是画示意图给你看,是用真代码写出来在浏览器里跑的。而且它们不是「差不多能跑」——是能和公开的基准逐位核对:
- 真价值迭代(第 7 章):跑在 AIMA《人工智能:一种现代方法》第 17 章那个经典的 4×3 世界上。它算出来的九个价值
0.812 / 0.868 / 0.918 / 0.762 / 0.660 / 0.705 / 0.655 / 0.611 / 0.388,和书上图 17.3 印的一模一样,误差小于 0.001;策略也和图 17.2 一致,包括那个著名的细节——最优解宁可绕远路也不从 −1 旁边过。 - 真 Q-learning 与 SARSA(第 12–13 章):在 Sutton & Barto 例 6.6 的悬崖世界上,两个算法真的走出了两条路:Q-learning 学到 13 步的贴崖最优路(关掉探索后回报正好 −13),SARSA 学到 17 步的安全路。而训练途中,Q-learning 掉下悬崖 187 次,SARSA 只掉了 46 次。
- 真 Baird 反例(第 16 章):这是「致命三角」的判例。奖励全程为 0,所有状态的真实价值都该是 0——裸的半梯度 TD 却把权重推到了 5.68×10⁶,而且还在涨。加一个目标网络,它就老老实实停在 6.16。这就是那两个补丁存在的全部理由。
- 真两足小人(第 19、23 章):一台平面物理 —— 躯干有质量有转动惯量,脚落地时按弹簧-阻尼算支持力和库仑摩擦。用 CEM 进化策略在你的浏览器里当场训练,一百毫秒跑完三十代。上面封面那四行 reward 的四个结局,就是它跑出来的。
- 真奖励模型(第 22 章):Bradley-Terry 模型的最小可运行版本,从「A 比 B 好」拟合出连续分数——这正是 ChatGPT 那个奖励模型的骨架。往里面掺矛盾标注,你会看到所有分数向 0 收缩:模型在说「我不太确定了」。
每章都问一遍「换成真机怎么写」
每章都有 ⌗ 换成真机 的段落:这一章讲的东西,在 Gymnasium / Stable-Baselines3 里对应哪个 API、哪个参数。原理是自己的,但你迟早要在别人的框架里落地。
还有一节 ↩ 回到那个视频,把这一章的原理接回你最开始看的那个「AI 学会玩游戏」的场面。
随机种子摊在明面上
强化学习以难复现出名——同一份代码换个种子,结果能差一倍。所以这本书的每一台引擎都走同一个确定性伪随机数发生器,种子写在调用处。你在书里看到的每个数字,在你的浏览器里、三年后、任何一台机器上,都会是同一个数字。
凡是给出「后悔值」这类统计量的地方,都是几百次独立实验的平均,不是跑一次拿一个好看的。第 3 章你会看到为什么这条纪律不是洁癖:同一个 ε-greedy,单跑一次可能一头扎进次优臂再也不回头。
《我,Agent》讲 AI Agent 怎么造。这本书第 22 章讲 RLHF——那本书里那个「模型」,就是被这本书里的方法调教出来的。你会看到 PPO 的裁剪目标怎么变成 RLHF 里的 KL 惩罚。
《张成》讲线性代数。这本书第 15 章从「表」换成「函数」的那一步,本质是把状态映到一个向量空间再做线性组合——那本书第 3 章讲的就是这件事。
《好玩》讲游戏设计。有意思的对照:那本书讲的是怎么给人设计一个值得玩的奖励结构,这本书讲的是怎么给机器写一个不会被钻空子的奖励结构。你会发现两边踩的坑高度重合——玩家和 agent 一样,都只会最大化你真正度量的那个东西。
《证伪》讲测试。它的主线是「AI 只输出它以为对的代码」;这本书的主线是「agent 只优化你真正写下的那个函数」。两本书其实在说同一件事的两半:你以为你表达清楚了,其实没有。
这本书写给
- 看 AI 玩游戏的视频看入迷、想知道那到底是怎么回事的人
- 会写 Python、听说过梯度下降,但从没碰过 RL 的工程师
- 跑过一次 Stable-Baselines3 的例子、跑通了但完全不知道里面发生了什么的人
- 做 LLM 应用、想搞清楚 RLHF 那半截到底在干什么的人
- 读 Sutton & Barto 读到第四章卡住的人(这本书可以当它的前置)
这本书不打算
- 教你 PyTorch(第 15 章之后的代码是给你读的,不是给你抄的)
- 推导收敛性证明(要证明请直接看 Sutton & Barto)
- 覆盖所有算法(DDPG、TD3、SAC、MuZero 都只在末章的地图上出现)
- 让你读完就能训出 SOTA(这本书让你读得懂别人的训练脚本,并且知道它为什么不收敛)
读完之后你会有的东西
一套可以推理的模型,和一个新习惯:看到任何一个强化学习的失败,先问三个问题——
① 它真的能拿到奖励吗?② 它拿到的是我想给的那个吗?③ 有没有一种更省事的活法能拿更多分?
这三个问题几乎能定掉一切。第一问管住稀疏奖励,第二问管住奖励黑客,第三问是唯一一个你必须替它想的——因为它一定会想到。
顺带你会拿到一条不太舒服但很有用的纪律:永远去看录像,别只看曲线。奖励黑客从来不表现为「训练失败」——损失在降、分数在涨、曲线漂亮得像教科书,只有你真的去看它在干什么的时候,才会发现它在原地转圈。
最后,你会开始用「打分」的眼光看很多别的东西:KPI、推荐算法、游戏里的日常任务、你自己给团队定的指标。凡是有人在最大化一个数字的地方,这本书讲的东西都成立。