主题
上下文工程
本章目标与前置知识(补充讲解)
先读RAG和工具调用。本章学习构造一次调用真正需要的信息,而不是无限追加聊天记录。
用户从“经济舱”改为“商务舱”,旧偏好、长篇工具结果和过期搜索都挤在窗口里,助手反而更容易混淆。 上下文(Context) 是本次模型可见的输入集合; 上下文工程(Context Engineering) 是选择、组织、压缩、隔离和更新这些输入的过程。提示工程主要关注指令怎么写,上下文工程还要决定数据从哪里来、多少、什么时候失效。
图:本次窗口由系统指令、当前任务、相关历史、工具描述和证据组成;记忆库只有被检索并选入的部分才进入窗口。上下文预算不是整个存储容量。
原课程精读:AI Agent 的上下文工程
(点击上方图像观看本课视频)
理解你正在为其构建 AI Agent 的应用复杂性,对于打造一个可靠的 Agent 非常重要。我们需要构建能够有效管理信息的 AI Agent,以满足超越提示工程的复杂需求。
在本课中,我们将探讨什么是上下文工程及其在构建 AI Agent 中的作用。
介绍
本课内容包括:
• 什么是上下文工程 以及它为何不同于提示工程。
• 有效上下文工程的策略 ,包括如何编写、选择、压缩和隔离信息。
• 常见的上下文失败 ,可能导致你的 AI Agent 失效的情况以及如何修复。
学习目标
完成本课后,你将能够理解并掌握:
• 定义上下文工程 并区别于提示工程。
• 识别大语言模型(LLM)应用中的关键上下文组成部分 。
• 应用编写、选择、压缩和隔离上下文的策略 ,以提升 Agent 性能。
• 识别常见的上下文失败 ,如中毒、分心、混淆和冲突,并实施缓解技术。
什么是上下文工程?
对于 AI Agent 而言,上下文驱动着 Agent 制定采取某些行动的计划。上下文工程是确保 AI Agent 拥有完成任务下一步所需正确信息的实践。上下文窗口大小有限,因此作为 Agent 构建者,我们需要构建系统和流程来管理上下文窗口中信息的添加、删除和压缩。
提示工程与上下文工程的区别
提示工程专注于一组静态指令,有效地用规则引导 AI Agent。上下文工程则是管理包含初始提示在内的动态信息集合,确保 AI Agent 随着时间推移拥有所需信息。上下文工程的核心是使该过程可重复且可靠。
上下文类型
重要的是要记住,上下文不只是单一内容。AI Agent 所需的信息可能来自各种不同来源,我们需确保 Agent 能够访问这些来源:
AI Agent 可能需要管理的上下文类型包括:
• 指令: 类似于 Agent 的“规则”——提示、系统消息、少量示例(示范 AI 如何做某事)以及 Agent 可用工具的描述。这是提示工程与上下文工程的结合点。
• 知识: 涵盖事实、从数据库检索的信息或 Agent 累计的长期记忆。若 Agent 需访问不同知识库和数据库,则包含整合检索增强生成(RAG)系统。
• 工具: Agent 可调用的外部函数、API 和 MCP 服务器的定义,以及使用工具后反馈(结果)。
• 对话历史: 与用户的持续对话。随着时间推移,这些对话变得越来越长、复杂,占据上下文窗口空间。
• 用户偏好: 随时间学习到的用户喜好或厌恶信息。可存储并在关键决策时调用,帮助用户。
有效上下文工程的策略
规划策略
良好的上下文工程始于良好的规划。下面的方法助你开始思考如何应用上下文工程概念:
- 定义明确的结果 - 应清晰定义 AI Agent 将分配的任务结果。回答问题——“当 AI Agent 完成任务时世界将是什么样子?”换言之,用户与 AI Agent 交互后应获得什么变化、信息或回应。
- 绘制上下文图谱 - 定义任务结果后,需要回答“AI Agent 完成该任务需要哪些信息?”基于此开始定位这些信息所在的上下文。
- 创建上下文流水线 - 确定信息位置后,需回答“Agent 如何获取这些信息?”可采用多种方式,包括 RAG、使用 MCP 服务器及其它工具。
实用策略
规划很重要,但当信息开始流入 Agent 的上下文窗口时,我们需要实用策略加以管理:
管理上下文
虽然部分信息会自动加入上下文窗口,但上下文工程更主动,具体可采用以下几种策略:
Agent 便签(Agent Scratchpad) 允许 AI Agent 在单次会话中记笔记,记录当前任务和用户交互的相关信息。便签应存于上下文窗口外的文件或运行时对象中,Agent 可在会话中需要时检索。
记忆(Memories) 便签用来管理单次会话上下文窗口之外的信息,记忆则支持跨多次会话存储和检索相关信息,包括摘要、用户偏好及改进反馈。
压缩上下文 当上下文窗口增长接近极限时,可使用摘要和裁剪等技术,包括仅保留最相关信息或删除较旧消息。
多 Agent 系统 开发多 Agent 系统也是一种上下文工程,因为每个 Agent 有自己的上下文窗口。应规划如何共享和传递上下文给不同 Agent。
沙箱环境 若 Agent 需运行代码或处理大量文档信息,这可能消耗大量Token。Agent 可利用沙箱环境执行代码,仅将结果及相关信息读入上下文窗口。
运行时状态对象 创建信息容器,管理 Agent 需要访问特定信息的场景。针对复杂任务,允许 Agent 逐步存储各子任务结果,使上下文仅关联该子任务。
检查上下文
应用策略后,值得检查下一次模型调用实际收到的内容。有用的调试问题:
Agent 加载了过多上下文、错误上下文,还是缺少所需上下文?
不必记录原始提示、工具输出或记忆内容。生产环境优选包含计数、ID、哈希及策略标签的小型上下文检查记录:
- 选择: 跟踪考虑了多少候选块、工具或记忆,选择了多少,及哪些规则或得分导致其他被过滤。
- 压缩: 记录源范围或追踪 ID、摘要 ID、压缩前后估计Token数,及是否排除原始内容。
- 隔离: 记录哪些子任务在独立 Agent、会话或沙箱中运行,返回了什么边界摘要,以及大型工具输出是否留在父 Agent 上下文之外。
- 记忆与 RAG: 存储检索文档 ID、记忆 ID、分数、选中 ID 及编辑状态,不存储完整检索文本。
- 安全和隐私: 使用哈希、ID、Token桶及策略标签,避免敏感提示文本、工具参数、工具结果或用户记忆正文。
目标不是保留更多上下文,而是留下足够证据,让开发者判断使用了哪种上下文策略及其是否按预期影响模型调用。
上下文工程示例
假设我们想让 AI Agent “帮我订一趟去巴黎的行程。”
• 仅使用提示工程的简单 Agent 可能直接回应: “好的,你想什么时候去巴黎?” 它仅处理用户当时直接提问的问题。
• 采用本课提到的上下文工程策略的 Agent,会做更多工作。在回应前,其系统可能:
◦ 检查你的日历 ,查找空闲日期(实时数据检索)。
◦ 回忆过去的旅行偏好 (来自长期记忆),比如你偏好的航空公司、预算或是否喜欢直飞。
◦ 识别可用工具 ,如航班和酒店预订。
- 然后,示例回应可能是:“嗨,[你的名字]!我看到你十月第一周有空。要帮你找[偏好航空公司]的直飞巴黎航班,预算控制在[预算]内吗?”这种更丰富、具上下文感知的回应展现了上下文工程的威力。
常见上下文失败
上下文中毒
定义: 当幻觉(LLM 生成的虚假信息)或错误进入上下文并反复被引用,导致 Agent 追求不可能目标或形成荒谬策略。
应对: 实施 上下文验证 和 隔离 。信息加入长期记忆前进行验证。若检测到潜在中毒,开启新的上下文线程,防止错误信息扩散。
旅行订票示例: Agent 错误生成了一个“从一个小地方机场直飞远国际城市”的航班,实际上该机场不提供国际航班。此不存在的飞行信息存入上下文。后续订票时,Agent 持续尝试找这条不可能航线,导致反复错误。
解决方案: 在将航班信息添加到工作上下文前,使用实时 API 验证航班和航线是否存在。验证失败的错误信息被“隔离”,不再使用。
上下文分心
定义: 当上下文过于庞大,模型过度关注累计历史信息而非训练中学到的内容,导致重复或无用行动。模型甚至可能在上下文窗口未满时就出错。
应对: 使用 上下文摘要 。定期将累计信息压缩为更短摘要,保留重要细节,移除冗余历史,帮助“重置”关注点。
旅行订票示例: 你们长时间讨论各个梦想旅行地,包括详细的两年前背包旅行回忆。当你最终请求 “帮我找下个月的廉价机票” 时,Agent 受旧而无关细节影响,不断询问背包装备或过去行程,忽视当前需求。
解决方案: 达到一定对话轮数或上下文过大时,Agent 应 总结最近且相关的对话部分 ——聚焦当前旅行日期与目的地,并用该凝练摘要作为下一次 LLM 调用的上下文,遗弃不相关历史对话。
上下文混淆
定义: 过多工具可用时,产生不必要上下文,导致模型生成错误回答或调用无关工具。小型模型尤为容易受影响。
应对: 实施 工具载入管理 ,利用 RAG 技术。将工具描述存储在向量数据库,针对具体任务只选择 最相关工具 。原文给出少于 30 个工具的经验建议,不能视为通用阈值;应通过具体模型与任务集验证。
旅行订票示例: Agent 可用数十个工具:book_flight、book_hotel、rent_car、find_tours、currency_converter、weather_forecast、restaurant_reservations 等。你问:“在巴黎怎样出行最好?”因工具过多,Agent 混淆尝试在巴黎境内调用 book_flight,或尽管你偏好公共交通却调用了 rent_car,原因可能是工具描述重叠或无法判断最佳工具。
解决方案: 对工具描述使用 RAG 策略 。询问巴黎出行时,系统动态检索 仅最相关工具 如 rent_car 或 public_transport_info,提供给 LLM 聚焦的工具列表。
上下文冲突
定义: 当上下文中存在矛盾信息,导致推理不一致或产生错误最终回答。常见于信息分阶段到达,早期错误假设留存上下文。
应对: 使用 上下文修剪 和 卸载 。修剪移除过时或冲突信息,卸载为模型提供单独“便签”工作空间,处理信息无须干扰主上下文。
旅行预订示例: 你最初告诉你的 Agent, “我想坐经济舱。” 后来在对话中,你改变主意说, “实际上,这次旅行,我们坐商务舱吧。” 如果两个指令都留在上下文中,Agent 可能会收到相互矛盾的搜索结果,或者不确定优先考虑哪个偏好。
解决方案: 实施 上下文剪枝 。当新指令与旧指令冲突时,较旧的指令会从上下文中移除或被明确覆盖。或者,Agent 可以使用 草稿本 先调和冲突的偏好后再做决定,确保只有最终、一致的指令指导其行动。
用一次退款问答理解信息选择(补充讲解)
输入问题“定制商品能退吗?”后,先保持系统策略和当前问题;检索时选入定制商品政策及一般规则;相关历史只保留“用户正在询问未发货订单”这类已确认信息;旧旅行聊天应移除。工具只提供查政策和查订单,不需要航班工具。
压缩不能丢掉否定与例外:“定制商品通常不接受无理由退货,质量问题另行处理”若摘要为“商品可退”,上下文反而被污染。摘要是新的派生资料,应记录来自哪些消息与生成时间,并允许查回原文。
原课程提出规划、上下文管理与检查、压缩、修剪、隔离、卸载,以及污染、干扰、混淆、冲突四类失败。可用的工程对应是:
| 策略 | 操作 | 保留的约束 |
|---|---|---|
| 选择 | 只加载当前任务需要的文档与工具 | 先做权限过滤,再做相关性排序 |
| 压缩 | 生成结构化摘要 | 保留来源、否定、例外、不确定性 |
| 卸载 | 原始结果放外部存储,窗口放引用 | 引用必须能重新读取且有权限 |
| 隔离 | 子任务使用独立工作上下文 | 交接只传经过验证的必要结果 |
| 修剪 | 移除已被覆盖的旧偏好 | 记录本次确认值及生效范围 |
“少于 30 个工具”是上游引用的经验方向, 不是适用于所有模型的硬阈值 。应在自己的工具描述、任务集和模型上比较选择准确率、延迟与输入成本。
代码实操:观察选入与落选(扩展实践)
本地最终项目用字符预算近似演示选择,不假装在计算模型 Token。Python 3.12+ 标准库,在根目录运行:
bash
python3 examples/assistant/app.py '定制商品能否退款?' --stage 3 --budget 700
python3 examples/assistant/app.py '定制商品能否退款?' --stage 3 --budget 0第一条应展示候选文档、实际选入上下文的 ID 和引用;第二条仍可能检索到候选,但上下文为空并说明缺少足够证据。 检索成功和有预算放入上下文是两次不同判断。
retrieval.py 的 select_context 按完整片段累计字符数,避免把半句例外截断;app.py 只依据已选片段回答。真实模型实验应换成该模型的 Token 计数方法,并为输出、系统指令和工具 schema 预留预算。字符数和 Token 数不存在对所有中文文本通用的固定比例。
常见失败与修复
- 污染: 引用的网页夹带“忽略规则”。保留为资料,不赋予执行权;工具层仍拒绝越权。
- 干扰: 长历史与当前问题无关。按任务筛选,摘要近期相关事实。
- 混淆: 工具命名相似且太多。改善描述与参数定义,按当前任务加载子集。
- 冲突: 旧“经济舱”和新“商务舱”并存。保存新确认值并注明旧值已覆盖;不要悄悄合并为虚假的偏好。
上下文调试记录文档 ID、片段数、Token/字符预算和版本即可起步。不要为了调试把整段含密钥的上下文写进公开日志。
自测与练习
给定 700 字预算,检索器返回 10 个相关片段。全部截成前 70 字是否合理?如果摘要错了,下一次检索还能补救吗?
参考答案
机械截断可能删除否定、例外与引用。应按相关性和完整信息单元选择,必要时用带来源的摘要。摘要错误必须能追溯原文并重新生成;若原文被删除且摘要被当作权威记忆,后续检索可能继续放大错误。练习可调低 --budget 并比较 candidates 与 context,确认不会引用未选入的片段。
上下文是“现在给模型看什么”;下一章记忆解决“哪些信息应该留到以后”。
原课程代码与补充材料
以下是本章实际源文件对应的阅读页。Notebook 已分解为说明、代码及原文件输出;云端示例未进行联网端到端验证。正文中的片段用于解释,运行时使用完整 Notebook 和准备篇的固定依赖。
本章来源
基于 英文原文 与 简体中文翻译 整理,原作者为 Microsoft 与开源贡献者,采用 MIT 许可证。本页标明“补充讲解”与“扩展实践”的内容为本项目新增。
来源提交:25b7985f3b2d · 获取日期:2026-09-14。参见版本校订记录。