# AI 代理的上下文工程

[![上下文工程](../../../translated_images/zh-CN/lesson-12-thumbnail.ed19c94463e774d4.webp)](https://youtu.be/F5zqRV7gEag)

> _(点击上方图像观看本课视频)_

理解你正在为其构建 AI 代理的应用复杂性，对于打造一个可靠的代理非常重要。我们需要构建能够有效管理信息的 AI 代理，以满足超越提示工程的复杂需求。

在本课中，我们将探讨什么是上下文工程及其在构建 AI 代理中的作用。

## 介绍

本课内容包括：

• <strong>什么是上下文工程</strong> 以及它为何不同于提示工程。

• <strong>有效上下文工程的策略</strong>，包括如何编写、选择、压缩和隔离信息。

• <strong>常见的上下文失败</strong>，可能导致你的 AI 代理失效的情况以及如何修复。

## 学习目标

完成本课后，你将能够理解并掌握：

• <strong>定义上下文工程</strong> 并区别于提示工程。

• **识别大型语言模型（LLM）应用中的关键上下文组成部分**。

• **应用编写、选择、压缩和隔离上下文的策略**，以提升代理性能。

• <strong>识别常见的上下文失败</strong>，如中毒、分心、混淆和冲突，并实施缓解技术。

## 什么是上下文工程？

对于 AI 代理而言，上下文驱动着代理制定采取某些行动的计划。上下文工程是确保 AI 代理拥有完成任务下一步所需正确信息的实践。上下文窗口大小有限，因此作为代理构建者，我们需要构建系统和流程来管理上下文窗口中信息的添加、删除和压缩。

### 提示工程与上下文工程的区别

提示工程专注于一组静态指令，有效地用规则引导 AI 代理。上下文工程则是管理包含初始提示在内的动态信息集合，确保 AI 代理随着时间推移拥有所需信息。上下文工程的核心是使该过程可重复且可靠。

### 上下文类型

[![上下文类型](../../../translated_images/zh-CN/context-types.fc10b8927ee43f06.webp)](https://youtu.be/F5zqRV7gEag)

重要的是要记住，上下文不只是单一内容。AI 代理所需的信息可能来自各种不同来源，我们需确保代理能够访问这些来源：

AI 代理可能需要管理的上下文类型包括：

• **指令：** 类似于代理的“规则”——提示、系统消息、少量示例（示范 AI 如何做某事）以及代理可用工具的描述。这是提示工程与上下文工程的结合点。

• **知识：** 涵盖事实、从数据库检索的信息或代理累计的长期记忆。若代理需访问不同知识库和数据库，则包含整合检索增强生成（RAG）系统。

• **工具：** 代理可调用的外部函数、API 和 MCP 服务器的定义，以及使用工具后反馈（结果）。

• **对话历史：** 与用户的持续对话。随着时间推移，这些对话变得越来越长、复杂，占据上下文窗口空间。

• **用户偏好：** 随时间学习到的用户喜好或厌恶信息。可存储并在关键决策时调用，帮助用户。

## 有效上下文工程的策略

### 规划策略

[![上下文工程最佳实践](../../../translated_images/zh-CN/best-practices.f4170873dc554f58.webp)](https://youtu.be/F5zqRV7gEag)

良好的上下文工程始于良好的规划。下面的方法助你开始思考如何应用上下文工程概念：

1. <strong>定义明确的结果</strong> - 应清晰定义 AI 代理将分配的任务结果。回答问题——“当 AI 代理完成任务时世界将是什么样子？”换言之，用户与 AI 代理交互后应获得什么变化、信息或回应。
2. <strong>绘制上下文图谱</strong> - 定义任务结果后，需要回答“AI 代理完成该任务需要哪些信息？”基于此开始定位这些信息所在的上下文。
3. <strong>创建上下文流水线</strong> - 确定信息位置后，需回答“代理如何获取这些信息？”可采用多种方式，包括 RAG、使用 MCP 服务器及其它工具。

### 实用策略

规划很重要，但当信息开始流入代理的上下文窗口时，我们需要实用策略加以管理：

#### 管理上下文

虽然部分信息会自动加入上下文窗口，但上下文工程更主动，具体可采用以下几种策略：

 1. **代理便签（Agent Scratchpad）**
 允许 AI 代理在单次会话中记笔记，记录当前任务和用户交互的相关信息。便签应存于上下文窗口外的文件或运行时对象中，代理可在会话中需要时检索。

 2. **记忆（Memories）**
 便签用来管理单次会话上下文窗口之外的信息，记忆则支持跨多次会话存储和检索相关信息，包括摘要、用户偏好及改进反馈。

 3. <strong>压缩上下文</strong>
  当上下文窗口增长接近极限时，可使用摘要和裁剪等技术，包括仅保留最相关信息或删除较旧消息。
  
 4. <strong>多代理系统</strong>
  开发多代理系统也是一种上下文工程，因为每个代理有自己的上下文窗口。应规划如何共享和传递上下文给不同代理。
  
 5. <strong>沙箱环境</strong>
  若代理需运行代码或处理大量文档信息，这可能消耗大量令牌。代理可利用沙箱环境执行代码，仅将结果及相关信息读入上下文窗口。
  
 6. <strong>运行时状态对象</strong>
   创建信息容器，管理代理需要访问特定信息的场景。针对复杂任务，允许代理逐步存储各子任务结果，使上下文仅关联该子任务。

#### 检查上下文

应用策略后，值得检查下一次模型调用实际收到的内容。有用的调试问题：

> 代理加载了过多上下文、错误上下文，还是缺少所需上下文？

不必记录原始提示、工具输出或记忆内容。生产环境优选包含计数、ID、哈希及策略标签的小型上下文检查记录：

- **选择：** 跟踪考虑了多少候选块、工具或记忆，选择了多少，及哪些规则或得分导致其他被过滤。
- **压缩：** 记录源范围或追踪 ID、摘要 ID、压缩前后估计令牌数，及是否排除原始内容。
- **隔离：** 记录哪些子任务在独立代理、会话或沙箱中运行，返回了什么边界摘要，以及大型工具输出是否留在父代理上下文之外。
- **记忆与 RAG：** 存储检索文档 ID、记忆 ID、分数、选中 ID 及编辑状态，不存储完整检索文本。
- **安全和隐私：** 使用哈希、ID、令牌桶及策略标签，避免敏感提示文本、工具参数、工具结果或用户记忆正文。

目标不是保留更多上下文，而是留下足够证据，让开发者判断使用了哪种上下文策略及其是否按预期影响模型调用。

### 上下文工程示例

假设我们想让 AI 代理 **“帮我订一趟去巴黎的行程。”**

• 仅使用提示工程的简单代理可能直接回应：**“好的，您想什么时候去巴黎？”** 它仅处理用户当时直接提问的问题。

• 采用本课提到的上下文工程策略的代理，会做更多工作。在回应前，其系统可能：

  ◦ <strong>检查您的日历</strong> ，查找空闲日期（实时数据检索）。

 ◦ <strong>回忆过去的旅行偏好</strong> （来自长期记忆），比如您偏好的航空公司、预算或是否喜欢直飞。

 ◦ <strong>识别可用工具</strong> ，如航班和酒店预订。

- 然后，示例回应可能是：“嗨，[您的名字]！我看到您十月第一周有空。要帮您找[偏好航空公司]的直飞巴黎航班，预算控制在[预算]内吗？”这种更丰富、具上下文感知的回应展现了上下文工程的威力。

## 常见上下文失败

### 上下文中毒

**定义：** 当幻觉（LLM 生成的虚假信息）或错误进入上下文并反复被引用，导致代理追求不可能目标或形成荒谬策略。

**应对：** 实施 <strong>上下文验证</strong> 和 <strong>隔离</strong>。信息加入长期记忆前进行验证。若检测到潜在中毒，开启新的上下文线程，防止错误信息扩散。

**旅行订票示例：** 代理错误生成了一个“从一个小地方机场直飞远国际城市”的航班，实际上该机场不提供国际航班。此不存在的飞行信息存入上下文。后续订票时，代理持续尝试找这条不可能航线，导致反复错误。

**解决方案：** 在将航班信息添加到工作上下文前，使用实时 API 验证航班和航线是否存在。验证失败的错误信息被“隔离”，不再使用。

### 上下文分心

**定义：** 当上下文过于庞大，模型过度关注累计历史信息而非训练中学到的内容，导致重复或无用行动。模型甚至可能在上下文窗口未满时就出错。

**应对：** 使用 <strong>上下文摘要</strong>。定期将累计信息压缩为更短摘要，保留重要细节，移除冗余历史，帮助“重置”关注点。

**旅行订票示例：** 你们长时间讨论各个梦想旅行地，包括详细的两年前背包旅行回忆。当你最终请求<strong>“帮我找下个月的廉价机票”</strong>时，代理受旧而无关细节影响，不断询问背包装备或过去行程，忽视当前需求。

**解决方案：** 达到一定对话轮数或上下文过大时，代理应<strong>总结最近且相关的对话部分</strong>——聚焦当前旅行日期与目的地，并用该凝练摘要作为下一次 LLM 调用的上下文，遗弃不相关历史对话。

### 上下文混淆

**定义：** 过多工具可用时，产生不必要上下文，导致模型生成错误回答或调用无关工具。小型模型尤为容易受影响。

**应对：** 实施 <strong>工具载入管理</strong>，利用 RAG 技术。将工具描述存储在向量数据库，针对具体任务只选择<strong>最相关工具</strong>。研究表明限制工具少于 30 个更有效。

**旅行订票示例：** 代理可用数十个工具：`book_flight`、`book_hotel`、`rent_car`、`find_tours`、`currency_converter`、`weather_forecast`、`restaurant_reservations` 等。你问：“在巴黎怎样出行最好？”因工具过多，代理混淆尝试在巴黎境内调用 `book_flight`，或尽管你偏好公共交通却调用了 `rent_car`，原因可能是工具描述重叠或无法判断最佳工具。

**解决方案：** 对工具描述使用 **RAG 策略**。询问巴黎出行时，系统动态检索<strong>仅最相关工具</strong>如 `rent_car` 或 `public_transport_info`，提供给 LLM 聚焦的工具列表。

### 上下文冲突

**定义：** 当上下文中存在矛盾信息，导致推理不一致或产生错误最终回答。常见于信息分阶段到达，早期错误假设留存上下文。

**应对：** 使用 <strong>上下文修剪</strong> 和 <strong>卸载</strong>。修剪移除过时或冲突信息，卸载为模型提供单独“便签”工作空间，处理信息无须干扰主上下文。


**旅行预订示例：** 你最初告诉你的代理，**“我想坐经济舱。”** 后来在对话中，你改变主意说，**“实际上，这次旅行，我们坐商务舱吧。”** 如果两个指令都留在上下文中，代理可能会收到相互矛盾的搜索结果，或者不确定优先考虑哪个偏好。

**解决方案：** 实施<strong>上下文剪枝</strong>。当新指令与旧指令冲突时，较旧的指令会从上下文中移除或被明确覆盖。或者，代理可以使用<strong>草稿本</strong>先调和冲突的偏好后再做决定，确保只有最终、一致的指令指导其行动。

## 对上下文工程有更多疑问？

加入[Microsoft Foundry Discord](https://discord.com/invite/ATgtXmAS5D)，与其他学习者见面，参与答疑时间，解决你的 AI 代理相关问题。
## 上一课

[Agentic Protocols](../11-agentic-protocols/README.md)

## 下一课

[Memory for AI Agents](../13-agent-memory/README.md)

---

<!-- CO-OP TRANSLATOR DISCLAIMER START -->
**免责声明**：
本文件由 AI 翻译服务 [Co-op Translator](https://github.com/Azure/co-op-translator) 翻译完成。尽管我们力求准确，但请注意，自动翻译可能包含错误或不准确之处。原始语言版文件应视为权威来源。对于重要信息，建议使用专业人工翻译。我们对因使用本翻译而产生的任何误解或误释不承担责任。
<!-- CO-OP TRANSLATOR DISCLAIMER END -->