大型语言模型(LLM)的上下文窗口正在不断扩大,例如Claude-sonnet-4-6拥有20万Token,GPT-4o也达到了12.8万Token。这些看似庞大的容量,在实际构建检索增强生成(RAG)应用时,往往仍然显得捉襟见肘。当需要同时传递大量文档上下文、完整的对话历史、详细的系统指令以及复杂的工具定义时,Token预算很快就会耗尽。在对话中途耗尽上下文窗口是一个无法挽回的故障,因此,有效管理Token已成为一项核心的工程实践。
Token计数方法
准确计算Token是管理上下文窗口的第一步。针对不同的LLM提供商,有不同的计数策略:
- Anthropic:可以直接利用其API提供的Token计数端点。通过调用
anthropic.messages.countTokens方法,可以精确计算出输入消息(包括系统提示)所占用的Token数量。 - OpenAI:通常使用本地的
tiktoken库进行Token计数,无需额外的API调用。开发者可以根据指定的模型(如'gpt-4o')对文本进行编码,并获取Token数量。
对话历史管理:截断策略
简单地将所有历史消息不断附加到上下文中会导致Token溢出。一种基础且有效的管理策略是截断最旧的消息:
该方法会定义一个最大上下文Token预算(例如10万Token),并预留一部分Token给系统提示、新消息以及模型生成响应。在剩余的预算内,算法会从最新消息开始倒序遍历对话历史。如果添加当前消息会导致超出预算,则停止添加并丢弃更早的消息,从而确保总Token数不超过限制。这种“保留最新,丢弃最旧”的策略能够有效控制Token使用。
对话历史管理:摘要策略
除了简单截断,更高级的策略是通过摘要来压缩历史信息。这种方法不是直接丢弃旧消息,而是利用一个成本较低的LLM(例如Anthropic的Claude-haiku)来对旧的对话部分进行总结:
具体实现上,会将需要摘要的对话历史(例如最旧的一半)整理成文本,然后发送给一个专门用于摘要的LLM。这个LLM会生成一个简洁的摘要,保留对话中的关键事实和决策。随后,这个摘要可以作为一条“浓缩”的历史记录,被添加到新的上下文窗口中,从而显著减少Token占用,同时尽可能地保留重要信息。这种策略尤其适用于需要长期记忆但又受限于上下文长度的AI应用。