上下文工程
1. 上下文窗口管理
上下文窗口的本质
上下文窗口是模型单次能处理的最大 Token 数量,直接影响模型的信息处理能力:
上下文窗口 (如 128K tokens)
├── System Prompt ← 固定开销
├── Few-shot 示例 ← 按需开销
├── 对话历史 ← 动态增长
├── 当前输入 ← 用户查询
└── 预留输出空间 ← 必须留足
QUESTION 面试高频:如何管理有限的上下文窗口? 核心策略:信息密度最大化 + 动态分配
- 固定部分(System Prompt)尽量精简
- 动态部分(对话历史)按策略裁剪
- 为输出预留足够空间
- 使用 RAG 按需注入相关知识,而非塞入全部文档
Token 预算分配
假设总上下文 = 128K tokens
System Prompt: 500 tokens (0.4%)
Few-shot 示例: 2K tokens (1.6%)
RAG 检索结果: 10K tokens (7.8%)
对话历史: 30K tokens (23.4%)
当前输入: 5K tokens (3.9%)
输出预留: 80K tokens (62.5%) ← 长输出任务需要更多
─────────────────────────────────
总计: 127.5K tokens
2. 信息密度优化
密度提升策略
| 策略 | 说明 | 效果 |
|---|---|---|
| 摘要压缩 | 对长文档先做摘要再注入 | 减少 50-80% Token |
| 关键信息提取 | 只提取与任务相关的信息 | 减少 70-90% Token |
| 结构化表示 | 用表格/列表替代自然语言 | 减少 30-50% Token |
| 去重 | 移除重复信息 | 减少 10-30% Token |
信息层次
核心信息 (必须包含)
├── 任务目标和约束
├── 关键定义和规则
└── 必要的示例
辅助信息 (按需包含)
├── 背景知识
├── 参考资料
└── 补充说明
冗余信息 (应当移除)
├── 重复表述
├── 无关细节
└── 过长的铺垫
3. 多轮对话设计
对话历史管理策略
滑动窗口策略
保留最近 N 轮对话,丢弃更早的历史:
[丢弃] Turn 1, Turn 2, Turn 3
[保留] Turn 4, Turn 5, Turn 6, Turn 7, Turn 8
↑ 当前轮
- 优点:简单高效
- 缺点:丢失早期重要上下文
摘要压缩策略
定期将旧对话压缩为摘要:
[摘要: 用户正在讨论 Python 并发编程...] ← 压缩的旧历史
Turn 6: 用户问...
Turn 7: 模型答...
Turn 8: 用户问... ← 最近完整历史
- 优点:保留全局信息
- 缺点:摘要可能丢失细节
混合策略
System Prompt ← 始终保留
对话摘要 (Turn 1-5) ← 压缩保留
完整最近对话 (Turn 6-8) ← 完整保留
当前查询 ← 完整保留
上下文优先级
QUESTION 面试高频:多轮对话中如何保持上下文连贯性?
- 维护对话状态摘要:持续更新用户的意图和关键信息
- 关键实体追踪:记录用户提到的关键实体和关系
- 话题检测:识别话题切换,调整上下文策略
- 指代消解:将代词替换为完整实体名后再传入模型
- 分层记忆:短期(最近几轮)+ 长期(摘要/向量检索)
4. RAG 上下文管理
检索增强生成中的上下文
用户查询
↓
Query 改写/扩展
↓
向量检索 → 获取 Top-K 相关片段
↓
重排序 (Reranking)
↓
选择最相关的 N 个片段
↓
注入到 Prompt 中
↓
模型生成回答
RAG 上下文优化
| 优化点 | 方法 | 说明 |
|---|---|---|
| 分块策略 | 语义分块 > 固定长度分块 | 保持语义完整性 |
| 检索质量 | Hybrid Search (稠密+稀疏) | 提高召回率 |
| 重排序 | Cross-encoder Reranking | 精确排序 |
| 压缩 | Context Compression | 去除片段中的噪声 |
| 去重 | MMR (Maximal Marginal Relevance) | 避免信息冗余 |
5. 上下文中的信息排序
位置效应(Lost in the Middle)
研究表明,模型对上下文开头和结尾的信息关注度更高,中间部分容易被忽略。
论文:《Lost in the Middle: How Language Models Use Long Contexts》(Liu et al., 2023)
信息关注度分布:
高 ┃█ █
┃█ █
┃█ ████ █
┃█ ███████ █
┃█ ██████████ █
低 ┃█ █████████████ █
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
开头 中间 结尾
QUESTION 面试高频:如何应对"Lost in the Middle"问题?
- 重要信息放首尾:将关键指令和示例放在开头和结尾
- 信息分块:避免在单个上下文中堆砌过多信息
- 重复关键指令:在开头和结尾重复核心要求
- 结构化标记:用标题和分隔符帮助模型定位信息
- 多次查询:将长文档拆分后多次查询,合并结果
6. 上下文工程最佳实践
设计清单
- System Prompt 精简到最少 Token
- 为输出预留充足空间
- 实现对话历史的自动管理策略
- 关键信息放置在上下文首尾
- RAG 检索片段经过重排序
- 使用结构化格式提升信息密度
- 监控 Token 使用量
- 设置上下文溢出的降级策略
监控指标
| 指标 | 说明 | 告警阈值 |
|---|---|---|
| 上下文利用率 | 实际使用 / 最大窗口 | > 80% |
| 输出截断率 | 被截断的回复比例 | > 5% |
| 信息召回率 | RAG 检索的准确度 | < 70% |
| 响应延迟 | 首个 Token 延迟 | > 5s |