共计 1665 个字符,预计需要花费 5 分钟才能阅读完成。
问题背景
上下文窗口(Context Window)是什么?
简单来说,上下文窗口就是大语言模型(LLM)能同时处理的文本量上限,比如 GPT-3.5 的 4096 tokens 或 GPT- 4 的 32k tokens。这就像电脑内存——超过限制就会报错。最近在处理长文档时,我就遇到了这个报错:

agent failed before reply: model context window too small (8192 tokens). min
典型触发场景
- 长文档处理 :比如解析 50 页的 PDF 时,原始文本很容易超限
- 多轮对话 :当聊天历史累积到一定长度后
- 复杂 Agent 系统 :多个工具调用结果拼接后超出限制
解决方案对比
方案 1:动态上下文压缩
核心思路:用大模型自己来压缩内容
- 优点:保留核心语义
- 缺点:增加 API 调用次数
示例方法:
1. 提取关键句子
2. 生成摘要
3. 删除冗余描述
方案 2:分块处理 + 记忆机制
实现步骤:
- 按 token 数拆分文档
- 处理每个分块
- 维护全局记忆
关键点:
– 分块时不要切断句子
– 保留分块间关联信息
方案 3:模型 API 参数优化
如果预算允许:
- 升级到 gpt-3.5-turbo-16k
- 使用 GPT-4-32k 版本
成本对比:
– 16k 版本价格是标准版的 2 倍
– 32k 版本是 4 倍
代码实现
分块处理示例(使用 LangChain)
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=2000, # 目标块大小
chunk_overlap=200, # 块间重叠
length_function=len, # 长度计算函数
)
chunks = text_splitter.split_text(long_document)
精确计算 token 数(Tiktoken 库)
import tiktoken
def count_tokens(text: str, model_name: str = "gpt-3.5-turbo") -> int:
encoding = tiktoken.encoding_for_model(model_name)
return len(encoding.encode(text))
错误重试机制
import openai
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
def safe_completion(prompt):
try:
return openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}]
)
except openai.error.InvalidRequestError as e:
if "context window" in str(e):
raise ValueError("Context window exceeded") from e
raise
生产环境考量
方案对比表格
| 方案 | 延迟影响 | 成本影响 | 实现难度 |
|---|---|---|---|
| 上下文压缩 | 高(多轮调用) | 中 | 中 |
| 分块处理 | 中 | 低 | 高 |
| API 升级 | 低 | 高 | 低 |
监控建议
- 设置 token 使用率告警(如 >70% 阈值)
- 记录各环节耗时
- 监控压缩后的信息保留率
避坑指南
常见问题
- 语义断裂 :分块时切断了关键句
-
解决方法:按段落 / 句子边界分块
-
摘要失真 :关键信息被遗漏
-
解决方法:保留原始数据索引
-
异步一致性问题
- 解决方法:使用全局会话 ID
安全提示
- 敏感信息摘要前需脱敏
- 不要直接压缩法律 / 医疗文本
延伸思考
- 如何设计自适应上下文窗口的 Agent?
- 能否动态预测所需 token 数?
- 混合方案(压缩 + 分块)的最佳平衡点在哪?
通过这次实战,我发现没有完美方案,需要根据具体场景做权衡。希望这些经验对你有帮助!遇到具体问题时,欢迎交流讨论。
正文完
