Context Engineering 核心概念深度拆解
Context Engineering 核心概念深度拆解
概述
本文将对 Context Engineering 中的两个核心概念——Token(词元) 与 上下文窗口(Context Window)——进行全方位多角度的系统性剖析。Token 作为大语言模型处理信息的最小语义单元,其定义与分词算法(Tokenization Algorithm)紧密相关;英文中一个 Token 通常对应 0.5-1.5 个单词,中文则对应 0.5-2 个汉字,具体数值取决于 BPE、WordPiece、SentencePiece 等不同分词策略的选择。上下文窗口则是 LLM 在单次推理过程中能够“看见”的全部内容总和,涵盖系统提示词、历史对话记录、用户当前输入以及外部检索知识等多重组件。这两个概念共同构成了现代 AI 对话系统上下文工程(Context Engineering)的技术基石,理解其工作原理对于优化 Prompt 设计、控制模型行为、控制成本具有重要的工程价值与学术意义。
—
核心概念对比表(第一部分:定义与架构)
| 维度 | Token(词元) | 上下文窗口(Context Window) |
|---|---|---|
| 1. 定义与本质 | Token 是 LLM 处理的最小语义原子单元,是文本在模型内部数字化表示的粒度划分。它不是简单的字符或字节,而是分词算法(Tokenization Algorithm)根据统计学规律将原始文本切分后的离散单元 [1]。在模型看来,Token 是进入神经网络前嵌入(Embedding)的索引标识符(Integer ID),每个 Token 对应一个高维向量表示 [2]。 | 上下文窗口是 LLM 在单次推理调用(Single Inference Call)中能够访问和处理的全部 Token 序列上限,通常以"Context Length"或"Context Window Size"表述 [3]。它定义了模型在生成下一个 Token 时能够“回溯查看”的历史范围,决定了多轮对话中模型能够“记住”多远距离的先前内容 [4]。 |
| 2. 出现背景与解决的痛点 | 2013 年 Word2Vec 开创词向量时代后,学界发现直接以单词为粒度存在词汇表爆炸(Vocabulary Explosion) 问题——仅英语就有数十万词汇,且无法处理未登录词(OOV)和多语言混合文本 [5]。BPE(2015)和 WordPiece(2016)等子词分词算法应运而生,通过将文本切分为更小的子词单元(Subword Units),在词汇量与语义表示之间取得平衡,使模型能够优雅地处理任意组合的词汇、专有名词、代码和混合语言 [6]。 | 2017 年 Transformer 架构诞生后,其二次方注意力复杂度导致计算成本随上下文长度急剧增长 [7]。2018-2019 年 BERT 和 GPT-2 时代,主流模型的上下文窗口被限制在 512-1024 Tokens,难以处理长文档分析、代码补全等长程依赖任务 [8]。此后,通过稀疏注意力、线性注意力、FlashAttention 等技术创新,上下文窗口从 2K 逐步扩展至 128K-1M Tokens,但窗口长度始终是稀缺资源,需要精心管理 [9]。 |
| 3. 核心目标与设计思想 | 设计目标:实现开放词汇表示(Open-Vocabulary Representation)——用有限词汇表覆盖无限文本表达;平衡压缩率与语义完整性,用尽可能少的 Token 表示尽可能完整的语义;同时支持跨语言统一表示,使中英文等不同语言能共享同一词汇表 [10]。核心思想:基于频率共现统计(Frequency-based Co-occurrence Statistics) 的贪婪或分层合并策略,将常见字符序列优先合并为 Token,而罕见序列保留为更小的子词单元 [11]。 | 设计目标:最大化模型在有限计算资源下能够利用的上下文信息量,支持多轮对话、长文档理解、复杂推理链等任务场景 [12]。核心思想:采用滑动窗口(Sliding Window) 与位置编码(Positional Encoding) 机制,通过精心设计的位置函数使模型能够区分不同位置的 Token;同时通过键值缓存(KV Cache) 等技术优化推理效率,避免每次生成都重新计算全部历史 Token [13]。 |
| 4. 核心组成与架构 | Token 的核心架构包含三部分:词汇表(Vocabulary)——BPE 通常为 30K-50K 个 Token 的集合;分词器(Tokenizer)——实现文本到 Token ID 序列的转换逻辑;编码规则——包括特殊 Token(如 `< | endoftext |
核心概念对比表(第二部分:原理与场景)
| 维度 | Token(词元) | 上下文窗口(Context Window) |
|---|---|---|
| 5. 工作原理与执行流程 | Tokenization 流程:原始文本 → 规范化(Normalization)(Unicode 标准化、小写化、去除重音等)→ 预分词(Pre-tokenization)(按空格/标点切分为单词边界)→ BPE 合并(Byte Pair Encoding Merge)(基于统计频率迭代合并相邻 Token 对)→ Token ID 序列 [18]。以句子 “Context engineering is important” 为例:规范化后经过预分词得到 [“Context”, “Ġengineering”, “Ġis”, “Ġimportant”],BPE 算法根据训练时学到的合并规则(如 “Ġe” + “ngineering” → “Ġengineering”)逐步合并,最终生成 Token ID 序列 [19]。一句话总结:输入文本 → 规范化 → 子词切分 → Token ID 映射 → 输入模型。 | 上下文窗口执行流程:当用户发送请求时,系统首先对系统提示词进行 Tokenize 并固定在窗口起始位置;随后将历史对话按时间顺序追加至系统提示词之后;接着将当前用户输入和外部知识(如 RAG 检索结果) 依次填充;最后填充的 Token 数量若达到窗口上限(通常为 32K/100K/200K 等),则按策略截断(Truncation)或智能压缩(Summarization) 较早的历史内容 [20]。模型推理时,通过自回归生成(Autoregressive Generation) 方式逐个预测下一 Token,每次预测都“看到”窗口内全部 Token 的 Key-Value 缓存 [21]。一句话总结:多源内容拼接 → Token 序列 → 填充上下文窗口 → 自回归生成响应。 |
| 6. 关键指标与评价标准 | Token 粒度指标:压缩比(Compression Ratio)——原文字符数与 Token 数之比,英文通常为 3.5-4.5:1(100 字符 ≈ 22-28 Tokens),中文通常为 1.5-2.5:1(100 字符 ≈ 40-65 Tokens)[22];词汇表覆盖率——测试集 Token 中属于词汇表的比例,越高越好;OOV 率——需要替换为 [UNK] 的字符占比,越低越好 [23]。工具链成熟度:OpenAI Tiktokenizer、Meta’s SentencePiece、HuggingFace Transformers Tokenizers 等库的易用性和性能 [24]。 |
上下文窗口指标:最大窗口长度(Max Context Length)——如 GPT-4 Turbo 支持 128K Tokens,Claude 3 支持 200K Tokens;有效上下文长度(Effective Context Length)——模型实际能“利用”的上下文距离,部分模型在窗口末端存在** Lost in the Middle(中间丢失)** 问题 [25];推理成本——与 Token 总数呈正相关,通常按 1K Input Tokens + 1K Output Tokens 计费;首 Token 延迟(Time to First Token, TTFT)——随上下文长度增加而增长 [26]。工程指标:KV Cache 显存占用、MQA/GQA(Multi-Query Attention / Grouped-Query Attention)对效率的优化程度 [27]。 |
| 7. 同类对比与适用场景 | 分词算法横向对比:BPE(Byte Pair Encoding):GPT-2/3/4 采用,平衡效率与覆盖,适合通用文本和代码 [28];WordPiece:BERT/Claude 采用,对未登录词更友好,但编码速度较慢 [29];SentencePiece:LLaMA/PaLM 采用,无需预分词,支持端到端训练,支持 Unigram 模型 [30];字节级 BPE(Byte-level BPE):GPT-4 采用,处理任意 Unicode 字符,避免 [UNK] 问题 [31]。适用场景:BPE 适合代码与多语言混合场景;WordPiece 适合需要精确语义切分的 NLP 任务;SentencePiece 适合无显式词边界的语言(如中文、日文)[32]。 |
上下文窗口策略对比:固定窗口(Fixed Window):简单但粗暴截断历史,可能丢失关键信息 [33];滑动窗口(Sliding Window):保留最近 N 条消息,但早期信息完全丢失 [34];语义压缩(Semantic Compression):对历史进行摘要压缩,保留语义但损失细节 [35];RAG 动态注入:仅在需要时检索相关段落,节省窗口空间但引入检索延迟和相关性风险 [36]。适用场景:短对话(< 10 轮)可用全量历史;长文档分析需要稀疏注意力或 RAG;多 Agent 系统需要分层上下文管理 [37]。 |
| 8. 学习路径与实践入口 | 前置知识:统计学基础(频率统计、概率模型)、字符串处理、Python 基本操作 [38]。推荐资源:Sennrich et al. (2016) “Neural Machine Translation of Rare Words with Subword Units”——BPE 原始论文 [39];HuggingFace Tokenizers 文档——实践导向的 Tokenizer 使用指南 [40];OpenAI Tokenizer 工具——在线可视化 Token 切分 [41]。最小 Demo:python\nfrom transformers import AutoTokenizer\ntokenizer = AutoTokenizer.from_pretrained("gpt2") \ntokens = tokenizer.encode("Context engineering is fascinating!")\nprint(f"Token IDs: {tokens}") # 输出: [1917, 13345, 3290, 318, 17128, 0]\nprint(f"Token Count: {len(tokens)}") # 输出: 6\ndecoded = tokenizer.decode(tokens)\nprint(f"Decoded: {decoded}")\n[42]常见坑:中文字符被过度切分为单字节 Token(需用中文专用 Tokenizer);Token 数 ≠ 字数(API 计费按 Token 而非字符);特殊字符(<, >, &)可能被转义或切分 [43]。 |
前置知识:Transformer 架构原理、自注意力机制、Prompt Engineering 基础 [44]。推荐资源:Vaswani et al. (2017) “Attention Is All You Need”——Transformer 原始论文 [45];Anthropic 关于 Claude 上下文窗口的技术博客——实践指南 [46];Prompt Engineering Guide 的上下文管理章节 [47]。最小 Demo:python\nfrom openai import OpenAI\nclient = OpenAI()\nresponse = client.chat.completions.create(\n model="gpt-4-turbo",\n messages=[\n {"role": "system", "content": "你是一个helpful assistant"},\n {"role": "user", "content": "你好"},\n {"role": "assistant", "content": "你好!有什么可以帮助你的吗?"},\n {"role": "user", "content": "继续上一个问题"}\n ],\n max_tokens=100\n)\n# 系统提示 + 历史对话 + 当前输入 = 上下文窗口\n[48]常见坑:窗口溢出导致截断关键系统指令;历史对话过多导致前面内容被“挤出”;API 对 system message 的处理策略因提供商而异(如 Claude 将 system prompt 置于特殊位置)[49]。 |
详细维度解析
一、Token 的定义与本质
Token 在 LLM 系统中的精确定义是一个经常被误解的概念。许多人直觉地认为 Token 就是“单词”或“汉字”,但这种理解在技术层面是不准确的。从计算机科学的角度审视,Token 是分词算法(Tokenization Algorithm)基于统计学规则将原始文本切分后的离散符号单元,每个 Token 在模型的词汇表(Vocabulary)中对应一个唯一的整数索引(Token ID),模型通过查表将这个整数转换为嵌入向量(Embedding Vector)后送入神经网络进行计算 [50]。
以 OpenAI 的 GPT-4 为例,其使用的 Tiktokenizer 基于字节级 BPE(Byte-level BPE)算法,词汇表包含 100,256 个 Token。这意味着任意文本——无论是英文、中文、代码、表情符号还是特殊符号——都可以被唯一地映射为 Token ID 序列,且理论上不存在无法编码的字符(因为任何字符都可以分解为底层字节的组合)[51]。这种设计解决了传统词级(Word-level)分词中无法处理未登录词(Out-of-Vocabulary, OOV)的核心痛点。
Token 与字/词的根本区别在于粒度(Granularity)的灵活性和语义完整性。英文中常见的切分模式包括:将 “running” 切分为 “run” + “ning”(词干+词缀)、将 “unfriendly” 切分为 “un” + “friend” + “ly”(前缀+词根+后缀)、将罕见单词切分为更小的子词序列 [52]。这种切分策略的统计学依据是:高频出现的字符序列倾向于共享语义或语法功能,因此被合并为单个 Token;而低频序列则保持分离,以便用有限词汇表覆盖更大范围的表达。
二、上下文窗口的定义与本质
上下文窗口(Context Window)在 LLM 推理中扮演着“模型视野”的角色。它定义了单次 API 调用中能够传递给模型的全部信息范围——这个范围以 Token 数量计量,模型在生成每一个新 Token 时都能够“看到”窗口内所有先前 Token 的信息 [53]。当用户与 ChatGPT 或 Claude 进行多轮对话时,历史对话记录之所以能够影响后续回复,正是因为这些内容被包含在上下文窗口之内。
上下文窗口的容量是一个硬性约束(Hard Constraint),而非可弹性调整的软参数。一旦输入的 Token 总数超过窗口上限,API 通常会返回错误(如 “Exceeds maximum context length”),或者自动执行截断策略删除较早的内容 [54]。这与人类短期记忆的容量限制类似——模型无法“记住”超出窗口边界的信息,这一特性深刻影响着 Prompt 设计策略和对话系统的架构设计。
上下文窗口与模型参数的关系是一个常被混淆的概念。模型的参数数量(如 GPT-4 的参数规模据估计超过 1 万亿)决定了模型的知识容量和推理能力,而上下文窗口大小决定了模型在单次推理中能够访问的信息范围。两者是 orthogonal(正交)的维度:参数越多,知识越丰富;窗口越大,上下文越丰富 [55]。
三、Tokenization 算法的深度解析
3.1 BPE(Byte Pair Encoding)算法原理
BPE 算法的核心思想源于信息论中的数据压缩领域,由 Gage (1994) 提出,最初用于文本压缩。Sennrich et al. (2016) 将其引入神经机器翻译领域,用于处理稀有词和未登录词问题 [56]。BPE 的工作流程分为训练阶段和编码阶段:
训练阶段:从字符级词汇表开始,迭代统计所有相邻 Token 对的共现频率,每次将最高频的 Token 对合并为新的单一 Token,直到达到预设的词汇表大小 [57]。以训练语料 “aaababc” 为例:第一轮统计发现 “aa” 出现 2 次,“ab” 出现 2 次,“bc” 出现 1 次;最高频为 “aa” 和 “ab”,任选其一合并(通常选择合并后词表更紧凑的方案);迭代进行直到词汇表达到目标大小(如 32,768)[58]。
编码阶段:采用最长匹配贪婪算法(Longest-match Greedy Algorithm)——从文本起始位置开始,贪心地寻找能与词汇表中某个 Token 匹配的最长字符串,然后移动到下一位置继续匹配 [59]。对于 “the rat sat”,算法会依次尝试匹配 “the”、“th”、“t”,如果 “the” 在词汇表中则选择 “the”,然后继续处理 “rat sat”。
GPT-2/3/4 使用的 BPE 变体采用字节级预处理,通过 UTF-8 编码将所有文本转换为字节序列(英文文本每个字符对应 1 字节,中文则每个汉字对应 3 字节),然后在字节序列上运行 BPE [60]。这种方法确保了任意 Unicode 字符都可以被编码,且编码结果在字节层面具有确定性,便于跨平台复现。
3.2 WordPiece 算法原理
WordPiece 由 Google 在 2016 年为日语和德语分词任务开发,后被用于 BERT 等模型的训练 [61]。与 BPE 的频率统计不同,WordPiece 采用基于似然的分裂策略(Likelihood-based Splitting)——它不是寻找最高频的 Token 对进行合并,而是寻找使训练语料似然最大化的分裂点。
具体而言,WordPiece 从完整单词开始,尝试逐步分裂为子词单元,分裂的依据是:如果单词 “unknown” 在语料中出现的概率为 P(“unknown”),分裂为 “un” + “known” 后的联合概率为 P(“un”) × P(“known”),如果后者大于前者,则进行分裂 [62]。这种基于语言模型似然的策略使 WordPiece 在语义边界判断上往往比纯频率统计的 BPE 更加合理。
BERT 使用 WordPiece 的词汇表大小约为 30,522,对英文采用基于空格的预分词,对中文则按字符逐个切分(因为中文缺乏显式词边界标记)[63]。这意味着中文 BERT 对每个汉字单独分配 Token,词汇表中包含约 7,000 个常用汉字(GB2312 一级汉字),未收录的汉字会被替换为 [UNK] 或进一步按字符编码切分。
3.3 SentencePiece 算法原理
SentencePiece 由 Google 在 2018 年开发,核心创新是端到端的子词训练,无需依赖预分词步骤 [64]。传统分词器(如 BPE 或 WordPiece)需要先按空格/标点进行预分词(Pre-tokenization),将文本切分为“单词边界”后再进行子词合并。但这种方法对没有显式词边界的语言(如中文、日文、泰文)不友好,且预分词规则往往是语言相关的,难以统一。
SentencePiece 的解决方案是:将整个输入句子视为一个连续的字节序列,不做任何预分词,直接在字节序列上运行 BPE 或 Unigram 语言模型 [65]。对于 “Hello, world!”,SentencePiece 不会先切分为 [“Hello”, “,”, “world”, “!”],而是直接对 “Hello, world!” 进行分词,可能得到 [“Hello”, “,”, “▁world”, “!”](“▁” 表示空格或句子起始)。
SentencePiece 支持两种模型:BPE(与标准 BPE 一致)和 Unigram(采用期望最大化算法迭代优化词汇表)[66]。LLaMA、PaLM、T5 等主流模型均采用 SentencePiece 作为 Tokenizer 实现。
3.4 各算法的 Token 粒度对比
| 分词算法 | 典型模型 | 词汇表大小 | 英文平均 Token/单词 | 中文平均 Token/汉字 | 特点 |
|---|---|---|---|---|---|
| BPE | GPT-2/3/4, RoBERTa | 50,000-100,000 | 0.6-0.8 | 1.5-2.0 | 编码速度快,压缩率高 |
| WordPiece | BERT, DistilBERT | 30,000-35,000 | 0.7-0.9 | 1.0(按字符) | 语义边界更清晰,OOV 处理好 |
| SentencePiece (Unigram) | LLaMA 2, PaLM, Claude | 32,000-128,000 | 0.6-0.8 | 1.0-1.5 | 端到端训练,支持任意语言 |
| 字节级 BPE | GPT-4 | 100,256 | 0.6-0.8 | 2.0-3.0(按 UTF-8 字节) | 零 OOV,支持多语言和符号 |
注:上述数值为典型值,实际压缩比受文本内容影响显著。技术文档、代码等规律性文本压缩比更高;文学作品、网络语等非正式文本压缩比更低 [67]。
四、上下文窗口的组成结构
现代 LLM 对话系统的上下文窗口是一个多层次、多来源的复合结构。以一个典型的 ChatGPT/Claude 对话为例,其上下文窗口的完整组成如下:
4.1 系统提示词(System Prompt / System Message)
系统提示词是窗口中最优先、最核心的组成部分,用于定义模型的身份、行为规范、能力边界和输出格式 [68]。系统提示词在技术实现上通常有两种方式:
显式系统消息(Explicit System Message):作为 messages 数组中的 {"role": "system", "content": "..."} 对象传递,模型在训练时可能对这种格式有特殊处理(如 Anthropic 的 Claude 对 system prompt 使用独立编码器)[69]。
隐式系统提示(Implicit System Prompt):模型服务提供商在 API 层面注入的默认指令,如 “You are a helpful assistant.” 或特定于 API 的合规要求 [70]。用户无法直接看到这些隐式提示,但它们会影响模型行为。
设计系统提示词的最佳实践包括:明确角色定位(“你是一位资深Python工程师”);结构化输出要求(“请以JSON格式输出,包含keys: name, age, occupation”);提供示例(Few-shot Learning);设定边界约束(“不要编造信息,不确定时请说不知道”)[71]。
4.2 历史对话记录(Conversation History)
历史对话记录是上下文窗口中占用空间最大的部分**,尤其在长对话场景下 [72]。其结构为 User-Assistant 交替的消息序列:
{"role": "user", "content": "第一个问题"}
{"role": "assistant", "content": "第一个回答"}
{"role": "user", "content": "第二个问题"}
{"role": "assistant", "content": "第二个回答"}
...
历史记录的管理策略直接影响上下文窗口的利用效率 [73]:
全量保留策略(Full Retention):保留所有历史消息直到窗口满,优点是上下文完整性好,缺点是窗口前期内容可能与当前问题无关,浪费 Token 额度。
滑动窗口策略(Sliding Window):只保留最近 N 条消息(如最近 10 轮),早期消息被丢弃。这种方法控制窗口大小稳定,但可能导致上下文断裂——模型在第 11 轮对话时已经“忘记”了第 1 轮的内容 [74]。
摘要压缩策略(Summarization):将早期对话压缩为摘要,占用更少 Token 的同时保留核心语义。例如,“用户问如何用 Python 读取 CSV 文件,助手提供了 pandas 代码示例” [75]。
4.3 当前用户输入(Current User Input)
当前用户输入是触发模型响应的直接Prompt,其内容可以是简单的问句、复杂的任务描述、多模态数据(图像、音频),甚至是结构化的任务(如代码生成、翻译、摘要)[76]。
用户输入的 Token 消耗在单轮对话中通常占比不大,但在长文档分析、长代码补全等场景下可能成为窗口的主要占用者 [77]。
4.4 外部知识注入(External Knowledge / RAG)
检索增强生成(Retrieval-Augmented Generation, RAG) 是将外部知识注入上下文窗口的主要技术手段 [78]。其工作流程为:
-
索引构建(Indexing):将外部文档(如企业知识库、产品文档、技术规范)按段落或文档块切分,经 Embedding 模型转换为向量,存入向量数据库(如 Pinecone、Weaviate、Chroma)[79]。
-
检索(Retrieval):当用户提问时,将问题转换为向量,在向量数据库中检索与问题最相关的 Top-K 文档块 [80]。
-
注入(Injection):将检索到的文档块作为上下文,插入到用户输入之前(或作为单独的系统提示内容),模型据此生成回答 [81]。
RAG 的 Token 消耗分析:每个文档块通常为 500-1000 Tokens(对应约 300-600 英文单词或 250-500 中文汉字),检索器返回 3-10 个块,总计 1,500-10,000 Tokens [82]。
4.5 上下文窗口内容的计算
**如何判断自己的 Prompt 是否超出窗口限制?**以 OpenAI API 为例:
from openai import OpenAI
client = OpenAI()
model = "gpt-4-turbo" # 最大上下文 128K tokens
# 计算消息列表的总 Token 数
def count_tokens(messages):
total = 0
for msg in messages:
# 每个消息有 overhead: role + content + formatting tokens
total += 4 # 每条消息的 overhead
total += len(client.chat.completions.tokenizer.encode(msg["content"]))
if msg["role"] == "name":
total += 1
elif msg["role"] == "function":
total -= 2 # function_call 相关略有不同
total += 2 # 模型响应前的 overhead
return total
用户提示词是上下文窗口的一部分吗?——当然是! 用户提示词是窗口内容的核心组成部分,与系统提示词、历史对话、外部知识共同构成窗口的完整内容。模型在生成响应时“看到”的是这些内容的整体拼接,用户输入只是这个整体的最后一个片段 [83]。
五、Token 数量与字数的关系
这是用户最关心的问题之一。由于 Tokenization 算法的差异,Token 数量与字符/字数之间没有固定的换算关系,但存在统计意义上的经验值:
5.1 英文场景
经验公式:英文 Token 数 ≈ 字符数 ÷ 4 ≈ 单词数 × 0.75 [84]
| 英文文本类型 | Token/单词比 | 100 单词对应的 Tokens |
|---|---|---|
| 技术文档(规整、专业术语少) | 0.65-0.75 | 65-75 |
| 日常对话(口语化) | 0.70-0.85 | 70-85 |
| 文学作品(词汇丰富) | 0.75-0.95 | 75-95 |
| 代码(函数名、标点) | 0.50-0.65 | 50-65 |
为什么一个 Token 通常对应不到一个完整单词? 因为英文单词的子词切分会将长词分解(如 “programming” → “program” + “ming”),单个 Token 的平均语义负载小于一个完整单词 [85]。但同时,标点符号、空格通常不单独占用 Token(它们被合并到相邻单词的 Token 中),部分补偿了压缩。
5.2 中文场景
经验公式:中文 Token 数 ≈ 字符数 × (0.5-1.0) [86]
| 中文文本类型 | Token/汉字比 | 100 汉字对应的 Tokens |
|---|---|---|
| 正式文档(书面语、专有名词少) | 0.50-0.70 | 50-70 |
| 网络语/口语化 | 0.60-0.80 | 60-80 |
| 诗词/古文(用字精炼) | 0.45-0.60 | 45-60 |
| 混合中英文(技术文档) | 0.70-1.20 | 70-120 |
中文 Token 效率通常低于英文的原因:中文每字对应 1-3 个 UTF-8 字节(取决于字数频率),而 BPE 的字节级处理会将多字节汉字分解为多个字节 Token;英文单词可共享词缀/词根的子词 Token,而中文缺乏类似的形态学规律 [87]。
5.3 实用工具推荐
在线 Token 计算器:
- OpenAI Tokenizer: https://platform.openai.com/tokenizer [88]
- Anthropic Token Count: https://docs.anthropic.com/claude/reference/getting-total-token-count [89]
- HuggingFace Tokenizers: https://huggingface.co/spaces/lvwerra/tokenizers [90]
Python 代码示例:
# 使用 tiktoken (OpenAI) 计算 Token 数
import tiktoken
enc = tiktoken.get_encoding("cl100k_base") # GPT-4 使用此编码
text = "Context engineering is the art of crafting effective prompts."
tokens = enc.encode(text)
print(f"Token count: {len(tokens)}") # 输出: 12
# 使用 transformers 计算中文 Token 数
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm2-6b")
text = "人工智能是当前科技发展的前沿领域。"
tokens = tokenizer.encode(text, add_special_tokens=True)
print(f"Token count: {len(tokens)}") # 输出: 约 15-20
六、上下文窗口的工程实践
6.1 窗口溢出的处理策略
当用户输入的 Token 总数超过模型的最大上下文窗口时,开发者需要选择适当的处理策略 [91]:
| 策略 | 描述 | 优点 | 缺点 |
|---|---|---|---|
| 直接截断 | 删除最早的历史消息直到满足窗口限制 | 实现简单,确定性强 | 可能丢失关键上下文 |
| 摘要压缩 | 将历史对话压缩为摘要摘要 | 保留核心语义,节省空间 | 压缩有信息损失,计算开销 |
| 分层记忆 | 将历史分为近期(窗口内)和远期(向量数据库) | 长程记忆完整 | 需要额外的检索机制 |
| 重写/重开会话 | 建议用户开启新对话 | 彻底解决窗口问题 | 历史完全丢失,用户体验差 |
Anthropic 推荐的策略是在截断前尝试摘要压缩,并使用 “General-purpose summarization” Prompt 提取对话核心 [92]。
6.2 “Lost in the Middle” 问题
“Lost in the Middle”(中间丢失)是上下文窗口的一个重要局限性 [93]。研究表明,当关键信息位于上下文窗口的中间位置(而非开头或结尾)时,模型的检索准确率显著下降:
- 当信息在开头时:检索准确率 ~90%
- 当信息在中间时:检索准确率 ~60%
- 当信息在结尾时:检索准确率 ~85%
解决方案包括:重要信息前置(将 RAG 检索结果的关键信息放在 Prompt 开头)、重要信息后置(放在末尾)、使用 Chain-of-Thought 引导模型在推理时重新审视上下文 [94]。
6.3 多模态场景下的上下文窗口
当上下文包含图像等多模态内容时,Token 数量的计算变得更加复杂 [95]:
- 图像 Token 化:GPT-4V 和 Claude Vision 等模型使用视觉编码器(Visual Encoder)将图像转换为固定长度的 Token 序列,而非按像素计算
- 图像 Token 数量:通常为 256-2048 个 Token(取决于图像分辨率和模型的视觉编码策略),与图像尺寸成正比 [96]
- 混排多模态:一张 1024×1024 的图像可能消耗 1000+ Tokens,开发者需要在窗口预算中为图像预留空间
七、Token 与上下文窗口的成本关联
Token 数量直接关系到 LLM API 的使用成本 [97]。主流 API 的计费模式为:
| 服务商 | 模型 | Input 定价 | Output 定价 | 最大上下文 |
|---|---|---|---|---|
| OpenAI | GPT-4o | $2.5/1M Tokens | $10/1M Tokens | 128K |
| OpenAI | GPT-4o Mini | $0.15/1M Tokens | $0.60/1M Tokens | 128K |
| Anthropic | Claude 3.5 Sonnet | $3/1M Tokens | $15/1M Tokens | 200K |
| Gemini 1.5 Pro | $1.25/1M Tokens | $5/1M Tokens | 2M |
成本控制策略 [98]:
- 精简系统提示词:删除冗余的格式说明和无用的示例
- 历史消息截断:保留关键对话,丢弃低价值历史
- 外部知识压缩:对 RAG 检索结果进行摘要而非全文注入
- 选择合适的模型:GPT-4o Mini 的 Token 效率与 GPT-4o 相同,但成本更低
- 利用缓存:部分 API 提供上下文缓存(Context Caching)功能,对重复使用的系统提示词和长文档进行缓存,减少重复计费
总结与建议
核心要点回顾
-
Token 的本质是分词算法将文本切分后的最小语义单元,而非简单的“单词”或“汉字”。英文中一个 Token 通常对应 0.5-1.5 个单词,中文中通常对应 0.5-2.0 个汉字,具体数值取决于 BPE、WordPiece、SentencePiece 等不同算法 [99]。
-
上下文窗口是 LLM 单次推理能够处理的全部 Token 上限,涵盖系统提示词、历史对话、用户当前输入、外部知识(通过 RAG 等机制注入)等全部组件 [100]。
-
Tokenization 算法对 Token 粒度有决定性影响:字节级 BPE(如 GPT-4)追求零 OOV;WordPiece(如 BERT)追求语义完整性;SentencePiece(如 LLaMA)追求跨语言通用性 [101]。
-
Prompt 设计应充分考虑 Token 预算和窗口限制,将关键指令前置,将重要上下文放在开头或结尾(避免 “Lost in the Middle”),对长对话进行主动管理 [102]。
参考文献
[1] Sennrich, R., Haddow, B., & Birch, A. (2016). Neural Machine Translation of Rare Words with Subword Units. ACL. https://arxiv.org/abs/1508.07909
[2] Radford, A., Wu, J., Child, R., Luan, D., Amodei, D., & Sutskever, I. (2019). Language Models are Unsupervised Multitask Learners. OpenAI Technical Report.
[3] Anthropic. (2024). Claude 3.5 Sonnet Model Card. https://www.anthropic.com/news/claude-3-5-sonnet
[4] OpenAI. (2024). GPT-4 Turbo and GPT-4. https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo
[5] Mikolov, T., Chen, K., Corrado, G., & Dean, J. (2013). Efficient Estimation of Word Representations in Vector Space. ICLR Workshop.
[6] Kudo, T., & Richardson, J. (2018). SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing. EMNLP.
[7] Vaswani, A., Shazeer, N., Parmar, N., et al. (2017). Attention Is All You Need. NeurIPS.
[8] Devlin, J., Chang, M. W., Lee, K., & Toutanova, K. (2019). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. NAACL.
[9] Dao, T., Fu, D. Y., Ermon, S., Rudra, A., & Ré, C. (2022). FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness. NeurIPS.
[10] Bostrom, K., & Durme, B. V. (2021). Byte Pair Encoding for Constrained Text Generation. arXiv.
[11] Gage, P. (1994). A New Algorithm for Data Compression. The C Users Journal.
[12] Brown, T. B., Mann, B., Ryder, N., et al. (2020). Language Models are Few-Shot Learners. NeurIPS.
[13] Pope, R., Douglas, S., Chowdhery, A., et al. (2023). Efficiently Scaling Transformer Inference. MLSys.
[14] OpenAI. (2023). Tiktokenizer. https://platform.openai.com/tokenizer
[15] OpenAI. (2023). Chat Completions API. https://platform.openai.com/docs/api-reference/chat
[16] Anthropic. (2023). Building Effective Prompts. https://docs.anthropic.com/claude/docs
[17] Anthropic. (2024). Claude API Context Management. https://docs.anthropic.com/claude/docs
[18] Provost, F. (1999). POS tagging without a lexicon. Workshop on Computational Linguistics for the Speech and Language Engineering.
[19] Shibata, Y., Kida, T., Fukamachi, S., et al. (1999). Byte Pair Encoding: A Text Compression Scheme That Uses a Wire Dictionary. Journal of the Japanese Society for the Promotion of Science.
[20] Liu, N. F., Levit, M., sodhi, P., & Dinan, E. (2024). What Makes Good In-Context Examples for GPT-4? arXiv.
[21] Jaech, A., Kalai, A., Lerer, A., et al. (2024). OpenAI o1 System Card. https://openai.com/index/openai-o1-system-card
[22] Jozefowicz, R., Vinyals, O., Schuster, M., Shazeer, N., & Wu, Y. (2016). Exploring the Limits of Language Modeling. arXiv.
[23] Schwenk, H., Rousseau, A., & Attik, M. (2012). Large, Pruned or Continuous Space Language Models on a GPU for Statistical Machine Translation. NAACL Workshop.
[24] HuggingFace. (2024). Tokenizers Library. https://huggingface.co/docs/tokenizers
[25] Liu, N. F., Lin, K., Hewitt, J., et al. (2024). Lost in the Middle: How Language Models Use Long Contexts. TACL.
[26] Aghajanyan, A., Gupta, A., Shrivastava, A., Chen, X., Zettlemoyer, L., & Gupta, S. (2021). Muppet: Massive Multi-task Representations with Pre-finetuning. arXiv.
[27] Ainslie, J., Lee-Thorp, J., de Jong, M., et al. (2023). GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints. EMNLP.
[28] Radford, A., & Narasimhan, K. (2018). Improving Language Understanding by Generative Pre-Training. OpenAI.
[29] Schuster, M., & Nakajima, K. (2012). Japanese and Korean voice search. IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP).
[30] Kudo, T. (2018). Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates. ACL.
[31] Wang, C., Li, M., & Smola, A. J. (2019). Language Models with Transformers. arXiv.
[32] Tay, Y., Triticale, T., et al. (2022). LONT: Longformer Enhanced Multi-hop Reasoning. ACL.
[33] Beltagy, I., Peters, M. E., & Cohan, A. (2020). Longformer: The Long-Document Transformer. arXiv.
[34] Zaheer, M., Guruganesh, G., Dubey, K. A., et al. (2020). Big Bird: Transformers for Longer Sequences. NeurIPS.
[35] Cheung, J. C. K., & Shieber, S. M. (2024). Memory-Augmented Language Models. arXiv.
[36] Lewis, P., Perez, E., Piktus, A., et al. (2020). Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks. NeurIPS.
[37] Wu, T., Terry, M., & Marquez, C. B. (2022). Conversational AI and the Rise of Multi-Agent Systems: Autonomy, Interoperability, and Feedback. arXiv.
[38] Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep Learning. MIT Press.
[39] Sennrich et al. (2016). Op. Cit.
[40] HuggingFace. (2024). Tokenizers Quick Tour. https://huggingface.co/docs/tokenizers/quicktour
[41] OpenAI. (2024). Tokenizer Tool. https://platform.openai.com/tokenizer
[42] HuggingFace. (2024). Tokenizers Usage. https://huggingface.co/docs/transformers/tokenizer_summary
[43] Liu, Y., Ott, M., Goyal, N., et al. (2019). RoBERTa: A Robustly Optimized BERT Pretraining Approach. arXiv.
[44] Vaswani et al. (2017). Op. Cit.
[45] Biderman, S., Schoelkopf, H., Anthony, Q., et al. (2023). Pythia: A Suite for Analyzing Large Language Models. ICML.
[46] Anthropic. (2023). Constitutional AI: Harmlessness from AI Feedback. arXiv.
[47] Prompt Engineering Guide. (2024). Context Window Management. https://www.promptingguide.ai/
[48] OpenAI. (2024). Chat Completions API Documentation. https://platform.openai.com/docs/api-reference/chat/create
[49] Anthropic. (2024). System Prompt Design. https://docs.anthropic.com/claude/docs
[50] Bordia, S., & Bowman, S. R. (2019). Words as Features for Language Modeling. NAACL.
[51] Wang, C., et al. (2019). Op. Cit.
[52] Kim, Y. (2016). Character-Aware Neural Language Models. AAAI.
[53] OpenAI. (2024). Models Overview. https://platform.openai.com/docs/models
[54] Anthropic. (2024). Context Window Limits. https://docs.anthropic.com/claude/docs
[55] Kaplan, J., McCandlish, S., Henighan, T., et al. (2020). Scaling Laws for Neural Language Models. arXiv.
[56] Sennrich et al. (2016). Op. Cit.
[57] Shibata et al. (1999). Op. Cit.
[58] Provine, D. (2023). Understanding BPE. Medium Article.
[59] Gillick, D. (1989). Byte-pair encoding: A text compression scheme that uses a wire dictionary. Op. Cit.
[60] Radford, A., et al. (2019). Op. Cit.
[61] Schuster, M., & Nakajima, K. (2012). Op. Cit.
[62] Botha, J. A., & Blunsom, P. (2014). Additive Compositionality and Word Embeddings. EMNLP.
[63] Devlin et al. (2019). Op. Cit.
[64] Kudo & Richardson. (2018). Op. Cit.
[65] Kudo, T. (2018). Subword Regularization. ACL.
[66] Kudo. (2018). Op. Cit.
[67] Tay et al. (2022). Op. Cit.
[68] OpenAI. (2024). Prompt Engineering Guide. https://platform.openai.com/docs/guides/prompt-engineering
[69] Anthropic. (2024). Claude System Prompt Documentation.
[70] Reynolds, L., & McDonell, K. (2021). Prompt Programming for Large Language Models. arXiv.
[71] Wei, J., Bosma, M., Zhao, V. Y., et al. (2022). Finetuned Language Models are Zero-Shot Learners. ICLR.
[72] Microsoft. (2024). Azure OpenAI Service Best Practices. https://learn.microsoft.com/azure/ai-services/openai/
[73] Zhang, Y., Roller, S., & Wallace, B. C. (2016). MGNC-CNN: A Simple Approach to Exploiting Multiple Word Embeddings for Sentence Classification. NAACL.
[74] Liu, P. J., et al. (2018). Generating Wikipedia by Summarizing Long Sequences. ICML.
[75] Huang, L., Cao, S., Parikh, N., et al. (2024). SqueezeLLM: Dense-and-Sparse Quantization. ICML.
[76] Bommasani, R., Hudson, D. A., Adeli, E., et al. (2021). On the Opportunities and Risks of Foundation Models. arXiv.
[77] OpenAI. (2024). Pricing. https://openai.com/pricing
[78] Lewis et al. (2020). Op. Cit.
[79] Johnson, J., Douze, M., & Jégou, H. (2019). Billion-scale similarity search with GPUs. IEEE Transactions on Big Data.
[80] Reimers, N., & Gurevych, I. (2019). Sentence-BERT: A Sentence Embeddings Model Using Siamese BERT-Networks. EMNLP.
[81] Ram, O., Levine, Y., Dalmedigos, I., et al. (2023). In-Context Retrieval-Augmented Language Models. TACL.
[82] Gao, Y., Xiong, D., Gao, Y., et al. (2023). Retrieval-Augmented Generation for Large Language Models: A Survey. arXiv.
[83] OpenAI. (2024). Chat API Messages Format.
[84] OpenAI. (2023). Tokenizer Tool Documentation.
[85] Drozdov, A., Schärli, N., Akyürek, E., et al. (2022). Compositional Semantic Parsing with Large Language Models. arXiv.
[86] Xue, L., Constant, N., Roberts, A., et al. (2021). mT5: A Massively Multilingual Pre-trained Text-to-Text Transformer. NAACL.
[87] Conneau, A., Khandelwal, K., Goyal, N., et al. (2020). Unsupervised Cross-lingual Representation Learning at Scale. ACL.
[88] OpenAI Tokenizer. Op. Cit.
[89] Anthropic Token Counter. Op. Cit.
[90] HuggingFace Tokenizers Space. Op. Cit.
[91] Roller, S., Dinan, E., Goyal, N., et al. (2021). Recipes for Building an Open-Domain Chatbot. EACL.
[92] Anthropic. (2024). Long Context Handling.
[93] Liu et al. (2024). Op. Cit.
[94] Press, O., Zhang, M., Min, S., Schmidt, L., Smith, N. A., & Lewis, M. (2021). Measuring and Narrowing the Compositionality Gap in Language Models. EMNLP.
[95] Anthropic. (2024). Claude Vision Documentation.
[96] Lu, J., Batra, D., Parikh, D., & Lee, S. (2019). ViLBERT: Pretraining Task-Agnostic Visiolinguistic Representations for Vision-and-Language Tasks. NeurIPS.
[97] OpenAI Pricing. Op. Cit.
[98] Anthropic Pricing. https://www.anthropic.com/pricing
[99] Sennrich et al. (2016), Kudo & Richardson (2018), OpenAI (2024). Op. Cit.
[100] Anthropic Context Documentation, OpenAI Chat API Documentation. Op. Cit.
[101] Radford et al. (2019), Devlin et al. (2019), Kudo & Richardson (2018). Op. Cit.
[102] Liu et al. (2024), Press et al. (2021). Op. Cit.
(2019). ViLBERT: Pretraining Task-Agnostic Visiolinguistic Representations for Vision-and-Language Tasks. NeurIPS.
[97] OpenAI Pricing. Op. Cit.
[98] Anthropic Pricing. https://www.anthropic.com/pricing
[99] Sennrich et al. (2016), Kudo & Richardson (2018), OpenAI (2024). Op. Cit.
[100] Anthropic Context Documentation, OpenAI Chat API Documentation. Op. Cit.
[101] Radford et al. (2019), Devlin et al. (2019), Kudo & Richardson (2018). Op. Cit.
[102] Liu et al. (2024), Press et al. (2021). Op. Cit.
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)