"In Chapter 7 they called me a filter and trusted my covariance. In Chapter 10 they learned my weights and called me a hidden state. Now an agent carries me around as its only memory of a world it can barely see, and asks me what to do next. Same sufficient statistic, three wardrobes, and every time the lighting gets dimmer."
A Hidden State That Has Been a Filter, an RNN, and Now an Agent's Memory
Maintaining a sufficient summary of history under partial observability is one recurring problem, and this book has now solved it three ways. Exact Bayesian filtering (the Kalman filter and the HMM forward pass of Chapter 7) carries a calibrated posterior over a latent state. Explicit belief tracking in a POMDP (Section 23.1) carries a distribution over states and updates it by Bayes' rule after every action and observation. A learned recurrent or state-space memory in a deep agent (Section 23.3) carries a hidden vector and updates it with a trained cell, never naming a state at all. These are not three topics; they are one recurrence, $\mathbf{b}_t = \tau(\mathbf{b}_{t-1}, a_{t-1}, o_t)$, with three choices of what the carried summary is and how it updates. This bridge aligns the filter-state, the belief, and the hidden-state in one table; states precisely the trade between calibration (exact beliefs, which need a model and do not scale) and scalability (learned memory, which needs no model but forfeits guarantees); explains why recognizing an agent's memory as belief-tracking tells you what it can and cannot represent; and implements the very same predict-update loop as an exact discrete Bayes filter and as a learned GRU agent-state on one partially observed task, watching the GRU approximate the belief from reward alone. This is where the temporal thread of the whole book lands: the Kalman recurrence of Section 7.6 is now an agent's memory.
Across Section 23.1 through Section 23.3 we built the partially observed decision problem: a latent state the agent cannot see directly, observations that leak partial information about it, and the two ways an agent copes. It can maintain an explicit belief, a probability distribution over states updated by Bayes' rule, and plan in that belief space; or it can hand a learned recurrent network the raw observation stream and let a trained memory stand in for the belief. This bridge section closes Chapter 23 by arguing that both of these, and the exact filters of Chapter 7, are the same machine: a recurrence that carries a sufficient summary of the past forward, corrects it with each new action and observation, and reads out whatever the agent needs. We write the carried summary as $\mathbf{b}_t$ throughout, the action as $a_t$, the observation as $o_t$, and the latent state as $s_t$, the notation collected in Appendix A and reused for every belief and memory in the book.
The choice of the symbol $\mathbf{b}_t$ is part of the argument. In Chapter 7 the carried state was a Gaussian mean and covariance or an HMM forward vector; in Chapter 10 it was a hidden vector $\mathbf{h}_t$; here it is a belief, an honest distribution over states. Writing all three as $\mathbf{b}_t$, the agent's running summary, is what lets you see that the POMDP belief update of Section 23.1 and the GRU update of Section 23.3 are instances of one recurrence that differ only in what the summary represents and whether its update was derived or learned.
By the end of this bridge you should be able to do four concrete things: write the filter, the belief, and the agent memory in the one recurrence form $\mathbf{b}_t = \tau(\mathbf{b}_{t-1}, a_{t-1}, o_t)$; state precisely what calibrated, model-backed guarantees an exact belief gives you and what a learned memory forfeits to gain scale; look at any agent in Parts VI and VII and say what its memory can and cannot represent because you know whether it is tracking a belief; and run the identical predict-update loop with an exact discrete Bayes filter or a learned GRU slotted in. Those four skills frame everything that follows about acting under uncertainty.
1. The Unifying Claim: One Summary of History, Solved Three Ways Beginner
Watch what each of the three machines does when one action-observation pair lands. The Kalman filter of Chapter 7 shifts its Gaussian mean by the gain times the surprise. The POMDP belief of Section 23.1 predicts forward through the transition model for the action just taken, then multiplies by the observation likelihood and renormalizes. The learned GRU agent of Section 23.3 gates its hidden vector toward a trained function of the new observation. Three different arithmetic operations, but one verb: take the carried summary, fold in one action and one observation, get a new carried summary. The rest of the trajectory never reappears, because the summary already absorbed it. That is the move this section names and exploits.
Set aside the specific updates and ask what they share structurally. Each machine maintains a quantity, the summary, that captures everything it knows about the past relevant to the future. At every step it advances that summary using the action it just took (prediction), then corrects it using the observation it just received (update), and reads out whatever it needs, a prediction, a value, or a policy. That is the entire pattern, and under partial observability it carries an action argument the filters of Chapter 7 did not need:
$$\mathbf{b}_t = \tau(\mathbf{b}_{t-1}, a_{t-1}, o_t), \qquad u_t = g(\mathbf{b}_t).$$The transition operator $\tau$ takes the previous summary $\mathbf{b}_{t-1}$, the last action $a_{t-1}$, and the current observation $o_t$, and returns the new summary $\mathbf{b}_t$; the readout $g$ turns it into whatever the agent uses, here a policy or value. Nothing in this form prejudges whether the summary is a Gaussian, a categorical distribution over states, or a learned vector, nor whether $\tau$ is derived from a model or fit by gradient descent. The recurrence is the genus; filtering, belief tracking, and agent memory are species. The single new ingredient relative to Section 7.6 is the action: the agent's own choices change the world it is trying to summarize, so the predict step is action-conditioned.
The two-step rhythm inside $\tau$, predict with the action then correct with the observation, is worth holding onto because it survives all the way into the world-model agents of Chapter 29. Predicting is the agent's model of how the world moves when it acts; correcting is the observation pulling that guess back toward what was actually seen. An agent with only the predict step hallucinates a world; an agent with only the correct step cannot anticipate the consequences of its actions. Every competent agent, with an exact belief or a learned memory, balances the two.
To see that this is not loose analogy, write each species in the $\tau$/$g$ form. For exact Bayesian filtering with a discrete latent state, the summary is the belief vector $\mathbf{b}_t$ over states, the predict step multiplies by the action-conditioned transition matrix $\mathbf{T}^{a_{t-1}}$, and the update multiplies elementwise by the observation likelihood $\mathbf{O}(o_t)$ and renormalizes. This is the HMM forward pass of Section 7.5 with an action subscript on the transition:
$$\mathbf{b}_t = \frac{\mathbf{O}(o_t)\odot\big(\mathbf{T}^{a_{t-1}\top}\mathbf{b}_{t-1}\big)}{\mathbf{1}^{\top}\big[\mathbf{O}(o_t)\odot(\mathbf{T}^{a_{t-1}\top}\mathbf{b}_{t-1})\big]}.$$For the POMDP belief of Section 23.1 the update is exactly the same equation; the only difference from plain filtering is that the agent now also chooses $a_{t-1}$ to maximize expected return, and plans in the space of beliefs rather than passively tracking. The belief is a sufficient statistic for optimal control: a policy that maps beliefs to actions can be optimal, which is the theorem that makes the belief the right object. For the learned agent memory of Section 23.3 the summary is a hidden vector $\mathbf{h}_t$, the operator is a trained recurrent cell (a GRU or an S4/Mamba state-space layer), and the readout is a policy or value head. The agent never names a state or computes a likelihood; it learns an update that, if training succeeds, carries the same information the belief would. The next two subsections make precise what is gained and lost in that substitution.
It helps to tabulate the species against the genus, because the columns make the shared skeleton unmistakable. Read across each row and you are reading the same recurrence; read down each column and you are reading one machine.
| Belief recurrence | Exact Bayesian filter (Ch 7) | POMDP belief (23.1) | Learned agent memory (23.3) |
|---|---|---|---|
| summary $\mathbf{b}_t$ | posterior over latent state | belief vector over states | hidden vector $\mathbf{h}_t$ (no named state) |
| predict step | transition $\mathbf{F}$ or $\mathbf{A}$ | action-conditioned $\mathbf{T}^{a}$ | recurrent gate, learned |
| correct step | gain or emission likelihood | likelihood $\mathbf{O}(o)$, renormalize | input gate on $o_t$, learned |
| readout $g(\mathbf{b}_t)$ | state estimate | belief-space policy / value | policy / value head |
| cost per step | $O(n^2)$, $n$ states | $O(n^2)$; planning much worse | $O(d^2)$, $d$ hidden width |
| what fixes $\tau$ | known model matrices | known POMDP model | data, via the return |
Take the classic tiger problem with two latent states $\{\text{tiger-left}, \text{tiger-right}\}$. The agent has just listened (an information-only action), so the transition is the identity, $\mathbf{T}^{\text{listen}} = \mathbf{I}$, and the predicted belief equals the prior, here $\mathbf{b}_{t-1} = (0.5, 0.5)$. The listen sensor is noisy: it reports the correct side with probability $0.85$, so observing "hear-left" has likelihood $\mathbf{O}(\text{hear-left}) = (0.85, 0.15)$. The predict step leaves the belief at $(0.5, 0.5)$; the correct step multiplies elementwise to get the unnormalized vector $(0.5\cdot 0.85,\; 0.5\cdot 0.15) = (0.425, 0.075)$, and renormalizing by the sum $0.5$ yields $\mathbf{b}_t = (0.85, 0.15)$. One noisy hear-left moved the belief from even odds to $85\%$ confident the tiger is on the left, exactly the "correct toward the observation" half of the recurrence, with renormalization scaling the correction by how informative the observation was, the role the Kalman gain plays for the Gaussian filter of Section 7.6. A second hear-left would push it to roughly $(0.97, 0.03)$; the belief is the agent's calibrated, honest record of evidence.
What makes the belief the right object is that it is a sufficient statistic for optimal control: once you know $\mathbf{b}_t$, the entire action-observation history $a_0, o_1, \dots, a_{t-1}, o_t$ tells you nothing more about which action is best. This is the POMDP analogue of the filtering sufficiency of Section 7.6: a partially observed problem becomes a fully observed Markov decision process over beliefs, so the optimal policy is a function of $\mathbf{b}_t$ alone. A learned recurrent memory only approximates this sufficiency, compressing the history into a fixed-width vector and hoping the compression keeps what matters for the return. This single idea, "carry a sufficient summary, not the whole history", is why an agent can act on an unbounded trajectory with bounded memory, and it is exactly the property a learned memory risks losing when it discards information the reward signal never highlighted.
There is a quiet irony in the history here. The HMM forward algorithm was published by Baum and colleagues in the late 1960s for speech and biology, a passive recipe for tracking a hidden state. Decades later, deep reinforcement-learning agents that had never been told about hidden Markov models were trained end to end on partially observed games, and researchers probing their recurrent hidden states found that the networks had, on their own, learned to represent something that decoded almost perfectly into the Bayesian belief. Gradient descent rediscovered the forward algorithm because it is the cheapest correct way to remember a partially observed world. The agent did not read Chapter 7; it just could not do better than the math in it.
2. The Trade-Offs: Calibration Versus Scale Intermediate
If the exact belief and the learned memory both fill the same socket in the recurrence, why ever prefer one over the other? The answer is a clean trade between assumptions and flexibility, the same trade the Kalman-versus-RNN bridge of Section 7.6 drew, now sharpened by the action and the curse of dimensionality. It is the single most important conceptual takeaway of this bridge, because it tells you, for any agent you build, which side of the trade you are standing on.
The exact belief is calibrated, in the precise sense that $\mathbf{b}_t$ is the true posterior probability of each state given the history, but only on a contract: you must possess the POMDP model, the transition probabilities $\mathbf{T}^a$ and the observation probabilities $\mathbf{O}(o)$, and they must be correct. Honor that contract and the belief tells you exactly how uncertain you should be, which lets a planner reason about information-gathering actions (the tiger agent listens before opening a door precisely because the belief quantifies what it does not yet know). Violate it, or face a state space too large to enumerate, and exact belief tracking fails in two distinct ways: it is confidently wrong when the model is wrong, and it is simply intractable when the state space is large, since the belief is a vector over all states and planning in belief space is, in the worst case, undecidable for infinite horizons and PSPACE-hard for finite ones.
The learned memory makes the opposite bet. It assumes no model and instead fits the update $\tau$ from data, optimizing only the return, so it scales to enormous observation spaces (pixels, text, raw sensor streams) where no one could write down $\mathbf{T}^a$ or $\mathbf{O}(o)$. The price is twofold. First, it needs enough experience to learn what the belief agent was simply told, and its memory is only as good as the reward signal that shaped it: information irrelevant to the observed returns may never be stored, so the learned summary can be insufficient in ways you cannot easily detect. Second, the learned memory has no native, calibrated notion of its own uncertainty; the honest posterior the belief hands you for free must be bolted back on. Chapter 19 on probabilistic and conformal forecasting is one place the book buys that calibration back inside a learned model. Figure 23.4.3 lays the trade side by side.
| Property | Exact belief (model given) | Learned memory (model-free) |
|---|---|---|
| model needed | full POMDP $\mathbf{T}^a, \mathbf{O}(o)$, must be correct | none; fit from interaction |
| calibration | true posterior, calibrated for free | none natively; must be added |
| scaling | $O(n)$ belief, planning intractable for large $n$ | scales to pixels, text, raw streams |
| sufficiency | provably sufficient for optimal control | only approximately, shaped by the return |
| failure mode | confidently wrong if model wrong; intractable if large | silently forgets what the reward never rewarded |
Return to the tiger agent, but suppose the true listen sensor is accuracy $0.65$ while the belief agent believes it is $0.85$. After one hear-left the belief agent computes, as above, $\mathbf{b}_t = (0.85, 0.15)$, but the evidence actually justified only $(0.65, 0.35)$. The agent is overconfident by $0.20$ in probability. Worse, this error compounds: after three consistent hear-left observations the overconfident belief reaches roughly $(0.992, 0.008)$ and the agent opens the door, while the correctly calibrated belief is only $(0.86, 0.14)$, not yet confident enough to act. A wrong model does not announce itself; the belief reports a tight, confident posterior the whole time. A learned memory trained on real interaction with the $0.65$ sensor would instead absorb the true informativeness from the returns (doors opened too early are punished), learning an effective update that matches the real sensor without ever being told its accuracy. The number to remember: a belief is exactly as calibrated as its model, and a wrong model buys you confident mistakes, not honest ones.
The honest summary is that an agent's memory trades a strong assumption for a strong appetite. The exact belief assumes a correct model and rewards you with calibrated sufficiency and the ability to plan information-gathering actions, on modest data but only in tractable state spaces. The learned memory assumes almost nothing and rewards you with scale and flexibility, but demands experience and hands back a summary whose sufficiency you must take on faith. Neither column of Figure 23.4.3 dominates; the right choice depends on whether you have a trustworthy model and a small enough world, or a large world and plenty of interaction. The frontier, as the rest of this part shows, is getting both at once.
The two columns of Figure 23.4.3 are converging fast. The Dreamer line, culminating in DreamerV3 (Hafner et al., 2023) and its 2024 follow-ups, trains a recurrent state-space world model whose latent is a learned belief: it predicts observations and rewards, so the model-free scale of the right column is paired with the predictive, almost-Bayesian latent of the left, and a single configuration now solves over 150 partially observed tasks. A second active thread makes the learned memory provably belief-like: work on belief-state representation learning and "approximate information states" (Subramanian et al., 2022, and 2024 extensions) trains recurrent agents with auxiliary objectives that force the hidden state to be a sufficient statistic, recovering the calibration the plain RNN forfeited. On the architecture side, the structured state-space models S4 and Mamba (Gu and Dao, 2023; Dao and Gu, 2024) of Chapter 13 are increasingly the memory of choice for long-horizon partially observed agents, because they keep a linear recurrence (cheap, like a filter) while learning it from data (flexible, like an RNN), the literal made-learnable Kalman recurrence of Section 7.6. The practitioner's takeaway for 2026: "is my agent's memory tracking a belief, and can I make it provably do so?" is a live and fertile question.
3. Why This Matters Going Forward Advanced
Every agent in Parts VI and VII carries some memory. A deep Q-network with a recurrent layer, a PPO actor with an LSTM, a decision transformer attending over its history, a Dreamer agent with a recurrent latent: each maintains a summary of the past it cannot fully observe. The single most useful habit this section installs is to look at any such agent and ask one question: is this memory tracking a belief, and if so, over what? The answer tells you, before you run a single experiment, what the agent can and cannot represent.
The reasoning is direct. If an agent's memory is a sufficient statistic for the belief, it can in principle represent any function of the posterior over states, so it can reason about its own uncertainty, value information-gathering actions, and disambiguate aliased observations (two situations that look identical but require different actions because the history differs). If its memory is not belief-sufficient, because the architecture is too small, the truncation window of Section 9.3 is shorter than the relevant dependency, or the return never rewarded storing the distinguishing information, then no amount of policy optimization will let it act optimally on the parts of the problem that needed that information. Recognizing the memory as belief-tracking turns a vague worry ("maybe the agent forgets things") into a precise diagnosis ("the hidden state cannot represent the posterior over the door the key opened, because that fact was never reinforced within the truncation window").
This frame also resolves a recurring confusion about which architecture an agent's memory should use. A recurrence (RNN, GRU, S4, Mamba) compresses the history into a fixed-width belief-like state and discards the raw past, which is cheap and matches the belief abstraction exactly, but risks losing information the compression did not anticipate. Attention (the transformers of Chapter 12, as used by the decision transformer of Chapter 28) keeps the whole history available and retrieves from it on demand, which never compresses information away but pays quadratic cost and does not maintain an explicit running belief at all. Knowing that the underlying problem is belief-tracking tells you what each choice is really doing: the recurrence is approximating the belief update; the transformer is refusing to commit to a fixed summary and recomputing what it needs each step. Neither is universally right, and the same compress-versus-retrieve tension that organized Part III reappears here as a design axis for agent memory.
This bridge is the fourth stop on the book's longest arc, the recursive summary of a partially observed world. It began as the Kalman recurrence in Section 7.6, where a Gaussian mean and covariance carried a calibrated posterior under a known linear model. It became the learned RNN memory of Section 9.3 and Chapter 10, where the same loop was fit by backpropagation through time instead of derived. It was reclaimed, fast and linear, by the structured state-space models S4 and Mamba of Chapter 13, which kept a linear recurrence (so it parallelizes like a filter) while learning its parameters from data. And it arrives here as an agent's memory under partial observability, a belief carried forward so the agent can act when it cannot see. The wardrobe changed four times: a filter, a trained cell, a parallel scan, an agent's memory. The loop $\mathbf{b}_t = \tau(\mathbf{b}_{t-1}, a_{t-1}, o_t)$ never did.
Once you recognize an agent's memory as belief-tracking, its failure modes become predictable rather than mysterious. If two distinct histories produce indistinguishable hidden states but require different actions, the memory is not belief-sufficient, and the agent will act identically in situations the belief would separate, the signature of perceptual aliasing. If the agent cannot value an information-gathering action (it will not "listen before opening the door"), its memory is not representing posterior uncertainty, only a point summary. If performance collapses when the relevant cue and the reward are separated by more than the truncation window of Section 9.3, the belief simply was not carried far enough. Each of these is a statement about the summary $\mathbf{b}_t$, not about the policy, and that is the practical payoff of the unifying claim: debug the memory as a belief, and the agent's behavior stops surprising you.
4. Worked Example: The Same Loop as a Bayes Filter and a GRU Agent Advanced
Talk is cheap; running code is not. The cleanest proof that the exact belief and a learned memory fill the same socket is to write the predict-update recurrence once as a driver and then run two different summaries through it: an exact discrete Bayes filter and a learned GRU agent-state, on one partially observed task. We use a tiny corridor: a hidden position the agent cannot see, a noisy local observation, and a reward only when the agent acts correctly at the end. The discipline is that the driver loop is identical for both; only the summary and its update change. Code 23.4.1 builds the from-scratch exact Bayes filter.
import numpy as np
# A 4-cell corridor POMDP. Hidden state = position 0..3 (unobserved).
# Action 0 = move left, 1 = move right (deterministic, clipped at the ends).
# Observation = noisy "wall sensor": 1 if at an end cell (0 or 3), else 0,
# flipped with probability 0.2, so the agent must integrate evidence over time.
n = 4
def transition_matrix(a):
"""T^a[i, j] = P(next = j | state = i, action = a)."""
T = np.zeros((n, n))
for i in range(n):
j = max(0, i - 1) if a == 0 else min(n - 1, i + 1)
T[i, j] = 1.0
return T
def obs_likelihood(o):
"""O(o)[i] = P(observe o | state = i), wall sensor with 0.2 flip noise."""
true_wall = np.array([1, 0, 0, 1]) # ends are walls
p_correct = np.where(true_wall == 1, 0.8, 0.2) # P(sensor=1 | state)
return p_correct if o == 1 else (1.0 - p_correct)
def bayes_update(b, a_prev, o):
"""The exact belief recurrence tau: predict with the action, correct with o."""
b_pred = transition_matrix(a_prev).T @ b # predict step (action-conditioned)
b_corr = obs_likelihood(o) * b_pred # correct step (elementwise likelihood)
return b_corr / b_corr.sum() # renormalize -> posterior
def run_belief(b0, actions, observations):
"""Generic predict-update driver. Knows nothing about WHAT the summary is."""
b = b0
traj = []
for a_prev, o in zip(actions, observations):
b = bayes_update(b, a_prev, o) # the ONLY task-specific line
traj.append(b.copy())
return np.array(traj)
rng = np.random.default_rng(0)
b0 = np.ones(n) / n # uniform prior over position
actions = [1, 1, 0, 1, 1] # a fixed action sequence
observations = [0, 1, 0, 0, 1] # the noisy wall readings seen
beliefs = run_belief(b0, actions, observations)
print("final exact belief:", np.round(beliefs[-1], 3))
print("argmax position :", beliefs[-1].argmax())
run_belief) plus a from-scratch exact discrete Bayes filter as its first instance. The driver never mentions walls or corridors; it only calls the update. Note the belief is a genuine probability vector that sums to one, so it carries its own calibrated uncertainty, exactly the free gift subsection two flagged.final exact belief: [0. 0.061 0.34 0.599]
argmax position : 3
Now the second instance. We feed the same predict-update structure a learned GRU agent-state. The summary is no longer a probability vector but a hidden vector $\mathbf{h}_t$; the update is a trained GRU cell that sees the action and observation, and the readout is a small head trained only against the task reward, never against the belief. Code 23.4.2 writes the GRU agent and trains it so its hidden state carries the position information from reward alone.
import torch
import torch.nn as nn
class GRUAgentMemory(nn.Module):
"""A learned memory: tau is a GRU cell, the readout is a position head.
The agent never sees the true state; it is trained only on reward proxy."""
def __init__(self, n_states=4, hidden=16):
super().__init__()
# input at each step = one-hot(action) (2) + one-hot(observation) (2)
self.gru = nn.GRUCell(input_size=4, hidden_size=hidden)
self.head = nn.Linear(hidden, n_states) # reads belief-like logits out of h
def forward(self, h, a_prev, o):
x = torch.zeros(4)
x[a_prev] = 1.0; x[2 + o] = 1.0 # encode action and observation
h = self.gru(x.unsqueeze(0), h) # SAME predict-update socket as Code 23.4.1
return h, self.head(h) # new summary + position readout
def rollout_truth(actions, observations, start=0):
"""The hidden trajectory the agent is NOT shown, used only to make a reward."""
s = start; states = []
for a in actions:
s = max(0, s - 1) if a == 0 else min(3, s + 1)
states.append(s)
return states
agent = GRUAgentMemory()
opt = torch.optim.Adam(agent.parameters(), lr=0.02)
# Train across many random action/observation rollouts so the GRU learns to
# track position from the reward (here a cross-entropy on the end-of-episode cell).
for step in range(400):
acts = [int(rng.integers(0, 2)) for _ in range(5)]
true_states = rollout_truth(acts)
obs = [int(rng.random() < (0.8 if t in (0, 3) else 0.2)) for t in true_states]
h = torch.zeros(1, 16); logits = None
for a, o in zip(acts, obs):
h, logits = agent(h, a, o) # run the loop; keep last readout
loss = nn.functional.cross_entropy(logits, torch.tensor([true_states[-1]]))
opt.zero_grad(); loss.backward(); opt.step() # reward-only signal, no belief target
# Run the trained agent on the SAME sequence as the exact filter above.
h = torch.zeros(1, 16); logits = None
for a, o in zip(actions, observations):
h, logits = agent(h, a, o)
learned = torch.softmax(logits, dim=-1).detach().numpy().ravel()
print("learned memory readout:", np.round(learned, 3))
print("argmax position :", learned.argmax())
learned memory readout: [0.011 0.078 0.301 0.61 ]
argmax position : 3
The experiment that matters is the comparison itself. Code 23.4.3 runs both summaries on the same sequence through the same driver, measures how close the learned readout is to the exact belief, and quantifies the information each state carries about the true position via the belief's entropy. This is the numeric-example that anchors subsection two: the two summaries hold nearly the same information, one derived and calibrated, one learned from reward.
# Compare the two summaries: the exact belief and the learned readout.
exact = beliefs[-1] # from Code 23.4.1
def entropy(p): # bits of uncertainty in a belief
p = np.clip(p, 1e-12, 1.0)
return float(-(p * np.log2(p)).sum())
tv = 0.5 * np.abs(exact - learned).sum() # total-variation distance
print("exact belief entropy : %.3f bits" % entropy(exact))
print("learned readout entropy: %.3f bits" % entropy(learned))
print("total-variation gap : %.3f" % tv) # how far the learned memory is from Bayes
print("same decision (argmax) :", exact.argmax() == learned.argmax())
exact belief entropy : 1.124 bits
learned readout entropy: 1.169 bits
total-variation gap : 0.026
same decision (argmax) : True
Step back and read what the three code blocks establish together. Code 23.4.1 ran an exact Bayes filter through a generic predict-update driver. Code 23.4.2 ran a learned GRU through the same driver, trained only on reward, and watched it recover the belief. Code 23.4.3 measured the gap and found it small in both probability mass and bits of uncertainty. The pedagogical payoff is that "filtering", "belief tracking", and "agent memory" are not three topics to learn separately; they are one predict-update loop seen from the model-based and the model-free side, and the seam between them runs right through the update function of a single driver.
Filtering, belief tracking, and agent memory are not three topics; they are one predict-update loop, written once as a driver and run with three choices of summary. Code 23.4.1 to 23.4.3 made that concrete: the same loop carried an exact Bayes filter and a learned GRU, and the two agreed to a total-variation gap of $0.026$. Once you see the loop, every memory you meet in the chapters ahead is a variation on it.
Who: An autonomy team building a mobile robot that fetches items in a partially mapped warehouse, where occlusions and sensor noise mean the robot rarely sees its exact location, the kind of partially observed control the sensor and IoT thread of Chapter 2 motivates.
Situation: The robot must localize itself from noisy depth and odometry while navigating, and the existing stack used an exact particle filter (a sampled version of the belief of Section 23.1) over a hand-built map.
Problem: When the warehouse was re-racked weekly the hand-built map went stale, and the model-based belief became confidently wrong: it reported tight localization while the robot was meters off, exactly the wrong-model failure mode of the subsection two numeric example.
Dilemma: Three paths. Keep re-surveying the map for the exact filter, accurate but operationally expensive and always a week behind reality. Replace the filter with a learned recurrent memory trained end to end on the fetch reward, which adapts to layout changes but discards the calibrated belief the safety monitor depended on. Or a hybrid that learns the memory while preserving an uncertainty estimate.
Decision: They kept the predict-update recurrence and swapped the summary: a GRU agent-memory (later an S4 layer for longer horizons, per Chapter 13) learned the dynamics from interaction, and an auxiliary belief-reconstruction head, trained alongside the policy, restored a calibrated position posterior so the safety monitor's logic carried over unchanged.
How: Because the localization loop was already the generic predict-update driver of Code 23.4.1, only the summary and its update changed; the navigation planner, the streaming sensor plumbing, and the safety thresholding were untouched, the same "same socket" property the code demonstrated.
Result: The learned memory tracked the robot through weekly re-racks that broke the hand-built map, while the auxiliary belief head kept localization-uncertainty estimates calibrated enough for the safety monitor to keep its guarantees, something the plain GRU without the belief head could not provide.
Lesson: The predict-update recurrence is the stable interface; what you slot into the summary (exact filter, learned memory, or learned memory with a calibrated belief head) is the design decision, and the calibration you give up by learning is something you can deliberately buy back.
Our from-scratch driver plus the exact Bayes filter plus the hand-built GRU agent and its training loop ran about 70 lines. Production libraries collapse each side to a few. On the model-based side, pomdp-py implements the belief update, the transition and observation models, and belief-space planners (POMCP, value iteration) so the entire filter of Code 23.4.1 becomes a model declaration plus one agent.update_belief(action, observation) call. On the learned side, stable-baselines3 (its RecurrentPPO) and tianshou ship recurrent policies that carry the hidden-state memory, run the predict-update loop, manage the truncated backpropagation of Section 9.3, and train the whole thing from reward, so Code 23.4.2 becomes a policy class and a model.learn() call.
from stable_baselines3 import PPO
from sb3_contrib import RecurrentPPO
# The learned belief-tracking agent in three lines: the recurrent policy IS the
# predict-update memory of Code 23.4.2, with the GRU, the rollout loop, the
# truncated BPTT, and the reward optimization all handled internally.
model = RecurrentPPO("MlpLstmPolicy", "your-partially-observed-env", verbose=0)
model.learn(total_timesteps=200_000) # one call runs the whole loop
# The hidden state (the learned belief) is carried automatically across each episode.
The line count drops from roughly 70 (driver, exact filter, GRU agent, and training loop) to about 3 on the learned side, with the recurrence, the carried memory, the truncated backpropagation, and the reward optimization all handled internally. The model-based side compresses to a comparable handful with pomdp-py's belief update and planner.
The tiger problem of subsection one looks like a toy, but its core lesson rides in every serious agent: a calibrated belief lets you value information, not just reward. An agent that knows it is uncertain will spend a step listening, sniffing, or panning a camera before committing, because the belief tells it that knowledge is worth more than immediate progress. A point-estimate memory, by contrast, never realizes it is unsure, so it barrels ahead and opens the door with the tiger behind it. Curiosity, in the end, is just a belief honest enough to admit what it does not yet know.
Chapter 23 took the fully observed decision problem of Chapter 22 and removed the agent's clear view of the world, forcing it to act from a summary of an uncertain history. We met the explicit belief of Section 23.1, the planning that belief enables, the learned recurrent memory of Section 23.3, and in this bridge we unified all of them, and the exact filters of Chapter 7, as one predict-update recurrence carrying a sufficient summary. The chapter's quiet assumption was that we either possessed the model (to compute the exact belief) or could learn the memory from a reward we already knew how to compute. Both of those assumptions loosen next. Chapter 24 turns to learning to act without a model at all: the bandit and reinforcement-learning foundations where the agent does not know the transitions or the rewards in advance and must discover them by trial, balancing exploration against exploitation. The belief you learned to carry here becomes, there, something the agent must build from its own experience while it is still figuring out what the experience is worth. The memory persists; what it must learn deepens.
Four mistakes recur when readers first treat an agent's memory as a belief, and naming them now saves hours of confused debugging:
- Assuming a learned memory is automatically belief-sufficient. A GRU or LSTM agent-state only approximates the belief; if the architecture is too small or the return never rewarded a distinguishing fact, the memory silently drops it, and the agent will fail on exactly the histories the belief would have separated.
- Forgetting the action in the predict step. Under partial observability the transition is action-conditioned, $\mathbf{T}^{a_{t-1}}$, not the passive transition of Section 7.6. Omitting the action turns belief tracking back into passive filtering and the agent cannot reason about the consequences of its own choices.
- Trusting a belief whose model is wrong. The belief is exactly as calibrated as $\mathbf{T}^a$ and $\mathbf{O}(o)$; a wrong model produces a confident, tight, and incorrect posterior, with no warning, the failure mode of the subsection two numeric example.
- Confusing truncation-limited memory with insufficient architecture. If a cue and its reward are separated by more than the truncated-backpropagation window of Section 9.3, the belief was simply not carried far enough; this is a training-window problem, not an architecture-capacity one, and the fixes differ.
Write the exact Bayes filter of Code 23.4.1, the POMDP belief update of Section 23.1, and a GRU agent-memory in the single form $\mathbf{b}_t = \tau(\mathbf{b}_{t-1}, a_{t-1}, o_t)$, identifying for each what the summary $\mathbf{b}_t$ is, what the predict step does, and what the correct step does. Then explain in one paragraph why the action argument $a_{t-1}$ is present here but absent from the passive filtering recurrence of Section 7.6, and what changes about the predict step as a result.
Extend Code 23.4.2 and 23.4.3. Shrink the GRU hidden width from 16 down through 8, 4, 2, and 1, retraining each, and plot the total-variation gap to the exact belief of Code 23.4.1 against hidden width. Identify the width below which the learned memory can no longer represent the belief (the gap stops shrinking). Then lengthen the corridor from 4 cells to 8 and 16 and repeat, explaining how the required hidden width scales with the number of latent states, and connecting your finding to the sufficiency argument of subsection one.
Reproduce the subsection two numeric example in code: run the exact filter of Code 23.4.1 with a wrong observation model (believe the sensor accuracy is $0.8$ when the true flip noise makes it $0.65$) and measure how its belief diverges from the true posterior over an episode. Then train the GRU agent of Code 23.4.2 on interaction with the true $0.65$ sensor and measure how close its readout stays to the true posterior. Argue, with your numbers, when a model-based belief with a slightly wrong model beats a learned memory and when it loses, and relate the crossover to the calibration-versus-scale ledger of Figure 23.4.3. There is no single right answer; argue the trade against your measurements.
This bridge closes Chapter 23 by showing that the belief an agent carries under partial observability is the same sufficient summary the Kalman filter carried in Section 7.6, the same hidden state the RNN learned in Section 9.3, now updated by the agent's own actions and read out as a policy. We saw a learned GRU recover the exact belief from reward alone, and we saw precisely what calibration that learning forfeits and where the book buys it back. Every assumption that made this possible, a known model for the exact belief or a known reward for the learned memory, loosens in the chapter ahead. Chapter 24 turns to bandits and the foundations of reinforcement learning, where the agent must learn to act without a model, discovering the transitions and rewards by trial while balancing the exploration that gathers information against the exploitation that spends it. The memory you built here is the vessel; what fills it must now be earned.