LLM Fundamentals
A large language model (LLM) scores every possible next token against the text so far, lets a sampler pick one, and repeats that until the answer ends. Chat, tool calls, reasoning and agents are all that single operation run many times. The page opens with twelve things a model does that look like defects and are not, each with the mechanism behind it and the fix, then covers the loop itself, why the same sentence costs more in Ukrainian, what the context window really holds, the limits that cannot be patched out, five documented failures, and what all of it costs in production.
- Unit of work
- One token at a time
- Memory
- The context window only
- Answers
- Generated, not retrieved
Twelve things that look like bugs and are not
Almost everyone arrives at this subject holding a specific complaint rather than a general question: the model did something that looked broken. Here is the whole list first, because it is the part you can use today, and because each row has an exact mechanical cause rather than a mood. The right-hand column matters more than it looks: eleven of these twelve are fixed somewhere other than the prompt, and reaching for the wrong correction is the most expensive habit on an AI project. Every mechanism named here is explained in full further down, and the row numbers are referred to from those sections.
| # | What you saw | The mechanism | What actually fixes it |
|---|---|---|---|
| 1 | It cannot count the letters in a word. | It never sees letters. Text arrives as token numbers, and the letters inside a token are not visible to it. | Do it in code. This is not a prompt that can be improved. |
| 2 | It forgot what we agreed three messages ago. | The API keeps nothing between calls. Your application resends the history, and something truncated it. | Decide deliberately what gets dropped or summarised instead of letting a library cut the beginning. |
| 3 | It invented a source that looked exactly right. | It produces the most plausible continuation, and there is no internal state for "I do not know". | Put the document in the prompt and give it a legitimate way to say the answer is not there. |
| 4 | The same prompt gave two different answers. | The sampler picks from a distribution, and picking is random by construction. | Test properties of the answer — the label, the schema, the citation — never its exact text. |
| 5 | It ignored the middle of the long document I pasted. | Attention is reliably strongest near the beginning and the end of a prompt and weaker in between. | Put the instruction and the question last, and paste less rather than more. |
| 6 | Turn twenty cost ten times what turn one cost. | The whole conversation is resent on every turn, so you pay to re-read the history each time. | Trim or summarise the history on purpose, and log token counts from the first day. |
| 7 | The answer stopped in the middle of a sentence. | The max-output-tokens ceiling cut generation off. The model was never told the limit existed. | Raise the ceiling so a valid answer fits, and treat a truncated response as an error, not a result. |
| 8 | It described a feature we shipped last month, incorrectly. | The weights were frozen at a training cutoff. Anything later simply is not in there. | Retrieval. Your own documentation has to arrive in the prompt on every request. |
| 9 | The arithmetic in the summary is wrong. | Numbers are predicted as tokens, like words. Nothing in the loop computes anything. | Call code for the total and let the model call the code, then quote the result. |
| 10 | The Ukrainian version costs twice as much per request. | The tokeniser was fitted on a mostly English corpus, so Cyrillic splits into far more tokens. | Budget context and cost per language. It also means the window fills sooner in Ukrainian. |
| 11 | It refused, then complied when I rephrased the request. | A refusal is learned behaviour over text, not a rule engine consulting a policy. | Enforce the policy in your code. Wording is a preference; permissions are a boundary. |
| 12 | It obeyed an instruction written inside a document we fetched. | Instructions and data are the same tokens. Nothing marks one part of the prompt as trusted. | Least privilege, validation in your code and confirmation before anything irreversible. |
One operation, repeated
The model does not read words. Text is first cut into tokens — fragments of roughly three or four characters in English — and every token has a number, so what the model actually receives is a sequence of numbers. That is the whole of row 1: ask it how many letters are in a word and it is guessing about something it has never seen, the way you would guess at the number of grooves on a record you were handed in a sealed sleeve.
Given that sequence, the model produces one thing: a score for every token in its vocabulary, saying how well each would continue the text. It does not produce an answer, a sentence or an opinion — it produces a distribution over perhaps a hundred thousand candidates. A sampler then picks one, appends it to the input, and the whole calculation runs again for the next token. A four-hundred-word answer is that loop run several hundred times, and this is why output is slower and more expensive than input: the input is processed in one pass, while every output token is a separate trip through the model.
The sampler is where the settings you can actually change live, and there are fewer of them than the tooling suggests. They shape how the distribution is turned into a choice — they cannot add knowledge, and they cannot make the model more careful. It is also where row 4 comes from: the same prompt can give different answers because a pick from a distribution is a pick, and even at the lowest temperature, batching and hardware differences on the provider side keep exact reproducibility off the table.
| Setting | What it does | Practical advice |
|---|---|---|
temperature | Flattens or sharpens the distribution before sampling. Higher means unlikely tokens get a real chance. | Low for extraction, classification and code. Higher only for drafting and ideation, where variety is the point. |
top_p | Keeps only the most likely tokens whose probabilities add up to p, then samples among them. | Change one of the two, not both — they interact, and tuning both at once makes results impossible to reason about. |
| Max output tokens | A hard ceiling on the response. The model is not told about it; generation is simply cut off. | Row 7. Set it high enough that a valid answer fits, and treat a truncated response as an error rather than a result. |
| Stop sequences | Strings that end generation the moment they appear. | Useful when you generate one item of a list at a time. Largely unnecessary if you ask for structured output. |
| Seed | Asks the provider to make sampling repeatable. Best effort, never a guarantee across model versions or infrastructure. | Useful for debugging one session. Never the basis of a test, because the guarantee you want is not on offer. |
Why the same sentence costs more in Ukrainian
A tokeniser has a fixed vocabulary, learned once from a training corpus, and it keeps whole what it saw often. That corpus is overwhelmingly English, so English words survive nearly intact while Cyrillic is cut into fragments of one or two characters. The consequence is row 10, and it is arithmetic rather than opinion: the same meaning, expressed in Ukrainian, arrives as roughly two to three times as many tokens.
Two practical consequences follow, and a Ukrainian-language product meets both. The first is the invoice: identical work costs more, on every request, forever. The second is quieter and matters more — the context window is counted in tokens, so the Ukrainian version of a feature runs out of room sooner than the English one. A chat history, a retrieved document set or a few-shot example block that fits comfortably in English can be the thing that pushes the Ukrainian version past the limit, and the symptom will look like row 2 rather than like a budgeting problem.
The context window is the whole memory
The context window is the maximum number of tokens the model can have in front of it on one call, and it holds everything at once: the system instructions, the conversation so far, any documents you pasted in, the tool definitions, and the answer being generated. It is not storage. Between two calls the model retains nothing whatsoever — the APIApplication Programming Interface — contract between programsThe rules one program follows to call another: which requests it may send, in what shape, and what comes back. To the caller it is a contract — everything behind it stays a black box, which is exactly what lets the other side be rewritten without breaking you.Full article →All terms is stateless, exactly like HTTPHyperText Transfer Protocol — the protocol of the webThe protocol browsers and servers talk in: the client sends a method and an address, the server answers with a status code and a body. It keeps no memory between requests — every request stands alone, which is why anything that must be remembered is carried explicitly.All terms.
A large window is not the same as attention to everything inside it. Models reliably use what is near the beginning and near the end of the prompt, and use the middle less well — that is row 5, and a long document dropped in the centre of a request is the classic way to get an answer that ignores half of it. Put the instruction and the actual question at the end, closest to where generation starts, and keep the padding out entirely. Filling a million-token window because it is available is a cost and a latency decision as much as a quality one.
This is also where prompt caching changes the economics, and it is the one optimisation worth understanding early. Providers can cache the processed form of a prefix of your request, so a repeated prefix is billed at a fraction of the normal input price and processed faster. The catch is that it is a prefix match: one changed byte anywhere before the end of the cached region invalidates all of it. Practically, that means putting the stable material first — system instructions, tool definitions, the long document — and everything volatile last. A timestamp or a request id at the top of the system promptthe standing instructionsThe part of a prompt carrying the role and the rules, sent on every call and normally not shown to the user. It is not a secret: it sits in the same window as everything else and has been extracted from production systems by asking, so anything genuinely confidential belongs outside it.Full article →All terms quietly destroys the cache on every single call, and nothing in the response tells you so except the usage counters.
The limits that are structural, not bugs
A model that always produces the most plausible continuation will produce a plausible continuation even when there is no true one available. That is what a hallucination is, and it is row 3: not a malfunction, but the same mechanism working on a question the weights have nothing solid for. It has no separate state for "I do not know", so the confident tone of a wrong answer is identical to the confident tone of a right one, and confidence carries no information you can use.
A database query
- Returns rows that exist, or an empty result. There is no third option.
- The same query on the same data gives the same answer every time.
- Wrong output means the data or the query is wrong, and you can point at which.
- Scales by making the lookup cheaper.
A model call
- Always returns something. An empty result is a behaviour you have to design for.
- The same prompt can give different answers, and prompts are re-tuned when the model changes.
- Wrong output usually means the prompt lacked the fact — the model had no way to signal that.
- Scales by spending more tokens, which is a direct and visible cost.
Two more limits follow from how a model is made. Its weights were frozen at a training cutoff, so anything later — a release, a price change, an incident, your own documentation from last week — simply is not in there, and asking about it produces the plausible-continuation behaviour above rather than an admission. That is row 8. And the refusals are the same kind of thing from the other direction: a refusal is learned behaviour over text rather than a policy engine, which is why row 11 happens and why any rule that genuinely must hold belongs in your own code.
Five failures and what was missing from each
None of these went wrong because the model malfunctioned. In every one the model did exactly what the mechanism above says it does, and the missing piece was a control somebody had assumed was unnecessary. They are worth knowing by name because each one is now the cheapest possible way to make an argument for that control in a planning meeting.
| Case | What happened | The control that was missing |
|---|---|---|
| Mata v. Avianca, June 2023 | A New York lawyer filed a brief citing six decisions that did not exist. Asked to confirm them, the model produced full texts for them as well. The court fined the lawyers and their firm $5,000. | Row 3 with nothing checked. Anything checkable gets checked in code — a citation exists or it does not. |
| Moffatt v. Air Canada, Feb 2024 | The airline’s chatbot described a bereavement-fare refund policy that contradicted the airline’s own published page. The tribunal ordered Air Canada to pay, and rejected the argument that the chatbot was a separate legal entity. | Row 8. The correct policy was on the same website and was never retrieved into the prompt. |
| CNET, January 2023 | Seventy-seven AI-assisted personal-finance articles were published quietly. Reviewers found errors in the compound-interest examples; corrections went onto dozens of them and the programme was paused. | Row 9. Numbers were predicted as text. Arithmetic belongs in code the model calls, not in the answer it writes. |
| Samsung, May 2023 | Engineers pasted internal source code into a public chatbot to get help with it. The company banned generative AI tools on company-owned devices shortly afterwards. | Not a model failure at all. A prompt is an outbound request: decide what may leave the building before people need to be told. |
| Stack Overflow, December 2022 | The site banned generated answers within weeks of ChatGPT’s release, on the stated grounds that they were plausible often enough to be expensive to moderate and wrong often enough to be harmful. | The cost of row 3 at scale. Confidence is not a signal, so volume without verification moves work onto whoever checks it. |
What it costs once real traffic arrives
Model choice is a range, not a decision made once. Providers ship a capable tier and a cheap fast tier, and the useful habit is to prove the task is possible on the strongest model available, then try to walk down the range with a fixed set of test cases in hand. Without that set you are not choosing a model, you are guessing at one — and the cheaper model will look fine on the three examples you happen to try.
The cost line on an LLM feature is almost always tokens per request multiplied by requests, and the term that grows unnoticed is the first one. Prompts accumulate: an instruction added after each incident, a longer example, three more retrieved documents, and the conversation history under all of it. Log the token counts of every call from the first day, alongside latency — it is the only way to see the growth, and it turns a vague "the AI feature got expensive" into a specific prompt you can trim.
Latency behaves unlike any other dependency you have. Time to the first token is roughly fixed, and everything after it is proportional to how much the model writes — so a request that produces a long answer is slow because it is long, and no amount of infrastructure tuning changes that. Two things follow: stream the response so the user sees progress instead of a spinner, and ask for shorter output when you actually want lower latency, because that is the variable that moves it.
Treat the provider as what it is: a third-party dependency with rate limits and an availability record you do not control. Every call needs a timeout and a retry with backoffwaiting longer between retriesWaiting before retrying a failed call, and waiting longer after each failure — for example 1, 2, 4 and 8 seconds — usually with a random jitter added so that many clients do not retry at the same moment. Without it, retries arrive exactly when the struggling service can least afford them.All terms, because a hung request holds a connection far longer than any database would. And decide in advance what the feature does when the model is unavailable, since "the page hangs" is a decision too, just not one anybody made.
Where it degrades
Everything above describes a component that generates plausible text and does nothing else. The honest limit of that component is easy to state and hard to accept: there is no configuration, no prompt and no model version that makes a generated answer self-verifying. Every arrangement below is an attempt to skip that fact, and each one fails in a way the twelve rows already predicted.
- Treating the model as a knowledge base about your own product, instead of putting your documents into the prompt.
- Tests that assert an exact response string, which fail on a change of sampling rather than a change of behaviour.
- A timestamp or request id at the top of the system prompt, which invalidates the prompt cache on every call.
- Raising the temperature to make answers "smarter", when it only makes unlikely tokens more likely.
- Letting a chat grow until a library silently truncates the beginning, taking the system instructions with it.
- Filling a huge context window because it exists, paying for tokens that make the answer worse rather than better.
- Sizing a Ukrainian feature on English token counts, so the window and the budget are both wrong by a factor of two.
- Treating a refusal as a security control, when it is learned behaviour that a rephrase can walk around.
- Shipping without token and latency metrics, so the first sign of a problem is the invoice.
When to use it
Use it when
- Work on text where a good answer has many valid forms — summarising, rewriting, classifying, extracting structure from prose.
- Interfaces where the input is genuinely open-ended and a form with fields would be the wrong shape.
- Tasks whose output a person reviews before it takes effect, so a wrong answer is caught rather than acted on.
- Problems where writing the rules explicitly would take longer than showing the model what good output looks like.
Avoid it when
- Anything requiring an exact, auditable answer — arithmetic, totals, eligibility rules. Call code for those and let the model call the code.
- Facts about your own domain with nothing retrieved into the prompt, where confident invention is the expected outcome.
- Paths where a wrong answer acts immediately and irreversibly — payments, deletions, outbound messages — without a human gate.
- High-volume, low-value calls where a rule, a lookup table or a small classifier does the same job for a thousandth of the cost.
Sources and method
What this page stands on
- 8 sources
- 5 documented failures
- Checked October 13, 2026
The failures this page learns from
the cases behind the twelve symptoms- Regulator reportMata v. Avianca, Inc., No. 22-cv-1461 — Opinion and Order on Sanctions (opens in a new tab)U.S. District Court, S.D.N.Y. · Jun 22, 2023
- Regulator reportMoffatt v. Air Canada, 2024 BCCRT 149British Columbia Civil Resolution Tribunal · Feb 14, 2024
- ArticleCNET Is Testing an AI Engine. Here’s What We’ve Learned, Mistakes and All (opens in a new tab)CNET · Jan 2023
- ArticleCNET’s Article-Writing AI Is Already Publishing Very Dumb Errors (opens in a new tab)Futurism · Jan 2023
- ArticleSamsung bans use of generative AI tools like ChatGPT after April internal data leak (opens in a new tab)TechCrunch · May 2, 2023
- DocumentationPolicy: Generative AI (e.g., ChatGPT) is banned (opens in a new tab)Meta Stack Overflow · Dec 5, 2022
Practices and where the terms come from
tokens, context windows and caching, as the providers document themResearched with Claude. Finding and cross-checking the primary sources was done with Claude (Anthropic). Selection, writing and fact-checking: the Anatomy of IT Product editors.
Found this useful?
Share it with someone who is working on the same problem.