Chapter 5 of 18

The model

What a language model is and is not: tokens, context, sampling, tools, cost, and why it sounds sure when it is wrong.

A language model is a program that takes some text and outputs what is likely to come next. It does that one step over and over until it stops. The model itself has no part that looks facts up, remembers yesterday or checks its own work. Anything like that is built around it. Most surprises with these tools come from forgetting that.

That one step accounts for the things that catch people out. Output sounds sure when it is wrong, because the text the model was trained on sounds sure. Ask why it did something and you get a new piece of writing, not a record of what happened. The same request gives different answers, because a dice roll is part of the design. And the model can't run anything: a tool call is text asking another program to act.

None of this makes a model useless, and none of it is cause for alarm. It tells you which output to trust and how to check the rest. Several benches here run a real language model in your browser, about the smallest that deserves the name. Commercial models are vastly better, but they are built around the same step, and the same questions apply. Prices and model names change quickly, so each one here carries the date we read it.

Language model

Also called LLM, Large language model

A program that takes text and outputs a probability for each piece of text that could come next. One piece gets picked and added to the text, and the step repeats. Everything it appears to do is built out of that step.

An agent's code, plans and progress reports are all output of this step. Reading well only shows that the text is likely, so whether it is correct has to be settled by something else.

Say it to your agent

“Don't tell me the migration worked. Run bun run db:migrate and then bun test, paste the output, and point at the line that shows it.”

Token

The unit a model reads and writes: a chunk of text such as a short word, part of a long word, a space plus a word, or a single symbol. Limits are counted in tokens, and so is what you pay.

A 3,000-line log that an agent reads costs real money, and it takes up room that the code could have had. Thinking in tokens is how you see that before it happens.

Say it to your agent

“Before you read that log into context, count it with wc -c. If it is over 100 KB, grep for the failing test name instead and read only the lines around it.”

Tokeniser

Also called Tokenizer, Byte pair encoding, BPE

The program that cuts text into tokens before the model sees it and joins tokens back into text afterwards. Its vocabulary is fixed in advance, so the same text can count differently on different models.

It explains costs that look strange: deep indentation, long names in code, encoded data such as base64, and languages that were rare in its training text all use tokens differently from the English you estimated with.

Say it to your agent

“Don't estimate by dividing characters by 4. Call the count_tokens endpoint for this model with the real system prompt, tools and messages, and tell me input_tokens.”

So where do the probabilities come from?

Training

Adjusting a model's numbers over a huge amount of text until it gets better at predicting what comes next. When training ends the numbers are frozen and shipped. Using the model doesn't change them.

Correcting an agent teaches the model nothing. Your correction is text in one conversation, and when that ends it is gone. For a lesson to reach the next session, it has to be written where the next session will read it.

Say it to your agent

“You won't remember this correction next session. Add it to AGENTS.md as a rule with one example from this repo, and show me the diff.”

Knowledge cutoff

Also called Training cutoff

The date after which a model's training text has little or nothing. Nothing tells it that time has passed, so it describes old versions and old APIs in the present tense unless the prompt says otherwise.

Agents reach for the version of a library that was common in their training text. The fix is cheap: make it read the installed version's types or docs instead of recalling them.

Say it to your agent

“You may be remembering an older version of this library. Read node_modules/zod/package.json and its type definitions before you write the schema, and name the file you checked.”

Inference

Running a trained model to get output. Each request is worked on separately, and the model itself carries nothing over from one to the next, so it starts every request knowing only what that request contains.

The whole conversation is sent again on every turn, each round of asking and answering, because it is the only way the model can see it. So long sessions cost more per turn, and a fresh session has no idea what you did this morning.

Say it to your agent

“This is a new session, so you know nothing about yesterday. Read docs/handoff.md and run git log -10, then tell me where the work stopped before you change anything.”

Since each request stands alone, everything the model is going to use has to fit into that one request.

Context window

The most tokens one request can involve: instructions, the conversation so far, files read, and the reply. What is outside it can't affect the output, any more than a program can use a file it never opened.

Agents fill windows quickly by reading files and logs. What happens next is decided by the program running the model, and the first thing to go may be the rule you set at the start.

Say it to your agent

“Don't read the whole log. Run grep -n "FAIL" test.log | head -50 and read only around those lines, so the window stays free for the code.”

System prompt

The part of a request set by whoever built the tool rather than typed by the user: the role, the rules, how to use tools. It is still text in the window, read as tokens like everything else.

It makes an instruction more likely to be followed, and that is all. The model can still do the other thing, so a rule that must always hold belongs in code that checks it.

Say it to your agent

“Put "database access only through src/db/" in AGENTS.md, and also add a test that fails if any other file imports the database client, because the line alone can be ignored.”

Prompt

Everything sent to the model in one request: system prompt, tool definitions, earlier messages, file contents and your latest words. In everyday speech it means only what you just typed, which is usually a small part.

Most of what shapes an agent's output isn't what you typed this turn. When output goes wrong, look at the whole of what was sent before you reword your sentence.

Say it to your agent

“Before you start, tell me which files you have read for this task and which you haven't. Then read src/cart.ts and src/cart.test.ts, and nothing else yet.”

Back to the one step. The model produces probabilities, and something still has to choose.

Sampling

Also called Temperature, Top-p, Top-k

Choosing the next token from the model's odds, by weighted dice. Temperature stretches or flattens the odds: low favours the likeliest token and high gives rare ones a chance. Top-p and top-k leave unlikely tokens out of the draw.

It is one reason a retry sometimes works, and why one success proves little. Advice to "set temperature to 0 for code" is also out of date on Claude's current API version, where the setting is gone.

Say it to your agent

“Remove temperature, top_p and top_k from this request: API version 2026-10-21 returns a 400 for them. If we need the same structure every time, use output_config.format with a JSON schema and validate the result.”

Non-determinism

The same input can give different output. Dice are the obvious cause. Even with the dice removed, a hosted model can vary, because of details such as how requests get batched together on the server.

An agent's success at a task is a rate, not a yes or a no, so one good run shows little and so does one bad run. Whatever must hold every time has to be checked by something that gives the same answer every time.

Say it to your agent

“Run this eval 20 times and report the pass count, not one result. If it is under 18 of 20, list the cases that failed, and don't call it fixed.”

Now the question most people start with: why does it sound so sure when it is wrong?

Hallucination

Output that reads as fact and isn't: a package, function, flag or citation that doesn't exist. It is produced by the same step as correct output, so nothing in the text marks it, and confident wording tells you nothing.

Agents act on it. They import packages and call methods that were never there. Type checks and installs catch a lot of this, but reading alone won't. Invented package names also give attackers something to register.

Say it to your agent

“Before you add any dependency, run npm view <name> version repository.url and show me the output. If it doesn't exist or the repository looks wrong, stop and tell me.”

Sycophancy

A tendency to produce what the person seems to want rather than what is true: backing down when challenged, praising weak work, confirming your guess about a bug.

Your question steers the answer. "That's the bug, right?" invites a yes, and a correct fix can get abandoned because you pushed back. Ask in a way that leaves room for you to be wrong.

Say it to your agent

“I may be wrong about the cause. Give me the two likeliest causes of this failure, the file and line behind each, and what would rule each one out. Don't assume my guess is one of them.”

When an agent does something strange, the natural thing is to ask it why. You will get an answer. It isn't the one you asked for.

Confabulated explanation

An account a model gives of its own behaviour, written as new text rather than read from a record. It may be right or wrong, and it reads the same either way. Asking "why did you do that" gets you a plausible story.

When an agent breaks something, its explanation isn't a log. Read what it actually did: the actions it asked for (tool calls, coming next), the results and the diff. Treat "why" as a source of hypotheses, then test them.

Say it to your agent

“Don't explain from memory. List the exact commands you ran this session that touched the database, in order, copied from the tool calls. Then we'll check them against the database logs.”

How does something that only outputs text change a file on your machine? It doesn't. It asks.

Tool call

Also called Function calling

Structured output asking for a named action with arguments, such as read_file on config.json. The model runs nothing. The program around it, which the next chapter calls the harness, decides whether to run it and sends back the result as text.

All real power sits in that program, so that is where the safety controls go, as the next chapter shows. It also means the model works from whatever comes back, including instructions hidden in a file it read.

Say it to your agent

“Expose read_file and run_tests as tools, not a general shell. Set strict: true on each one, return failures as a tool_result with is_error: true, and log every call with its arguments.”

Thinking and effort

Also called Reasoning, Extended thinking, Effort level

Tokens a model produces before its answer, working a problem through, which tends to help on hard tasks. Effort is the setting that controls how much of this happens. More effort costs more and takes longer.

Effort is a dial to try before changing model. Thinking is billed at the output price, whether you can see it or not, and it isn't a trustworthy record of why the model did something.

Say it to your agent

“Run the codebase search at effort low and the migration design at effort high. Show me usage.output_tokens_details.thinking_tokens for both before we change anything else.”

Now the money. An agent resends its whole conversation every turn, which would be ruinous if every token cost full price every time.

Prompt caching

The provider keeps the processed start of your request for a few minutes. If your next request begins with exactly the same bytes, that part costs a fraction of the price. One changed byte invalidates everything after it.

For long agent sessions this usually matters more than any wording trick. A timestamp at the top of a system prompt breaks every hit, and because saving to the cache costs extra, you then pay more than with no caching at all.

Say it to your agent

“Move the date out of the system prompt and into the last user message. Then send two identical requests and show me usage.cache_read_input_tokens from the second: it must be above zero.”

Model tiers

Providers sell a ladder of models at very different prices. Higher rungs cost more per token, tend to be slower and tend to do better on hard work. The names change often, so check the current list rather than remembering one.

Using the top rung to rename a variable is waste, and the cheapest rung on a hard task can cost more in retries than getting it right once. Judge a tier by its cost per finished task, on your tasks.

Say it to your agent

“Use claude-haiku-5-5 for the bulk file summaries and claude-opus-5-5 for the plan. Log cost and pass or fail per task for this week, and show me the table before we change the split.”

Token cost

What a request costs: the tokens of each kind multiplied by that kind's price per million. Input, cache writes, cache reads and output are all priced separately, and output is the most expensive, five times input on current Claude models.

An agent's bill grows with the length of the session, not only the size of the task, since every turn carries everything before it. Starting a fresh session is a cost decision as well as a quality one.

Say it to your agent

“Run this with claude -p --output-format json and read total_cost_usd. Do that for three real tasks, then tell me the cost per task and which step used the most tokens.”

Embedding

Also called Vector embedding

A list of numbers standing for a piece of text, produced so that texts with related meanings get similar numbers. Compare two lists and you get a measure of how related the texts are, even if they share no words.

It is what makes search by meaning possible, and you will meet it in tools that search documents on a model's behalf. It isn't automatically better than plain search: for an exact function name, a text search is faster, cheaper and right.

Say it to your agent

“Search for handleLogin with rg first. If that finds nothing, tell me before you build an embedding index, and if we do build one, measure it on 20 real questions against plain rg.”

Model benchmarks

Also called SWE-bench, Leaderboard

A fixed set of tasks that models are scored on so they can be compared. SWE-bench is the best known for coding: given a real bug report from GitHub and the project's code, the model has to produce a change, and tests decide whether it worked.

A score tells you how a model did on those tasks under those tests. The tests can be wrong, the answers may have been in the training text, and your code base isn't in it. Treat scores as a shortlist, then test on your own work.

Say it to your agent

“Don't pick the model from a leaderboard. Take 10 tasks we have already solved from git log, run each candidate on them in its own worktree, score with our test suite plus a test it can't see, and show me pass count and cost.”

Jagged frontier

Models do some tasks very well and others badly, and the boundary is not where you would guess: two tasks that seem equally hard can fall on opposite sides. The output looks equally polished on both.

A general feeling that "AI is good at this" doesn't transfer safely from one task to the next. Keep a record of where your agent has been wrong on your code, and check hardest there.

Say it to your agent

“You have got concurrency wrong in this repo before. Write a failing test that reproduces the race before changing any code, and I will review this diff line by line.”

Fine-tuning

Training a copy of a model further on your own examples, so that it leans towards your format or style. It changes tendencies. It isn't a way of giving a model your code base, which changes daily anyway.

People reach for it to teach an agent about their project. Instructions and search almost always do that better: they cost little, can be edited in a minute, and are in the repo where you can review them.

Say it to your agent

“Don't fine-tune for this. Put our naming conventions in AGENTS.md with three real examples from src/, then run the same task twice and show me whether the output now matches.”

One last field, because ignoring it produces the most quietly broken output of all.

Stop reason

Also called stop_reason, Truncated output, max_tokens

A field on each response saying why the model stopped: it finished, hit your token limit, wants a tool run, or declined. It arrives on a success, so code that only reads the text can treat half an answer as a whole one.

An agent that saves a file from a cut-off response saves half a file, with status 200 and no error. Whatever drives a model has to check this field before it uses the content.

Say it to your agent

“Check response.stop_reason before using the content. On max_tokens, save nothing and retry with a higher limit. Add a test that feeds in a truncated response and asserts that no file gets written.”

Do it for real

Reading gets you the words. This gets you the experience behind them, and something to show.

Catch your model inventing something

Reading about hallucination changes little. Measuring your own rate on your own stack changes how you read every suggestion afterwards, and gives you a number you measured yourself.

  1. Pick a niche task in your language, such as parsing a rare file format. Ask your agent, with no web access, for 20 packages that do it, as a plain list of names.
  2. Write a small script that runs npm view (or pip index versions) on each name and records whether it exists.
  3. For the names that exist, open three and check that they do what the agent claimed.
  4. Write down: how many didn't exist, how many existed but did something else, and which model and date this was.

Done when: A committed script and a results file showing the count of invented packages from a real run, with the model name and the date.

Price one real task

Most people can't say what a task costs them. Working it out once, by kind of token, shows you where the money goes.

  1. Pick a small real task, and run it headless: claude -p "<task>" --output-format json > run.json.
  2. Read total_cost_usd from run.json. Then find the token counts in the same file, by kind.
  3. Use the current pricing page to recompute the cost by hand. If your number differs, find out why.
  4. Run the same task again in a new session and compare. Note how much of the input came from cache.

Done when: A short table with input, cache read, cache write and output tokens, the dollars for each, and your explanation of any difference from total_cost_usd.

Run the same prompt twenty times

Non-determinism only becomes real when you see the spread. This also gives you the habit of reporting a rate rather than a single result.

  1. Choose a task whose result a script can check, such as making one failing test pass in a throwaway copy of a repo.
  2. Write a shell loop that resets the copy with git checkout, runs your agent headless, runs the test and appends pass or fail to results.txt.
  3. Run it 20 times, on the cheapest model that can do the task.
  4. Write down the pass rate, and what the failures had in common.

Done when: A results.txt with 20 lines, the loop script that made it, and one sentence stating the pass rate and the cost of getting it.

The build, stage 5 of 18

Invented names, and the bill

A list of package names the model made up, a database behind the app, and the cost of a real task worked out by hand from its tokens.

About 45 to 75 minutes, on the same app as every other stage. We ran it first and show what went wrong.

Open stage 5 of the build

Gate 5: The model

0 of 6 right

  1. 1Your agent writes a neat usage example for a package called fast-csv-guard, and says it is "the standard choice". You have never heard of it. What next?

  2. 2An agent dropped a database column it shouldn't have. You ask why, and it gives a clear, sensible, apologetic explanation. How much does that tell you?

  3. 3A task passed yesterday and fails today, with the same prompt and the same code. A colleague says to set temperature to 0. You are on Claude's API version 2026-10-21. What is your answer?

  4. 4The model's response contains a tool_use block asking to run rm -rf build/. At that moment, what has happened to the build folder?

  5. 5To help the agent, you add the current time to the first line of your system prompt. A week later your bill has gone up. What most likely happened?

  6. 6A script asks a model for a config file and saves the reply. Status is 200 and no exception is thrown, but the file ends halfway down a list. Where should the check go?

Get every answer right to install it, and to put a file in your repo. Wrong answers cost nothing.

Next chapterThe agent

The workshop

Name a word, or describe what you mean in everyday language.