Agent 上下文工程实战:System Prompt、Memory、Tools 和 Files 怎么分层

"Effective context engineering for AI agents"
团队把 40 条仓库规则全写进 system prompt,Agent 还是把临时日志当源码改。规则里有”只修改 src 目录下的文件”,有”不要碰 logs 目录”,有”删除前必须确认”,但到第 5 轮对话时,这些约束就像不存在一样。
这不是模型不够聪明,而是所有规则挤在一个层,互相稀释。上下文窗口有限,规则、资料、状态、记忆、工具输出混在一起,每轮对话都在抢 token 预算。
本文提供一套上下文分层决策框架:八个载体(System Prompt、Memory、Files、Tools、State、Trace、Output Contract、User Task),迁移规则决策树,以及可执行的工程审计清单。帮你从”规则堆砌”升级到”分层治理”。
第一章:从症状到根因——为什么规则写在 prompt 仍然被忘
1.1 团队真实案例:40 条规则写进 system prompt 仍然忘文件边界
某个代码审查 Agent 的 system prompt 里写了 40 条规则:只修改 src 目录、不碰 logs 和 tmp、删除前要用户确认、返回 JSON 格式、用英文注释、每次修改要写 commit message。
前 3 轮对话一切正常。第 4 轮用户问”帮我清理一下日志文件”,Agent 直接执行了 rm -rf logs/。第 5 轮用户说”这些临时测试文件可以删掉吗”,Agent 把 tmp 目录下的 12 个文件全删了,其中 3 个是正在用的测试 fixture。
团队复盘时发现,规则”只修改 src 目录”在 prompt 的第 17 行,“不要碰 logs”在第 23 行,“删除前确认”在第 31 行。这些约束在前几轮能遵守,但对话历史变长后,新的 tool output、检索到的文档片段、中间推理过程塞进上下文,原有规则被”稀释”了。
这不是模型突然变笨。Anthropic 的工程博客指出,上下文是有限资源,需要主动策划和管理,而不是把所有规则堆进去。
1.2 其他典型症状:工具误调用、记忆污染、状态丢失、上下文膨胀
工具误调用:工具描述只写 update_record: 更新记录,没写”何时不调用”。Agent 在用户只是查询信息时,也调用了更新工具,把只读数据改了。
记忆污染:第 2 轮 Agent 记住”用户偏好简短回答”,第 8 轮用户说”这次要详细解释”,但 Agent 还是简短输出。跨轮事实冲突,旧记忆没有更新机制。
状态丢失:Agent 在步骤 3(生成测试用例)时中断,重启后从步骤 1(分析需求)重新开始。任务进度没有持久化,runtime state 只存在当轮上下文里。
上下文膨胀:每轮对话都把历史 tool result、检索到的文档、中间推理塞进 context。第 10 轨时 token 数已经是第 1 轨的 4 倍,但回答质量没提升,反而因为噪音太多开始偏离目标。
这些症状指向同一个根因:上下文载体职责不清。
1.3 症状根因:上下文载体职责不清,所有规则挤在一个层
OpenAI Agents SDK 的官方文档里,instructions 字段不是唯一上下文载体。Agent 还会收到用户任务、对话历史、检索到的文档、工具定义、运行时状态、输出契约。
如果 40 条规则全塞在 system prompt,就会和用户任务、检索文档、工具输出挤在一起。每轮对话 token 预算有限(比如 128k),规则被其他内容稀释后,模型无法判断哪个约束优先级更高。
Redis 的技术博客用”竞争视角”描述这个问题:System instructions、Goal specification、Conversation memory、Tool results、Retrieved documents、Intermediate reasoning,六个输入都在抢上下文窗口。
真正的问题不是”模型记不住”,而是”你把规则放在了不适合的位置”。有些规则应该进 System Prompt(全局行为边界),有些应该进 Tool Description(调用时机约束),有些应该进 Memory(用户偏好),有些应该进 Files(可检索知识库)。
第二章:上下文分层框架——八个载体和六个竞争输入
2.1 八层上下文载体概览图
Agent 的上下文不是单一容器,而是八个职责不同的载体:
| 载体 | 职责 | 适用场景 |
|---|---|---|
| System/Developer Instructions | 角色、行为边界、输出契约 | 全局约束、角色定义、安全边界 |
| User Task | 当轮任务目标、用户输入 | 动态任务、查询请求 |
| Memory | 用户偏好、跨会话事实 | 短期记忆(会话内)、长期记忆(跨会话) |
| Retrieval/Files | 可检索文档、知识库 | API 文档、产品手册、代码仓库 |
| Tool Schema/Description | 工具功能、调用约束 | 工具调用时机、风险边界 |
| Runtime State | 任务进度、分支选择 | 步骤追踪、待审批动作 |
| Trace | 调用历史、审计日志 | 事后分析、评估复盘 |
| Output Contract | 输出格式、验证规则 | 结构化输出、下游依赖 |
OpenAI Agents SDK 把 instructions 定义为”Agent 的行为指南”,但不是唯一上下文来源。LangGraph 的 Persistence 层区分了 checkpointer(短期状态)和 store(长期记忆)。Anthropic 的工程博客强调,上下文需要分层选择、压缩、隔离和更新,而不是堆砌。
2.2 RAM vs Disk 类比
MachineLearningMastery 的开发者指南用硬件类比:上下文窗口像 RAM(快、贵、易失),外部存储像 Disk(慢、便宜、持久)。
RAM 不适合放”版本会变的知识库”。比如 API 文档的某个字段从 user_id 改成 userId,如果把旧版文档贴在 prompt 里,Agent 会用错误的字段名调用接口。这类内容应该进 file search,每次按需检索最新版本。
RAM 也不适合放”跨会话复用的用户偏好”。比如用户在第 1 次会话说”我喜欢简短回答”,第 5 次会话时这个偏好应该从长期记忆加载,而不是每次重新问用户。
RAM 适合放的是”当轮必须遵守的约束”:角色定义(你是代码审查助手)、安全边界(不要删除生产环境文件)、输出契约(返回 JSON 格式)。这些内容需要高带宽、即时生效,适合塞进 system prompt。
2.3 六个输入竞争上下文窗口
Redis 的技术博客列出六个输入竞争上下文窗口:
- System instructions — Agent 的行为指南、角色定义、安全边界
- Goal specification — 当轮任务目标、用户查询内容
- Conversation memory — 对话历史、会话内的上下文
- Tool results — 工具调用返回的结果、外部 API 响应
- Retrieved documents — 从 vector store 检索到的文档片段
- Intermediate reasoning — Agent 的思考过程、中间步骤
每个输入都在抢有限的 token 预算。如果 System instructions 写 2000 token(40 条规则),Goal specification 占 500 token,Conversation memory 累积到 3000 token(10 轨对话),Tool results 累积到 5000 token(多次调用),Retrieved documents 占 2000 token(检索 10 个片段),Intermediate reasoning 占 1000 token,总上下文已经 13500 token。
模型在这么多噪音里找”不要删除文件”这条规则,就像在 13 页文档里找一句话。如果规则在第 5 轮被稀释,不是因为模型忘,而是因为其他输入挤占了注意力。
第三章:System/Developer Instructions——角色定义与行为边界
3.1 Instructions 职责边界
System Prompt(或 OpenAI Agents SDK 的 instructions 字段)适合承载:
- 角色定义:你是代码审查助手、你是数据分析 Agent
- 行为边界:不要删除生产环境文件、不要调用未授权的 API
- 约束规则:每次修改前要用户确认、返回结果要包含来源链接
- 输出契约:返回 JSON 格式、输出必须包含 status 字段
不适合承载:
- 用户偏好:用户喜欢简短回答 — 应进 Memory
- 可检索文档:API 文档说明 — 应进 Files/Retrieval
- 工具调用细节:何时调用 update_record — 应进 Tool Description
- 运行时状态:已完成步骤 3 — 应进 Runtime State
OpenAI Agents SDK 的官方文档指出,instructions 不是唯一上下文载体。Agent 还会收到 tools schema、conversation history、retrieved documents。如果把所有规则塞进 instructions,其他载体的职责就被稀释。
3.2 Instructions 适用场景
System Prompt 适合放三类内容:
- 全局约束:安全边界(不要删除生产环境数据)、行为红线(不要调用外部 API)、一致性约束(所有输出用英文)
- 角色定义:Agent 的身份和能力边界(你是代码审查助手,只审查代码,不修改运行环境)
- 输出契约:输出格式(返回
{status, data, error}JSON)、输出验证(必须包含 status 字段)
不适合放的内容:
- 动态任务目标:用户当轮的查询请求 — 应进 User Task
- 用户偏好:用户上次说喜欢简短回答 — 应进 Long-term Memory
- 业务知识库:API 文档、产品手册 — 应进 Files/Retrieval
3.3 Instructions 易错点:规则堆砌
易错点一:规则越多越容易稀释。40 条规则写进 system prompt,模型无法判断哪条优先级更高。第 5 轮对话时,新内容(tool output、检索文档)挤占上下文,原有规则被”稀释”。
易错点二:规则冲突时模型无法判断优先级。Prompt 里既写”详细回答用户问题”,又写”保持简短”,模型无法判断何时该详细、何时该简短。
易错点三:规则跨轮次遗忘。文件边界规则在第 1-3 轮能遵守,第 5 轮后被忽略。Anthropic 的 cookbook 指出,长任务 Agent 需要在 memory、compaction、tool clearing 之间做取舍,而不是单纯堆砌规则。
第四章:Memory——短期记忆与长期记忆的边界
4.1 Memory 职责边界:短期 vs 长期
| 类型 | 职责 | 载体 | 易失性 |
|---|---|---|---|
| 短期记忆 | 当前会话历史 | messages 列表、checkpoints | 会话结束清除 |
| 长期记忆 | 用户偏好、跨会话事实 | memory store、vector store | 跨会话保留 |
LangGraph 的 Persistence 层把短期记忆定义为”线程状态”(thread state),通过 checkpointer 存储会话内的对话历史。长期记忆通过 store 存储用户偏好、跨会话事实,需要明确写入、读取和过期策略。
4.2 Memory 适用场景:何时该写入长期记忆
适合长期记忆的内容:
- 用户偏好:用户是素食者、用户喜欢简短回答、用户习惯用中文交流
- 跨会话事实:用户上次提到想迁移到 AWS、用户的项目用的是 TypeScript
- 程序记忆:该用户喜欢简短回答、该用户习惯先看代码再看解释
不适合长期记忆的内容:
- 当轮任务目标:用户当前的查询请求 — 应进 User Task
- 会话内的临时状态:当前任务进度 — 应进 Runtime State
Mem0 的博客把记忆分成三类:事实记忆(用户是素食者)、情景记忆(上周三聊过报价方案)、程序记忆(该用户喜欢简短回答)。三类记忆都需要明确写入、更新和过期策略。
4.3 Memory vs Files/Retrieval 辨析
问:memory 和 files/retrieval 有什么区别?
答:memory 适合保存用户偏好、跨会话事实和任务经验;files/retrieval 适合查找外部文档和知识库。
两者都需要明确写入、检索和过期策略。记忆没有治理(过期、更新)会导致污染:三年前的偏好仍然生效,跨轮事实冲突。文件检索没有策略会导致噪音:检索了无关文档,塞进上下文浪费 token。
4.4 Memory 易错点:记忆污染与过期缺失
易错点一:记忆污染。第 2 轮 Agent 记住”用户偏好简短回答”,第 8 轨用户说”这次要详细解释”,但 Agent 还是简短输出。旧记忆没有更新机制,跨轮事实冲突。
易错点二:过期缺失。三年前的偏好仍然生效,用户已经改成”喜欢详细回答”,但记忆没有过期策略,Agent 用旧偏好做决策。
易错点三:写入策略缺失。不知道什么时候该写记忆。每次对话都写,导致记忆膨胀;从不写记忆,导致用户偏好丢失。
LangGraph 的 add memory 文档指出,记忆需要明确写入路径、读取路径和更新路径。
4.5 Memory 内链指引
这里先限定 memory 在上下文分层中的边界。详细记忆类型(事实记忆/情景记忆/程序记忆)、存储方案(vector store vs relational DB)、记忆治理(写入/更新/过期策略),见站内文章 Agent 记忆系统设计:从会话到长期记忆。
第五章:Retrieval/Files——知识库检索与文件边界
5.1 Files/Retrieval 职责边界
Files/Retrieval 适合承载:
- 可检索文档:API 文档、产品手册、技术规范
- 版本会变的知识库:SDK 文档、框架版本说明
- 大体量资料:代码仓库、历史数据集
不适合承载:
- 永远必须遵守的规则:不要删除文件 — 应进 system prompt 或 tool schema
- 用户偏好:用户喜欢简短回答 — 应进 memory
- 当轮任务目标:用户当前的查询请求 — 应进 user task
OpenAI API 的 file search 文档指出,file search 适合检索知识库,不适合放行为规则。因为检索不保证遵守,模型可能检索后仍然忽略。
5.2 Files 适用场景:何时该用 file search
适合 file search 的内容:
- API 文档查询:OpenAI Agents SDK 的 tools 字段包含什么、LangGraph persistence 的推荐后端
- 产品手册检索:某个功能的使用说明、配置参数范围
- 代码仓库搜索:某个函数的实现细节、某个模块的依赖关系
不适合 file search 的内容:
- 全局行为规则:不要删除文件、不要调用未授权 API — 应进 system prompt
LangChain 的博客指出,文件系统可以作为上下文挂载点,但需要区分”检索”和”遵守”。检索到的内容不保证被模型遵守,仍需要 system prompt 或 tool schema 约束。
5.3 Files 易错点:把知识库当规则库
易错点一:知识库检索不保证遵守。规则”不要删除文件”放在知识库,Agent 检索后仍然删除。因为 file search 只提供信息,不约束行为。行为规则应该进 system prompt 或 tool schema。
易错点二:知识库不适合放”必须遵守”的约束。知识库适合放”可以参考”的资料(API 文档、产品手册),不适合放”必须遵守”的约束(安全边界、行为红线)。
5.4 Files 阈值:何时该贴进 prompt vs 用 file search
BuildingAgenticAI 的博客指出,上下文窗口是最高带宽记忆。短小(< 500 token)、稳定、必须当轮遵守的内容可以贴进 prompt。
阈值判断:
- 短小资料(< 500 token):3 行的 YAML 示例、5 个字段的 API schema → 贴进 prompt
- 长文档(> 500 token):50 页的 API 文档、完整代码仓库 → 用 file search
- 版本会变的内容:SDK 文档、框架版本说明 → 用 file search(每次检索最新版本)
- 必须当轮遵守的内容:当轮任务的约束、紧急安全边界 → 贴进 prompt
第六章:Tool Schema/Description——微型行为控制器
6.1 Tool Description 职责边界:微型行为控制器
Anthropic 的工程博客指出,工具描述不应只当 API 注释,而是微型行为控制器。
应该包含:
- 功能说明:update_record 的功能是什么
- 输入约束:哪些参数必填、哪些参数可选
- 调用时机:何时应该调用
- 不调用场景:何时不应该调用
- 风险边界:调用可能带来什么风险
- 返回结构:返回数据的格式、字段含义
不应该只写:
- 单纯的 API 注释:
update_record: 更新记录(缺少调用时机、风险边界) - 缺少调用时机:没写”何时不调用”
- 缺少风险警告:没写”只能在用户确认后调用”
6.2 Tool Description 结构要素
Anthropic 的工程博客列出工具描述的六要素:
- 功能:update_record 的功能是更新数据库记录
- 输入约束:id 和 data 字段必填,overwrite 字段可选
- 调用时机:用户明确要求更新数据时调用
- 不调用场景:用户只是查询信息时不调用,未授权时不调用
- 风险边界:只能在用户确认后调用,不能在未授权时修改生产环境数据
- 返回结构:返回
{status: "success", updated_id: string}
示例:工具 update_record 的描述应包含”只能在用户确认后调用,不能在未授权时修改生产环境数据”。
6.3 Tool Description 易错点:描述太简或太冗
易错点一:描述太简。只写 update_record: 更新记录,模型误调用。因为缺少”何时不调用”,Agent 在用户只是查询信息时也调用了更新工具。
易错点二:描述太冗。描述写 500 token,浪费上下文预算。六要素应该精简到 100-200 token。
易错点三:缺少风险边界。没写”只能在用户确认后调用”,Agent 直接修改了生产环境数据。
工具误调用不是因为模型笨,而是描述没写何时不调用。
6.4 Tool Description FAQ
问:tool description 应该写多详细?
答:应写清功能、输入约束、何时调用、何时不调用、风险边界和返回结构。不要把它当普通后端 API 注释,而是微型行为控制器。工具质量会直接影响 Agent 表现,Anthropic 的工程博客强调工具描述应被设计、评估和优化。
6.5 Tool Description 内链指引
这里先限定 tool description 在上下文分层中的边界。详细工具调用流程(定义、注册、调用、验证)、工具评估(误调用率、成功率)、工具治理(更新、废弃策略),见站内文章 Agent 工具调用实战。
第七章:Runtime State——任务进度与分支
7.1 Runtime State 职责边界:任务进度与分支
Runtime State 适合承载:
- 当前任务进度:已完成步骤 3、正在执行步骤 4
- 分支选择:用户选择了方案 A、用户拒绝了方案 B
- 待审批动作:等待用户确认删除、等待用户选择分支
不适合承载:
- 用户偏好:用户喜欢简短回答 — 应进 memory
- 全局规则:不要删除文件 — 应进 system prompt
LangGraph 的 Persistence 文档指出,runtime state 是线程状态的一部分。任务中断后应该可恢复,而不是从步骤 1 重新开始。
7.2 Runtime State vs Memory 辨析
问:runtime state 和 memory 有什么区别?
答:runtime state 是当前任务进度、分支选择、待审批动作;memory 是跨任务复用的信息。
状态应该可恢复:任务中断后能从断点继续。记忆应该可治理:有写入、更新、过期策略。
Aakashx 的博客指出,memory 是”跨任务复用的信息”,state 是”当前任务进度”。
7.3 Runtime State 易错点:状态丢失不可恢复
易错点一:状态丢失。Agent 在步骤 3(生成测试用例)时中断,重启后从步骤 1(分析需求)重新开始。任务进度没有持久化,runtime state 只存在当轮上下文里。
易错点二:状态污染。不同分支的状态混在一起。用户选择方案 A 和方案 B 的状态都塞进同一个 context,Agent 无法判断当前分支。
LangGraph 的 Persistence 文档指出,状态应该可恢复。使用 checkpointer 持久化线程状态,中断后能从断点继续。
第八章:Trace——调用历史与审计
8.1 Trace 职责边界:调用历史与审计
Trace 适合承载:
- 调用历史:调用了 update_record 工具、返回了 success 状态
- 审计日志:谁在何时批准了删除操作、谁在何时修改了配置
- 事后分析:为什么 Agent 选择了错误路径、哪个工具被误调用
不适合承载:
- 当轮决策输入:应进 conversation memory
- 用户偏好:应进 memory
AndriiFurmanets 的博客指出,trace-based evaluation 用于事后分析和评估,不是当轮决策输入。
8.2 Trace vs Conversation Memory 辨析
问:trace 和 conversation memory 有什么区别?
答:trace 是调用历史、审计日志,用于事后分析和评估;conversation memory 是会话内决策输入,用于当轮推理。
LangGraph 的 Persistence 文档指出,trace 是持久化的一部分,但不是上下文的必需内容。
8.3 Trace 易错点:把 trace 当决策输入
易错点一:trace 太长。所有历史调用塞进上下文,Agent 在第 10 轮时,上下文包含前 9 轨的所有调用历史,token 翻倍。
易错点二:trace 误用。把审计日志当决策输入,Agent 用历史调用结果做当轮决策,而不是用当轮的 user task 和 tool output。
Anthropic 的 cookbook 指出,tool clearing 策略可以减少历史 tool result 的噪音。只保留当轮必要的 tool output,历史调用结果移到 trace。
第九章:Output Contract——输出格式与约束
9.1 Output Contract 职责边界:格式与约束
Output Contract 适合承载:
- 输出格式:返回 JSON 格式
{status, data, error} - 输出约束:不要返回用户密码、不要返回敏感数据
- 输出验证规则:必须包含 status 字段、data 字段不能为 null
不适合承载:
- 用户偏好:用户喜欢简短回答 — 应进 memory
- 全局行为规则:不要删除文件 — 应进 system prompt
OpenAI Agents SDK 的官方文档指出,guardrails 包含输出契约。输出需要验证格式、约束和安全边界。
9.2 Output Contract 适用场景
Output Contract 适合三类场景:
- 结构化输出:返回
{status, data, error}JSON,下游 API 需要解析 - 安全约束:不要返回用户密码、不要返回敏感数据
- 下游依赖:输出必须符合下游 API 的 schema
9.3 Output Contract 易错点:契约缺失导致下游失败
易错点一:格式不一致。有时返回 JSON,有时返回文本。下游 API 无法解析,流程中断。
易错点二:缺少验证。Agent 返回了 XML 格式,但下游 API 只接受 JSON。契约没有验证,导致下游失败。
OpenAI Agents SDK 的 guardrails 文档指出,输出需要验证。不符合契约的输出应该拦截或重试。
第十章:迁移规则——如果一条规则反复被忘,该如何判断迁移到哪一层
10.1 迁移决策树
当一条规则反复被 Agent 忽略时,先判断它的类型,再迁移到适合的载体:
决策树分支:
-
行为规则?(不要删除文件、不要调用未授权 API)
- 是 → 迁移到 System Prompt(全局约束、安全边界)
-
用户偏好?(喜欢简短回答、习惯用中文交流)
- 是 → 迁移到 Long-term Memory(跨会话复用)
-
业务资料?(API 文档、产品手册、代码仓库)
- 是 → 迁移到 Files/Retrieval(按需检索)
-
工具约束?(何时调用 update_record、何时不调用)
- 是 → 迁移到 Tool Description(微型行为控制器)
-
运行状态?(已完成步骤 3、等待用户确认)
- 是 → 迁移到 Runtime State(任务进度追踪)
-
输出契约?(返回 JSON 格式、必须包含 status 字段)
- 是 → 迁移到 Output Contract(输出验证)
-
调用历史?(历史 tool result、审计日志)
- 是 → 迁移到 Trace(事后分析)
迁移的核心原则:不是”把规则换个地方”,而是”找到它应该驻留的载体”。每个载体有自己的职责边界、生命周期和治理策略。
10.2 迁移案例 1:从 System Prompt 迁移到 Tool Description
迁移前:
规则”只能在用户确认后修改生产环境数据”写在 system prompt 第 28 行。Agent 在第 5 轨时仍然直接修改了生产环境数据库,没有等待用户确认。
System prompt 有 40 条规则,包括文件边界、输出格式、角色定义、API 文档片段、用户偏好、工具约束。所有规则挤在一起,第 5 轨后互相稀释。
迁移后:
把”只能在用户确认后修改生产环境数据”迁移到工具 update_record 的 description:
{
"name": "update_record",
"description": "更新数据库记录。只能在用户明确确认后调用。不能在未授权时修改生产环境数据。调用前需要用户输入 '确认' 或 '批准'。",
"parameters": {...}
}
System prompt 减到 10 条核心规则:角色定义(你是代码审查助手)、安全边界(不要删除生产环境文件)、输出契约(返回 JSON 格式)。
对比:
| 维度 | 迁移前 | 迁移后 |
|---|---|---|
| System prompt 规则数量 | 40 条 | 10 条 |
| Tool description 详细度 | 只写功能 | 包含调用时机、不调用场景、风险边界 |
| 第 5 轮遵守率 | 被忽略 | 需要用户确认才调用 |
迁移后,Agent 在第 5 轮调用 update_record 时,tool description 明确要求”用户确认后调用”。如果没有用户确认,Agent 会先请求用户输入,而不是直接修改。
10.3 迁移案例 2:从 System Prompt 迁移到 Memory
迁移前:
规则”用户喜欢简短回答”写在 system prompt 第 35 行。但在不同会话中不一致:第 1 次会话用户说”喜欢简短回答”,第 5 次会话用户说”这次要详细解释”,system prompt 仍然写”简短回答”。
System prompt 把用户偏好当成全局规则,但用户偏好是动态的、跨会话的。
迁移后:
把”用户喜欢简短回答”迁移到长期记忆(memory store)。每次会话开始时,Agent 从 memory 加载用户偏好:
# 伪代码
memory = load_memory(user_id)
if "preference" in memory:
if memory["preference"] == "简短回答":
conversation_context.append("本次会话保持简短回答风格")
elif memory["preference"] == "详细解释":
conversation_context.append("本次会话提供详细解释")
记忆需要治理:用户在第 5 次会话说”这次要详细解释”时,更新 memory:
update_memory(user_id, {"preference": "详细解释"})
对比:
| 维度 | 迁移前 | 迁移后 |
|---|---|---|
| 用户偏好位置 | System prompt 第 35 行 | Long-term memory |
| 跨会话一致性 | 不一致(system prompt 写死) | 动态加载(memory 可更新) |
| 用户改变偏好后 | 仍用旧偏好 | 记忆更新后用新偏好 |
迁移后,用户偏好可以在不同会话中动态更新。记忆治理(过期、更新)确保三年前的偏好不会仍然生效。
10.4 迁移案例 3:从 System Prompt 迁移到 File Search
迁移前:
规则”OpenAI Agents SDK 的 tools 字段包含什么”的 API 文档片段贴在 system prompt 第 12-15 行。但 SDK 版本从 0.1 升到 0.3 后,字段名称从 tools 改成 tool_schema,system prompt 里的旧版文档仍然生效。
System prompt 把版本会变的 API 文档当成固定规则,导致 Agent 用错误字段名调用接口。
迁移后:
把 API 文档迁移到 vector store(file search)。每次查询时,Agent 检索最新版文档:
# 伪代码
query = "OpenAI Agents SDK 的 tools 字段包含什么"
results = file_search(query, vector_store_id="api_docs_v0.3")
System prompt 只写角色定义和安全边界,不写具体 API 文档片段。
对比:
| 维度 | 迁移前 | 迁移后 |
|---|---|---|
| API 文档位置 | System prompt 第 12-15 行 | Vector store (file search) |
| 版本更新后 | 旧版文档生效(字段名错误) | 检索最新版文档 |
| Token 占用 | 每轮都在 context(占用 200 token) | 按需检索(不占用常驻 token) |
迁移后,API 文档版本更新时只需更新 vector store,不需要修改 system prompt。知识库检索不保证遵守,仍需要 tool schema 约束调用格式。
10.5 迁移易错点:迁移后规则仍然被忘
易错点一:tool description 写太简。迁移后只写功能,没写调用时机、不调用场景、风险边界。规则仍然被忘。
易错点二:memory 没治理。迁移后记忆没有过期策略、更新策略。三年前的偏好仍然生效,跨轮事实冲突。
易错点三:file search 检索不保证遵守。迁移后规则放在知识库,Agent 检索后仍然忽略。因为 file search 只提供信息,不约束行为。仍需要 system prompt 或 tool schema 约束。
迁移只是第一步。各层都需要治理:system prompt 需要审计规则冲突,tool description 需要优化六要素,memory 需要过期更新策略,files 需要版本管理。
第十一章:工程审计清单——可执行的上下文分层审计
11.1 System Prompt 审计清单
审计 System Prompt 时,按以下步骤检查:
- 统计规则数量:超过 30 条 → 建议迁移。规则越多越容易稀释,需要分层。
- 检查规则冲突:如”详细回答” vs “简短回答”、“快速响应” vs “充分验证”。冲突规则需要明确优先级或迁移到不同载体。
- 检查规则类型:行为规则 vs 用户偏好 vs 业务资料。用户偏好应迁移到 memory,业务资料应迁移到 files。
- 检查易忘规则:第 5 轮后被忽略的规则。记录哪些规则易忘,判断迁移目标。
- 给出迁移建议:易忘规则迁移到 tool description 或 memory,业务资料迁移到 files。
11.2 Tool Description 审计清单
审计 Tool Description 时,按以下步骤检查:
- 检查描述长度:< 100 token → 太简(缺少调用时机、风险边界),> 500 token → 太冗(浪费上下文预算)。
- 检查六要素:功能、输入约束、调用时机、不调用场景、风险边界、返回结构。缺失要素需要补充。
- 检查误调用记录:哪些工具被误调用、何时误调用。误调用工具需要优化 description。
- 给出改进建议:太简的 description 补充调用时机和风险边界,太冗的 description 精简到 100-200 token。
11.3 Memory 系统审计清单
审计 Memory 系统时,按以下步骤检查:
- 检查记忆类型:短期记忆(会话内)vs 长期记忆(跨会话)。确保职责边界清晰。
- 检查写入策略:何时写入?谁写入?用户偏好、跨会话事实应该明确写入路径。
- 检查过期策略:多久过期?如何更新?三年前的偏好不应该仍然生效。
- 检查记忆污染:跨轮事实冲突。第 2 轮和第 8 轨的用户偏好不一致,需要更新机制。
- 给出治理建议:建立写入、更新、过期策略。使用 memory store 明确存储路径。
11.4 Files/Retrieval 审计清单
审计 Files/Retrieval 时,按以下步骤检查:
- 检查文件类型:文档(API 文档、产品手册)vs 规则(行为约束)。规则不适合放知识库。
- 检查检索时机:何时检索?检索什么?每次检索应该有明确 query 和 target。
- 检查文件更新:版本会变吗?如何更新?SDK 文档版本更新后,vector store 应同步更新。
- 检查检索结果:检索后遵守了吗?检索不保证遵守,需要 tool schema 约束。
- 给出改进建议:规则从知识库迁移到 system prompt 或 tool description,文档建立版本管理。
11.5 Runtime State 审计清单
审计 Runtime State 时,按以下步骤检查:
- 检查状态类型:任务进度(已完成步骤 3)/ 分支选择(用户选择方案 A)/ 待审批动作(等待确认删除)。
- 检查状态持久化:中断后可恢复吗?使用 checkpointer 持久化线程状态。
- 检查状态污染:不同分支混在一起吗?分支状态应该隔离,避免冲突。
- 给出改进建议:建立状态持久化机制,使用 LangGraph Persistence 或类似方案。
11.6 Output Contract 审计清单
审计 Output Contract 时,按以下步骤检查:
- 检查输出格式:JSON vs Text vs XML。下游 API 需要哪种格式?
- 检查输出验证:下游能解析吗?建立 guardrails 验证输出。
- 检查安全约束:是否返回敏感数据?用户密码、敏感配置不应出现在输出。
- 给出改进建议:建立输出验证机制,使用 OpenAI Agents SDK 的 guardrails 或类似方案。
11.7 Trace 审计清单
审计 Trace 时,按以下步骤检查:
- 检查 trace 长度:是否塞进上下文?历史 tool result 不应该常驻上下文。
- 检查 trace 用途:审计 vs 决策输入。trace 用于事后分析,不用于当轮推理。
- 检查 trace 清理:tool clearing 策略。历史 tool result 移到 trace,只保留当轮必要的 tool output。
- 给出改进建议:建立 tool clearing 策略,历史调用结果移到审计日志。
第十三章:下一步与延伸阅读
13.1 系列上游内链
本文是 AI Agent 工程化指南系列第 18 篇。上游文章 AI Agent 工程化 2026:从 LangGraph 到 OpenAI Agents SDK 怎么选 讲框架选型,本文承接后聚焦上下文分层。选型后需要设计上下文架构,避免规则堆砌。
13.2 深水页内链
这里先限定各载体在上下文分层中的边界。深入学习可参考:
- Agent 记忆系统设计:Agent 记忆系统设计:从会话到长期记忆 — 详细记忆类型(事实/情景/程序)、存储方案、治理策略
- Agent 工具调用实战:Agent 工具调用实战 — 工具调用流程、误调用率评估、工具治理
- DeepAgents 架构:DeepAgents 架构 — Planning Tools、File System、System Prompts 的上游概念
13.3 系列下一步
上下文分层后,后续系列文章会深入各层治理:
- 人工审批机制(HITL):《Agent 人工审批机制:何时引入人类介入》 — 某些动作需要人工审批,避免误操作
- 成本预算:《Agent 成本预算:Token 消耗与上下文预算规划》 — 每层都有 token 成本,需要预算规划
- 权限模型:《Agent 权限模型:工具权限、数据访问规则和租户隔离》 — 各层需要权限边界
- 状态机:《Agent 状态机:任务进度、分支选择和错误恢复》 — runtime state 需要状态机设计
- 评测数据集:《Agent 评测数据集:如何构建上下文分层评估基准》 — 各层有效性评测
- 上线清单:《Agent 上线清单:从原型到生产的上下文工程审计》 — 生产部署前的完整审计
结论
上下文工程不是把规则写进 prompt 就结束了,而是主动策划八个载体的职责边界、生命周期和治理策略。
核心框架:八个载体(System Prompt、Memory、Files、Tools、State、Trace、Output Contract、User Task),迁移规则决策树(从行为规则、用户偏好、业务资料、工具约束、运行状态、输出契约、调用历史七个分支判断目标载体),工程审计清单(七个载体各一个清单,每个清单 4-7 条检查项)。
行动建议:从 System Prompt 审计清单开始。统计当前规则数量,检查是否有规则冲突,判断哪些规则应该迁移到 Tool Description、Memory 或 Files。不要等到第 5 轮规则被忘才反思,提前分层治理。
拆分 Agent 上下文的步骤
把现有 prompt、memory、files、tools 和 state 拆成职责清晰的上下文载体,减少规则稀释和误调用。
⏱️ 预计耗时: 30 分钟
- 1
步骤 1: 列出所有规则和资料
先把 system prompt、开发者规则、用户任务说明、工具描述、检索资料和输出格式要求摊开,标出重复、冲突和易忘项。 - 2
步骤 2: 标注每条内容的类型
判断它是行为边界、用户偏好、业务资料、工具约束、运行状态、输出契约还是调用历史。 - 3
步骤 3: 迁移长期和外部信息
把跨会话偏好迁到 memory,把长文档和会变化的知识库迁到 retrieval 或 file search。 - 4
步骤 4: 收紧工具和状态边界
把工具调用时机、不调用场景和风险边界写进 tool schema/description,把任务进度和审批点放进 runtime state。 - 5
步骤 5: 用真实任务回归测试
拿多轮任务、误调用案例和中断恢复场景验证规则是否仍然生效,记录哪些层还需要治理。
常见问题
Agent 上下文工程是什么?
规则都写进 system prompt,为什么 Agent 还是会忘?
System prompt 和 memory 有什么区别?
文件资料应该放进 prompt 还是 file search?
Tool description 应该写什么?
Agent 规则经常失效怎么办?
31 分钟阅读 · 发布于: 2026年9月11日 · 修改于: 2026年9月11日
AI Agent 工程化专题:架构、工具调用、评估与恢复
如果你是从搜索进入这篇文章,建议顺手补上上一篇或继续下一篇,这样更容易把同一主题读完整。
上一篇
2026 AI Agent 工程化全景:从 LangGraph 到 OpenAI Agents SDK 怎么选
用状态管理、工具调用、HITL、guardrails、eval、可观测性和部署复杂度比较 LangGraph、OpenAI Agents SDK、AutoGen、CrewAI 与 Temporal,帮你从 Agent demo 进入生产选型。
第 17 / 22 篇
下一篇
Human-in-the-loop Agent 设计:哪些步骤必须人工审批
用风险分级设计 AI Agent 的人工审批点:哪些动作可以自动执行,哪些必须暂停等待确认,以及 approve/reject/resume、超时、补偿和审计记录怎么做。
第 19 / 22 篇



评论
使用 GitHub 账号登录后即可评论