How the Model Actually Works
The model is stateless and emits only text: see the messages array your harness resends every turn, and how to budget a plan with a weekly cap.
The one line: the model is a stateless text function, your harness resends the whole conversation on every turn, and everything you control is what sits in that array.
A conversation is an array you resend
The model keeps nothing between calls. No session, no memory of your last message. Every request carries the full conversation as an array of messages, and the answer comes from that array alone.
This is why a bare follow-up fails. Send only this:
const messages = [
{ role: "user", content: "What is your best memory about him?" },
];There is no "him". Send the array instead:
const messages = [
{ role: "user", content: "Who is General Kenobi?" },
{ role: "assistant", content: "A Jedi Master and general in the Clone Wars." },
{ role: "user", content: "What is your best memory about him?" },
];Now "him" resolves, because the earlier turns are physically in the payload.
The harness holds the state. Claude Code, Codex and Cursor each store the transcript,
append your new message, and resend the lot. Your CLAUDE.md, your AGENTS.md, your tool
schemas, the output of the last forty tool calls: all of it is text folded into that same
array before it leaves your machine. "Context management" means nothing more exotic than
choosing what goes in there.
Everything the model emits is text
Models produce tokens. That is the whole output surface. An edit is text. A tool call is text. JSON, an SVG, a git diff: text in a shape the harness has agreed to recognise.
A tool call is a round trip:
- The harness sends the array plus the tool schemas.
- The model emits a structured block naming one tool and its input.
- The harness stops generation, runs the tool for real, and appends the result.
- The longer array goes back for the next turn.
// what the model emitted
const assistantTurn = {
role: "assistant",
content: [
{
type: "tool_use",
id: "toolu_01",
name: "Read",
input: { file_path: "/src/auth.ts" },
},
],
};
// what the harness appends after running it, before resending everything
const toolResultTurn = {
role: "user",
content: [
{
type: "tool_result",
tool_use_id: "toolu_01",
content: "export const verifyToken = (token: string) => { ... }",
},
],
};Step 3 is the part people skip. The model never opened the file. It emitted a request, and your machine did the reading. Same for edits: the model writes a patch as text and the harness applies it to disk. Permission prompts live exactly in that gap, between emitted text and real action.
Two consequences run through the rest of this course. Anything the model appears to "know" about your repository is there because something wrote text into the array: a rules file, a file read, a tool result, a compaction summary. And cost and latency scale with the size of that array, because you pay for it again on every turn.
For runnable demos of tool calls, structured output and file handling, see How AI-Powered Apps Actually Work.
How much fits
As of writing, current Claude models run a 1M-token window by default on the API; 200K is what you get on older and smaller models such as Haiku 4.5. Fable 5, Sonnet 5, Opus 4.6 and newer, and Sonnet 4.6 support a 1M window; Sonnet 5 is always 1M on the API. In Claude Code the upgrade is automatic for Opus only on Max, Team and Enterprise plans; Sonnet 4.6 at 1M needs usage credits on every plan. A bigger window is not a free upgrade: the whole array is re-sent and re-billed each turn, so filling it carelessly costs you on every message after.
Your plan is a budget, not a tap
On the Max 20x plan two limits apply at once. A rolling five-hour window controls how hard you can push in one sitting. A weekly cap controls the month. On that plan Fable 5 has its own separate allowance, and I still almost never use it: I would rather run a hundred Opus agents than one Fable pass, and I reach for Fable only when a genuinely hard design question needs a second opinion.
Treat the weekly cap like an allowance. Early in the week, look at what is left, count the days you plan to work, and divide. Check the usage readout before firing anything heavy. A long refactor, or a workflow that spawns dozens of subagents, can swallow a day's share in one run. Check daily until you know your own pattern. Running out is not a hard stop: paid plans can buy extra usage, and Anthropic sometimes grants promotional credits on top of the cap. My own test, again a personal one: if the weekly cap is still untouched on Friday, I have not been coding enough.
Where you do spend, spend wide rather than deep. Many cheap agents working in parallel beat one very expensive model working alone on most real tasks, and the parallel version finishes sooner. When usage runs low, one line in your global rules file can push all subagents onto a smaller model while your main session stays on Opus. That file is Rules Files and Scope.
Every remaining lesson is about that array. Rules files decide what is in it at startup. Context management decides what stays. Skills, hooks and MCP decide what gets appended mid-run, and what never has to be.
What to do
- Read one session transcript and identify the message boundaries: system prompt, rules files, your turns, tool results. Raw JSONL is punishing;
peektracerenders it as readable sections. - Assume nothing carries over between turns unless you can point at the text that carries it.
- Check your plan usage before starting a long refactor or a multi-agent run, not after.
- Divide your remaining weekly allowance by the days you plan to work, and re-check daily until you know your pattern.
- Default to several cheaper agents in parallel over one maximum-effort model on a single thread.
- Set your global rules file to downgrade subagent models when usage is tight.