切换主题

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

Easton editorial illustration: one central memory library linking recent notes to durable knowledge shelves
8
上下文载体
instructions、user task、memory、retrieval/files、tool schema、runtime state、trace、output contract。
6
竞争输入
system instructions、goal specification、conversation memory、tool results、retrieved documents、intermediate reasoning。
7
迁移判断分支
行为规则、用户偏好、业务资料、工具约束、运行状态、输出契约、调用历史。
6
工具描述要素
功能、输入约束、调用时机、不调用场景、风险边界、返回结构。
数据来源: 本文自定义上下文分层框架,基于阶段一官方文档调研整理

"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 的技术博客列出六个输入竞争上下文窗口:

  1. System instructions — Agent 的行为指南、角色定义、安全边界
  2. Goal specification — 当轮任务目标、用户查询内容
  3. Conversation memory — 对话历史、会话内的上下文
  4. Tool results — 工具调用返回的结果、外部 API 响应
  5. Retrieved documents — 从 vector store 检索到的文档片段
  6. 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 适合放三类内容:

  1. 全局约束:安全边界(不要删除生产环境数据)、行为红线(不要调用外部 API)、一致性约束(所有输出用英文)
  2. 角色定义:Agent 的身份和能力边界(你是代码审查助手,只审查代码,不修改运行环境)
  3. 输出契约:输出格式(返回 {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 适合检索知识库,不适合放行为规则。因为检索不保证遵守,模型可能检索后仍然忽略。

适合 file search 的内容:

  1. API 文档查询:OpenAI Agents SDK 的 tools 字段包含什么、LangGraph persistence 的推荐后端
  2. 产品手册检索:某个功能的使用说明、配置参数范围
  3. 代码仓库搜索:某个函数的实现细节、某个模块的依赖关系

不适合 file search 的内容:

  • 全局行为规则:不要删除文件、不要调用未授权 API — 应进 system prompt

LangChain 的博客指出,文件系统可以作为上下文挂载点,但需要区分”检索”和”遵守”。检索到的内容不保证被模型遵守,仍需要 system prompt 或 tool schema 约束。

5.3 Files 易错点:把知识库当规则库

易错点一:知识库检索不保证遵守。规则”不要删除文件”放在知识库,Agent 检索后仍然删除。因为 file search 只提供信息,不约束行为。行为规则应该进 system prompt 或 tool schema。

易错点二:知识库不适合放”必须遵守”的约束。知识库适合放”可以参考”的资料(API 文档、产品手册),不适合放”必须遵守”的约束(安全边界、行为红线)。

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 的工程博客列出工具描述的六要素:

  1. 功能:update_record 的功能是更新数据库记录
  2. 输入约束:id 和 data 字段必填,overwrite 字段可选
  3. 调用时机:用户明确要求更新数据时调用
  4. 不调用场景:用户只是查询信息时不调用,未授权时不调用
  5. 风险边界:只能在用户确认后调用,不能在未授权时修改生产环境数据
  6. 返回结构:返回 {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 适合三类场景:

  1. 结构化输出:返回 {status, data, error} JSON,下游 API 需要解析
  2. 安全约束:不要返回用户密码、不要返回敏感数据
  3. 下游依赖:输出必须符合下游 API 的 schema

9.3 Output Contract 易错点:契约缺失导致下游失败

易错点一:格式不一致。有时返回 JSON,有时返回文本。下游 API 无法解析,流程中断。

易错点二:缺少验证。Agent 返回了 XML 格式,但下游 API 只接受 JSON。契约没有验证,导致下游失败。

OpenAI Agents SDK 的 guardrails 文档指出,输出需要验证。不符合契约的输出应该拦截或重试。

第十章:迁移规则——如果一条规则反复被忘,该如何判断迁移到哪一层

10.1 迁移决策树

当一条规则反复被 Agent 忽略时,先判断它的类型,再迁移到适合的载体:

决策树分支

  1. 行为规则?(不要删除文件、不要调用未授权 API)

    • 是 → 迁移到 System Prompt(全局约束、安全边界)
  2. 用户偏好?(喜欢简短回答、习惯用中文交流)

    • 是 → 迁移到 Long-term Memory(跨会话复用)
  3. 业务资料?(API 文档、产品手册、代码仓库)

    • 是 → 迁移到 Files/Retrieval(按需检索)
  4. 工具约束?(何时调用 update_record、何时不调用)

    • 是 → 迁移到 Tool Description(微型行为控制器)
  5. 运行状态?(已完成步骤 3、等待用户确认)

    • 是 → 迁移到 Runtime State(任务进度追踪)
  6. 输出契约?(返回 JSON 格式、必须包含 status 字段)

    • 是 → 迁移到 Output Contract(输出验证)
  7. 调用历史?(历史 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 可更新)
用户改变偏好后仍用旧偏好记忆更新后用新偏好

迁移后,用户偏好可以在不同会话中动态更新。记忆治理(过期、更新)确保三年前的偏好不会仍然生效。

迁移前

规则”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 时,按以下步骤检查:

  1. 统计规则数量:超过 30 条 → 建议迁移。规则越多越容易稀释,需要分层。
  2. 检查规则冲突:如”详细回答” vs “简短回答”、“快速响应” vs “充分验证”。冲突规则需要明确优先级或迁移到不同载体。
  3. 检查规则类型:行为规则 vs 用户偏好 vs 业务资料。用户偏好应迁移到 memory,业务资料应迁移到 files。
  4. 检查易忘规则:第 5 轮后被忽略的规则。记录哪些规则易忘,判断迁移目标。
  5. 给出迁移建议:易忘规则迁移到 tool description 或 memory,业务资料迁移到 files。

11.2 Tool Description 审计清单

审计 Tool Description 时,按以下步骤检查:

  1. 检查描述长度:< 100 token → 太简(缺少调用时机、风险边界),> 500 token → 太冗(浪费上下文预算)。
  2. 检查六要素:功能、输入约束、调用时机、不调用场景、风险边界、返回结构。缺失要素需要补充。
  3. 检查误调用记录:哪些工具被误调用、何时误调用。误调用工具需要优化 description。
  4. 给出改进建议:太简的 description 补充调用时机和风险边界,太冗的 description 精简到 100-200 token。

11.3 Memory 系统审计清单

审计 Memory 系统时,按以下步骤检查:

  1. 检查记忆类型:短期记忆(会话内)vs 长期记忆(跨会话)。确保职责边界清晰。
  2. 检查写入策略:何时写入?谁写入?用户偏好、跨会话事实应该明确写入路径。
  3. 检查过期策略:多久过期?如何更新?三年前的偏好不应该仍然生效。
  4. 检查记忆污染:跨轮事实冲突。第 2 轮和第 8 轨的用户偏好不一致,需要更新机制。
  5. 给出治理建议:建立写入、更新、过期策略。使用 memory store 明确存储路径。

11.4 Files/Retrieval 审计清单

审计 Files/Retrieval 时,按以下步骤检查:

  1. 检查文件类型:文档(API 文档、产品手册)vs 规则(行为约束)。规则不适合放知识库。
  2. 检查检索时机:何时检索?检索什么?每次检索应该有明确 query 和 target。
  3. 检查文件更新:版本会变吗?如何更新?SDK 文档版本更新后,vector store 应同步更新。
  4. 检查检索结果:检索后遵守了吗?检索不保证遵守,需要 tool schema 约束。
  5. 给出改进建议:规则从知识库迁移到 system prompt 或 tool description,文档建立版本管理。

11.5 Runtime State 审计清单

审计 Runtime State 时,按以下步骤检查:

  1. 检查状态类型:任务进度(已完成步骤 3)/ 分支选择(用户选择方案 A)/ 待审批动作(等待确认删除)。
  2. 检查状态持久化:中断后可恢复吗?使用 checkpointer 持久化线程状态。
  3. 检查状态污染:不同分支混在一起吗?分支状态应该隔离,避免冲突。
  4. 给出改进建议:建立状态持久化机制,使用 LangGraph Persistence 或类似方案。

11.6 Output Contract 审计清单

审计 Output Contract 时,按以下步骤检查:

  1. 检查输出格式:JSON vs Text vs XML。下游 API 需要哪种格式?
  2. 检查输出验证:下游能解析吗?建立 guardrails 验证输出。
  3. 检查安全约束:是否返回敏感数据?用户密码、敏感配置不应出现在输出。
  4. 给出改进建议:建立输出验证机制,使用 OpenAI Agents SDK 的 guardrails 或类似方案。

11.7 Trace 审计清单

审计 Trace 时,按以下步骤检查:

  1. 检查 trace 长度:是否塞进上下文?历史 tool result 不应该常驻上下文。
  2. 检查 trace 用途:审计 vs 决策输入。trace 用于事后分析,不用于当轮推理。
  3. 检查 trace 清理:tool clearing 策略。历史 tool result 移到 trace,只保留当轮必要的 tool output。
  4. 给出改进建议:建立 tool clearing 策略,历史调用结果移到审计日志。

第十三章:下一步与延伸阅读

13.1 系列上游内链

本文是 AI Agent 工程化指南系列第 18 篇。上游文章 AI Agent 工程化 2026:从 LangGraph 到 OpenAI Agents SDK 怎么选 讲框架选型,本文承接后聚焦上下文分层。选型后需要设计上下文架构,避免规则堆砌。

13.2 深水页内链

这里先限定各载体在上下文分层中的边界。深入学习可参考:

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

    步骤 1: 列出所有规则和资料

    先把 system prompt、开发者规则、用户任务说明、工具描述、检索资料和输出格式要求摊开,标出重复、冲突和易忘项。
  2. 2

    步骤 2: 标注每条内容的类型

    判断它是行为边界、用户偏好、业务资料、工具约束、运行状态、输出契约还是调用历史。
  3. 3

    步骤 3: 迁移长期和外部信息

    把跨会话偏好迁到 memory,把长文档和会变化的知识库迁到 retrieval 或 file search。
  4. 4

    步骤 4: 收紧工具和状态边界

    把工具调用时机、不调用场景和风险边界写进 tool schema/description,把任务进度和审批点放进 runtime state。
  5. 5

    步骤 5: 用真实任务回归测试

    拿多轮任务、误调用案例和中断恢复场景验证规则是否仍然生效,记录哪些层还需要治理。

常见问题

Agent 上下文工程是什么?
Agent 上下文工程是把模型可见的信息按职责分层管理,包括 prompt、memory、retrieval、tool schema、runtime state、trace 和输出契约,而不是简单增加 prompt 长度。
规则都写进 system prompt,为什么 Agent 还是会忘?
因为 prompt 不是唯一上下文载体,也不是状态机或权限系统。长期规则、当前任务、文件资料、工具约束和运行状态混在一起,会互相稀释。
System prompt 和 memory 有什么区别?
System prompt 约束当次运行的稳定行为边界;memory 保存可跨会话复用的偏好、事实和经验。长期信息不应全部塞进 system prompt。
文件资料应该放进 prompt 还是 file search?
短小、稳定且必须当轮遵守的资料可以进 prompt;长文档、版本会变的知识库和可检索资料更适合 file search 或 retrieval。
Tool description 应该写什么?
Tool description 应写清工具用途、输入约束、适用场景、禁用场景、风险边界和返回结构,帮助模型判断何时调用以及何时不能调用。
Agent 规则经常失效怎么办?
不要只加长 prompt。先把规则分类:行为边界进 instructions,工具约束进 schema,业务资料进 retrieval,任务进度进 state,输出格式进 output contract。

31 分钟阅读 · 发布于: 2026年9月11日 · 修改于: 2026年9月11日

评论

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

Easton BlogEaston Blog