为什么和 AI 聊得越久,有时它反而越容易遗漏之前说过的信息?为什么上传一份很长的文档,模型可能无法一次处理?
这背后涉及两个基础概念:Token 和上下文窗口。理解它们,才能理解大模型的信息处理能力,以及 AI 应用为什么需要上下文管理。
一、Token:大模型是怎样读取文字的?
我们习惯用汉字、单词和句子理解文字,但大语言模型处理文本时,使用的基本单位并不是汉字或完整单词,而是 Token(词元)。
Token 可以是一个字符、一个词的一部分、一个完整单词,也可以是标点符号等。
例如:
原始文本:
Today is a beautiful day!
模型处理:
Today | is | a | beautiful | day | !
上面只是便于理解的示意切分,真实的 Token 切分由模型使用的 Tokenizer 决定。
Tokenizer(分词器) 就是负责把文本转换为 Token 序列的工具。
这里有三个容易混淆的地方:
- 一个汉字不一定对应一个 Token。
- 一个英文单词可能被拆成多个 Token。
- 同一段文字,在不同模型中可能产生不同数量的 Token。
因此,Token 数量不能简单按照字数或单词数量计算。语言、编码方式、空格和文本内容都会影响切分结果。
Token 为什么重要?
Token 不仅是模型处理文本的基本单位,还直接影响三个方面:
1. 模型处理能力
模型接收输入时,需要将文本转换为 Token 序列,再进行后续处理。
2. 上下文容量
模型一次能够处理多少内容,通常以 Token 数量衡量。
3. API 使用成本
许多模型平台按照输入和输出 Token 计费。输入内容越多,通常意味着需要处理的 Token 越多,具体费用取决于模型和平台的计费规则。
在 OpenAI 的 API 中,还需要区分输入 Token、输出 Token、缓存输入 Token,以及部分推理模型使用的推理 Token。
因此,一段看起来很短的回答,也不一定只消耗显示出来的文字对应的 Token。
二、为什么 AI 需要上下文窗口?
理解 Token 后,就可以回答一个更重要的问题:
如果模型处理文字依赖 Token,那么它一次最多能处理多少 Token?
这就涉及 Context Window(上下文窗口)。
上下文窗口可以理解为模型一次请求能够处理的信息容量,通常以 Token 数量表示。
例如,假设某个模型的上下文窗口是 32K Token。
这并不意味着用户可以输入 32K Token 的文字。
因为模型接收到的内容不只有用户输入。
一次请求中可能包含:
- 系统指令:告诉模型应该遵循什么规则。
- 用户输入:当前提出的问题。
- 历史对话:之前交流过的内容。
- 工具定义:Function Calling 的工具和参数说明。
- 工具返回:外部 API 或 MCP 工具执行后的结果。
- 检索资料:RAG 从知识库中找到的相关内容。
- 多模态输入:图片、文件等内容。
这些信息都会影响请求的 Token 使用量。
此外,模型生成的输出,以及部分模型使用的推理 Token,也可能占用上下文容量。具体计算方式取决于模型和接口。
用一个例子理解上下文容量
假设一个模型的上下文窗口为 32K Token。
某次请求已经使用:
| 内容 | Token 数量 |
|---|---|
| 系统指令 | 2K |
| 历史对话 | 8K |
| 工具定义 | 2K |
| RAG 检索资料 | 10K |
| 当前用户输入 | 2K |
| 合计输入 | 24K |
此时已经使用了 24K Token。
如果该模型的输入和输出共用 32K 上下文容量,那么留给输出及其他内部处理的空间就会受到限制。
32K 只是示例,不代表所有模型的实际上下文窗口。不同模型的上下文容量、最大输出长度和计算规则都可能不同。
上下文窗口决定了模型一次能够处理多少信息,而不是决定模型永久能够记住多少信息。
三、为什么对话越长,AI 越容易遗漏信息?
假设你正在咨询一笔订单退款。
对话刚开始时,你提供了订单编号:
订单编号:20261103001
随后又讨论了退款政策、商品问题、物流进度和其他订单。
经过几十轮交流,你再次询问:
“刚才那笔订单现在是什么状态?”
AI 却回答:
“请提供订单编号。”
这是不是意味着模型忘记了?
不一定。至少存在以下几种可能。
1. 早期信息已经不在当前上下文中
当历史对话不断增长,应用程序可能需要裁剪较早的消息,避免超过上下文窗口限制。
如果订单编号被裁剪掉,模型本次请求就无法直接读取它。
2. 历史内容经过摘要,但关键信息丢失
有些系统不会一直保存完整对话,而是把较早的内容压缩成摘要。
例如,原始对话包含:
订单编号:20261103001
申请时间:11月3日
退款原因:商品质量问题
当前状态:退款处理中
但摘要只保留:
用户正在咨询商品质量问题导致的退款。
订单编号和具体状态就丢失了。
3. 信息仍然存在,但模型没有正确利用
即使订单编号还在上下文中,周围存在大量无关信息,也可能影响模型定位和使用关键信息的能力。
因此,扩大上下文窗口不等于模型一定能够准确利用其中所有内容。
4. 检索或生成环节出现错误
如果系统通过 RAG 检索历史资料,可能检索到了错误订单。
也可能是资料本身正确,但模型在生成回答时理解错误。
所以,AI 遗漏信息不能全部归因于上下文窗口。
需要区分:信息没有进入上下文、信息进入了但没有被正确利用,以及外部检索和生成环节出现错误。
四、上下文、长期记忆、RAG 和数据库有什么区别?
解决长对话信息丢失,不能只依赖扩大上下文窗口。
还需要理解四种不同的能力。
| 概念 | 主要职责 | 典型内容 |
|---|---|---|
| 上下文窗口 | 提供当前请求需要的信息 | 当前对话、系统指令、检索结果 |
| 长期记忆 | 保存跨会话仍有价值的信息 | 用户偏好、稳定事实 |
| RAG 知识库 | 从外部资料中检索相关知识 | 企业 SOP、产品手册、技术文档 |
| 业务数据库 | 保存真实业务状态 | 订单、支付、退款、库存 |
它们不是相互替代的关系。
1. 长期记忆:保存值得长期保留的信息
例如,用户长期偏好简洁的回答,或者某个业务助手需要记住用户的常用设置。
这些信息可以保存在记忆系统中,在后续任务中按需读取。
但长期记忆不应该被理解为保存全部聊天记录。
2. RAG:需要知识时再检索
假设企业有几万份产品文档和售后政策。
如果每次都把全部文档发送给模型,显然不现实。
RAG 的处理方式是:
- 用户提出问题。
- 检索系统从知识库中查找相关资料。
- 选取与问题有关的内容。
- 将检索结果放入当前请求的上下文。
- 模型结合资料生成回答。
因此,RAG 并不是扩大上下文窗口,而是减少无关信息,让有限的上下文空间优先容纳真正需要的知识。
3. 数据库:保存真实业务状态
如果用户询问:
“我的退款到账了吗?”
退款状态属于实时业务数据,应该通过业务 API 查询真实数据库,而不是依赖模型记忆或普通知识库检索。
例如:
用户提出退款查询
↓
调用订单查询 API
↓
读取真实退款状态
↓
将查询结果加入上下文
↓
模型组织回答
模型负责理解和表达,业务系统负责提供真实状态。
这一区分非常重要:知识库适合回答规则是什么,业务数据库适合回答现在发生了什么。
五、实际 AI 应用如何管理上下文?
当 AI 应用需要持续处理大量对话、知识和工具调用时,不能简单地把所有历史信息一直追加到请求中。
通常需要采用几种管理方式。
1. 历史消息裁剪
保留当前任务相关的消息,删除已经没有价值的历史内容。
适合简单对话,但需要注意不能误删重要事实。
2. 历史摘要
将较长的历史对话压缩成结构化摘要。
例如:
{
"order_id": "20261103001",
"refund_reason": "商品质量问题",
"refund_status": "processing",
"next_action": "查询退款到账情况"
}
相比保留全部聊天记录,结构化摘要更容易保留关键业务信息。
但摘要仍然可能遗漏事实,重要业务状态不能只依赖摘要作为最终依据。
3. RAG 按需检索
不把所有知识库内容放进上下文,而是根据当前问题检索相关资料。
这既能控制 Token 使用量,也能降低无关内容对模型的干扰。
4. 外部状态存储
对于订单编号、审批结果、任务进度等关键数据,应该保存在数据库或其他可靠的状态存储中。
需要时通过 API 查询,再把必要结果加入上下文。
这样即使对话被裁剪或重新开始,关键业务状态仍然可以恢复。
5. Token 预算管理
在工程实现中,还需要关注:
- 系统指令占用了多少 Token?
- 工具定义是否过于冗长?
- 历史对话是否需要压缩?
- RAG 是否检索了过多无关内容?
- 是否为模型输出预留足够空间?
- 实际请求的 Token 使用量是否超过预期?
这些都属于上下文工程需要解决的问题。
六、开发中如何统计 Token?
如果使用 OpenAI 模型,可以通过官方 Tokenizer 或 tiktoken 进行文本 Token 统计。
例如:
import tiktoken
encoding = tiktoken.encoding_for_model("gpt-4o")
text = "为什么 AI 需要上下文窗口?"
tokens = encoding.encode(text)
print("Token 数量:", len(tokens))
print("Token 内容:", tokens)
这里需要注意:
- Tokenizer 应与目标模型匹配。
- 不同模型可能使用不同编码。
- 单独统计一段文本,不等于完整统计一次 API 请求。
- 消息结构、工具定义、Schema、图片和文件等,也可能影响完整请求的 Token 数量。
如果需要统计完整 API 请求,应优先使用模型平台提供的输入 Token 统计能力,并在请求完成后检查实际 usage 数据。[^1]
七、总结:上下文窗口不是 AI 的长期记忆
理解 Token 和上下文窗口,实际上是在理解大模型的信息处理边界。
几个概念需要明确区分:
- Token:模型处理文本的基本单位。
- Tokenizer:负责将文本转换为 Token。
- 上下文窗口:模型一次能够处理的信息容量。
- 长期记忆:保存跨会话仍有价值的信息。
- RAG:从外部知识库检索当前需要的资料。
- 业务数据库:保存真实业务状态。
它们之间的关系可以概括为:
外部系统负责保存信息,记忆和检索负责找到信息,上下文负责把当前需要的信息交给模型,模型负责理解和生成。
AI 应用的能力,不仅取决于模型本身有多强,也取决于能否在有限的上下文容量内,准确提供完成任务所需要的信息。