3.2 上下文管理——选而不是全塞
概念
上下文窗口(Context Window)就像你的办公桌:再大也是有限的。你以为窗口 128K token 很大,但塞进去的不只是用户输入——系统 Prompt、历史对话、工具调用结果、RAG 检索的文档片段,全要挤在这张桌子上。
用法
上下文管理的核心策略是选而不是全塞。你不需要把所有信息都喂给模型,你需要判断"当前这一步,模型需要什么"。
| 信息类型 | 该不该塞 | 取舍原则 |
|---|---|---|
| 系统 Prompt(角色/规则) | 必塞 | 每轮都在,定义模型行为边界 |
| 当前用户输入 | 必塞 | 本轮要处理的任务 |
| 工具返回结果 | 按需塞 | 只塞跟当前任务相关的字段,砍掉冗余元数据 |
| 历史对话 | ⚠️ 选择性塞 | 近轮保留,远轮摘要或丢弃 |
| RAG 检索文档 | ⚠️ Top-K 塞 | 按相关度排序,只塞 Top 3-5 片段 |
| 全量知识库 | ❌ 不塞 | 用 RAG 按需检索,不要全塞 |
一个实用的上下文预算分配:
总窗口 128K token 的分配建议:
├── 系统 Prompt + 规则: 5K(固定)
├── 工具定义 + API Schema: 3K(固定)
├── RAG 检索片段: 5K(按需)
├── 历史对话摘要: 2K(滚动更新)
├── 当前用户输入 + 工具结果: 3K(变化)
└── 输出预留: 110K(剩余给模型生成)
示例
假设你做一个 IT 运维问答 Agent,用户问"昨天那台服务器怎么了"。
错误做法(全塞):
把最近 30 天所有服务器日志全部塞进去 → 200K token,超窗口,报错。
正确做法(选着塞):
1. 从用户问题提取关键词:"昨天" + "服务器"
2. RAG 检索:只检索昨天时间范围内、与服务器相关的日志摘要 → 3K token
3. 历史对话:保留最近 3 轮 → 1K token
4. 系统 Prompt:运维专家角色 + 分类规则 → 2K token
5. 喂给模型的总量:6K token,远在窗口内
**⚠️ 风险提示:**不要用"摘要"替代"原文"来省钱。如果关键证据在原文细节里,摘要会丢失信息。正确做法是:摘要用于远距离历史(3 轮以前),近 3 轮保留原文。同时,工具返回结果如果是大 JSON,先做字段裁剪再塞——只留模型决策需要的字段,砍掉 metadata 、 requestId 等对任务无意义的字段。
随堂测
逐题作答,即时反馈
1. 按上下文管理「选而不是全塞」的取舍原则,下列哪项处理方式与课文一致?
2. IT 运维问答 Agent 中用户问「昨天那台服务器怎么了」,课文的正确做法(选着塞)是?
3. 按课文 128K token 总窗口的上下文预算分配建议,留给模型生成的「输出预留」约为?