大模型上下文窗口:Token 预算、性能瓶颈与 RAG 的关系

上下文窗口是什么

大模型每次生成回答时,只能处理有限数量的 Token。这个范围就是上下文窗口。它通常要同时容纳系统指令、用户问题、对话历史、RAG 证据、工具定义、工具结果以及模型输出。

不同 API 对输入上限、最大输出和内部推理 Token 的计算方式可能不同,使用时应查看对应模型的官方说明,不能只记住一个"总长度"数字。

Token 不是字符。一个英文单词可能由一个或多个 Token 构成,中文字符、标点、代码和空格也会按分词器规则组合。最可靠的做法是使用模型对应的 tokenizer 实际计算。

大模型并不会自动记住上一轮

多数聊天 API 的模型调用是无状态的。界面看起来像连续对话,是因为应用在每次请求时重新发送必要的历史消息:

json 复制代码
{
  "messages": [
    {"role": "system", "content": "你是一名技术助手"},
    {"role": "user", "content": "我使用的是 Linux"},
    {"role": "assistant", "content": "好的。"},
    {"role": "user", "content": "怎样查看端口占用?"}
  ]
}

历史越长,占用的窗口越多,调用成本和首字延迟也可能上升。应用需要自己决定保留哪些原文、哪些消息可以总结、哪些已经与当前问题无关。

窗口里到底放了什么

一个带工具和 RAG 的智能体,请求预算可能由以下部分组成:

text 复制代码
系统指令              1,200 tokens
工具定义                900 tokens
近期对话              3,000 tokens
检索证据              6,000 tokens
当前问题                200 tokens
输出预留              2,500 tokens
--------------------------------
合计                 13,800 tokens

这只是预算示例,不代表某个具体模型限制。工程上应先为输出预留空间,再计算输入还能使用多少:

python 复制代码
usable_input = context_limit - reserved_output - safety_margin

if token_count(prompt_parts) > usable_input:
    prompt_parts = compress_to_budget(prompt_parts, usable_input)

若把窗口全部塞满输入,即使请求没有立刻报错,也可能没有足够空间生成完整回答。

为什么窗口不能无限增大

标准全注意力机制需要让序列中的 Token 相互计算注意力,计算量常被概括为随序列长度呈平方增长。现代模型会使用高效注意力、稀疏结构、缓存和工程优化,实际表现不完全等同于简单公式,但长输入依然需要更多计算与显存。

自回归生成时还会维护 KV Cache。它通常随序列长度、网络层数和注意力头配置增长。上下文越长,缓存越大,单请求占用资源越多,可并发的请求数量也会下降。

因此,模型标称"支持很长窗口"不等于每次都应该填满。无关内容会增加成本,还可能稀释真正重要的证据。

超出窗口会发生什么

行为取决于 API 和应用实现。有些接口直接返回长度错误;有些聊天框架会自动删除较早消息;有些系统会总结历史或截断单条内容。

自动截断如果不可见,会带来隐蔽错误:用户早先给出的关键约束被删掉,模型却继续给出看似连贯的答案。应用应显式记录裁剪策略,并尽量保留系统规则、当前问题和高优先级事实。

即使没有超限,长上下文也不保证模型能同等利用每一部分。研究和实践中常见"Lost in the Middle"现象:关键信息放在很长上下文中部时,模型可能不如处理开头或结尾的信息稳定。解决办法不是简单复制关键内容,而是减少噪声、重排证据并做好评估。

五种上下文管理方法

1. 滑动窗口

只保留最近若干轮对话,适合即时聊天。缺点是早期约束可能被遗忘,因此要把长期有效信息单独保存。

python 复制代码
recent_messages = messages[-10:]

2. 对话摘要

将较早对话压缩为结构化摘要,而不是保留每句话:

json 复制代码
{
  "environment": "Ubuntu 24.04",
  "goal": "部署 Python Web 服务",
  "constraints": ["不能使用容器", "端口必须为 8080"],
  "resolved": ["已安装 Python 3.12"]
}

摘要也可能遗漏信息,最好保留原始历史的可追溯存储,并在关键决策前重新读取相关消息。

3. 按需检索历史

把长期对话、用户偏好或项目记录放入外部存储,只在与当前问题相关时检索。这与 RAG 的思路相同:不把全部记忆一直带在窗口里。

4. 控制工具定义与结果

智能体若一次暴露几十个工具,其 JSON Schema 就会占用大量 Token。可以先按任务路由,只提供当前需要的工具;工具返回的大表格和日志则先筛选、聚合或分页。

5. 为 RAG 证据设预算

检索不是越多越好。先召回较多候选,再通过重排、去重和压缩,留下能覆盖问题的少量证据:

python 复制代码
candidates = retrieve(question, top_k=30)
ranked = rerank(question, candidates)
evidence = pack_by_token_budget(ranked, budget=5000)

若问题包含多个子任务,可以按子问题分配预算,避免一个主题占满全部空间。

长上下文会取代 RAG 吗

不会。长上下文和 RAG 解决的不是同一个问题。

长上下文提高了单次请求能阅读的材料量,适合一次性分析一份长报告、代码仓库中的若干文件或完整会议记录。RAG 则从更大的数据集合中筛选当前需要的证据,还能处理更新、权限、引用和多租户隔离。

假设知识库有一万份文档,即使模型能容纳其中几份,也没有必要把一万份全部传入。RAG 先做搜索与过滤,再利用长上下文同时阅读更多高质量候选,两者是互补关系。

text 复制代码
海量知识库
   ↓ RAG:找出相关且有权限的资料
少量候选文档
   ↓ 长上下文:联合阅读、比较和归纳
最终回答

怎样设计一份可执行的预算

先确定模型限制和预期输出,再按优先级分配输入空间:

python 复制代码
budget = {
    "system": 1200,
    "tools": 800,
    "history": 2500,
    "evidence": 6000,
    "question": 500,
    "output": 3000,
    "margin": 1000,
}

数字应来自实际 tokenizer 和请求分布。监控中至少记录输入 Token、输出 Token、被裁剪内容、证据数量、延迟和错误率。之后才能判断,应该增加窗口、优化检索,还是精简提示词。

小结

上下文窗口是大模型每次调用的工作区,也是必须主动管理的资源。它容纳的不只有用户文字,还包括系统指令、历史、RAG 证据、工具信息和输出预留。

可靠的做法是先做预算,再按重要性压缩和检索,最后验证关键约束有没有在长输入中丢失。更长的窗口能处理更多材料,但不能替代信息筛选;RAG 负责找到值得阅读的内容,长上下文负责把这些内容一起读好。

相关推荐
罗西的思考1 小时前
AI 时代的 “房谋杜断”:如何培养能力、品味与判断力
人工智能·算法·机器学习
字节跳动视频云技术团队2 小时前
720P 直升 8K,解密 2026 抖音美好奇妙夜巨幕超分黑科技
人工智能·音视频开发
打工仔折腾 AI2 小时前
在 Ubuntu ARM64 部署 Q1 V3.0 MuJoCo 模型:加载、单步推理与执行器响应解析
linux·运维·人工智能·python·深度学习·ubuntu·性能优化
逐米时代2 小时前
从试点验证到协同深化:制造业AI转型三年路线图设计方法
人工智能
GlobalInfo2 小时前
全球及中国风电叶片检测机器人行业研究报告(2026版):市场现状、行业前景与占有率分析
运维·网络·人工智能·机器人
stormzhangV3 小时前
AI 越强,失业越严重
人工智能·aigc
夏文强4 小时前
Rerank 与混合检索:怎么让 RAG 从「能用」变成「好用」
人工智能·大模型·向量数据库·rag·检索增强生成
救救孩子把4 小时前
AI面试八股文-23_23-Agent可观测性与生产监控面试题
人工智能·面试·职场和发展·agent·langsmith·langfuase
IT_陈寒4 小时前
Java静态变量初始化坑得我头皮发麻
前端·人工智能·后端
知行产研4 小时前
白马山领跑、南山矿扩编 31 台,安徽露天矿无人驾驶进入规模化阶段
人工智能