clamp repair. The agent read, edited, tested, and submitted, and the hidden tests then returned one number. Before we can ask a model to learn that behavior, we need a precise language for it. That language must say what the agent controls, what it observes, what is random, what the objective is, and how the quality of a decision is measured when its consequence arrives several turns later.
This chapter supplies that language. It is the standard theory of Markov decision processes, but every object is built in a few lines of torch on a repair MDP, a seven-state abstraction of the clamp episode. Because the MDP is tiny, we can compute values exactly with a linear solve, check them against sampling, find the optimal policy, and differentiate the objective with autograd. None of those exact computations survive the move to a language model, and seeing precisely why they fail explains the design of everything from Chapter 6 onward.
We save two functions for the rest of the book, discounted_return and policy_evaluation, plus the repair MDP builder and value_iteration, which later chapters use as exact references.
2.1 Markov Decision Processes
An RL problem has two parts: an agent that chooses actions, and an environment that responds. The interface between them is a loop. At each step the environment is in a state , the agent chooses an action , and the environment returns a reward and a next state . The loop ends when the environment reaches a terminal state. A Markov decision process (MDP) formalizes that loop as a tuple :- is the set of states and the set of actions.
- is the transition probability of moving to after taking in .
- is the expected immediate reward for taking in .
- is the distribution of the initial state.
- is the discount factor (Section 2.4).
The repair MDP
We abstract theclamp episode into seven states. The agent starts with the file unread. Reading moves it to read. Editing produces either edited_ok or edited_bad, and the probability of a correct edit depends on whether the agent is informed: an edit made after reading the file, or after seeing a failing test, succeeds with probability 0.8; any other edit is a guess that succeeds with probability 0.3. Testing an edited file moves it to passed or failed. Submitting ends the episode in done and pays reward 1 if the file is correct, 0 otherwise. All numbers are invented for teaching; they are not measured on any model.
repair_transitions is the specification in words: reading is only useful once, testing only changes an edited file, and every edit is a fresh random draw. Reading or testing in other states leaves the state unchanged, which is a self-loop that costs a step.
A tabular MDP stores as a tensor of shape [S, A, S] and as [S, A]. We fill both from the specification. The terminal state done gets an all-zero row in : an episode that reaches it simply stops. This makes substochastic (rows sum to 1 for live states and 0 for the terminal state), a convention that lets us solve for values without special-casing termination.
submit action from a correct state. An optional step_cost charges every action; Section 2.9 uses it. Let us check the tensors.
submit column for edited_ok and passed. Figure 2.1 draws the same tensors.
unread a guess lands in edited_ok only 30% of the time. From read or failed the informed edit succeeds 80% of the time. The test arrows do not change whether the file is correct; they only move the agent to a state that reports it. Under full observability, as here, a report of something the agent already knows has no value. Section 2.7 shows that it acquires value as soon as the agent cannot see the state.
2.2 Policies, Trajectories, and Returns
A policy is a distribution over actions for each state. In a tabular MDP it is a tensorpolicy: [S, A] whose rows sum to 1. A deterministic policy puts all of its mass on one action per state. For a language model, the policy is the model itself: is the probability that the model emits action given its context.
A policy and an MDP together define a distribution over trajectories :
The factorization separates what the agent controls () from what it does not ( and ). That separation is the reason policy gradients work without a model of the environment: Chapter 6 differentiates and the factors vanish because they do not depend on .
The return of a trajectory is the discounted sum of its rewards,
and the objective of RL is the expected return from the initial distribution, . For a parameterized policy we write . Computing a return is the first function we save.
policy[s] and a next state from P[s, a] until the terminal row is reached.
deterministic_policy turns a list of one action name per state into a one-hot [S, A] tensor. We define three policies that we will use throughout the chapter:
- careful reads, edits, tests, submits after a pass, and re-edits after a failure;
- read-edit-submit reads, edits once, and submits without testing;
- blind edits immediately and submits.
2.3 Value Functions and the Bellman Equations
The return from a single episode is noisy. The state-value function averages it out: and the action-value function conditions on the first action as well: Split the return into the first reward and the rest. The rest, from on, is a return of the same kind, so its conditional expectation is . This gives the Bellman expectation equations: Substituting the first into the second removes : This is a linear system in unknowns, . It has a unique solution whenever is invertible. That holds for any , because is substochastic and its spectral radius is at most 1. For it holds exactly when the policy reaches the terminal state with probability 1 from every state (a proper policy). Solving the system is exact policy evaluation, the second function we save.einsum/sum lines are the definitions of and ; the solve is the Bellman equation. Compare with Monte Carlo.
read, edit, test, submit. The advantage of the action the careful policy takes is exactly 0, by definition. The other entries are informative. In edited_ok, submitting has an advantage of : careful’s test spends a discounted step on a file that is already correct, which costs exactly the factor of the reward. In edited_bad, submitting has an advantage of , because it throws away the whole value of the state. A policy that acts on these numbers would submit from edited_ok and keep testing from edited_bad, where test has the highest action value. That is the policy improvement step of Section 2.5. The final line checks the Bellman equation to machine precision.
Pitfall. torch.linalg.solve in float32 can drift visibly for close to 1, where is nearly singular. The repair MDP uses float64 throughout. The same concern appears at scale whenever long-horizon returns or log-probability sums are accumulated in low precision.
2.4 Discounting
The discount factor plays two different roles, and conflating them is a common source of confusion.- A modeling choice. says that a reward steps later is worth of the same reward now. A geometric discount is equivalent to an episode that terminates independently with probability at every step, so its effective horizon is about steps.
- A mathematical convenience. guarantees that is invertible and that returns are bounded even for policies that never terminate.
submit or when a turn budget runs out. Its success is what we care about, and an equivalent fix found in turn 5 rather than turn 3 is not worth less to the user. That argues for as the model of the task. But discounting changes which policy is preferred. Evaluate the three policies over a range of .
2.5 Optimal Policies and Why We Will Not Compute Them
Evaluation tells us how good a policy is. Improvement makes it better. The policy improvement theorem states: if is greedy with respect to , that is, , then for every state. The proof is short. Greediness gives ; unroll the Bellman equation under one step at a time and apply the same inequality at every step. Iterating evaluation and improvement converges to an optimal policy , whose value satisfies the Bellman optimality equation: Value iteration applies the right-hand side as an update until it stops changing. For the update is a contraction in the max-norm, so it converges from any start.edited_ok and tests from edited_bad. Testing a known-bad file is useful because it leads to failed, the state from which an informed edit succeeds 80% of the time, rather than a 30% guess from edited_bad. And it never tests a correct file, because it can see that the file is correct. The gap between careful and optimal is the cost of testing when the answer is already known.
Why this does not scale to language models
Value iteration needs a table with one entry per state and a sweep over all actions. For a language model under the token-level casting of Section 2.8, a state is a token prefix and an action is a token. Count them.policy_evaluation is differentiable: it is an einsum and a linear solve.
2.6 Bandits: The One-Step Case
A bandit is an MDP whose episodes last one step. There is no next state, so and the only question is which action has the highest expected reward. A contextual bandit adds a context drawn at the start: . Single-turn RLVR is a contextual bandit. The context is the prompt, the action is the entire response, and the reward is the verifier’s score of that response. The response is generated token by token, but the environment does not react between tokens, so the only stochasticity apart from the policy is in the prompt. Methods such as GRPO treat each prompt as a small bandit problem: sample responses, observe rewards, and push probability toward the better ones (Chapter 9). Bandits isolate the problem that the tabular MDP hid: exploration. The value of an action is unknown until it is tried, and a policy that stops trying an action can never learn that it was good. Compare a greedy learner, which always picks the arm with the highest estimated mean, with epsilon-greedy, which picks a random arm with probability . We run 2,000 independent copies in parallel.2.7 Partial Observability
So far the agent saw the state. A real coding agent does not. It sees the issue text, the outputs of its tools, and its own messages. It does not see the hidden tests that will grade it, the parts of the repository it has not read, or whether its edit is correct. A partially observable MDP (POMDP) adds an observation function : the environment’s state evolves as in an MDP, but the agent receives only an observation . An agent in a POMDP should condition on its whole history , or on the belief , which is a sufficient statistic for it. A policy that maps only the current observation to an action can be strictly suboptimal. For a language model, the context window is the history: the model conditions on every earlier message and tool output. That is a strength, and it is also why context truncation (Section 2.9) is a modeling change rather than a mere engineering detail. In the repair MDP, makeedited_ok and edited_bad look identical: after an edit, the agent sees only edited. Every other state is observed as itself.
edited must lead to the same action in both hidden states. Submitting blindly after an edit is worth 0.65; testing first is worth 0.775. Under partial observability, testing is the better choice, because the test’s output reveals the hidden variable. The fully observed optimum, 0.825, is higher still. The difference between 0.825 and 0.775 is the value of the information that the agent cannot observe directly and must pay a step to acquire.
The same structure appears at full scale. Reading files, running tests, and searching the repository are information-gathering actions. They earn no reward themselves, and their value exists only because the agent is partially observing its world. An outcome-only reward must teach the agent to take them, which is a credit-assignment problem (Chapter 7, Chapter 12). The hidden tests are also, by design, never observed. That is what makes them a reward the agent cannot fit directly (Chapter 11).
2.8 Three Ways to Cast an LLM Agent as an MDP
A language model agent fits the MDP framework in more than one way, and the choice decides what an “action”, a “step”, and an “advantage” mean in code. Take one scripted episode from Chapter 1, written as segments with their owners.<call> edit swap_minmax </call>, and the state is the conversation so far. Its probability is the product of its token probabilities. The horizon shrinks to the number of turns, which is the natural scale for credit assignment: a turn-level advantage says “this tool call was good”. It costs an action space that is combinatorially large and a ratio that is a product of many per-token ratios, so it can explode (Chapter 8).
Episode level. The whole trajectory is one action, and the problem becomes a contextual bandit over trajectories, with the task as context and the final reward as payoff. This is the casting implicit in GRPO-style outcome RL (Chapter 9): every policy token in a trajectory receives the same trajectory-level advantage. It buys simplicity and no value function. It costs all credit assignment within the episode: a useless read and the decisive edit receive the same signal.
These are not competing theories. They are three views of the same sampling process, and practical systems mix them. A common combination computes log-probabilities at the token level, advantages at the episode level, and masks at the turn level.
2.9 Design Problems in Practice
Problem: choosing the discount for finite coding episodes. Symptom: with , the agent learns to skip verification steps. With , a critic’s value estimates diverge or a policy that loops forever has undefined value. Cause: makes later success worth less, which changes the optimal policy (the crossing in Figure 2.2). leaves singular for any policy that can avoid termination. Options: (a) with a hard turn or token budget that forces termination; this matches the task’s success criterion, but the budget becomes part of the environment and truncated episodes need a rule (Chapter 12). (b) slightly below 1, which keeps values bounded at the cost of a bias toward short episodes. (c) An explicit step cost (next problem), which expresses urgency in reward units rather than through the discount. Default: the book uses plus a turn budget, and treats any urgency as an explicit, measured cost. This is a recommendation, not a universal rule.The singular case is easy to reproduce. A policy that reads forever never terminates.
Problem: terminal rewards versus step costs. Symptom: after a step penalty is added to discourage long episodes, the agent starts submitting without testing, or submits immediately with no edit. Cause: a step cost subtracts times the expected episode length from every policy’s value, and policies of different lengths lose different amounts. Above a threshold, a shorter and less reliable policy becomes optimal; at a higher threshold, giving up is optimal. Options: (a) terminal reward only, with a budget, which is unbiased with respect to success but gives no pressure toward efficiency. (b) A small step cost, set well below the threshold at which the optimal policy changes. (c) Report cost separately and select among successful policies by cost during evaluation. Default: terminal reward only during early training, then a small step cost only if efficiency matters, after checking that it does not move the optimal policy on representative tasks.
submit from unread: the agent gives up immediately. Giving up costs one action, so it becomes optimal once , that is, , where the expected cost of attempting the repair exceeds its reward of 1. In an LLM run, this is the “agent learns to submit immediately” pathology of Chapter 12, reproduced in a seven-state table.
Problem: is the prefix a Markov state? Symptom: the same visible context leads to different outcomes, value estimates are noisy for no visible reason, or behavior changes after a context-management change. Cause: the token prefix is Markov for the agent’s decision process only when it contains everything that determines future observations and rewards. Three things break this. The environment has hidden state, such as the file system, hidden tests, and random seeds. The context may be truncated or summarized, which discards history the policy could have used. And a state abstraction may merge histories with different futures; in the repair MDP,edited_badreached by a guess andedited_badreached by an informed edit are one state only because we declared that edits do not remember how they were made. Options: (a) keep the full history in context, which is expensive at long horizons; (b) use explicit, faithful state summaries, such as having tools report the current diff, so that truncation loses less; (c) treat the problem as a POMDP and accept that values are conditioned on the observable history only. Default: treat the agent as a POMDP whose policy conditions on its full context; make tool outputs report relevant state explicitly; and treat any change in truncation or summarization as a change in the policy’s input distribution that requires re-evaluation.
Summary
- An MDP separates what the agent controls, , from what it does not, and ; the trajectory distribution factorizes into those parts, and this is why policy gradients do not need a model of the environment.
- Value functions satisfy the linear Bellman expectation equations. For a tabular MDP,
policy_evaluationsolves them exactly, and the result matches Monte Carlo estimates within their error bars. - The discount and step costs are not neutral scalings: both can change which policy is optimal. For finite coding episodes, the book uses with a turn budget.
- Value iteration finds the optimal policy only when states and actions can be enumerated. Language models cannot, so we optimize a parameterized policy by gradient ascent on , which on the repair MDP can still be done exactly by autograd.
- Single-turn RLVR is a contextual bandit, and exploration is limited by the policy’s own sampling distribution. A real coding agent is partially observed, which is what gives information-gathering actions their value.
- An LLM agent can be cast as a token-level, turn-level, or episode-level decision process. Practical systems take log-probabilities per token, advantages per episode or turn, and masks per turn.
Exercises
- Prove that is invertible for any when is substochastic. (Hint: bound the spectral radius by the max row sum.) Then construct a two-state example in which it is singular at .
- Change the informed edit success probability from 0.8 to 0.5. Recompute the value table of Section 2.4. Does the crossing between careful and read-edit-submit move to a higher or lower ? Explain why before running the code.
- Modify
make_repair_mdpso thattestonedited_okfails with probability 0.1 (a flaky test). How do and the optimal policy change? What does this predict about training against flaky verifiers (Chapter 11)? - In Section 2.5, replace the exact with a Monte Carlo estimate from 16 sampled episodes per step, computed by
mc_value. Why can you no longer callbackward()on it? What is missing? (This is the question Chapter 6 answers.) - Extend
run_banditwith an upper-confidence-bound rule: pick . Compare it with -greedy at . - Augment the repair MDP state so that it remembers whether the agent has read the file, and make edits from any state succeed with probability 0.8 if and only if the file has been read. How many states do you need? Which policy is optimal?
- Design review: your team proposes adding a reward of for every
testcall, because “agents that test more succeed more”. Using Section 2.7 and the step-cost results, argue what the agent will learn, and propose a better way to encourage useful testing.