0.1
第 0 部分 / 基础概念 · 贯穿全书的直觉认知

LLM 思维模型。

本章旨在帮助你对语言模型建立足够深刻的理解,使你能够大致预测模型对给定提示词(prompt)的行为,并在出现故障时解释其原因。这里讲的不是"什么是 LLM"——你已经用过了。我们要建立的,是把 LLM 从黑盒变成可推理系统所需的工作直觉:令牌(token)是真正的基本单元,上下文窗口(context window)是有限资源,采样是需要驾驭的概率分布,以及幻觉(hallucination)是具有明确机制的可预测故障模式。本指南其余所有章节都以这些直觉为前提。

STEP 1

令牌:真正的基本单元。

语言模型既不读字符,也不读单词。它读的是令牌(token)——子词单元,英文中通常为 2 到 6 个字符,由分词器(tokenizer)选取,以平衡词汇量和序列长度。内化这一点是一切认知的基础,因为 LLM 工程中半数的 bug 和意外,都源于对"什么算一个令牌"的误解。

首先要看到的

对几个字符串运行分词器,看看会发生什么。以下是 Anthropic 的 Claude 分词器的结果(OpenAI 的 tiktoken 对英文的处理类似):

"Hello"           → 1 token
"Hello world"     → 2 tokens  (Hello | world)
"ChatGPT"         → 1 token   (one canonical chunk)
"Anthropic"       → 1 token
"unhappiness"     → 3 tokens  (un | happiness ... or un | happi | ness)
"supercalifragilisticexpialidocious" → 8 tokens

"Czesław Miłosz"  → 7 tokens  (C | z | es | ł | a | w |  Mił | osz ...)
"日本語"          → 3 tokens  (one per character)
"🦀"             → 2 tokens  (the emoji decomposes into bytes)

"{\"name\":\"alex\"}"           → 7 tokens
"{ \"name\" : \"alex\" }"       → 10 tokens (extra spaces cost real tokens)

这个列表中有四点值得特别关注。

"ChatGPT"是一个令牌。训练语料库中频繁出现的字符串会获得专属令牌,因为这样更高效。"Anthropic"也是如此。"OpenAI"大概是一两个令牌。常见的产品名、API 名、编程关键字——都是一个令牌,因为它们出现得足够频繁,分词器训练过程将它们合并了。这也是为什么 Python 中的 def function_name(): 所用令牌数,少于对同一事物的英文描述。

波兰语、日语和 emoji 消耗的令牌多得多。"Czesław"——一个普通的波兰人名——需要六七个令牌,因为分词器主要在英文语料上训练,对波兰语变音符号并未优化。同一个名字的英文转写("Czeslaw")只需 2-3 个令牌。这不是 bug,而是训练分布的直接结果。实际影响:为非英语用户服务的聊天机器人,每轮对话的成本(cost)比服务英语用户高出 2-4 倍,且有效上下文窗口更小,因为每条用户消息消耗的令牌更多。

空白符和格式化也是真实的令牌。两个 JSON 示例仅在空白符上有区别,但这个区别是有意义的。制表符、换行符、多余的空格——都消耗令牌。"紧凑型"提示词格式比"可读性强"的格式实际上更省钱。在生产环境中,你为每个令牌付费,乘以每次请求,这一点尤为重要。

分词是确定性的,但并不直观。分词器是一段代码,将字符串转换为整数序列(令牌 ID)。相同输入,每次输出相同。但分词边界由算法决定,该算法在语料库上训练而来,而非基于语言学规则。你无法通过目测预测分词结果;必须实际运行分词器才能知道。

对提示词成本的影响

在生产中你会切实感受到的三个具体结果:

你的提示词成本不是字符数、单词数,也不是任何可以目测的量。它是分词器输出的计数,唯一知道它的方式就是去测量。服务商的计费面板会在事后显示真实数字;如果想提前知道,就在本地对输入运行分词器。

# Pre-flight token counting (Anthropic)
from anthropic import Anthropic
client = Anthropic()

count = client.messages.count_tokens(
    model="claude-sonnet-4-5",
    messages=[{"role": "user", "content": prompt}],
)
print(f"input tokens: {count.input_tokens}")

# Or locally with tiktoken for OpenAI
import tiktoken
enc = tiktoken.encoding_for_model("gpt-5.5")
print(f"input tokens: {len(enc.encode(prompt))}")

对故障的影响

三种可追溯到令牌的故障模式,在你检查之前,它们看起来都像别的问题:

JSON 输出中名称被截断。模型正在生成一个包含名称字段的 JSON 对象。max_tokens 设为 200。模型输出了 {"name": "Czesł 就停了,因为完成这个波兰人名加上剩余 JSON 所需的令牌超出了预算。JSON 格式损坏,下游代码崩溃。如果在设置 max_tokens 之前测量过令牌数,你会给它 250。

结构化输出中的子词溢出。你要求模型输出三个类别之一:"critical"、"warning"、"info"。结果你得到了"criti"或"warning_"或"infos"。模型开始输出正确的令牌,但在子词边界处采样偏移了。严格模式和 JSON schema 约束生成可以防止这种情况;它们的存在本身就说明了令牌为何重要。

边缘情况下的行为不一致。你的提示词在 ASCII 输入的示例上运行正常,但在使用弯引号("智能"引号)的相同示例上却失败了。原因在于:"" 的分词结果不同。模型在训练中见过 ASCII 版本一百万次,而见过弯引号版本可能只有一万次。对人类看起来相同的输入,行为却出现了差异。

LLM 工程师最值得养成的单一习惯:查看你正在优化的任何提示词的分词结果。免费的分词器演示工具(Anthropic 和 OpenAI 都提供了网页工具)允许你粘贴文本并看到带颜色的令牌边界。花五分钟盯着你的提示词如何被分词,能发现你追了好几个小时的 bug。

Question
分词器词汇表有多大?

大约 100,000-200,000 个令牌。Claude 的分词器约为 200K;OpenAI 的 cl100k_base 是 100,256。Llama 的分词器因版本而异。词汇表在分词器训练时确定——一旦固定,就成为模型的一部分。词汇表越大,每个令牌平均覆盖的文本就越多,相同输入的令牌数就越少,成本也越低,但嵌入层的参数也越多。

实际要点:分词器的选择影响成本,但你无法控制它。服务商选择分词器;你为它给出的结果付费。

Question
为什么"ChatGPT"是一个令牌,而"Czesław"要六个?

BPE(字节对编码,即该算法)将训练语料库中出现频率最高的字符对合并为词汇条目。"ChatGPT"在分词器训练期间出现得足够频繁,获得了专属条目。"Czesław"没有,所以它被拆分成更小的片段("ł"在英文文本中稀有到通常单独占一个令牌,甚至分解为 UTF-8 字节)。词汇表是训练语料库的频率加权快照。

这就是为什么技术英语(包含"function"、"object"、"request"等词)的分词效果好——这些词在以代码为主的训练语料库中极为常见。

Question
模型看到的是令牌 ID 还是令牌字符串?

令牌 ID——整数。模型从来看不到字符串"ChatGPT";它看到的是类似 [5942] 这样的东西。模型的嵌入层将每个 ID 映射为高维向量,之后一切都是向量运算。字符串到 ID 的映射(分词器)是一段独立的代码,在模型接收任何输入之前运行,在模型输出任何内容之后运行。

这就是为什么在极少数情况下,模型可能输出无法解码为有效 UTF-8 的令牌——模型在 ID 上操作,分词器在字符串上操作,对于字节回退令牌,往返转换可能失败。流式传输必须缓冲,直到出现有效的 UTF-8。

STEP 2

上下文窗口是有限且对位置敏感的资源。

你听到"200K 上下文窗口",直觉上以为"200,000 个令牌的空闲空间"。这种直觉的两半在生产环境中都是错的。这些空间需要真实的费用,而且窗口内并非所有位置都平等——位于长上下文中间的内容,性能可测量地差于位于开头或结尾的相同内容。将上下文窗口视为均匀的平坦内存,是产生微妙质量 bug 的根源,而这些 bug 在开发环境中不会暴露。

上下文成本随使用量而非容量增长

那个显眼的数字——Claude Sonnet 4.5 的 200K 上下文窗口——是上限,不是价格档位。你为实际使用的令牌付费,而且每轮对话都要付费。一个积累了 80K 令牌历史记录的多轮智能体(agent)对话,在每次后续模型调用时都要为 80K 输入令牌付费,而不是只付一次。在 20 轮对话中,同样的积累历史要付费 160 万个输入令牌。提示词缓存(第 2.2 章)在上下文稳定时能显著降低这一成本,但基本规律是"上下文成本随对话长度复利增长"。

推论:上下文是智能体消耗的最昂贵资源。不是模型调用,不是工具调用(tool calling),而是积累的上下文令牌。优化智能体携带多少上下文向前推进(摘要、截断、如第 1.3 章所述的子智能体隔离)通常是可用的最高杠杆成本优化。

"迷失在中间"效应

更难以直觉把握的是:在上下文窗口内的位置,影响模型能够可靠使用其中内容的程度。2023-2025 年的多项研究记录了一种被称为"迷失在中间(lost in the middle)"的规律:当你将 30 个文档放入上下文并要求模型使用其中一个时,模型更有可能使用位于上下文开头或结尾的文档,而不是中间的文档。

该效应的形态:

Recall accuracy by document position in a 30-doc context ↑ 100 │██ ██ │██ ██ 80 │██████ ██████ │██████ ██████ 60 │████████ ████████ │████████ ↓ "lost middle" ████████ 40 │████████ ████████████████████ ████████ │████████ ████████████████████ ████████ 20 │████████ ████████████████████ ████████ │████████ ████████████████████ ████████ 0 └─────────────────────────────────────────→ start end of context of context Recall is high at the start (the model anchored on the first few) and at the end (recency effect — these were seen most recently). In the middle, performance can drop by 20-40 percentage points.

该效应有充分的实证支撑,随模型和任务的不同而在量级上有所差异,并随新模型的推出而有所减弱(但并未消失)。2026 年的前沿(frontier)模型处理长上下文比 2023 年的模型好得多,但中间位置的性能损失仍然可测量。请在设计时考虑这一点。

如何应对

对你在提示词中排布信息的方式,有三个实际影响:

将最重要的内容放在开头和结尾。如果你的系统提示词有关键规则("绝不透露 API 密钥"),就把它们放在最顶部或最底部——不要埋在 2000 个令牌的系统提示词中间。如果你检索的上下文有 10 个按相关性排序的片段,就把排名最高的片段放在边界处,而不是中间。

在用户实际问题附近重申关键指令。如果系统提示词写着"仅以 JSON 格式回复",然后跟着 5 万个令牌的对话历史,模型在生成回复时可能已经忘记了 JSON 约束。解决方法:在用户消息末尾加上简短的重申("请以 JSON 格式回复,如系统提示词所指定")。这种冗余看起来丑陋,但值得这样做。

不要因为可以就把上下文填满。在检索增强(retrieval-augmented)生成中增加更多文档,在某个点之后往往会损害质量,不是因为模型读不了,而是因为相关文档现在被埋在中间,模型无法聚焦在它上面。大多数生产 RAG 系统最终采用 top-5 或 top-10 的片段,不是因为模型只能处理这么多,而是因为这是"迷失在中间"开始抵消边际上下文收益之前的甜点区域。

思维模型:注意力作为预算

"迷失在中间"背后的机制:上下文中每个令牌在生成下一个令牌时都必须被关注。注意力机制从根本上就是对所有输入令牌进行加权——而当有 100,000 个令牌作为输入时,每个令牌默认只分到一小片注意力。开头的令牌在处理早期就被"锚定"(某种意义上模型的表征从左到右构建);结尾的令牌在序列中最新,获得强烈的位置权重。中间的令牌既未被锚定,也不是最新的。

理解这个数学不是必须的,使用这个直觉就够了:把注意力看作模型分配给输入令牌的有限预算,其中开头和结尾有结构性优势。你希望模型真正使用的信息,应该放在预算最充裕的地方。

┌─────────────────────────────────────────────────────────────┐ │ WHERE TO PUT WHAT │ │ │ │ Start of context: │ │ ─ System prompt with critical rules │ │ ─ Most important retrieved documents │ │ ─ Tool definitions (model needs them throughout) │ │ │ │ Middle of context: │ │ ─ Bulk content the model needs to read but probably won't │ │ refer back to constantly │ │ ─ Historical conversation turns the model can summarize │ │ │ │ End of context (just before model generation): │ │ ─ User's most recent message │ │ ─ Restated critical instructions ("respond in JSON") │ │ ─ Any "do this next" prompt for the assistant │ └─────────────────────────────────────────────────────────────┘

长上下文与 RAG:比看起来更深刻的问题

"直接把所有内容倒进上下文,窗口够大"是检索增强生成的一个诱人替代方案。有时这是正确答案,有时不是,其权衡有三个维度:

  • 成本(Cost)。每轮输入 20 万个令牌是昂贵的——按 2026 年的定价,在 Sonnet 上大约每轮 $0.60。使用 5 个检索片段的 RAG 每轮约 $0.015。差距会复利增长。
  • 延迟(Latency)。即使使用了优化推理,处理 20 万个令牌也需要可观的时间——通常是 3-10 秒才输出第一个令牌。上下文较小的 RAG 在不到一秒内就能输出第一个令牌。
  • 质量(Quality)。有时长上下文胜出(当正确答案需要跨多个文档综合时)。有时 RAG 胜出(当正确文档需要处于上下文的开头/结尾以规避"迷失在中间"时)。在你的评估(eval)集上测量。

实话实说:长上下文是一种工具,不是检索的替代品。当你需要对已知语料库进行跨文档推理时使用它。当语料库太大无法放入,或成本和延迟重要,或大多数查询只需要几个片段时,使用 RAG。

Question
"迷失在中间"在新模型上有所改善吗?

有,但并未消失。2026 年的前沿模型处理 100K+ 上下文比 2023 年的模型好得多——中间位置的召回率有了显著提升,尤其是随着上下文训练和改进的注意力变体等技术的应用。但在中间上下文检索的基准(benchmark)测试中,你仍然可以测量到开头/结尾与中间位置之间 5-15 个百分点的差距,具体取决于任务。

对于智能体设计:将"迷失在中间"视为一个真实效应,你可以通过合理定位内容来缓解它,但不应假定它不存在。将重要内容放在边界处的成本几乎为零;这样做的代价是偶发的、无法复现的质量回归(regression)。

Question
我看到有人说"200K 上下文但实际有效只有 8K",这是什么意思?

这些说法来自"大海捞针"基准测试,测试要求模型从长文档中检索一个特定事实。它们方向上是正确的——召回率随上下文长度而退化——但对于典型用法,往往夸大了程度。真实情况:对于需要跨文档推理的任务,现代长上下文模型效果良好。对于需要找到一个被埋没的事实的任务,效果较差,检索增强方法通常胜出。

务实的规则:如果你的任务是"找到并使用",用 RAG。如果你的任务是"跨文档综合",考虑长上下文。无论如何,都在你的具体评估集上测量,而不是相信泛泛的说法。

Question
提示词缓存会改变这些情况吗?

提示词缓存(第 2.2 章详细介绍)在成本维度上会带来显著降低——缓存的令牌按正常输入价格的 10% 计费。它不会改变质量维度;模型仍然需要关注所有令牌,"迷失在中间"依然适用。缓存改变了长上下文的经济性,但不改变与之协作的认知形态。

STEP 3

采样:模型是一个概率分布,而非一个函数。

思维模型中最有用的单一转变:模型不会为给定输入选择单一输出。对于每个下一个令牌,它生成整个词汇表上的概率分布,然后由独立的采样步骤从中选取一个令牌。不同的采样设置,不同的输出——相同的输入,相同的模型。内化这一点,能消解一类困惑("为什么这次得到了不同的答案?"),并为生产智能体提供一个控制面。

模型实际输出的是什么

在每一步生成中,模型输出一个 logit 向量——每个词汇条目一个数值,通常是 100,000-200,000 个数。对它们做 softmax,就得到了下一个令牌可能是什么的概率分布:

Prompt: "The capital of France is"
Model's distribution over next token:
  " Paris"   →  0.847
  " the"     →  0.043
  " a"       →  0.022
  " located" →  0.018
  " known"   →  0.011
  " Lyon"    →  0.008
  ... 200,000 more tokens, mostly near zero ...

Sampling picks one of these. Then the process repeats for the next token,
conditioned on the new sequence.

模型的输出不是" Paris"——而是整个分布。采样是将分布缩减为单一令牌的操作。不同的采样选择,沿着概率树走出不同的路径。

用白话说温度(temperature)

温度是一个单一数值——通常在 0 到 2 之间——控制分布在最高概率令牌上的集中程度。

温度 0:每次都取概率最高的单一令牌。分布在采样前被折叠为独热向量(one-hot vector)。有时称为"贪婪解码(greedy decoding)"。这是模型行为最接近确定性的状态。

温度 1:按实际分布采样。模型的自然可变性。

温度 2:平坦化分布。高概率令牌被采样的频率降低,低概率令牌被采样的频率升高。输出变得更加多样,也更缺乏连贯性。

temperature 0 temperature 1 temperature 2 P=1.0 │█ │ │ │█ │█ │ │█ │█ │ │█ │█ │ │█ │██ │█ │█ │██ │██ │█ │████ │████ │█ │██████ │██████ │█ │████████ │████████ │█ │██████████ │██████████ P=0.0 │█ · · · · · · · · · │██████████ · · · · │██████████████ └──────────────────── └──────────────────── └──────────────────── one peak. Always broad. Most likely flat. Anything could picks the highest. wins, but variety come out. is real. The model's underlying distribution is the same in all three cases. Temperature is just a transformation applied before sampling.

温度 0 仍然不是确定性的

对于从传统软件转来的人,采样中最令人意外的事情是:即使在温度 0 下,相同的提示词也可能产生不同的输出。不是总是,但频率足以在生产中造成影响。

为什么?"总是取概率最高的令牌"这条确定性路径,依赖于概率向量在各次运行中完全相同。实际上,概率向量可能因以下原因在各次运行之间有所不同:

  • 批处理推理中的浮点非确定性。现代推理服务器将请求批量处理以提高 GPU 效率。你的请求落入的具体批次影响矩阵乘法中加法的顺序,这(由于浮点加法不满足结合律)可能使 logit 值产生微小偏移。通常无关紧要。但偶尔足以使 top-1 从一个令牌翻转到另一个。
  • 模型快照更新。服务商部署了新的小版本。API 调用中相同的模型名称,权重略有不同,分布略有不同。你"确定性"的运行出现了分歧。
  • 服务端处理变化。缓存、路由、故障转移机制——即使你指定了 temperature=0,所有这些都可能引入微小扰动。

实际影响:将 temperature=0 视为"低方差",而非"零方差"。如果你需要真正的可重现性(用于测试或评估重运行),你需要将 temperature=0 与显式种子(seed)结合使用(在服务商支持的情况下),最好还要固定模型快照——即便如此,也要预期偶发的漂移。

何时使用哪个温度

这个决策由任务驱动,而非个人偏好驱动。粗略指南:

任务
温度
理由
分类、提取
0 到 0.2
存在唯一正确答案。你想要概率最高的那个;多样性有害无益。
工具调用决策
0 到 0.3
希望对相同输入有可预测的行为。少量可变性可以接受,随机性不行。
代码生成
0.2 到 0.4
低但不为零——为新问题保留一点创造性,对熟悉的问题主要走最高概率路径。
摘要、改写
0.3 到 0.7
措辞的多样性确实是可取的:相同内容,不同表达。
创意写作、头脑风暴
0.7 到 1.0
你想要惊喜。概率最高的令牌往往是最平庸的。

top_p(核采样):另一个旋钮

top_p 是约束采样的另一种方式。温度对整个分布进行变形,而 top_p 对其截断:只从累积概率超过 top_p 的最小令牌集合中采样。在 top_p = 0.9 时,你从合计占 90% 概率质量的顶部令牌中采样——在 20 万个令牌中通常只有几十个。

直觉:top_p 限制了令牌有多不可能仍能被采样。它保证你不会意外选到概率极低的令牌,同时仍允许"足够可能"的令牌之间的多样性。

大多数生产智能体将 top_p 保持在默认值(1.0,即不截断),只依赖温度。偶尔同时使用两者是有用的:温度 0.7 加 top_p 0.9 给你"多样但不狂野"。除非你有特定的故障模式需要缓解,否则很少值得调整。

种子与可重现性的局限

Anthropic 和 OpenAI 都支持 seed 参数。承诺是:相同的种子 + 相同的提示词 + 相同的模型 + 相同的参数 → 相同的输出。现实更接近于"极有可能是相同的输出,但不能保证"——服务商明确将种子记录为尽力而为(best-effort),而非合同保证。早先提到的非确定性来源(批处理、快照漂移)在边缘情况下仍然适用。

种子确实能给你的:在短时间窗口内的测试中有意义的可重现性。如果你在早上 9 点用固定种子运行评估套件(eval suite),然后在 10 点再次运行,结果几乎肯定相同。但如果一个月后再运行,在模型快照更新之后,结果可能不同。

种子的实际用途:在测试和 CI 运行中设置种子,以防单个示例上的噪声污染你的评估信号。不要在生产中设置它——生产受益于多样性,而且确定性本来也无法保证。

思维模型升级:当模型对相同提示词产生不同答案时,停止认为模型"出错了"。把它看作从概率分布中采样。正确的问题是"分布是否以适当的置信度集中在正确答案上?"——这在你的评估集上是可测量的。一个 80% 时间正确的模型,平均下来确实是 80% 正确的;某次运行可能落在那 20% 里。这不是 bug,这是采样。

Question
如果温度 0 不是确定性的,为什么还要用它?

因为"低方差"几乎总是生产智能体所需要的。在温度 0 下出现分歧的运行,是在两个概率接近的令牌边界上翻转的——恰恰是模型不确定的情况。输出不是"随机的";它是在两个合理的延续之间做选择。对于分类或提取任务,这完全没问题。对于你主动需要多样性的创意任务,你本来就会使用更高的温度。

不要抱着期望确定性重放的想法去选择温度 0。选择它是因为期望"大多数时候走最高概率路径"。这才是正确的框架。

Question
我的评估分数在各次运行之间波动 ±2 个百分点,这是采样噪声吗?

几乎可以肯定是,第 3.1 章的噪声基线(noise floor)测量方法可以精确量化这一点。正确的应对方式不是追求确定性——而是多次运行有噪声的指标并报告均值。均值两倍标准差以上才算"真实变化";低于此的是采样噪声。

如果你的评估集有 50 个示例,其中三个恰好处于模型的 top-1 令牌可能从"正确"翻转为"错误"的边界,那么每次运行 ±2 个百分点正是你应该预期的。多次运行测量可以吸收这种噪声。

Question
温度会影响工具调用吗?

会——而且几乎在所有情况下,你都希望工具调用时温度较低。在较高温度下,模型可能会选择调用与温度 0 时不同的工具,或者传递略有不同的参数。对于大多数智能体来说,这是不希望发生的:你希望在工具调度步骤上有可预测的行为。如果你的代理循环(agent loop)大量使用工具调用,请将温度设置为 0-0.3。

一些智能体框架在工具决策步骤使用温度 0,在最终综合步骤使用较高温度——当你希望确定性的工具选择但更多样化的最终答案措辞时,这是一个有用的模式。

STEP 4

幻觉是可预测的故障模式,而非随机错误。

"幻觉"这个词被过度使用了。人们用它指代从轻微的事实错误,到自信捏造的引用,再到彻头彻尾的编造,涵盖万象。将其视为单一现象意味着你无法调试它;将其视为三四种不同的机制,意味着你可以命名当前面对的那种,并选择正确的修复方法。

以下是四种机制,它们解释了生产智能体中被称为"幻觉"的大多数情况。每一种都是模型工作方式的可预测结果,每一种都有独特的修复方法。

机制一:延续偏差(Continuation bias)

模型从根本上是一个下一令牌预测器。给定一个部分写好的回复,它生成最能延续该模式的令牌。当模式良好时,这是一个特性。当模型已经提交到一个听起来自信但没有事实支撑的开头时,它就成了故障模式。

具体来说:问模型"《威斯特伐利亚和约》哪年结束的?",它可能开始说"《威斯特伐利亚和约》结束于"——此时下一令牌分布强烈倾向于一个具体年份。如果模型经过足够多的来源训练,知道是 1648 年,你就得到了正确答案。如果模型不确定,分布仍然倾向于某个年份(因为还有什么能完成这个句子呢?),然后它就采样了一个。错误的年份听起来和正确的年份一样自信,因为句法形态是相同的。

机制:一旦模型提交到某个句子形态,即使必须编造内容来完成它,它也会这样做。在默认情况下,下一令牌计算中没有"等等,我其实不知道这个"的分支。

修复方法:明确授权不确定性的提示词。"如果你不知道答案,就说'我不知道'"的效果比你预期的好——它给了模型一个被允许的延续,而不是"编造一个自信的答案"。结合接地(grounding)效果更好:"仅根据提供的来源作答。如果答案不在来源中,就说明这一点。"这能大幅减少延续偏差导致的幻觉。

机制二:训练分布缺口(Training-distribution gaps)

模型知道它在训练期间见过的内容。对于没有出现在训练中(或很少出现)的话题、人物、产品或事件,模型是在没有可靠信号的情况下运作的。合理令牌上的分布趋于平坦,采样变得更加可变,输出在事实上变得不可靠,程度与该话题在训练中的代表性成反比。

症状:在冷门话题上自信地错误,在常见话题上准确,而用户没有任何明确的信号来区分哪种情况。询问重要历史人物的用户得到正确答案;同一用户询问次要地方人物时得到自信的虚构。模型在这两种情况下都不暴露自己的不确定性。

机制:模型从稀疏的训练数据中进行合理插值,而"合理"从外部看与"事实"完全相同

修复方法:检索增强生成(第 1.2 章)。不要问模型它知道什么;给它相关文档,让它从这些文档中作答。模型在"从提供的文本中综合"方面,比"从训练中回忆"好得多。接地将工作负载从记忆(不可靠)转移到阅读(可靠)。

机制三:指令冲突(Instruction conflict)

模型被训练为遵循用户指令并给出有帮助的答案。当这两者冲突时——当遵循指令会产生听起来不够有帮助的答案,或反之——模型会协调这个冲突,有时落在错误的一边。

具体例子:用户要求"按字母顺序列出 API 端点"并提供了 20 个端点的列表。模型正确排序了大多数端点,但在过程中悄悄修正了一个端点名称中的拼写错误。用户说的是"列出它们"——不是"列出它们并悄悄纠正拼写"——但模型的帮助性训练推动它朝着产生"明显更正"版本的方向走。用户可能没有注意到这一点;模型可能对哪个拼写是正确的判断有误;无论如何,用户得到了一个以他们未曾要求的方式与输入不同的输出。

机制:模型在生成过程中平衡多个目标,当它们相互拉扯时,协调结果可能引入用户未要求的内容

修复方法:明确指出哪个维度重要。"精确保留输入;不要纠正或规范化。""简洁;除非被问到,不要添加解释。"这些指令关闭了帮助性训练原本会推动的路径。

机制四:压力下的虚构(Confabulation under pressure)

第四种也是最棘手的机制:模型产生的文本听起来像是记忆或事实,但实际上是当场生成的,背后没有任何检索或计算支撑。这是人们说"幻觉"时通常所指的令人担忧的情况——捏造的引用、编造的函数签名、虚构的引语。

这种情况最常发生在模型被要求提供特定结构化事实声明时——引用、函数签名、日期、电话号码——而它实际上并不知道这些。因为答案的句法形态定义明确(引用用"作者(年份)",代码用"function_name(arg1, arg2)"),模型可以产生完全符合形态的内容,而无需拥有其中的实质内容。

机制:模型生成符合所要求格式的输出,即使它没有内容来填充它们,因为格式符合性正是其训练所奖励的

修复方法是多层次的。接地(机制二的修复方法)在提供了来源材料的情况下有帮助。验证(第 1.2 章的接地检查模式)在生成后可以对照来源验证声明时有帮助。明确的提示词有边际帮助:"仅引用提供的上下文中存在的来源;如果你没有真实引用,就说明这一点。"对于高风险输出——医疗、法律、代码执行——三者结合使用,并将任何未经验证的声明视为可疑。

推理模型与对话模型:新的维度

从 2024 年起,服务商推出了一类独特的"推理"模型——带有扩展思考的 Claude、OpenAI 的 o 系列和 GPT-5 推理模式、DeepSeek-R1 及类似模型。这些模型在产生可见回复之前,会在内部生成"思考"令牌。思考对用户隐藏,但消耗真实的令牌和真实的算力。

关于推理何时有帮助的直觉:

  • 有帮助:多步骤逻辑问题、数学、代码审查、复杂规划,以及任何模型受益于"先推导出答案再提交"的场景。思考令牌本质上是模型与自身对话,探索分支,发现自身错误。
  • 没有帮助(且成本更高):简单的事实查询、分类、提取、对话式回复。没有什么需要"推理"的——模型要么知道答案,要么不知道,额外的思考令牌是浪费的算力。
  • 适得其反(反直觉地):模型立即知道答案但扩展思考引入过度思考或自我质疑的任务。某些经过良好校准的、训练有素的行为,当你让模型先"多思考"时会变得更加嘈杂。

对智能体设计的实际影响:在智能体中将模型与任务匹配。在规划步骤(决定下一步做什么)使用推理模型,在综合步骤(写最终答案)使用更快的非推理模型,在分类步骤(决定调用哪个工具)使用能胜任的最便宜模型。第 2.2 章的成本梯度就是建立在这一洞察之上的。

诚实的注意事项:这个建议是 2026 年初的实践现状,"推理"模型与"对话"模型之间的边界正在模糊。Sonnet 4.5 和 GPT-5.5 都有混合模式,可以在需要时思考,不需要时不思考,由单一参数控制。趋势是走向"一个模型,可调节的思考预算",而非"两个模型系列"。但底层思维模型——扩展思考对难题有帮助,对简单问题有害——仍然适用。

总结:30 秒内的幻觉分类诊断

当你在生产中看到幻觉时,依次过一遍四种机制:

┌─────────────────────────────────────────────────────────────┐ │ HALLUCINATION TRIAGE │ │ │ │ Did the model commit to a sentence shape and then │ │ invent content to complete it? │ │ → Mechanism 1: continuation bias. │ │ Fix: authorize "I don't know" in the prompt. │ │ │ │ Is the topic obscure, niche, or post-training-cutoff? │ │ → Mechanism 2: training-distribution gap. │ │ Fix: retrieval-augmented generation. │ │ │ │ Did the output differ from the input in ways the user │ │ didn't ask for? │ │ → Mechanism 3: instruction conflict. │ │ Fix: explicit "preserve / don't add / be terse" rules. │ │ │ │ Did the model produce a specific structured claim │ │ (citation, signature, date) with no underlying source? │ │ → Mechanism 4: confabulation. │ │ Fix: grounding + post-generation verification. │ └─────────────────────────────────────────────────────────────┘

生产智能体中几乎每一个幻觉都是这四种之一,或它们的组合。命名机制是修复的一半——它将你引向具体的干预手段,而不是模糊的"把提示词改好一点"的猜测。

Question
如果我使用更强大的模型,大多数幻觉不就消失了吗?

部分会——但不是全部。更强大的模型有更大的训练语料库(更小的机制二缺口)、更好的校准(更少的机制一延续偏差)、以及更好的指令遵循(更少的机制三冲突)。但这些机制中没有一个从根本上被规模化解决了。尤其是虚构——机制四——在所有模型规模上都持续存在,因为模型正在做其训练所奖励的事情:产生符合格式的输出。

思维模型:规模化降低幻觉率,但不能消除它们。智能体设计必须假设幻觉会发生,并通过验证、接地和不确定性确认来工程化应对。不要把下一个模型版本发布寄望于修复今天你的检索管道应该修复的问题。

Question
"幻觉"这个词用对了吗?

这是该领域使用的词,所以你还是会不断遇到它。但它具有误导性——它暗示模型在产生这些输出时做了某件不寻常或病态的事情,而实际上它正在做它被训练去做的事情(预测合理的下一个令牌)。这些输出在任何有意义的层面上都不是"幻觉";它们是合理文本生成的可预测故障模式。这种框架很重要,因为它改变了修复方法:你不能通过告诉模型不要产生幻觉来修复幻觉;你要修复的是产生幻觉的条件。

Question
扩展思考何时真正值回票价?

三种成本合理的粗略模式:

  • 复杂规划,有很多约束——扩展思考让模型在提交一个方案之前枚举、评估并排除选项。
  • 数学和逻辑谜题,有明确的逐步结构——模型利用思考令牌实际完成这些步骤。
  • 自我纠正任务,如代码审查或事实核查——模型可以在思考中识别出单次遍历回复中不会浮现的问题。

扩展思考被浪费的标志:模型的"思考"输出(如果你能通过流式传输看到它的话)只是在重述问题或漫无目的地游荡。这是一个信号,说明任务不需要它,你应该退回到更快的模型。

End of chapter 0.1

可交付成果

一个能让你大致预测模型在给定输入上的行为、并在出现故障时解释故障模式的 LLM 工作思维模型。你将令牌视为真正的基本单元,并在优化提示词之前对输入进行分词。你将上下文窗口视为有限的、对位置敏感的资源,并据此放置重要信息。你将模型视为概率分布,并根据任务而非个人偏好选择温度。你能通过机制识别幻觉——延续偏差、训练缺口、指令冲突或虚构——并应用匹配的修复方法。本指南中的所有其他章节都以这些直觉为前提,而现在它们属于你了。

  • 对一个代表性提示词运行分词器;了解令牌都花在了哪里
  • 在实际工作负载上测量有效上下文长度;与名义上限进行比较
  • 将关键内容放在上下文的开头/结尾;绝不将其埋在中间
  • 根据任务有意识地选择温度(工具调用用 0-0.3,创意任务用 0.5+)
  • 停止将温度 0 视为"确定性";将其视为"低方差"
  • 在测试中使用种子,不要在生产中使用
  • 对每一个幻觉,在修复之前先命名其机制
  • 在提示词中授权"我不知道",以化解延续偏差
  • 使用 RAG 来处理训练分布缺口
  • 添加明确的"保留/不添加"规则,以化解指令冲突
  • 根据任务复杂度(而非默认设置)匹配模型类型(推理型与对话型)