主题
上下文工程(Context Engineering)
上下文工程(Context Engineering)是大模型工程的第二、三代之间承上启下的关键范式,研究如何高效组织进入 LLM 上下文窗口(Context Window)的信息,让模型获得最相关的内容并给出最佳回答。它既服务于单次 Prompt 的质量,也是后续 Workflow / RAG / Agent / Graph 的信息供给层。
核心不是把更多内容塞进窗口,而是用最小、最相关的信息密度,让模型在有限窗口内"看得清、记得住、不被干扰"。
为什么需要 Context Engineering
上下文窗口里的所有内容都会参与计算,但窗口并非"越大越好":
上下文窗口 = LLM 一次能处理的最大 Token 数
GPT-4o:128K tokens ≈ 约 10 万字
Claude 3.5:200K tokens ≈ 约 15 万字
Gemini 1.5 Pro:1M tokens ≈ 约 75 万字问题 1:上下文太长(超窗口)→ 截断开头,丢失信息
问题 2:上下文太短(信息不足)→ 模型回答质量差
问题 3:上下文有噪声(无关信息)→ 模型分心,效果差在五代演进中,Context Engineering 位于 Prompt 之上、Workflow/RAG 之中——它解决了"Prompt 写对了,但喂给模型的信息不对/太多/太乱"的瓶颈,并为 Agent 与 Graph 的状态管理提供理论基础。
Prompt → Prompt Chain → Workflow → Loop → Graph
对应系统进化:输入 → 流程 → 状态 → 反馈 → 自治与已有工程层的关系
Graph Engineering(图工程) ← 用图编排多个 Loop / Workflow
Loop Engineering(循环工程) ← 多步反馈循环、终止条件
Harness Engineering(承载管控) ← 执行、验证、安全边界
Context Engineering(上下文工程) ← 信息输入、上下文管理 ◀ 本文
Prompt Engineering(提示工程) ← 单次输入优化Context 是 Prompt 的"内容引擎":Prompt 决定"怎么问",Context 决定"给模型看什么"。同时,Loop 中每一步的上下文裁剪、Graph 中共享状态的读写,本质都是 Context Engineering 的延伸。
核心要素
| 要素 | 说明 |
|---|---|
| 窗口管理 | 控制 Token 总量,避免超限截断 |
| 信息密度 | 去除无关内容,只保留关键信号 |
| 位置策略 | 重要信息放开头/结尾(Lost in the Middle) |
| 上下文压缩 | 用 LLM 或 Rerank 压缩/重排历史 |
| 分块检索 | 先检索最相关片段(RAG)再注入 |
| 记忆机制 | 短期(会话内)+ 长期(跨会话) |
核心技巧
1. 信息密度优化
去掉上下文中无关的内容:
差(啰嗦):
"你好,我是一名前端开发者,最近在学习 React,
遇到了一个问题,就是..."
好(简洁):
"React useEffect 清理函数不执行,代码如下:..."2. 关键信息前置(Lost in the Middle)
研究发现,LLM 对上下文的开头和结尾内容记忆最好,中间内容容易"丢失":
重要信息放开头或结尾,不要在中间埋没python
# 优化前(重要指令在中间)
context = f"""
对话历史:{history}
请只用中文回答
用户问题:{question}
不要超过 200 字
"""
# 优化后(指令放开头和结尾)
context = f"""
[指令] 请只用中文回答,不超过 200 字
对话历史:{history}
用户问题:{question}
[指令] 记住:只用中文,不超过 200 字
"""3. Few-Shot 示例放最后
让 LLM 模仿示例,把示例放在问题前面(最近原则):
[系统提示]
[少量示例 1]
[少量示例 2]
[少量示例 3]
[当前问题] ← LLM 会优先参考最近的示例4. 上下文压缩(Context Compression)
当上下文太长时,用 LLM 自己来压缩:
python
# 用 LLM 总结对话历史,再作为上下文
summary_prompt = f"总结以下对话的关键信息:\n{history}"
summary = llm(summary_prompt)
# 用压缩后的 summary 代替完整 history
context = f"历史摘要:{summary}\n当前问题:{question}"5. 分块检索(RAG)
不要一次性把所有资料都塞进上下文,先检索最相关的:
python
# 差:把所有文档都放进上下文
context = "\n".join(all_docs) # 可能超长
# 好:先检索最相关的 5 段
relevant_docs = vector_db.search(query, k=5)
context = "\n".join(relevant_docs)长上下文模型的使用技巧
即使模型支持长上下文(如 Claude 200K),也不意味着你应该填满它:
上下文长度 → 成本 → 速度 → 效果
填满 200K:
- 成本高(按 Token 计费)
- 速度慢(推理时间长)
- 效果可能反而差(Lost in the Middle)
建议:只放必要信息,控制在 32K 以内上下文管理工具
LangChain - Memory 模块
python
from langchain.memory import ConversationBufferMemory
from langchain.memory import ConversationSummaryMemory
# 方式 1:保留完整历史(短对话)
buffer_memory = ConversationBufferMemory()
# 方式 2:总结历史(长对话)
summary_memory = ConversationSummaryMemory(llm=llm)
# 自动用 LLM 总结早期对话,节省 TokenLangChain - Contextual Compression
python
from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank
# 检索后,用 Rerank 模型重新排序,只保留最相关的
compressor = CohereRerank()
compression_retriever = ContextualCompressionRetriever(
base_retriever=vectorstore.as_retriever(),
base_compressor=compressor
)不同场景的上下文策略
| 场景 | 策略 |
|---|---|
| 短对话(< 10 轮) | BufferMemory(保留全部) |
| 长对话(> 10 轮) | SummaryMemory(总结早期) |
| RAG 问答 | 只检索 Top 5 相关片段 |
| 代码生成 | 只引用相关文件和函数(@File) |
| 文档分析 | 分章节处理,不要一次传整本书 |
设计原则
- 密度优于体量:宁可少而精,不要多而杂。
- 关键置顶/置尾:规避 Lost in the Middle。
- 该压缩就压缩:长对话用 Summary,长文档用 RAG 检索。
- 为下游留接口:Loop 的上下文裁剪、Graph 的共享状态都依赖本层能力。
- 成本意识:上下文长度直接转化为费用与延迟。