# How LLMs actually work: one weighted draw per token, measured across 180 asks

> How do LLMs work? Each word is a weighted draw. Asked one brand question 30 times, a model kept its five brands and shuffled their order, even at temperature 0.

Canonical: https://brandonlazovic.dev/articles/how-llms-actually-work/  
Author: Brandon Lazovic  
Published: 2026-10-18

## The short version

- A large language model writes one token at a time, and it picks each token by a weighted draw from probabilities it computes. That draw is why the same question can come back with a different answer.
- Across 180 asks of three buying questions on one model, the same five brands came back in at least 28 of every 30 asks, while their order moved. The robot-vacuum list came back in 10 different orders at default settings.
- Temperature 0, the setting meant to make answers repeatable, cut the vacuum orderings from 10 to 4 and did not stop them. First place still split 16 to 14 between two brands.
- Training shifts the odds, and web search should too, without removing the draw, so a brand's visibility in AI answers is a rate measured across many asks, and one check is one sample.

A large language model, the kind of AI system behind ChatGPT, Gemini and Claude, writes its answer one small chunk of text at a time, and it picks each chunk by a weighted draw. Picture pulling a slip from a hat that holds more slips for the likelier words. I asked one model the same three buying questions 30 times each. The brands it named barely changed, while the order they came in kept moving, and a robot-vacuum shortlist came back in <span class="hand-ring">10 different orders</span> across 30 asks. [11]

Turning the model's randomness setting down to zero cut that to four orders, and it did not stop the movement. If you check where your brand appears in AI answers, one check shows you one draw. The number that means something is how often you appear across many.

> Asked the same robot-vacuum question 30 times, one AI model named the same five brands in 28 of the answers and put them in 10 different orders.

## What does a large language model actually do when it answers?

A large language model (LLM) answers a question by repeatedly predicting what text should come next. It reads everything in front of it, computes a probability for each possible next piece of text, picks one piece, adds it to the end, and starts again. A paragraph of answer is a few hundred of these steps run in a row, each one reading everything the steps before it wrote.

<figure class="gen-loop" style="margin:2rem auto;max-width:460px"><svg viewBox="0 0 420 372" role="img" aria-labelledby="gl-title gl-desc" data-sketch style="display:block;width:100%;height:auto;font-family:var(--sans)"><title id="gl-title">The four steps an LLM repeats for every token it writes</title><desc id="gl-desc">Four boxes in a loop. Step one reads everything written so far, here a sentence ending in flat feet is. Step two scores every possible next token, here Bro at 88.8%, AS at 10.6% and the rest at 0.6%. Step three draws one token weighted by those scores, here Bro. Step four adds it to the end and starts again, and on the next pass oks comes back at 100%, spelling Brooks. An arrow returns from step four to step one.</desc><rect x="20" y="20" width="320" height="56" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="36" y="44" style="fill:var(--ink);font-size:15px;font-weight:700">1. Read everything so far</text><text x="36" y="64" style="fill:var(--ink-soft);font-size:13px">“…running shoe brand for flat feet is”</text><line x1="180" y1="78" x2="180" y2="104" style="stroke:var(--stone);stroke-width:2"/><polyline points="174,98 180,106 186,98" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="20" y="112" width="320" height="56" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="36" y="136" style="fill:var(--ink);font-size:15px;font-weight:700">2. Score every next token</text><text x="36" y="156" style="fill:var(--ink-soft);font-size:13px">“Bro” 88.8%, “AS” 10.6%, the rest 0.6%</text><line x1="180" y1="170" x2="180" y2="196" style="stroke:var(--stone);stroke-width:2"/><polyline points="174,190 180,198 186,190" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="20" y="204" width="320" height="56" style="fill:var(--amber);fill-opacity:.18;stroke:var(--amber);stroke-width:2"/><text x="36" y="228" style="fill:var(--ink);font-size:15px;font-weight:700">3. Draw one by its odds</text><text x="36" y="248" style="fill:var(--ink-soft);font-size:13px">this time the draw picked “Bro”</text><line x1="180" y1="262" x2="180" y2="288" style="stroke:var(--stone);stroke-width:2"/><polyline points="174,282 180,290 186,282" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="20" y="296" width="320" height="56" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="36" y="320" style="fill:var(--ink);font-size:15px;font-weight:700">4. Add it, then start again</text><text x="36" y="340" style="fill:var(--ink-soft);font-size:13px">next pass, “oks” at 100%, spelling Brooks</text><polyline points="342,324 396,324 396,48 350,48" style="stroke:var(--amber);stroke-width:2;fill:none"/><polyline points="356,42 348,48 356,54" style="stroke:var(--amber);stroke-width:2;fill:none"/></svg><figcaption style="margin-top:.75rem;font-size:.875rem;color:var(--stone)">The loop behind every answer, shown with the real odds <code>gpt-6-luna</code> gave when finishing a sentence about running shoes. A paragraph of answer is this loop run a few hundred times. [11]</figcaption></figure>

The research name for this is autoregressive, meaning each output becomes part of the input for the next step. OpenAI's 2020 paper describing GPT-3 calls it "an autoregressive language model with 175 billion parameters." [2] A parameter is one adjustable number inside the model. Training is the process that sets all 175 billion of them, by showing the model enormous amounts of text and nudging each number until its guesses about the next piece of text get better.

The design that made this work at scale is the transformer, introduced by Google researchers in 2017 as an architecture "based solely on attention mechanisms." [1] Attention is the step where every piece of text in the input weighs every other piece when the model works out what comes next. That step is how the word "it" in a long prompt gets connected to the product named three sentences earlier.

"Just autocomplete" undersells what happens inside. The output arrives one piece at a time, but Anthropic's interpretability team, which studies what happens inside a model while it runs, traced Claude writing rhyming poetry and reported, "Instead, we found that Claude plans ahead." [8]

Anthropic's write-up says the model "will plan what it will say many words ahead, and write to get to that destination." [8] Anthropic calls it "powerful evidence" and says models "may think on much longer horizons." My read is that both descriptions hold at once. The computation can look ahead, and the text still comes out as one weighted pick after another.

## What is a token?

A token is the unit of text a language model reads and writes, usually a short whole word or a fragment of a longer one. OpenAI's rule of thumb for English is that "1 token is approximately 4 characters" and "approximately three-quarters of a word." [3] The model never sees letters. It sees a sequence of token numbers, and every probability it computes is a probability over tokens.

Brand names show what this means in practice. When I asked OpenAI's `gpt-6-luna` to name a running-shoe brand, the word "Brooks" came out as two tokens, "Bro" followed by "oks." [11] The second fragment had a 100% probability once the first was chosen. So the real decision happened at "Bro," before the brand was even spelled out.

Token counts are also what you pay for. API prices are quoted per million tokens in and out, so the 180-ask test in this article cost about a quarter of one cent to run. OpenAI also notes that "other languages can have different relationships between characters, words, and tokens," so the same sentence can cost more in one language than in another. [3]

## How does an LLM choose the next word?

An LLM chooses the next word by giving every candidate token a probability and then drawing one, weighted by those probabilities. I asked `gpt-6-luna` to finish the sentence "The best running shoe brand for flat feet is" and had the API return the odds for its first token. "Bro," the start of Brooks, came back at 88.8%. "AS," the start of the shoe brand ASICS, came back at 10.6%. [11]

<figure class="token-odds" style="margin:2rem auto;max-width:460px"><svg viewBox="0 0 420 170" role="img" aria-labelledby="to-title to-desc" data-sketch style="display:block;width:100%;height:auto;font-family:var(--sans)"><title id="to-title">Probability of each first token when the model finishes a sentence about running-shoe brands</title><desc id="to-desc">Three bars. The token Bro, the start of Brooks, has an 88.8% probability. The token AS, the start of ASICS, has 10.6%. Every other token together has 0.6%.</desc><text x="20" y="28" style="fill:var(--ink);font-size:15px;font-weight:700">“Bro” (the start of Brooks)</text><rect x="20" y="38" width="266" height="16" style="fill:var(--amber);fill-opacity:.22;stroke:var(--amber);stroke-width:2"/><text x="298" y="51" style="fill:var(--amber);font-size:15px;font-weight:700">88.8%</text><text x="20" y="86" style="fill:var(--ink);font-size:15px;font-weight:700">“AS” (the start of ASICS)</text><rect x="20" y="96" width="32" height="16" style="fill:var(--indigo);fill-opacity:.22;stroke:var(--indigo-lit);stroke-width:2"/><text x="64" y="109" style="fill:var(--ink-soft);font-size:15px">10.6%</text><text x="20" y="144" style="fill:var(--ink);font-size:15px;font-weight:700">Every other token</text><rect x="20" y="152" width="2" height="12" style="fill:var(--stone);stroke:var(--stone);stroke-width:1"/><text x="32" y="163" style="fill:var(--ink-soft);font-size:15px">0.6%</text></svg><figcaption style="margin-top:.75rem;font-size:.875rem;color:var(--stone)">The odds <code>gpt-6-luna</code> gave its first token when asked to finish "The best running shoe brand for flat feet is". A weighted draw from these odds starts with ASICS about one time in ten. [11]</figcaption></figure>

A draw from `gpt-6-luna`'s first-token odds names ASICS about one time in ten. When an ask returns ASICS instead of Brooks, the model has not changed, and the system is working as designed. These odds come from a sentence-completion prompt, which is why they differ from the list questions measured later in this article, where ASICS took first place in 8 of 30 asks. [11]

The setting that controls how adventurous the draw is gets called temperature. OpenAI's API reference describes it as a value "between 0 and 2," where "Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic." [4] At a high temperature the 10.6% option gets picked more often. At temperature 0 the model is supposed to take the top option every time.

Models are not run at temperature 0 by default, because always taking the single likeliest token writes badly. A 2019 study of text generation found that maximizing likelihood produces text that is "bland and strangely repetitive," and proposed drawing only from the smallest set of tokens that together hold most of the probability. [5] My read is that the randomness in your AI answers is a deliberate trade made for readable text.

## Why does the same question get a different AI answer?

The same question gets a different AI answer because every token is a fresh weighted draw, and an early draw changes everything written after it. In my test, three buying questions asked 30 times each, the set of brands an LLM named barely moved, while the order of those brands moved a lot. The robot-vacuum list came back in 10 different orders across 30 asks. [11]

<figure class="draw-tree" style="margin:2rem auto;max-width:460px"><svg viewBox="0 0 420 290" role="img" aria-labelledby="dt-title dt-desc" data-sketch style="display:block;width:100%;height:auto;font-family:var(--sans)"><title id="dt-title">How the first draw split 30 identical robot-vacuum questions into branches</title><desc id="dt-desc">A tree with 30 asks at the root. The first slot splits evenly, with Roborock first and iRobot second in 15 asks, and iRobot first and Roborock second in the other 15. On the Roborock branch, Shark came third 12 times and Eufy 3 times. On the iRobot branch, Shark, Dreame and Eufy each came third 5 times.</desc><rect x="6" y="118" width="110" height="64" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="15" y="144" style="fill:var(--ink);font-size:13px;font-weight:700">Same question</text><text x="15" y="164" style="fill:var(--ink-soft);font-size:13px">30 asks</text><line x1="116" y1="150" x2="130" y2="76" style="stroke:var(--amber);stroke-width:2"/><line x1="116" y1="150" x2="130" y2="224" style="stroke:var(--amber);stroke-width:2"/><rect x="130" y="40" width="140" height="72" style="fill:var(--amber);fill-opacity:.18;stroke:var(--amber);stroke-width:2"/><text x="140" y="62" style="fill:var(--ink);font-size:14px;font-weight:700">Roborock first</text><text x="140" y="81" style="fill:var(--ink-soft);font-size:13px">iRobot second</text><text x="140" y="100" style="fill:var(--amber);font-size:13px;font-weight:700">15 asks</text><rect x="130" y="188" width="140" height="72" style="fill:var(--amber);fill-opacity:.18;stroke:var(--amber);stroke-width:2"/><text x="140" y="210" style="fill:var(--ink);font-size:14px;font-weight:700">iRobot first</text><text x="140" y="229" style="fill:var(--ink-soft);font-size:13px">Roborock second</text><text x="140" y="248" style="fill:var(--amber);font-size:13px;font-weight:700">15 asks</text><line x1="270" y1="76" x2="296" y2="58" style="stroke:var(--stone);stroke-width:2"/><line x1="270" y1="76" x2="296" y2="94" style="stroke:var(--stone);stroke-width:2"/><text x="302" y="63" style="fill:var(--ink-soft);font-size:13px">Shark third, 12</text><text x="302" y="99" style="fill:var(--ink-soft);font-size:13px">Eufy third, 3</text><line x1="270" y1="224" x2="296" y2="196" style="stroke:var(--stone);stroke-width:2"/><line x1="270" y1="224" x2="296" y2="224" style="stroke:var(--stone);stroke-width:2"/><line x1="270" y1="224" x2="296" y2="252" style="stroke:var(--stone);stroke-width:2"/><text x="302" y="201" style="fill:var(--ink-soft);font-size:13px">Shark third, 5</text><text x="302" y="229" style="fill:var(--ink-soft);font-size:13px">Dreame third, 5</text><text x="302" y="257" style="fill:var(--ink-soft);font-size:13px">Eufy third, 5</text></svg><figcaption style="margin-top:.75rem;font-size:.875rem;color:var(--stone)">The 30 robot-vacuum answers at default temperature, traced slot by slot. The first draw split the asks evenly, and each branch then drew its third place from different odds. [11]</figcaption></figure>

The three questions asked for running shoes for flat feet, customer relationship management (CRM) software for a 10-person marketing agency, and a robot vacuum for a home with two shedding dogs.

The setup was deliberately bare. I sent each question to `gpt-6-luna` through OpenAI's API with no instructions beyond the question, no web search, no memory, and reasoning switched off, so the model wrote no hidden draft before it answered. Each question asked for five brands, one per line, so a script could count them without a second model reading the answers.

I ran 30 asks at the default temperature and 30 at temperature 0 for each question, 180 in all, and none failed or came back unreadable. [11]

Each row of this table counts 30 asks of one question at one temperature setting.

| Question | Temperature | Same five brands | Different orders | First place |
|---|---|---|---|---|
| Running shoes | Default | 30 | 4 | Brooks 22, ASICS 8 |
| Running shoes | 0 | 30 | 1 | Brooks 30 |
| CRM software | Default | 28 | 4 | HubSpot 30 |
| CRM software | 0 | 30 | 2 | HubSpot 30 |
| Robot vacuum | Default | 28 | 10 | Roborock 15, iRobot 15 |
| Robot vacuum | 0 | 30 | 4 | Roborock 16, iRobot 14 |

The brand set was steady, with the same five names in at least 28 of every 30 asks, and first place was steady only where one brand led clearly, as HubSpot did for the CRM question. Where two brands were close, as Roborock and iRobot were, first place split almost evenly. [11]

Ecovacs took Dreame's place in 2 of the 30 vacuum answers at default temperature, and Copper and Insightly each took the CRM list's fifth slot once, in place of Salesforce. [11] The fifth slot is where brands appeared and vanished. A brand at the edge of a model's shortlist is present in some answers and absent from others, and one check cannot tell you which you saw.

The model also named one brand four different ways. Salesforce came back as "Salesforce," "Salesforce Sales Cloud," "Salesforce Starter" and "Salesforce Starter Suite," and my count merges them only because I added the spellings to its list after the run. [11] A tracking tool that matches one exact brand name would have under-counted Salesforce in this test.

<figure class="first-place" style="margin:2rem auto;max-width:460px"><svg viewBox="0 0 340 392" role="img" aria-labelledby="fp-title fp-desc" data-sketch style="display:block;width:100%;height:auto;font-family:var(--sans)"><title id="fp-title">Which brand came first in 30 asks, for each question at default temperature and at temperature 0</title><desc id="fp-desc">Six bars, each 30 asks wide. For running shoes, Brooks came first 22 times and ASICS 8 at default temperature, and Brooks 30 times at temperature 0. For the CRM question, HubSpot came first all 30 times at both settings. For the robot vacuum, Roborock and iRobot each came first 15 times at default temperature, and 16 and 14 times at temperature 0.</desc><text x="20" y="34" style="fill:var(--ink);font-size:14px;font-weight:700">Running shoes, default</text><rect x="20" y="42" width="220" height="16" style="fill:var(--amber);fill-opacity:.22;stroke:var(--amber);stroke-width:2"/><rect x="240" y="42" width="80" height="16" style="fill:var(--indigo);fill-opacity:.22;stroke:var(--indigo-lit);stroke-width:2"/><text x="20" y="76" style="fill:var(--ink-soft);font-size:13px">Brooks 22, ASICS 8</text><text x="20" y="96" style="fill:var(--ink);font-size:14px;font-weight:700">Running shoes, temperature 0</text><rect x="20" y="104" width="300" height="16" style="fill:var(--amber);fill-opacity:.22;stroke:var(--amber);stroke-width:2"/><text x="20" y="138" style="fill:var(--ink-soft);font-size:13px">Brooks 30</text><text x="20" y="158" style="fill:var(--ink);font-size:14px;font-weight:700">CRM software, default</text><rect x="20" y="166" width="300" height="16" style="fill:var(--amber);fill-opacity:.22;stroke:var(--amber);stroke-width:2"/><text x="20" y="200" style="fill:var(--ink-soft);font-size:13px">HubSpot 30</text><text x="20" y="220" style="fill:var(--ink);font-size:14px;font-weight:700">CRM software, temperature 0</text><rect x="20" y="228" width="300" height="16" style="fill:var(--amber);fill-opacity:.22;stroke:var(--amber);stroke-width:2"/><text x="20" y="262" style="fill:var(--ink-soft);font-size:13px">HubSpot 30</text><text x="20" y="282" style="fill:var(--ink);font-size:14px;font-weight:700">Robot vacuum, default</text><rect x="20" y="290" width="150" height="16" style="fill:var(--amber);fill-opacity:.22;stroke:var(--amber);stroke-width:2"/><rect x="170" y="290" width="150" height="16" style="fill:var(--indigo);fill-opacity:.22;stroke:var(--indigo-lit);stroke-width:2"/><text x="20" y="324" style="fill:var(--ink-soft);font-size:13px">Roborock 15, iRobot 15</text><text x="20" y="344" style="fill:var(--ink);font-size:14px;font-weight:700">Robot vacuum, temperature 0</text><rect x="20" y="352" width="160" height="16" style="fill:var(--amber);fill-opacity:.22;stroke:var(--amber);stroke-width:2"/><rect x="180" y="352" width="140" height="16" style="fill:var(--indigo);fill-opacity:.22;stroke:var(--indigo-lit);stroke-width:2"/><text x="20" y="386" style="fill:var(--ink-soft);font-size:13px">Roborock 16, iRobot 14</text></svg><figcaption style="margin-top:.75rem;font-size:.875rem;color:var(--stone)">First place across 30 asks of each question. Amber is the brand named first in each count and indigo the second. Temperature 0 settled the running-shoe question and left the robot-vacuum question split between two brands. [11]</figcaption></figure>

### Why didn't temperature 0 make the answers identical?

Temperature 0 did not make an LLM's answers identical in my test, and the likeliest cause is small numeric differences on the server that can flip which token wins when two candidates are close. Across 30 asks per question, temperature 0 cut robot-vacuum orderings from 10 to 4, CRM orderings from 4 to 2, and running-shoe orderings from 4 to 1. [11]

The question that stayed unsettled was the one with two brands nearly tied for first place.

A 2025 investigation by Horace He at Thinking Machines Lab explains why "deterministic" settings still vary. The underlying cause it names is that "The culprit is floating-point non-associativity," which means a computer can get a slightly different result when it adds the same numbers in a different order. [9]

The post traces the trigger to server load. Load changes how many requests the server processes together, and that grouping changes the order of the arithmetic for each request. [9]

My explanation for the vacuum split is suspected, not measured. A tiny numeric difference does nothing when one brand leads by a wide margin, and it can flip the winner when two brands are close to even, which is what the first-place counts show.

My API test measures the floor of the variation, and an AI product adds more on top. ChatGPT and similar products wrap the model in their own instructions, live search results, memory of past chats and personalization, and every one of those changes the input the draw starts from. My test also covers one model, three questions and one day, with 30 asks per cell.

## If it only predicts tokens, how does it follow instructions?

An LLM follows instructions because it receives extra rounds of training after it learns to predict text. The first round, called pretraining, teaches it to continue any text it sees. Later rounds train it on examples of good answers and on human ratings of which of two answers is better, shifting probability toward helpful replies. Every reply is still produced by the same weighted draw.

<figure class="train-layers" style="margin:2rem auto;max-width:460px"><svg viewBox="0 0 420 388" role="img" aria-labelledby="tl-title tl-desc" data-sketch style="display:block;width:100%;height:auto;font-family:var(--sans)"><title id="tl-title">The layers that shape an LLM's odds before the weighted draw picks each word</title><desc id="tl-desc">Five stacked boxes joined by arrows. Pretraining learns to continue any text. Instruction training learns from examples of good answers. Preference training learns from people's ratings of two answers. Reasoning models then write a hidden draft before the visible answer. At the bottom, highlighted, the same weighted draw picks every word you see, one token at a time.</desc><rect x="20" y="16" width="380" height="52" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="36" y="38" style="fill:var(--ink);font-size:14px;font-weight:700">Pretraining</text><text x="36" y="57" style="fill:var(--ink-soft);font-size:13px">learns to continue any text it sees</text><line x1="210" y1="70" x2="210" y2="86" style="stroke:var(--stone);stroke-width:2"/><polyline points="204,80 210,88 216,80" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="20" y="92" width="380" height="52" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="36" y="114" style="fill:var(--ink);font-size:14px;font-weight:700">Instruction training</text><text x="36" y="133" style="fill:var(--ink-soft);font-size:13px">learns from examples of good answers</text><line x1="210" y1="146" x2="210" y2="162" style="stroke:var(--stone);stroke-width:2"/><polyline points="204,156 210,164 216,156" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="20" y="168" width="380" height="52" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="36" y="190" style="fill:var(--ink);font-size:14px;font-weight:700">Preference training</text><text x="36" y="209" style="fill:var(--ink-soft);font-size:13px">learns from people's ratings of two answers</text><line x1="210" y1="222" x2="210" y2="238" style="stroke:var(--stone);stroke-width:2"/><polyline points="204,232 210,240 216,232" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="20" y="244" width="380" height="52" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="36" y="266" style="fill:var(--ink);font-size:14px;font-weight:700">Reasoning models only</text><text x="36" y="285" style="fill:var(--ink-soft);font-size:13px">write a hidden draft before the visible answer</text><line x1="210" y1="298" x2="210" y2="314" style="stroke:var(--stone);stroke-width:2"/><polyline points="204,308 210,316 216,308" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="20" y="320" width="380" height="52" style="fill:var(--amber);fill-opacity:.18;stroke:var(--amber);stroke-width:2"/><text x="36" y="342" style="fill:var(--ink);font-size:14px;font-weight:700">The same weighted draw</text><text x="36" y="361" style="fill:var(--ink-soft);font-size:13px">picks every word you see, one token at a time</text></svg><figcaption style="margin-top:.75rem;font-size:.875rem;color:var(--stone)">The first three layers are training rounds, and the fourth runs only in reasoning models at answer time. Each one changes the odds, and none of them replaces the draw at the bottom. [6] [10]</figcaption></figure>

OpenAI's 2022 paper on this technique, called reinforcement learning from human feedback, reported that "outputs from the 1.3B parameter InstructGPT model are preferred to outputs from the 175B GPT-3." [6] In that quote, 1.3B and 175B mean 1.3 billion and 175 billion parameters. A model with more than 100 times fewer parameters won, and my read is that its probabilities pointed toward the kind of answer people wanted.

Reasoning models add one more layer, and it is built from the same parts. OpenAI's documentation says "Reasoning models use internal reasoning tokens before producing a response," and that those tokens "are not visible via the API" while still being "billed as output tokens." [10]

A reasoning model drafts hidden text first, then writes the answer it shows you while reading its own draft. I switched that step off in my test so the count measured the plain draw with nothing hidden in front of it.

## Where do live facts and citations in AI answers come from?

Live facts and citations in AI answers come from text fetched at the moment you ask and placed in front of the model. A model's training stops at a cutoff date, so anything newer has to arrive as input. A search step finds pages, puts their text into the model's input, and the model then predicts an answer from that text and can point to the pages it used.

<figure class="retrieval-flow" style="margin:2rem auto;max-width:460px"><svg viewBox="0 0 420 392" role="img" aria-labelledby="rf-title rf-desc" data-sketch style="display:block;width:100%;height:auto;font-family:var(--sans)"><title id="rf-title">How fetched pages reach an AI answer alongside what the model learned in training</title><desc id="rf-desc">A chain of five boxes. Your question goes to a search step that fetches pages. Their text joins the model's input. A highlighted box, the weighted draw, writes the answer, and a side box shows training, frozen at a cutoff date, feeding into the same draw. The last box shows the answer can cite those pages.</desc><rect x="150" y="16" width="250" height="48" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="166" y="45" style="fill:var(--ink);font-size:13px;font-weight:700">Your question</text><line x1="275" y1="66" x2="275" y2="88" style="stroke:var(--stone);stroke-width:2"/><polyline points="269,82 275,90 281,82" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="150" y="96" width="250" height="48" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="166" y="125" style="fill:var(--ink);font-size:13px;font-weight:700">A search step fetches pages</text><line x1="275" y1="146" x2="275" y2="168" style="stroke:var(--stone);stroke-width:2"/><polyline points="269,162 275,170 281,162" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="150" y="176" width="250" height="48" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="166" y="205" style="fill:var(--ink);font-size:13px;font-weight:700">Their text joins the input</text><line x1="275" y1="226" x2="275" y2="248" style="stroke:var(--stone);stroke-width:2"/><polyline points="269,242 275,250 281,242" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="150" y="256" width="250" height="48" style="fill:var(--amber);fill-opacity:.18;stroke:var(--amber);stroke-width:2"/><text x="166" y="285" style="fill:var(--ink);font-size:13px;font-weight:700">Weighted draw writes the answer</text><rect x="20" y="240" width="110" height="80" style="fill:none;stroke:var(--stone);stroke-width:2"/><text x="32" y="264" style="fill:var(--ink);font-size:13px;font-weight:700">Training</text><text x="32" y="284" style="fill:var(--ink-soft);font-size:13px">frozen at a</text><text x="32" y="304" style="fill:var(--ink-soft);font-size:13px">cutoff date</text><line x1="132" y1="280" x2="146" y2="280" style="stroke:var(--stone);stroke-width:2"/><polyline points="140,274 148,280 140,286" style="stroke:var(--stone);stroke-width:2;fill:none"/><line x1="275" y1="306" x2="275" y2="328" style="stroke:var(--stone);stroke-width:2"/><polyline points="269,322 275,330 281,322" style="stroke:var(--stone);stroke-width:2;fill:none"/><rect x="150" y="336" width="250" height="48" style="fill:var(--indigo);fill-opacity:.12;stroke:var(--indigo-lit);stroke-width:2"/><text x="166" y="365" style="fill:var(--ink);font-size:13px;font-weight:700">Answer can cite those pages</text></svg><figcaption style="margin-top:.75rem;font-size:.875rem;color:var(--stone)">Retrieval adds new text to the input, while training sets the odds the model brings with it. Both feed the same draw, so a fetched page should raise a brand's chances without guaranteeing a mention, which my search-free test did not measure. [7]</figcaption></figure>

The 2020 paper that named this pattern, retrieval-augmented generation, paired a model's built-in knowledge with "a dense vector index of Wikipedia." [7] A vector index is a searchable store of text that finds passages by meaning instead of by exact words. AI search products that fetch pages before answering follow the same pattern.

Retrieved pages change the odds, and the draw still happens. A page of yours in the input should make your brand more likely to appear without making it certain, though my test ran without search and did not measure that. Which pages a system chooses to cite is its own selection step, covered in [does AI prefer Reddit](/articles/does-ai-prefer-reddit/). Why a model can hold a fact and still fail to produce it is covered in [recall, not knowledge](/articles/encoded-but-not-recalled/).

## What does this mean for tracking brand visibility in AI answers?

Tracking brand visibility in AI answers means measuring a rate, how often a brand appears across many asks of the same question, because each ask is one weighted draw. A single check that shows your brand in first place says little. In my test, the robot-vacuum question put Roborock first in 15 asks and iRobot first in the other 15, so either result was one coin flip.

Three habits follow from the data.

1. Ask each question many times and report your brand's answer share, the number of answers that name it divided by the number of asks, with both numbers shown. Thirty asks resolved the steady brands in my test. A brand that appears in 2 of 30 answers, as Ecovacs did, holds a contested slot, and 30 asks are too few to pin its rate down. [11]
2. Watch the last slot of a shortlist, because that is where brands came and went in this test.
3. Count every name a model uses for your brand, since one brand came back four ways.

Before you trust an AI visibility number, from a tool, an agency or your own team, ask how many times each question was asked. Then ask how the count matched brand names, for example whether "Salesforce Starter" was counted as Salesforce.

## Sources

1. Vaswani et al., Attention Is All You Need (arXiv, 2017) — https://arxiv.org/abs/1706.03762
2. Brown et al., Language Models are Few-Shot Learners (arXiv, 2020) — https://arxiv.org/abs/2005.14165
3. OpenAI Help Center: Understanding and counting tokens — https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them
4. OpenAI API reference: Create chat completion (temperature, logprobs, top_logprobs) — https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create
5. Holtzman et al., The Curious Case of Neural Text Degeneration (arXiv, 2019; ICLR 2020) — https://arxiv.org/abs/1904.09751
6. Ouyang et al., Training language models to follow instructions with human feedback (arXiv, 2022) — https://arxiv.org/abs/2203.02155
7. Lewis et al., Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (arXiv, 2020) — https://arxiv.org/abs/2005.11401
8. Anthropic: Tracing the thoughts of a large language model (March 27, 2025) — https://www.anthropic.com/research/tracing-thoughts-language-model
9. Horace He, Thinking Machines Lab: Defeating Nondeterminism in LLM Inference (September 10, 2025) — https://thinkingmachines.ai/blog/defeating-nondeterminism-in-llm-inference/
10. OpenAI API documentation: Reasoning models — https://developers.openai.com/api/docs/guides/reasoning
11. First-hand: 180 brand-list asks and one token-probability read on OpenAI's gpt-6-luna, October 18, 2026, counted by the script sampling_spread.py in this site's repository
