Skip to content

How LLMs work

docs.scrimba.com

First, the name. LLM is short for large language model: the kind of AI behind tools like ChatGPT, the thing you send a prompt to and get text back from. This chapter is the working picture of what one actually is.

You type a question, and a few seconds later a fluent, confident answer appears. It reads like the model understood you and looked up the answer. That impression is useful, and it is also wrong in ways that matter, and the gap between the two is where most beginner mistakes come from.

This is the chapter that pays off for the rest of your career with these tools. You do not need to know the math behind training a model to build with one. You do need a working picture of what is actually happening when it answers, because that picture explains everything else: why prompting works, why the same question gives different answers, why models invent facts, why they cost what they cost, and why some features are hard that look like they should be trivial. Everything later in this handbook is a consequence of the ideas here.

This chapter is the mental model underneath these systems: what a model is, the one loop it runs, and the handful of properties that explain the rest of the handbook. None of it is math. All of it is the difference between coding against a black box and knowing why it behaves the way it does.

Every technique in later chapters, prompting, structured output, retrieval, agents, is a consequence of what you are about to read. Get this picture right and the rest stops feeling like a bag of tricks and starts feeling like one machine you can predict.

These models fail in specific, repeatable ways, and this chapter is why. Strip the interface and a language model is a frozen function that predicts text one chunk at a time, and almost every production failure mode, nondeterminism, cost blowups, lost context, confident wrong answers, falls out of that single fact.

There is no new math here, and that is the point: the durable engineering advantage is in the mechanism, not the model of the month. Read it as the substrate every later decision rests on.

What a model actually is

Strip away the chat interface and a large language model is one thing: an enormous mathematical function, a fixed set of billions of numbers called parameters (you will also hear them called weights). That is the whole model. Not a database, not a search engine, not a little person in a box. It is a very large pile of numbers that takes text in and produces text out.

Those numbers did not come from a programmer typing them. They were set during training. The provider fed the model a staggering amount of text, books, code, articles, web pages, and ran a simple drill billions of times: hide the next word, ask the model to predict it, and nudge its numbers slightly whenever it guessed wrong. Repeat that at enormous scale and the numbers slowly settle into values that are good at predicting text. That is what training is: tuning billions of dials until the prediction gets good.

Two things follow from this, and they explain a lot of behaviour you will meet later. First, training happens once, ahead of time, and it is hugely expensive. By the time you call the model, the numbers are frozen. The model does not learn from your conversation. Nothing you say changes its parameters. It feels like it remembers and adapts, but that is the software around it, not the model itself, a point that comes back hard in the context window section.

Second, there is no table of facts inside it. The "knowledge" lives as patterns baked into those numbers, the way a baker who has made ten thousand loaves has the technique in their hands without reading a recipe. The model learned the shape of correct, sensible text. That is why it can be fluent and wrong in the same sentence: it is reproducing the shape of a good answer, not reading a stored fact off a shelf.

JunoWhat a model actually is So a model is a huge pile of fixed numbers that turns text into text, and those numbers were tuned once during training and then frozen. It does not learn from you while you chat, and it has no neat table of facts inside, it has patterns. That is why it can sound sure and still be wrong, so always check anything that matters.

A model is a pure function: you give it (weights, input) and it computes an output, nothing more. The weights are the billions of learned numbers fixed during training; the input is the text you send. Because it is a function, the same input under the same settings produces the same underlying scores every time. Any variation you see between runs comes from the sampling step that picks words from those scores, not from the model changing its mind.

The knowledge that function carries is stored lossily, smeared and compressed across the weights all at once, not filed as retrievable records. There is no row you can read, no cell you can edit. A fact the model "knows" is really a strong pattern that the weights reconstruct on demand, and sometimes reconstruct slightly wrong. You cannot point at where a fact lives, and you cannot patch one fact without retraining.

The practical move is to treat the model as a fixed function you call, not as a knowledge base you query. Lean on it for shaping language, reasoning over text, and following instructions. When you need something specific, current, or auditable, put that information into the input yourself instead of trusting the weights to hold it. That single habit, supply the facts rather than expect them, prevents a large share of confident wrong answers.

JunoWhat a model actually is Think of the model as a pure function of weights and input: same input, same settings, same underlying scores, with run-to-run variation coming from sampling. Its knowledge is compressed lossily across the weights, so you cannot look up or edit a single fact in there. Build accordingly: treat it as a fixed function you call, and feed specific or current facts in through the input rather than hoping the weights remember them.

A deployed model is frozen weights behind an API: billions of learned numbers, fixed at training time, computing a pure function of (weights, input). The only time its behaviour actually changes is when the provider ships a different model.

That has a sharp operational edge. A silent update underneath the same endpoint can shift your outputs without a single line of your code changing, so pin a specific model version, treat that version as part of your contract, and re-run your evals before you adopt a new one. Adopting "the latest" on trust is how a working system quietly regresses.

The weights are compressed parametric memory, and it is both lossy and unauditable. You cannot diff what a model "knows" between versions, you cannot enumerate its facts, and you cannot prove a given fact is in there or correct. So never put a load-bearing fact's correctness on parametric recall. If a wrong answer would cost you, supply the fact in the input from a source you control and can cite, and keep the model in the role of phrasing and reasoning over that source, not being the source.

Deliberately changing the weights is what fine-tuning does, and it is worth being clear about what it buys. Fine-tuning reliably shifts behaviour and form, tone, format, task habits, but it does not give you a dependable, queryable store of facts. Reach for it to shape how the model responds, not to install knowledge you need to trust. Keep facts in the input, keep style in the weights, and you will not be surprised by either.

JunoWhat a model actually is The weights are frozen, so behaviour only moves when the provider ships a different model: pin the version, make it part of your contract, and re-run evals before upgrading or a silent swap will regress you while you sleep. Parametric memory is lossy and unauditable; you cannot diff what it knows, so keep load-bearing facts in the input from a source you control, not in recall. And fine-tuning shifts behaviour and form, not a reliable fact store, so use it for how the model responds, not for what it should know.

Predicting the next token

With that pile of numbers in place, the model does exactly one job: it predicts the next chunk of text, over and over.

Here is the loop in slow motion. You give it some text. It runs that text through all those parameters and produces a probability for every possible next chunk it knows about, tens of thousands of options at once. After "The capital of France is", the chunk "Paris" might get a 97% score, "a" a 1% score, and everything else almost nothing.

The model then picks one chunk, adds it to the text, and runs the whole thing again to pick the next. It repeats until the answer is done.

That is the entire engine. A reply you read as a single thought was built one chunk at a time, each chunk chosen from a fresh ranking of likelihoods, with no plan for where the sentence is going beyond "what is probable next". Every capability you will use, chat, code, translation, tool use, reasoning, is this same loop running underneath.

The phone keyboard that suggests your next word is the same idea in miniature. The difference is the billions of parameters behind the guess. Trained on enough text, "what is the most probable next chunk" turns out to be good enough to write working code and clear explanations. But the underlying move never changes: it is prediction, not understanding, and not looking up a stored answer.

JunoPredicting the next token The whole engine is one small loop: read the text so far, score every possible next chunk, pick one, and go again until the answer is finished. The model has no plan for the sentence beyond what is probable next, so a reply you read as a single thought was actually built one chunk at a time. That is prediction, not understanding, and not a stored answer being looked up.

The model does one thing on repeat: at each step it reads all the text so far and emits a score for every token (a token is a chunk of text, often part of a word) in its vocabulary, tens of thousands of them at once. Those scores become a probability distribution, and the model samples one token from it. Then it appends that token to the text and runs the whole thing again to choose the next. After "The capital of France is", "Paris" might hold almost all the probability and everything else almost none.

This feeding-back is why it is called autoregressive: each new token depends on all the text so far, including the tokens it has already written this turn. There is no global plan and no draft to revise. The model commits one token at a time, and because it cannot take a token back, it can paint itself into a corner: a confident early word can force the rest of the sentence down an awkward path it then has to finish.

That single fact explains a few things you will use in practice. Letting the model write out its reasoning before its final answer helps, because more tokens mean more steps and more computation spent on the problem before it commits to an answer. Output structure is decided strictly left to right, so the shape of a response is set as it goes, not planned up front. And the same loop is what drives tool use: the model predicts the tokens that form a call, you run it, and the result is fed back as more text for the next prediction.

JunoPredicting the next token At each step the model scores every token in its vocabulary, samples one, feeds it back, and repeats: that feedback loop is what autoregressive means. There is no plan and no undo, so it commits token by token and can paint itself into a corner. That is why writing out reasoning before the answer helps, and why tool use is the same loop with a result fed back in.

Generation is sequential by construction: the model produces one token (a chunk of text), feeds it back, and predicts the next, so each output token is a separate forward pass through the network. Reading your input is comparatively cheap, processed in one go; the slow, expensive part is the model writing. Latency and cost scale with output length, not input length. The practical levers fall out of that: keep outputs short, stream tokens so the user sees progress instead of waiting for the full reply, and do not pay for verbose formatting you will throw away.

The other consequence is correctness. Because there is no global plan, a single pass is not self-correcting: the model commits left to right and cannot revise a token once it is out. That is why anything that has to be right wants verification or a second pass over the first draft, and why a model that writes its reasoning before its answer tends to do better, you are buying it more steps to commit on. Treat the first generation as a draft, not a verdict.

One lever worth wiring in: many setups expose per-token probabilities (logprobs, the model's own confidence score for each token it picked). You can read them to flag low-confidence spans, gate an answer that the model was unsure about, or route uncertain cases to a second pass or a human. It is a cheap signal you already have, and it turns "the model might be wrong here" into something you can act on programmatically rather than guess at.

JunoPredicting the next token Every output token is its own forward pass, so cost and latency track output length, not input: keep replies short, stream them, and stop paying for formatting you discard. There is no plan and no undo, so one pass does not self-correct; treat the first generation as a draft and add a verification pass for anything that has to be right. If you can read per-token logprobs, use them to flag or route the spans the model was least sure about, it is confidence you already have and rarely spend.

The randomness dial

If the model always grabbed the single highest-scoring chunk, it would hand you the same answer to the same prompt every time, and that answer would often be flat and repetitive. So most of the time the pick has a little randomness in it: it usually takes a high-probability chunk, but not always the very top one. This is why you can ask the exact same question twice and get two different replies. That is the system working as designed, not a fault.

You control how much randomness through a setting called temperature, which you set when you call the model in the chapter on calling models from code. The intuition is worth having now. At a low temperature, the model sticks close to its top picks: focused, consistent, predictable, which is what you want for pulling a number out of an invoice or sorting text into categories. At a higher temperature, lower-probability chunks get chosen more often: more varied and creative, and more likely to wander somewhere wrong. Brainstorming and creative writing want the higher end; anything with a correct answer wants the lower end.

So a single dial slides the model between "careful and repeatable" and "surprising and inventive". It is the same prediction loop either way; temperature only changes how boldly the model reaches past its safest guess.

JunoThe randomness dial Temperature is your randomness dial. Turn it low for tasks with a right answer, like extraction or sorting, and you get focused, repeatable replies. Turn it up for brainstorming and creative work, and you get more variety along with more chances to wander off. Same prediction loop, only a bolder or safer reach.

Before the model picks its next chunk, it has a probability for every candidate. Temperature reshapes that distribution before the model samples from it. A low temperature sharpens the distribution toward the single most likely token (closer to always taking the top pick), so output gets focused and repeatable. A high temperature flattens it, giving less likely tokens a real chance, so output gets more varied and more likely to drift wrong. That is why the same prompt can return different replies: there is a draw happening, and temperature sets how skewed the odds are.

Temperature is not the only knob here. Top-p (sample only from the smallest set of tokens whose probabilities add up to p) and top-k (only the k most likely tokens) both trim the candidate pool before sampling. They overlap with temperature in effect, so it helps to think of them as one randomness setting rather than three independent ones.

The practical move is to set temperature explicitly per task instead of trusting whatever default ships. Go low for extraction, classification, and anything that emits structured output you parse later; go higher for ideation and drafting where variety is the point. Watch for interactions: stacking a high temperature with a top-p of 1 leaves the full tail in play, which works against you when you need reliable, parseable results.

JunoThe randomness dial Temperature reshapes the probability distribution before sampling: low sharpens it toward the top token for focused output, high flattens it for variety. Treat temperature, top_p, and top_k as one randomness setting, not three. Set it per task: low for extraction, classification, and structured output; higher for ideation. Do not pair a high temperature with top_p of 1 when you need parseable results.

Temperature scales the score distribution before sampling, and the tempting shortcut is to set it to 0 and call the output deterministic. It is close, but it is not a guarantee. Floating-point math, server-side batching, and routing inside large models all introduce small nondeterminism even at 0. So do not build exact-match caching or exact-match tests that assume byte-identical output for a repeated prompt; that assumption fails intermittently, and intermittent failures are the expensive kind to chase.

This shapes how you test sampled behaviour. A single run tells you almost nothing about a stochastic system (one whose output varies from run to run), so evaluate a prompt by running it several times and looking at the distribution of outputs: how often it lands in spec, how wide the variance is, where the tail goes wrong. That is the job your evals do, and they want enough samples to see the spread, not one lucky pass.

Treat temperature, top-p (sample only from the smallest set of tokens whose probabilities reach a cumulative p) and top-k (keep only the k most likely tokens) as one sampling budget you tune together rather than three dials you set by reflex. Pick the lowest randomness that still gives acceptable variety for the task: tightening all three at once can collapse output into something repetitive and brittle, while leaving them all open hands you variance you then have to validate around. The cost is real on both sides, so spend it deliberately.

JunoThe randomness dial Temperature 0 is near-deterministic, not guaranteed: floating-point, batching, and internal routing leak nondeterminism, so skip exact-match caching and exact-match tests. Evaluate sampled behaviour over several runs and read the distribution, not one pass; that is what your evals are for. Tune temperature, top_p, and top_k as one sampling budget, and pick the lowest randomness that still gives acceptable variety.

Tokens

The "chunks" a model predicts have a name: tokens. A token is a piece of text, often a whole word, sometimes only part of one. Common words are usually a single token, while longer or rarer words get split into several.

"tokenization"  ->  "token" + "ization"
"unbelievable"  ->  "un" + "believ" + "able"
"cat"           ->  "cat"

Why chop text into these odd pieces instead of using whole words or single letters? It is a trade-off. Single letters would make every sequence enormously long, and length is what the model has to compute over. Whole words would need a vocabulary of millions of entries and would still break the first time someone invents a word or makes a typo. Tokens are the middle path: a fixed vocabulary of a few tens of thousands of common pieces that can be snapped together to spell anything, including words the model has never seen.

Here is the under-the-hood consequence that surprises people. The model never sees letters. It sees tokens, which to it are really ID numbers for those chunks. So tasks that look effortless to us can be hard for it: counting the letters in a word, reversing a string, noticing that "strawberry" has three r's.

It is not being dim. It does not perceive the individual characters at all, the way you cannot taste the separate grains of flour in a finished loaf. When a model fumbles a spelling or character-counting task, this is why, and the fix is usually to do that part in normal code instead.

Tokens are also the unit of two things you will care about constantly:

  • Money: providers bill per token, both the tokens you send and the tokens the model writes back, so a long document in and a long answer out both cost more. A rough gauge for English is about four characters per token, or 100 tokens for every 75 words; code and other languages often split into more tokens, which is part of why they can cost more. You will meet this directly when you start calling models from code.
  • Limits: there is a ceiling on how many tokens the model can handle at once, which is the next section.
JunoTokens A token is a chunk of text, usually a word or part of one, and the model reads those chunks as ID numbers, not as letters. That is why it can stumble on counting or spelling, so hand that work to plain code. And since you pay per token both ways and there is a cap on how many fit at once, fewer tokens means less cost and more room.

The model predicts tokens, pieces of text that are often a whole word and sometimes a fragment. The piece that does the splitting is the tokenizer, and it works off a learned vocabulary built by repeatedly merging the most common pairs of characters until you have a fixed set of a few tens of thousands of pieces (a scheme usually called byte-pair encoding, or BPE). That history is why frequent words end up as a single token while rare ones fragment into parts: the common patterns got merged during training, the uncommon ones never did.

Two practical facts fall out of this. First, the model never handles characters, only token IDs, so any character-level operation (counting letters, reversing a string, slicing at an exact position) is shaky inside a prompt and reliable in your own code. Push that work to code and let the model do the language part. Second, tokenization is model-specific, so token counts are not portable. The same sentence can cost a different number of tokens on a different tokenizer, which matters the moment you budget cost or fit content into a window.

The takeaway for building: do not eyeball token counts from character length. Count with the actual tokenizer the model uses, because that is the number you are billed on and limited by. You meet all of this concretely when you start calling models from code, where the count you send plus the count you get back is the bill.

JunoTokens A tokenizer splits text using a learned vocabulary (BPE), which is why common words are one token and rare ones fragment. Tokenization is model-specific, so count with the model's own tokenizer rather than guessing from characters. And keep character-level work (counting, reversing, exact slicing) in your code, not in the prompt.

Tokens are the meter on everything you ship. A token is a text piece from the tokenizer's learned vocabulary, and the per-token bill plus the fixed context ceiling are the two numbers that shape your cost and your design. The comforting four-characters-per-token rule of thumb holds for plain English prose and falls apart exactly where production lives: code, JSON, deeply nested formatting, and non-Latin scripts all fragment into far more tokens than the heuristic predicts. So budget with the real tokenizer, not the gauge, or your cost and capacity estimates will be wrong precisely on the payloads you actually send.

The fragmentation is not evenly distributed, and that is a fairness and cost problem at scale. The same meaning in a non-Latin language can cost several times the tokens of its English version, so the same feature is quietly more expensive, and slower, for some of your users than others. Worth measuring per language before you promise anyone a flat price or a fixed latency.

Two more habits from the field. Format is spend: whitespace, verbose delimiters, and decorative markdown all cost tokens for zero added meaning, so keep the structure you feed the model compact and let your code add presentation later. And feed clean, normal text, because rare or malformed tokens (mojibake, stray control characters, odd encodings) sit in the thin, undertrained corners of the vocabulary and can trigger strange output. None of this is exotic; it is the difference between a token budget you trust and one that surprises you in the invoice.

JunoTokens The four-chars-per-token rule breaks on code, JSON, and non-Latin scripts, which is where your real traffic lives, so budget with the actual tokenizer. Non-Latin languages can cost several times more tokens for the same meaning, a real cost and fairness gap worth measuring per language. Strip decorative formatting to save tokens, and feed clean text so rare or malformed tokens do not buy you strange behaviour.

The context window

The context window is how much text the model can take in at one time, measured in tokens. Picture it as the size of the model's desk. Everything involved in a single request has to fit on that desk at once: your instructions, the conversation so far, any documents you pasted in, and the reply the model is writing.

Why is there a limit at all? It comes from how the prediction works. To choose the next token, the model weighs how every token in the input relates to every other token, so it can tell that "it" refers to the cat three sentences back. That all-to-all comparison is what lets the model track meaning across a passage, and it is also what makes long inputs expensive to process. The provider sets a ceiling, the context window, to keep each request manageable.

When the desk is full, something has to come off. If a conversation runs long enough to overflow the window, the earliest parts fall away and the model can no longer see them. This is why a long chat seems to "forget" what you said at the start. It did not forget in any human sense; those tokens are off the desk. It also helps to know that models tend to pay closest attention to the beginning and end of what is on the desk and can lose track of things buried in the middle, so where you put important text matters when you fill the window.

Now the point that catches almost every beginner, and it matters more than all the rest. The model has no memory between separate requests. Remember that its numbers are frozen. Each call starts with a blank desk. The model does not remember your last question, your name, or anything from a minute ago.

A chat app feels like one flowing conversation only because the app quietly resends the entire history with every new message. The continuity is something the software around the model builds, not something the model has.

That single fact shapes how you build everything from here. If you want the model to know something, you have to put it on the desk in that request: the conversation so far, the user's details, the relevant documents, all of it, every time. A large part of this handbook is really about doing that one thing well, getting the right text onto the desk.

JunoThe context window The context window is the model's desk: every request has to fit on it, and when it overflows the oldest text falls off. The model keeps no memory between calls, so the app resends the whole history each time to fake a continuous chat. Your job from here is to get the right text onto that desk in every single request.

Think of the context window as a fixed budget of tokens that one request gets to spend, covering your instructions, the running conversation, any pasted documents, and the answer being generated. The window exists because of how the model reads input: a mechanism called attention compares every token against every other token to work out what relates to what. That comparison is what lets the model resolve a "it" back to the noun it points at, and its cost grows roughly with the square of the input length. Double the tokens and you more than double the work, which is the real reason long inputs are slow and run up cost.

Fitting inside the window is not the same as the model using everything in it. There is a well-documented effect called lost in the middle: models attend most reliably to the start and end of the input and can skim over material parked in the center. So place your most important instructions and data near the top or bottom of the prompt, not buried in a wall of pasted text.

The other half of this is memory, and the key fact is that the model is stateless: it remembers nothing between separate requests. Each call begins with an empty window, so the only way the model knows the conversation so far is that you send it again every time. Resending and shaping that history is your job, not the model's. As the chat grows past the window, manage it yourself by trimming old turns or replacing them with a short summary, so the tokens you keep are the ones that still matter.

That puts context construction at the center of building with these models. Deciding what goes into the window, in what order, and how to compress what came before is most of the work, and prompting is where you learn to shape it deliberately.

JunoThe context window The window is a token budget covering instructions, history, documents, and the reply; attention makes long inputs cost roughly the square of their length. Models suffer a lost-in-the-middle effect, so put what matters near the start or end. The model is stateless, so resending and trimming the conversation history is on you, every call.

Treat the context window as a ceiling, not a target. It is the token budget a single request gets, spanning your instructions, the running history, retrieved documents, and the output.

Every token you put in it costs money and latency, because the attention step (the all-to-all token comparison the model runs to read input) scales roughly with the square of length. Worse, effective recall degrades well before you reach the limit: the lost in the middle effect means accuracy on material buried in the center drops off even when it technically fits. So curate context rather than dumping everything in, and when the source data is large, retrieve only the relevant pieces with RAG instead of pasting the whole corpus.

Order is a lever, not a detail. Providers can reuse the computation for an unchanged prefix through prompt caching, where the cached internal state is the KV cache, the model's stored work for tokens it has already read. Put stable content first (system instructions, fixed reference material) and variable content last, and repeated calls get cheaper and faster because the front of the prompt is served from cache. Reorder that prefix carelessly and you invalidate the cache and pay full price again.

Memory across turns is not a feature the model has; it is an engineering choice you make, and each option fails in its own way:

  • Plain windowing, keeping the most recent turns, is cheap but silently drops early facts the user still expects you to know.
  • Summarisation holds more history in fewer tokens but loses detail and can quietly encode its own errors.
  • Retrieval pulls back only what is relevant but depends entirely on your index returning the right pieces.

Pick per use case, and assume whichever you choose will eventually surface the wrong thing; instrument for it rather than trusting it.

JunoThe context window The window is a ceiling, not a goal: cost and latency climb with every token and recall rots before you hit the limit, so curate and lean on retrieval for anything large. Stable content first, variable last, so prompt caching (the KV cache) actually pays off. Cross-turn memory is your design choice among windowing, summarisation, and retrieval, and I have been caught out by all three, so instrument the one you pick.

What the model does not know

All of a model's knowledge was baked in while it was training, so it only knows what was in that training data, and that data was gathered up to some cutoff point in the past. Two limits fall straight out of this.

First, it does not know anything that happened after its cutoff. Ask about last week's news or a library that came out this month and it has no real idea, though it may happily produce a plausible-sounding answer anyway. Second, it never knew anything private. Your company's internal docs, a user's order history, the contents of your database: none of that was in the public text it trained on, so it cannot know it, no matter how nicely you ask.

There is a quieter limit too. The model usually cannot tell you where something it "knows" came from, because the knowledge is blended together inside it rather than filed away as separate, sourced facts. It can write you a citation, but it is predicting what a citation should look like, not looking up a real one.

This is the reason for a technique you will meet later called retrieval, or RAG. If you want a model to answer about recent events or your own private data, you do not retrain it. You fetch the relevant text yourself and set it on the desk at request time, so the model has the facts in front of it instead of guessing. A model is a reasoner over the text you give it far more than a reliable well of specific facts.

JunoWhat the model does not know A model only knows what was in its training data, up to a cutoff in the past, so it misses recent events and anything private, and it cannot reliably say where its facts came from. When you need current or private information, do not retrain: fetch the relevant text and hand it to the model in the request. Treat the model as something that reasons over what you give it, not as a trustworthy memory.

A model's built-in knowledge, its parametric knowledge (the facts encoded in its weights, the tunable numbers set during training), is frozen at the training cutoff. Nothing that happened after that date is in there, and nothing private ever was, because the weights were shaped by public text. So memory gives you two predictable gaps: recency, anything after the cutoff, and privacy, anything that was never in public training data.

Those two gaps are really one gap seen from two sides, and they close the same way: put the needed text into the request. You fetch the recent article or the relevant database row yourself and supply it alongside the question, so the model reads the fact instead of recalling it. This is the core idea behind RAG, retrieval-augmented generation, which you will use whenever answers must reflect current or proprietary information.

Parametric knowledge also carries no source attached. The facts are blended across the weights, not stored as discrete entries with provenance, so the model cannot reliably tell you where something came from. A citation it produces is generated to look right, not retrieved from a record, which is exactly why grounding the answer in text you provide is worth the effort.

The practical rule for building: do not ask the model to recall current or proprietary facts from memory. If a fact must be right, fetch it and supply it, and let the model reason over it.

JunoWhat the model does not know Parametric knowledge, the facts encoded in the weights, is frozen at the training cutoff and carries no source, so the model misses recent and private information and cannot reliably cite anything. Both gaps close the same way: fetch the relevant text and put it in the request, which is the idea behind RAG. As a rule, do not have the model recall current or proprietary facts from memory; supply them and let it reason over them.

The model's parametric memory, the knowledge held in its weights (the tunable numbers fixed during training), is unversioned and unauditable. You cannot diff it, point at where a claim lives, or confirm it has not drifted. So for anything that must be correct, current, or compliant, do not trust the model's say-so: ground the answer in a retrieved source and cite that source. Treat built-in knowledge as a fluent prior, not a system of record.

The cutoff is also fuzzier than a single date suggests. Training data is not uniform right up to that date: recent material is thinner and less digested than older, well-covered material, so recent-but-pre-cutoff facts are known unevenly. A model can be confident and wrong about something from a year before its cutoff while nailing a decade-old fact, which is why "is it before the cutoff?" is a weaker guarantee than it looks, and why you retrieve anything that has to be right.

Reach for the right tool for the gap, because the two common ones are not interchangeable. Retrieval supplies facts at request time and stays current as your sources update. Fine-tuning, continuing training on your own examples, shifts form and behaviour, tone, format, how the model follows your conventions, and it is a poor, stale way to inject knowledge: facts trained in are frozen again, hard to update, and still unsourced. Use retrieval for what is true, fine-tuning for how it should sound.

JunoWhat the model does not know Parametric memory is unversioned and unauditable, so for anything that must be correct, current, or compliant, ground the answer in a retrieved source and cite that, not the model's word. Remember the cutoff is fuzzy: recent-but-pre-cutoff facts are known unevenly, so retrieve anything that has to be right. And match the tool to the gap: retrieval supplies facts, while fine-tuning shifts form and behaviour and is a stale way to inject knowledge.

Why models make things up

Sometimes a model states something false with total confidence: a quote no one said, a function that does not exist, a citation to a study that was never written. This is called a hallucination, and after the last few sections it should feel almost inevitable rather than mysterious.

The reason is that the model has no internal sense of "true" versus "false". It only has "likely text" versus "unlikely text". Most of the time those line up, because in the text it learned from, true statements are far more common than false ones, so the probable continuation is usually the correct one.

But when the model hits a gap, something it was never trained on, or your private data it could never have seen, it does not stop and flag the gap. It cannot reliably tell what it does not know. It does the only thing it ever does: produces the most probable-sounding continuation.

A confident, well-formed, wrong answer is often exactly what sounds most probable. The same machinery that makes it fluent makes it fluent when it is wrong.

This is the part to sit with: hallucination is not a glitch you can fully prompt away. You can reduce it, and later chapters show how. Telling the model it is allowed to say "I do not know" helps a little. Asking it to answer only from text you provide helps much more, because now there is no gap to fill from frozen training. But the tendency comes from what the model fundamentally is, a probability machine with no fact-checker inside, so the durable fixes are structural: give it the facts to work from rather than hoping they were in its training, and verify answers that matter rather than trusting them.

Carry one rule out of this chapter above all others: a model's confidence tells you nothing about whether it is right. Fluency and correctness are produced by the same process and come apart all the time. Build as though any single answer could be wrong, because any single answer could be.

JunoWhy models make things up A hallucination is the model confidently filling a gap with text that sounds right but is not, because it only knows "likely" and not "true". You can lower how often it happens, but you cannot prompt it away completely, so the safe move is to hand the model the facts it needs and check the answers that matter. And remember the big one: a confident tone is not proof, so never trust certainty on its own.

When a model invents a quote, a function, or a citation and states it with total confidence, that is a hallucination, and it falls straight out of how the model works. The model has no signal for truth. It scores continuations by "likely text" versus "unlikely text", and most of the time likely and true overlap because true statements dominated its training data.

Hallucination spikes exactly where that overlap breaks down: at the edges of its knowledge, on rare or niche topics, and on your private data it was never trained on. There the model still produces its most probable continuation, and a fluent, well-formed, wrong answer is often what scores highest.

So you cannot fix this with wording alone, but you can rank your mitigations by how much they actually help. The biggest lever by far is grounding: put the real facts in the prompt and tell the model to answer only from that supplied text, ideally quoting it. Now there is no gap for it to fill from frozen training. Retrieving the right text to supply is its own technique, covered in RAG.

Below that, give the model an explicit escape hatch, permission to answer "I do not know" instead of guessing, which removes some of the pressure to invent. And keep temperature (the randomness dial on token selection) modest for factual work, since high randomness widens the door to unlikely, off-base continuations.

The practical consequence: constrain the model to context you provide, and verify outputs that matter. Treat prompt phrasing as a small adjustment on top of those structural moves, never as the whole defense. A model that sounds certain has told you nothing about whether it is correct, because fluency and correctness come from the same process and routinely diverge.

JunoWhy models make things up Hallucination is the model emitting fluent, likely text with no internal check for truth, and it gets worse at the edges of its knowledge and on data it never saw. Rank your fixes by impact: ground it in text you supply (the biggest lever), give it room to say "I don't know", tell it to answer only from the provided context and quote it, and keep temperature modest for factual work. Constrain to context and verify the outputs that matter; do not lean on wording tricks alone.

Hallucination is the model returning confident, well-formed text that happens to be false, and it is a property of the architecture, not a bug you patch. The model ranks continuations by likelihood with no truth signal attached, so at the edges of its training, rare topics, fresh events, anything private, it still emits its most probable guess. You will not eliminate this. The job is to design the system so a wrong answer is caught or contained before it reaches anything that matters.

That means three structural moves, none of them prompt wording. Validate the shape of every answer: make the model return data against a schema so malformed or out-of-range output fails loudly instead of flowing downstream, which is what structured output buys you. Measure your actual hallucination rate with evals, a held-out set of inputs with known-good answers scored automatically, rather than spot-checking a few prompts and calling it fine. And keep a human in the loop wherever the cost of being wrong is high, because no automated guard catches everything.

The trap underneath all of this is calibration. Model confidence is poorly calibrated: stated certainty is not evidence of correctness, and the tone of an answer carries no information about its truth value. So never gate a decision on the model sounding sure.

Build and prefer an abstain path, a sanctioned "I cannot answer this from what I was given", and make abstaining cheap so the system reaches for it instead of inventing. That structural mindset, assume any single answer can be wrong and contain the damage, is what the whole safety and limits chapter is built on.

JunoWhy models make things up You cannot delete hallucination, so engineer for containment: validate structure with schemas, measure the rate with evals instead of eyeballing a few outputs, and keep a human where being wrong is expensive. Model confidence is badly calibrated, so a sure tone is not evidence and you never gate on it. Give the system a cheap, sanctioned way to abstain, and prefer it over a confident guess every time.

Putting it together

Everything in this chapter is one idea seen from different angles. A model is a frozen pile of numbers that predicts the next token, and almost every behaviour you will deal with falls out of that:

  • It predicts one token at a time from a ranking of probabilities, so it improvises rather than recalls, and a touch of randomness (temperature) means answers vary.
  • Tokens are the chunks it works in: the unit of your bill, the unit of your size limit, and the reason it cannot reliably count letters.
  • The context window is a single request's desk, shared by everything, and the model remembers nothing between requests, so continuity is your job.
  • Its knowledge is frozen at a training cutoff and never included your private data, which is why you fetch facts and put them in the prompt.
  • Hallucination is the price of a system that predicts likely text with no sense of truth, reduced by grounding and checking, never by clever wording alone.

Hold these together and a surprising amount of AI engineering turns out to be one task in different costumes: get the right text onto the desk, in the right shape, at the right moment, and never trust the output blindly. The next chapter, Open and closed models, looks at what kinds of models there are and how you get one, and then prompting is where you start steering all this prediction toward what you actually want.

JunoPutting it together Almost everything about a model follows from one fact: it is a frozen set of numbers predicting the next token. From that come varied answers, token-based cost and limits, no memory between requests, a training cutoff, and hallucination. A lot of building with these models is getting the right text onto the desk and never trusting the output blindly.

One fact generates the whole chapter: a model is a frozen function that predicts the next token from a probability distribution. Trace the consequences and you have your working model:

  • Prediction plus sampling means output varies; temperature sets how much.
  • Tokens are the unit of cost, the unit of the limit, and why character-level tasks belong in code.
  • The context window is finite and stateless, so you resend and curate everything the model needs.
  • Knowledge is frozen at a cutoff and unsourced, so current and private facts come from retrieval, not recall.
  • Hallucination is structural, reduced by grounding and verification, not by wording.

The pattern under all of it is the same: get the right text into the context, in the right shape, at the right time, and verify what comes back. That is what the rest of the handbook builds, starting with the landscape of open and closed models and then prompting.

JunoPutting it together The whole chapter is one fact and its fallout: a frozen next-token predictor gives you varied output, token-based cost and limits, statelessness, a knowledge cutoff, and hallucination. The job that follows is constant: get the right text into the context in the right shape, then verify what comes back. Prompting is where you start doing it.

Everything here reduces to one sentence: a frozen function predicts the next token over the text you provide, with no state, no truth signal, and no plan. Every production property you manage is a corollary:

  • Output is stochastic, so you test distributions, not single runs.
  • Cost and latency track tokens, especially output, so you budget and stream.
  • Context is finite and stateless, so memory is an engineering choice with failure modes.
  • Parametric knowledge is frozen, lossy, and unsourced, so anything load-bearing gets grounded and cited.
  • Confidence is uncalibrated, so you verify rather than trust.

The payoff is that none of this moves when the model does. Pin a version, build the harness around the failure modes, and the next release is an upgrade you evaluate, not a surprise you absorb. The rest of the handbook is that harness, and it begins with the landscape, open and closed models, then prompting.

JunoPutting it together One sentence runs the chapter: a frozen, stateless next-token predictor with no truth signal. Stochastic output, token-driven cost, finite context, frozen knowledge, and uncalibrated confidence are all corollaries, and your harness exists to contain each one. The upside is that it does not move when the model does, so pin a version and build around the failure modes.