第 7 章 AI AgentAgentic Patterns上下文

第 7 章 上下文最小化:别让脏东西留在脑子里

装得下还不够,还得干净

上一章讲"怎么装得下"。这一章讲一个更容易被忽略、但同样致命的问题:装进去的东西,干不干净?

想象你让 Agent 处理用户输入。用户可能是普通人,也可能是心怀恶意的攻击者——他们会在输入里藏指令,试图操纵 Agent(这就是 prompt injection,提示词注入)。

更隐蔽的问题是:就算输入一开始是干净的,它在上下文里待得太久也会变脏。Agent 处理完某段用户文本,本该把它忘掉,但它还留在上下文里。下一轮做无关任务时,这段旧文本里的恶意指令(或只是噪音)仍然在"暗中影响"模型的推理。

这一章讲三个模式,核心都是"让上下文保持干净、精简":

  1. Context Minimization(上下文最小化):用过的不可信内容,立刻从上下文里清掉。
  2. Dynamic Context Injection(动态上下文注入):需要时才注入,而不是常驻。
  3. Session-Scoped Context Runtime(会话级上下文运行时):用一个运行时层管理上下文,读写走缓存,避免重复粘贴。

模式一:上下文最小化(Context Minimization)

问题

在长会话里,原始的用户文本和工具输出,经常在它们早就用完之后还留在上下文里。如果这些 token 里藏着对抗性指令,它们会在几轮之后"悄悄激活"——即使当前这一步和它们完全无关。这就造成了延迟的提示词注入风险,外加不必要的上下文膨胀。

方案

用过即焚:一旦某段不可信内容完成了它的使命,就把它们从上下文里清除或脱敏

典型的流程:

  1. 把不可信的输入转成一个安全的中间形式(比如把用户自然语言转成一个结构化的查询、一个对象)。
  2. 把原始 prompt 从上下文里删掉
  3. 之后的推理只看到可信数据,潜伏的注入指令就失去了作用。

更激进的做法是:连中间产生的 LLM 输出也一起清掉(如果它们可能被污染过)。

把上下文当成一条分阶段的流水线:摄入不可信文本 → 转换 → 激进地丢弃原始污染材料 → 只留下已经"签字确认"的结构化产物给下游使用。

sql = LLM("把这句话转成SQL", 用户提示词)
清除(用户提示词)              # 污染token 消失
行 = 数据库.查询(sql)
答案 = LLM("总结这些行", 行)

证据

  • 来自学术论文(Luca Beurer-Kellner 等人,2025),和 Plan-Then-Execute 同源。
  • 这是对抗 prompt injection 的核心策略之一:让攻击面越小越好

怎么用

  • 凡是"用户输入或工具输出会进入上下文"的 Agent,都该考虑。
  • 转换动作要发生在摄入之后、使用之前,转换完立刻清原。
  • 判断哪些内容"可能被污染"要有标准——宁可多清,不可留着。

取舍

  • 好处:消除延迟注入风险;上下文更精简。
  • 代价:需要设计"安全的中间形式";如果转换丢了信息,后续就没法用了。

模式二:动态上下文注入(Dynamic Context Injection)

问题

有些 Agent 把上下文全放在"分层配置文件"里(第 5 章讲过),但真实工作流里,Agent 常常临时需要某个特定信息:某个文件的内容、某个脚本的输出、某段常用的复杂指令。如果每次都去改配置文件、或者往 prompt 里手动粘一大段文本,又慢又笨。

方案

给用户提供在会话中动态注入上下文的机制。两个最经典的实现:

1. 文件/文件夹 @ 提及

用户输入一个特殊字符(比如 @)加上文件或文件夹路径,Agent 就把该文件内容(或该文件夹的摘要)读进来,注入当前上下文。

用户: 帮我改一下这个按钮的样式 @src/components/Button.tsx
Agent: (读取 Button.tsx,注入上下文)好的,我看到这个按钮组件了...

2. 自定义斜杠命令

用户可以把常用的复杂指令或上下文片段存成单独文件,用斜杠命令一键加载。比如 ~/.claude/commands/deploy.md 里存了部署检查清单,输入 /deploy 就把它注入上下文。

这样,上下文是按需、精准加载的,而不是一上来就全塞进去。这也是 Claude Code 这类工具的标配交互方式。

证据

  • 来自 Boris Cherny(Claude Code 相关实践),状态 established(成熟)。
  • 几乎所有主流编码 Agent 工具(Claude Code、Cursor 等)都实现了 @ 提及或斜杠命令。

怎么用

  • 给 Agent 工具设计交互时,加上 @ 提及和斜杠命令。
  • 常用复杂指令固化成命令文件,团队共享(配合第 9 章的技能库)。
  • 和上一章的"精选窗口"配合:动态注入是"用户主动触发"的精选。

取舍

  • 好处:上下文按需加载,精简高效;用户体验流畅。
  • 代价:需要实现注入机制;依赖用户知道"该 @ 什么"。

模式三:会话级上下文运行时(Session-Scoped Context Runtime)

问题

编码 Agent 有个常见的浪费:同一个文件、同一个命令输出,一个会话里要被读很多次。每一次读取,都把完整文本粘进模型上下文——哪怕那个文件根本没变过。成本和延迟就随着"重复 + 啰嗦"一起涨。

方案

在 Agent 旁边放一个上下文运行时(context runtime,通常是一个 MCP server),专门负责"工作区的状态如何进入模型":

  1. 会话级缓存:对读操作做缓存,用便宜的校验方式(比如文件修改时间)确认没变过。相同的内容,第二次读就命中缓存,不再发完整内容。

  2. 结构化读取模式:提供多种"瘦身"读取方式——依赖图谱、函数签名、diff、按任务过滤的摘录。Agent 请求恰好支持下一步决策的最小表示,而不是整个文件。

  3. 归一化的工具通道:shell 和搜索结果经过压缩适配器(对稳定的格式,比如常见的 git、包管理器输出,做模式化压缩)。

运行时夹在 IDE/宿主和模型之间:工具先调它,它返回紧凑的、带类型的上下文,并记录"这个 session 里哪些内容已经在缓存里了"。

on_读取(路径, 模式):
    if 缓存有效(路径): 返回 缓存项(路径, 模式)
    解析结果 = 加载并解析(路径)
    投影 = 投影(解析结果, 模式)   # 依赖图谱 | 签名 | diff | ...
    存缓存(路径, 模式, 投影)
    返回 投影

证据

  • 来自 Lean-ctx 等项目实践,基于 Anthropic 的 MCP 规范。
  • 状态偏 emerging,但思路(缓存 + 结构化读取)在系统设计里是成熟套路。

怎么用

  • 编码类 Agent、或任何"反复读同一批文件/命令输出"的场景。
  • 把读、搜、shell、目录树操作都统一走运行时,让路由一致。
  • 缓存校验要便宜(mtime 就够),别让"检查缓存"本身变成开销。

取舍

  • 好处:重复内容不再重复花钱;上下文紧凑;延迟下降。
  • 代价:多一层基础设施(一个运行时/MCP server);投影逻辑要维护。

三个模式怎么选

场景 推荐模式
用户/工具输入可能带注入,且会滞留 上下文最小化(必做)
需要交互式、按需给 Agent 喂信息 动态上下文注入
同一个文件/输出反复读 会话级上下文运行时

三个模式角度不同:最小化管"干净",动态注入管"按需",运行时管"去重"。它们和上一章的"压缩与精选"一起,构成完整的上下文管理体系。

实践清单

  • 不可信输入转成安全中间形式后,立刻清除原始内容
  • 判断"可能被污染"的标准要明确,宁可多清
  • 工具交互加上 @ 提及和斜杠命令,按需注入
  • 常用复杂指令固化成命令文件,团队共享
  • 反复读的文件/输出,加会话级缓存(用 mtime 校验)
  • 提供结构化读取模式(签名、diff、摘要),别让 Agent 读全文
  • 自问:Agent 上下文里,还有多少内容是"早该删掉"的?

本章小结

  • 上下文最小化:用过即焚,把污染材料和噪音从上下文里清掉。
  • 动态上下文注入:需要时才注入,@ 提及 + 斜杠命令。
  • 会话级上下文运行时:缓存读写结果,结构化读取,去重去冗余。
  • 装得下(第 6 章) + 装干净(本章)= 健康的上下文。

下一章,我们讲记忆体系——让 Agent 不只是"记得住这个会话",而是"记得住过去很多会话"。

📑 Agent 模式实战:生产级 AI Agent 的工程模式

1 第 1 章 什么是 Agent 模式 2 第 2 章 规划-执行-观察:先想清楚,再动手 3 第 3 章 反思闭环:让 Agent 学会检查自己的作业 4 第 4 章 委派:让主 Agent 学会把活分出去 5 第 5 章 上下文预算治理:把 token 当成钱来管 6 第 6 章 上下文压缩与精选:装不下怎么办 7 第 7 章 上下文最小化:别让脏东西留在脑子里 8 第 8 章 记忆体系:让 Agent 记得住过去 9 第 9 章 学习沉淀:让 Agent 和团队一起变聪明 10 第 10 章 工具接口哲学:让 Agent 能用、好用、用得起 11 第 11 章 工具发现:让 Agent 在几百个工具里找到对的 12 第 12 章 执行环境:Agent 在哪动手、怎么动手 13 第 13 章 代码执行与沙箱:先写码,再跑码 14 第 14 章 结构化输出与契约:让 Agent 的输出能接住 15 第 15 章 验证循环:Agent 怎么检查自己的作业 16 第 16 章 评测基建:怎么系统地检验 Agent 17 第 17 章 可观测性:看见 Agent 在想什么、在干嘛 18 第 18 章 韧性工程:扛得住部分失效 19 第 19 章 威胁模型:先看风险长什么样,再谈防御 20 第 20 章 控制流隔离:把"谁做决定"和"谁执行"分开 21 第 21 章 权限与审批:谁有权干什么、谁点头 22 第 22 章 凭据与出口:Agent 手里的钥匙和门 23 第 23 章 多智能体信任:多个 Agent 之间怎么互信、怎么审计 24 第 24 章 反馈信号设计:给 Agent 的是信号,不是更大的提示词 25 第 25 章 评测驱动的改进:让 Agent 在真实使用和对抗测试里变强 26 第 26 章 强化学习:把反馈变成训练信号 27 第 27 章 复合式进化:让 Agent 系统越用越值钱 28 第 28 章 多智能体协调:让一群 Agent 一起干活不掉链子 29 第 29 章 模型路由:谁用哪个模型,怎么用得起 30 第 30 章 推理搜索结构:让 Agent 多想想,而不是一条道走到黑 31 第 31 章 控制谱系:从自动补全到完全自主的滑动条 32 第 32 章 团队与产品:把 Agent 变成团队资产,而不是个人玩具
← 返回本书大纲