MDP 状态、动作与奖励 本节摘要:马尔可夫决策过程(Markov Decision Process, MDP)就是五样东西——状态、动作、转移、奖励、折扣。整个强化学习里的一切——Q 学习、PPO、DPO、GRPO——都在优化这个形状。把它学透一次,剩下的强化学习几乎可以「免费」读懂。本节将把 MDP 拆成五个对象讲清楚,再带你亲手在一个 4×4 网格世界(GridWorld)上把它跑起来:每步扣 -1、四向移动、抵达终点。你会看到随机策略平均回报 -60,而最优策略是 -6,这道差距就是整章强化学习要填的鸿沟。最后我们用贝尔曼方程(Bellman Equation)迭代出精确的状态价值,并讲清折扣因子 γ 的物理含义——它是「视野长度」的旋钮。
本节摘要:马尔可夫决策过程(Markov Decision Process, MDP)就是五样东西——状态、动作、转移、奖励、折扣。整个强化学习里的一切——Q 学习、PPO、DPO、GRPO——都在优化这个形状。把它学透一次,剩下的强化学习几乎可以「免费」读懂。本节将把 MDP 拆成五个对象讲清楚,再带你亲手在一个 4×4 网格世界(GridWorld)上把它跑起来:每步扣 -1、四向移动、抵达终点。你会看到随机策略平均回报 -60,而最优策略是 -6,这道差距就是整章强化学习要填的鸿沟。最后我们用贝尔曼方程(Bellman Equation)迭代出精确的状态价值,并讲清折扣因子 γ 的物理含义——它是「视野长度」的旋钮。
对应原课程:Phase 9 · Lesson 01 ·
mdps-states-actions-rewards(原英文phases/09-reinforcement-learning/01-mdps-states-actions-rewards/docs/en.md)。
阅读完本节,你应当能够:
(S, A, P, R, γ)。V^π。1/(1-γ)。你在写一个下棋机器人。或者一个库存调度器。或者一个交易智能体。或者一个训练推理模型的 PPO 循环。四个完全不同的领域,却都塌缩成同一个数学对象。
监督学习给你的是 (x, y) 数据对,让你拟合一个函数。强化学习不给你任何标签——它只给你一串状态流、你采取的动作,以及一个标量奖励。这一步赢棋了吗?这次补货省钱了吗?这笔交易赚了吗?LLM 刚生成的那个 token,有没有从评判器拿到更高的分?
你无法从这样一串数据中学到任何东西,直到你把它形式化。「我看到了什么」「我做了什么」「接着发生了什么」「那有多好」——每一个都要变成你能推理的对象。这个形式化就是马尔可夫决策过程。本章每一个 RL 算法,包括末尾的 RLHF 与 GRPO 循环,都在这个形状上做优化。
S:智能体做决策所需的全部信息。GridWorld 里是单元格;下棋是棋盘;LLM 里是上下文窗口加任何记忆。A:可选项。上下左右移动;落子;生成一个 token。P(s' | s, a):给定状态 s 和动作 a,下一状态的分布。下棋是确定性的;库存是随机的;LLM 解码几乎是确定性的。R(s, a, s'):标量信号。赢=+1,输=-1;收益减成本;GRPO 里的对数似然比项。γ ∈ [0, 1):未来奖励相对当前奖励的权重。γ = 0.99 买到约 100 步的视野;γ = 0.9 买到约 10 步。💡 写训练循环之前,先在纸上把这五元组列清楚。多数「RL 不 work」的 bug 报告,追根究底都是 MDP 形式化在纸上就是坏的。
马尔可夫性 P(s_{t+1} | s_t, a_t) = P(s_{t+1} | s_0, a_0, …, s_t, a_t):未来只依赖当前状态。如果它不成立,那不是方法的失败,而是状态表示不完整——状态里漏了某些信息。
DQN 在 Atari 上为什么要把 4 帧叠在一起?因为单帧看不出速度。状态是「最近 4 帧的堆叠」,这才让马尔可夫性成立。
π(a | s):把状态映射到动作分布。G_t = r_t + γ r_{t+1} + γ² r_{t+2} + …:未来奖励的折扣和。V^π(s) = E[G_t | s_t = s]:在策略 π 下从 s 出发的期望回报。Q^π(s, a) = E[G_t | s_t = s, a_t = a]:在策略 π 下、第一步指定为 a 的期望回报。每一个 RL 算法都在估计这两个量之一,然后据此改进 π。
本章所有方法的根基——一组不动点方程:
V^π(s) = Σ_a π(a|s) Σ_{s', r} P(s', r | s, a) [r + γ V^π(s')] Q^π(s, a) = Σ_{s', r} P(s', r | s, a) [r + γ Σ_{a'} π(a'|s') Q^π(s', a')]
它们把期望回报拆成「这一步的奖励」加上「落地状态的折扣价值」。这是递归的。本章每一个算法要么把这个方程迭代到收敛(动态规划)、要么从中采样(蒙特卡洛)、要么单步自举(时间差分)。
有效视野大约是 1 / (1 - γ)。
| γ | 有效视野 | 典型用途 |
|---|---|---|
| 0.9 | ~10 步 | 短视,扣分重的迷宫 |
| 0.99 | ~100 步 | 控制任务的标准 |
| 0.999 | ~1000 步 | 长视野策略游戏 |
| 1.0 | 无限 | 仅当回合短且有界(LLM RLHF) |
γ 太小,智能体短视;γ 太大,信用分配变噪,因为太多早期步骤共同对远期奖励负责。LLM 的 RLHF 通常用 γ = 1,因为回合短(约 200 token)且有界;控制任务用 0.95~0.99;长视野策略游戏用 0.999。
⚠️ γ = 1 在无限视野任务上会让每个价值都趋于无穷。务必用有限视野或
γ < 1封顶。
我们把概念落到一个最小可运行的环境:4×4 GridWorld。智能体从左上角出发,右下角是终点,每步奖励 -1,动作集合 {up, down, left, right}。完整代码见原课程 code/main.py,下面是关键骨架。
GRID = 4 TERMINAL = (3, 3) ACTIONS = {"up": (-1, 0), "down": (1, 0), "left": (0, -1), "right": (0, 1)} def step(state, action): if state == TERMINAL: return state, 0.0, True dr, dc = ACTIONS[action] r, c = state nr = min(max(r + dr, 0), GRID - 1) nc = min(max(c + dc, 0), GRID - 1) return (nr, nc), -1.0, (nr, nc) == TERMINAL
五行代码,这就是整个环境:确定性转移、固定步长惩罚、吸收型终点。
策略是从状态到动作分布的函数。最简单的是均匀随机。
def uniform_policy(state): return {a: 0.25 for a in ACTIONS} def rollout(policy, max_steps=200): s, total, steps = (0, 0), 0.0, 0 for _ in range(max_steps): a = sample(policy(s)) s, r, done = step(s, a) total += r steps += 1 if done: break return total, steps
跑 1000 次随机策略,4×4 棋盘上的平均回报大约在 -60 到 -80 之间。最优回报是 -6(一条直达右下的对角路径)。填平这道差距,就是整章强化学习的全部主题。
对小型 MDP,贝尔曼方程是一个线性系统。枚举所有状态,套用期望,迭代到值不再变化为止。
def policy_evaluation(policy, gamma=0.99, tol=1e-6): V = {s: 0.0 for s in all_states()} while True: delta = 0.0 for s in all_states(): if s == TERMINAL: continue v = 0.0 for a, pi_a in policy(s).items(): s_next, r, _ = step(s, a) v += pi_a * (r + gamma * V[s_next]) delta = max(delta, abs(v - V[s])) V[s] = v if delta < tol: return V
这就是迭代策略评估(Iterative Policy Evaluation)。它是 Sutton & Barto 教材里的第一个算法,也是后面每一个 RL 方法的理论根基。
💡 这段循环的形状会反复出现:扫一遍所有状态 → 用贝尔曼期望更新 V → 记下最大变化量
delta→ 直到delta < tol。第 02 节的动态规划、第 04 节的 TD 学习,本质都是这副骨架的变体。
在工程实践中,你很少手写 GridWorld——但先在纸上把五元组写清楚,再碰代码,是 2026 年 RL 流水线的标配。下表把常见决策任务对齐到 MDP 五元组:
| 场景 | 状态 S | 动作 A | 奖励 R | γ |
|---|---|---|---|---|
| 控制(行走、机械臂) | 关节角度 + 速度 | 连续力矩 | 任务相关、已塑形 | 0.99 |
| 博弈(棋、围棋、扑克) | 棋盘 + 历史 | 合法落子 | 赢=+1 / 输=-1 | 1.0(有限) |
| 库存 / 定价 | 库存 + 需求 | 下单量 | 收益 - 成本 | 0.95 |
| LLM 的 RLHF | 上下文 token | 下一个 token | 回合末尾的奖励模型分 | 1.0(回合约 200 token) |
| 推理模型的 GRPO | 提示 + 部分响应 | 下一个 token | 回合末尾验证器 0/1 | 1.0 |
OpenAI 的 gym(现 gymnasium)把 MDP 封装成 reset() / step(action) 两个 API,返回 (observation, reward, terminated, truncated, info) 五元组——和我们手写的 step(state, action) -> (s', r, done) 完全同构,只是把「状态」叫做 observation、把「结束」拆成 terminated(到达吸收态)和 truncated(超时截断)两个标志。这是第 03 节起所有实验的标准接口。
# import gymnasium as gym # env = gym.make("FrozenLake-v1") # obs, info = env.reset() # for _ in range(100): # action = policy(obs) # obs, reward, terminated, truncated, info = env.step(action) # if terminated or truncated: # break
💡
gym的真正价值不在算法,而在统一接口:同一份 PPO 代码可以无缝换到 Atari、MuJoCo、FrozenLake 上跑——因为它们都是 MDP。这正是本节「一切皆五元组」的工程落地。
本节产出一个可复用 skill(位于原课程 outputs/skill-mdp-modeler.md)——给定任务描述,产出 MDP 规格并标记形式化风险。骨架如下:
--- name: mdp-modeler description: 给定任务描述,产出 MDP 规格并在训练前标记形式化风险。 version: 1.0.0 phase: 9 lesson: 1 tags: [rl, mdp, modeling] --- 给定任务(控制 / 博弈 / 推荐 / LLM 微调),输出: 1. 状态。精确的特征向量或张量规格。论证马尔可夫性。 2. 动作。离散集合或连续范围。维度。 3. 转移。确定性 / 已知随机模型 / 仅能采样。 4. 奖励。函数与来源。稀疏 vs 塑形。终局 vs 每步。 5. 折扣。取值与视野论证。 拒绝交付任何状态非马尔可夫、却未显式提到帧堆叠或循环状态的 MDP。 拒绝任何不基于目标结果定义的奖励。 标记任何无限视野任务上 γ ≥ 1.0。 标记任何奖励范围超过典型步奖励 100 倍的情况——梯度爆炸源。
code/main.py 中实现 4×4 GridWorld 与随机策略滚动,跑 10000 回合,报告回报的均值与标准差,并与最优回报 -6 对比。γ ∈ {0.5, 0.9, 0.99} 跑 policy_evaluation,把每个 V 打印成 4×4 网格。解释为什么 γ 越大,接近终点的状态值增长得越快。p = 0.1 滑到垂直方向。重新评估均匀策略。V[start] 变好还是变坏?为什么?[-1, 1] 左右。(S, A, P, R, γ):状态、动作、转移、奖励、折扣。本章所有算法都在优化这个形状。π(a|s) 把状态映射到动作分布;回报 G_t 是未来奖励的折扣和。V^π 与 Q^π 分别是「状态有多好」「动作有多好」的期望回报——每个 RL 算法都在估计其一。~1/(1-γ):γ=0.9 视野 10 步,γ=0.99 视野 100 步;LLM RLHF 常用 1.0(回合短且有界)。下一节,我们假设你已经知道
P和R(模型已知),用动态规划求出精确的最优策略——它是后续所有采样方法试图逼近的金标准。