LLM fundamentals
The next-token loop
A decoder-only model is a function from tokens so far to the next token. Products wrap that loop with different prompts and stop rules.
A decoder-only language model is a function: given the tokens so far, score every vocabulary entry for "what comes next." Generation is a loop that samples one token, appends it, and repeats. Chat, tools and agents are this loop with different strings in the prompt and different stop rules.
Concept
Before you start: the model reads tokens, not words. A logit is an unbounded score for one vocabulary entry. Higher means "more likely" before normalization. Softmax turns logits into probabilities that sum to 1. You almost never see raw logits in app code unless you request logprobs.
Walking through one reply
- Encode the prompt as token IDs.
- Run the transformer to get a logit for every vocabulary entry.
- Turn those logits into one token via sampling.
- Append that token and repeat until a stop condition.
P(next_token | tokens_so_far)Stop conditions include an end-of-turn token, a max length, a stop string, or a tool-call boundary. If the stop was tool-use, your app runs the tool, appends the result as tokens, and resumes the loop. A "stuck" agent is often an unbounded decode. A slow first paint is the first full pass over the prompt. A slow stream is one-token-at-a-time throughput.
def generate(prompt_ids, max_new, score_fn, sample_fn, stop_id):
"""Toy loop: score, sample, append. score_fn returns logits for the next position."""
ids = list(prompt_ids)
for _ in range(max_new):
next_id = sample_fn(score_fn(ids))
ids.append(next_id)
if next_id == stop_id:
break
return ids
print(generate([10, 20], max_new=3, score_fn=lambda ids: [0, 0, 99], sample_fn=lambda logits: logits.index(max(logits)), stop_id=99))Output:
[10, 20, 2, 2, 2]The toy scorer always prefers token 2 (the highest logit). A real model changes the logits as the sequence grows. The product wrapper is the same: bound max_new, honor stop_id, and do not let the loop run forever.
Why this picture matters
You do not ship the scorer. You do ship the bounds. Long outputs are slow because each token waits for the one before it. Stream them, and ask for brevity. Private docs, live prices and account state are not in the frozen weights — they must be inserted as tokens or fetched with tools.
Hallucinations are not a separate module. Next-token prediction produces fluent continuations whether or not a fact is grounded. Fine-tuning makes the model helpful; it does not install a truth database. Grounding (RAG, tools, citations) and refusal policies are how products constrain the dream.
Concept
A hallucination in LLM products means confident, plausible output that is not supported by the provided context or by reality. It is the default failure mode of a generative prior. Expect it whenever the model must recall rather than read.
Common mistakes
- Unbounded decode. Set a max token count and a stop rule on every call.
- Waiting for the full answer before showing anything. Tokens arrive one at a time; stream them.
- Treating fluency as truth. A fluent continuation is what the loop is for, grounded or not.
Check yourself
- Why is a 400-token answer slower to appear than a 40-token one, even after the first token? Decode is one token at a time, so length adds steps to the loop.
- The model stops with a tool-call boundary. What does your app do next? Run the tool, append the result as tokens, and resume the loop.
Key takeaways
- The model scores the next token; sampling picks one; the loop appends and repeats.
- Products wrap that loop with prompts, tools and stop rules.
- Bound the loop. Stream the tokens. Do not treat fluency as evidence.
Further learning
Sampling is how a logit becomes a token. Next, the mixer inside each step: attention.
Related
How transformers work (practitioner view)
Just enough transformer internals to predict model behavior — attention, context, and why the KV cache shapes pricing.
Tokens and context windows
How text becomes tokens, what that means for cost and limits, and how to budget a context window.
Sampling and decoding
Temperature, top-p, top-k and other knobs that turn logits into text, and when to touch them.