A language model is stateless. Each API call starts from nothing: the model reads the tokens it is sent, writes a reply, and keeps nothing. A chat that seems to remember is an application that stores the conversation and resends it, so the model's memory is whatever the application decides to put in the context window on the next call. This film makes that choice visible.
It opens on the conversation as the API receives it: a list of messages, with the developer's system message first, then the user's message and the assistant's reply. Every call sends that whole list again. The recorded calls send the first role as system; OpenAI's newer models call the same slot developer.
The scenario is one real conversation with `google/gemini-3.8-flash` at temperature 0, recorded on 11 September 2026. In turn 1 the user says the API returns every JSON field in snake_case, never camelCase, and the model promises to follow it. Turn 3 adds that money is stored as integer pence. Four unrelated questions follow, about pagination, cursor headers, caching and request ids. Then the user asks for the TypeScript type of an order response, which only comes out right if the model still knows the rules. Each chapter sends that same request with a different window and shows one of five recorded replies, with the tally across all five.
On the left of the bench is the transcript shelf: the application's stored conversation history, every turn with its real token count from the o200k_base tokenizer. Next to it is the memory store, a few saved facts from this session and earlier ones, and below it the slot for the current request. The upright column is the context window, 300 tokens to the red limit, and every card in it is as tall as its token count. The model box sees only the column. Each call copies cards into the column from the three compartments; whatever is left behind does not exist for the model.
Sent whole, the conversation is 417 tokens and every run uses snake_case. Asked after turn 3, at 192 tokens, the rule is in the window and every run uses it, and four of five name the field total_pence. After turn 7, an application with a 300-token budget does what many chat applications do by default and keeps the newest turns that fit. Turns 1 to 3 drop out without any error or warning, and all five runs switch to camelCase, exactly like a call sent with no history at all. The model did not forget. It was never told.
Persistent memory is the usual fix, and the film shows why it is not a guarantee. A memory store is still just text the application selects and resends. Here the application embeds the request, retrieves the two most similar saved facts and puts them in the system prompt. The snake_case fact comes back, and so does snake_case in every run. The pence fact scores 0.06 against a request that never mentions money units, ranks last behind facts about deploy days and the on-call rota, and is not sent, so no run says pence. Pinning the conventions that must always hold, so they ride in every call whatever the similarity, restores both rules to the window: snake_case holds in five of five runs, and the total is named in pence in two. Having the rule in the window makes it available, not obeyed, so check the output too. Pinned text is not free either: it takes the same slice of the budget on every call, which here left room for only turns 5 to 7 of the history.
The practical rules follow. Decide what must persist, and pin it into every call rather than hoping retrieval ranks it. Retrieve the rest deliberately, and log what was retrieved and what was left out. Track the token budget per call, because truncation is silent from the model's side. Summarising older turns (compaction) is another option not recorded here: it keeps more history in fewer tokens, but a summary can drop a rule just as quietly as truncation does.
The honest caveat is scale. Real context windows run to hundreds of thousands of tokens, so a 300-token budget is shrunk to make the window fill in seven turns; in production the same truncation happens after far longer conversations, or much sooner when an application caps history to save cost and latency. There are five runs per condition, one model and one conversation, and the pence check reads only field names, so a reply that keeps pence in a comment would count as a miss.
The maths
- The window budget
Every call is rebuilt from pieces: the system prompt, any saved facts, the stored turns the application chooses (the set S) and the new request. Each card in the column is as tall as its token count, and the red bar is B. The film shrinks B to 300 so a seven-turn conversation of 417 tokens can overflow it.
- Truncation keeps the newest turns that fit
The common default walks back from the newest turn and stops at the first one that does not fit. With the system prompt and request fixed at 60 tokens, turns 4 to 7 fit in 285 and turns 1 to 3 drop out, including the one that set snake_case. Nothing in the reply says so.
- Retrieval chooses by similarity, not importance
Each saved fact f is scored against the request with openai/text-embedding-3-small. The snake_case fact scored 0.19 and was sent; the integer-pence fact scored 0.06, last of five, below facts about deploy days and the on-call rota, so it never reached the window.
- The model conditions only on the window
The reply is a function of the window w and the fixed weights, nothing else. A stored turn that is not in w has exactly the influence of a turn that was never said, which is why the truncated run and the no-history run give the same camelCase reply.
Transcript
The narration, chapter by chapter. A timestamp opens the film at that moment.
- 0:00A list of messages
- Every chat reaches the model as a list of messages: a system message from the developer sets the rules, the user asks, and the assistant replies. The model keeps no memory between calls, so every call sends this whole list, system message first.
- 0:18Every call starts empty
- Call one sends just the system message and the first user message, and the model promises snake_case. Then the window empties: the model sees only what the application puts in it.
- 0:30Resend the history
- So the application resends the whole conversation on every call, and seven turns in it comes to 417 tokens, against a window we have shrunk to 300 so you can watch it fill.
- 0:44Still in the window
- Ask for the order type while the first turn still fits, at 192 tokens, and all five runs answer in snake_case, with the total named in pence in four.
- 0:55Silent truncation
- Here is the failure mode: after turn seven the application keeps only the newest turns that fit, the first three drop out silently, and all five runs switch to camelCase.
- 1:08Retrieved memory
- Memory is the obvious fix, yet it is only text the application picks to resend: similarity brought snake_case back in all five runs, but ranked the pence fact last, at 0.06, so it never arrived.
- 1:24Pinned conventions
- Pinning the conventions that must always hold keeps snake_case in five of five runs, yet only two named the total in pence, so check the output too.
- 1:34What to keep
- So pin what must persist, retrieve the rest on purpose, and watch the budget, because truncation is silent: the model never knows what it did not see.
Also available as captions (WebVTT), the video file and a Markdown copy of this page.
Related terms
- StatelessStateless means the model API keeps no memory between requests. Each call starts blank, so every request must carry all the context the model needs. This is foundational to how agents are built.
- StatefulStateful describes anything that keeps state across requests: conversation history, memory, a session. In an agent that job belongs to the harness or app, never to the stateless model API.
- Context windowThe context window is the maximum amount of text, measured in tokens, that a model can consider for a single request. It is a hard ceiling, and it is the main resource you manage when working with an agent.
- SessionA session is one continuous conversation with an agent that accumulates history in the context window. Resetting or ending it clears that history and starts the agent from a blank slate.
- Memory systemA memory system is an external store the harness uses to persist facts across sessions and reload them into context. It is how a stateless model ends up behaving as if it remembers you and your project.
- CompactionCompaction is condensing older conversation history into a summary to reclaim context-window space while keeping the important gist. It is lossy by design.
More visualisations
Embed this film
Paste this into a post, a course page or a newsletter. The film plays in place, with the same controls as here, and credits the source.