Token 与上下文窗口
成本、长度限制,以及“模型此刻到底能看到什么”。
一句话理解:Token 是模型计费和计长度的单位,上下文窗口是模型每次调用时的全部“视野”;窗口之外的东西,对模型来说就是不存在。
“为什么这个 Agent 跑一次要花 1 美元?”“为什么聊到第 30 轮它就忘了最开始的要求?”“为什么把整份 200 页的手册塞进去,回答反而更差了?”——这三个问题的答案都藏在 Token 和上下文窗口里。
对产品经理来说,这一课决定了你能不能算清成本、能不能估出功能边界,以及能不能在需求评审时问出“这一步模型到底看得到什么”。
Token:模型眼中的文字
模型不直接读“字”或“词”,而是读 Token。分词器(tokenizer)会把文本切成模型词表里的片段:常见英文单词可能是一个 Token,长单词会被拆成几段;中文里一个汉字可能是一个 Token,也可能多个汉字合成一个,或者一个汉字占多个 Token;空格、标点、换行、JSON 里的引号和括号也都算 Token。
理解 Token 要记住三件事:
- 没有通用的换算比例。 不同厂商、甚至同一厂商的不同代模型,分词器都可能不同。例如 Anthropic 官方说明,Claude Opus 4.7 及之后的模型使用新的分词器,同样的文本会比旧模型多出约 30% 的 Token。所以别拿 A 模型测出的 Token 数去估算 B 模型的成本。
- 中文、代码、JSON 和英文的“密度”不一样。 同样的信息量,结构化数据里的大量符号会显著增加 Token 数。估算时要用真实样本去测,而不是按字数拍脑袋。
- 图片和 PDF 也会变成 Token。 以 Claude 为例,图片按 28×28 像素的图块计算视觉 Token,PDF 每一页既会提取文字也会转换成图像处理,详见 多模态。
最可靠的做法是用官方接口计数。Claude 提供免费的 Token 计数接口(结果是估算值,可能与实际调用略有差异):
import anthropic
client = anthropic.Anthropic()
response = client.messages.count_tokens(
model="claude-opus-5",
system="你是客服工单分析助手。",
messages=[{"role": "user", "content": "工单 #10231:订单付款三天了还没有发货,帮我查一下原因。"}],
)
print(response.input_tokens)
上下文窗口:一次调用里的全部视野
上下文窗口 是模型单次调用能处理的 Token 总量上限。关键在于理解“什么算进窗口”——按 Claude 官方文档的说法,请求里的所有内容都算:系统提示词、messages 中的每条消息(包括工具结果、图片和文档)、工具定义,以及模型本轮生成的输出(包括思考内容)。
以一个「客服工单分析 Agent」执行到第 4 步时的一次调用为例:
有三个反直觉的事实必须记住:
- 模型没有记忆,API 是无状态的。 每次调用都要把历史重新发一遍。所谓“多轮对话”,是你的程序在每一轮把前面的内容重新拼进请求。
- 不在窗口里的,模型就不知道。 上周用户说过的偏好、另一个会话里的结论、数据库里的新状态,如果没有被放进本次请求,就等于不存在。这正是 Context Engineering 和 Memory 两个模块要解决的问题。
- 窗口大不等于应该塞满。 官方文档明确提到,随着 Token 数增长,模型的准确率和召回能力会下降,这被称为“上下文腐化”(context rot),详见 上下文腐化。
超出窗口时会发生什么?以 Claude 为例:如果输入本身就超过窗口,API 直接返回 400 错误(提示 prompt is too long);如果输入没超,但生成过程中触到窗口上限,较新的模型会停止生成并返回 stop_reason: "model_context_window_exceeded"。另外,输出长度还受 max_tokens 限制,达到它时 stop_reason 是 max_tokens,回答会被截断。这些都需要程序处理,而不是假装没发生。
成本:输入、输出与 Agent 的“滚雪球”
模型按 Token 计费,输入和输出分开定价,输出通常贵得多。以官方模型概览页(2026 年 9 月查阅)为例:
| 模型 | 输入(每百万 Token) | 输出(每百万 Token) | 上下文窗口 |
|---|---|---|---|
| Claude Opus 5 | $5 | $25 | 1M |
| Claude Sonnet 5 | $2 | $10 | 1M |
| Claude Haiku 4.5 | $1 | $5 | 200K |
价格会调整,做预算时请以官方定价页为准。真正值得产品经理警惕的是 Agent 的成本结构和聊天完全不同。聊天一问一答,输入不大;Agent 每走一步都要把之前所有工具结果重新发一遍,输入像滚雪球一样增长。
用一个简化的例子算一下:上面这个工单分析 Agent 固定部分(系统提示词 + 工具定义)8,000 Token,每一步新增约 3,500 Token(工具结果 + 模型输出),每步输出约 500 Token,共走 10 步:
第 1 步输入:8,000
第 2 步输入:8,000 + 3,500 × 1 = 11,500
……
第 10 步输入:8,000 + 3,500 × 9 = 39,500
10 步输入合计 = 8,000 × 10 + 3,500 × (0+1+…+9) = 237,500 Token
10 步输出合计 = 500 × 10 = 5,000 Token
按 Claude Opus 5 计:
输入 0.2375 × $5 ≈ $1.19
输出 0.005 × $25 ≈ $0.13
单次任务合计 ≈ $1.31(未使用缓存)
把每一步的输入画出来,滚雪球的形状就很直观了:
可以看到,在 Agent 场景里输入成本往往占大头,而且和步数近似平方增长。这也解释了为什么生产级 Agent 普遍使用提示缓存(Claude 官方说明缓存读取价格为基础输入价的 10%,详见 提示缓存)、清理旧工具结果、精简工具返回值(见 工具设计原则)。完整的成本估算方法在 成本模型 一课展开。
常见误区
- “上下文窗口 1M,就可以把整个知识库塞进去。” 能塞进去不代表能用好:成本、延迟都会上升,关键信息还可能被淹没。先检索,再放入少量相关内容。
- “模型记得我们之前聊过的内容。” 它只“看得到”本次请求里的内容。跨会话的记忆需要专门设计。
- “一个汉字大约等于 N 个 Token,按字数估就行。” 不同模型分词器不同,结构化数据差异更大,要用计数接口或实际账单校准。
产品经理检查清单
- 每一步调用里,上下文由哪几部分构成?各占多少 Token?哪些可以删掉或按需加载?
- 最长的会话或任务会走多少步?最坏情况下输入会膨胀到多大,会不会超过窗口?
- 输出被
max_tokens截断或触到窗口上限时,产品如何处理和提示? - 单次任务成本是多少?乘以日调用量后,是否在预算和商业模式能承受的范围内?
- 换模型或换厂商时,是否重新测过 Token 数,而不是沿用旧数据?
练习
为「SEO 诊断 Agent」做一次上下文预算(约 45 分钟):
- 找一个真实网页,把它的 HTML 源码、一份 Search Console 导出的 CSV 片段和你写的一段系统提示词准备好。
- 用 Token 计数接口(或官方控制台)分别统计三部分的 Token 数。
- 假设 Agent 要诊断 20 个页面、每页调用 3 次工具,估算一次完整诊断的输入 Token 与成本。
- 提出至少两个削减方案(例如只抽取
<head>与正文文本、只保留异常行),重新估算,比较节省了多少。
延伸阅读
- Context windows:哪些内容计入窗口、超出时的行为、思考与工具调用如何占用窗口。
- Token counting:Token 计数接口与新分词器的说明。
- Claude 模型概览:各模型的价格、上下文长度与输出上限。
下一步
知道了“模型能看到什么、要花多少钱”,下一课「调用模型 API」就动手发出第一个请求,看清消息结构、流式输出与常见报错。