Appearance
Context Engineering:决定 Agent 依据什么事实行动
系列第 06 篇
核心问题:正确的信息怎样在正确时机进入、使用、验证和退出上下文
最后核验:2026-07-20
对应视频:第 03 集(上)《Context Engineering 实战:让 Agent 读到正确的信息》
Prompt Engineering 关注“这一轮怎样表达”,Context Engineering 关注“整个执行系统在每一步能看到什么、能调用什么、怎样判断信息仍然有效”。对于只回答一次问题的 Chat,Prompt 可能是主要输入;对于持续搜索、编辑和运行命令的 Agent,仓库规则、检索结果、工具说明、历史压缩和测试反馈共同组成决策环境。
很多看似模型能力不足的问题,其实是上下文问题:Agent 没读到真正实现;读了太多无关代码;长日志挤掉了非目标;旧计划与新代码冲突;MCP 返回中的文本被误当成指令;会话压缩保留了结论却丢失例外。
阅读路线:先看全局,再进入机制
视频版先展示整章地图,再逐层展开。博客沿用同一判断顺序,但保留更多机制、案例、失败模式和生产边界:
- 工作集:区分任务、仓库、代码、工具和反馈五层上下文。
- 检索与压缩:按决策需要渐进加载,控制长日志和历史压缩的损失。
- 污染与调试:从权威性、相关性、时效性和冲突定位首次偏离。
- 生命周期:让稳定知识沉淀、临时信息退出、敏感信息及时撤销。
这四步不是目录装饰,而是一条决策链:工作集 → 检索与压缩 → 污染与调试 → 生命周期。阅读后面的案例时,可以随时回到这条链判断当前问题发生在哪一层。
真实问题:更多上下文为什么反而更差
一个团队把架构文档、编码规范、所有命令、数据库 Schema、产品需求和历史事故全部放进常驻规则,希望 Agent “完全了解项目”。结果每次简单改动都携带大量信息,工具描述和规则占据预算,关键路径规则彼此冲突,模型在旧文档与当前代码之间摇摆。
另一个团队只给一句任务,让 Agent 自己搜索。它读到同名旧模块,把相似实现当成当前事实。两种失败一个来自过量,一个来自不足。Context Engineering 的目标不是最大化信息,而是最大化当前决策的有效信号。
机制:五层上下文

任务上下文定义目标、范围和验收;仓库上下文保存架构、命令和长期规则;代码上下文是当前实现、调用链和测试;工具上下文描述可以访问的外部数据和动作;反馈上下文包含编译、测试、日志、截图和 Review。
五层的生命周期不同。仓库规则可能持续数月,任务只持续一个分支,代码读取只服务几轮决策,失败日志可能下一轮就应被摘要,工具权限在任务结束后应撤销。把它们都当成一段永久 Prompt,会造成过期和噪声。
1. Prompt 只是当前指令层

用户说“实现取消订单”时,模型还会受到系统安全指令、AGENTS.md、路径 Rules、当前 Git Diff、打开文件、检索结果、终端输出、工具 Schema 和历史对话影响。一个精心写作的 Prompt 如果与仓库规则冲突、引用错误文件或缺少验证环境,仍然会失败。
因此,优化顺序应是:先确认事实来源和工具可用,再补任务决策,最后优化表达。很多团队花时间研究 XML 标签和角色扮演,却没有给出正确工作目录和测试命令。
2. 上下文预算怎样被消耗

系统指令和工具说明是固定成本;常驻规则每轮加载;代码和文档按探索加入;命令输出可能一次占用大量空间;对话历史持续累积。达到窗口限制前,Harness 也可能为了成本和延迟主动压缩。
预算不是只看 Token 数。相同长度的信息,如果结构明确、来源权威、与当前决策相关,价值更高。重复粘贴同一代码、完整保留成功构建日志、加载与任务无关的所有 MCP 工具,都会降低信号密度。
可以把上下文当作 CPU Cache:不是长期存储,而是当前工作集。权威知识仍在仓库和外部系统中,需要时检索;临时结果完成决策后退出。
3. 代码检索应从任务实体开始

订单取消任务包含 Order、状态、Repository、HTTP 和测试等实体。Agent 可以先搜索领域符号和路由,再追踪定义与引用,读取相邻测试,最后加入少量相关文件。直接读取整个 src 会把配置、支付和无关示例一起带入。
理想探索顺序:
text
目录与构建文件
-> 任务入口和领域符号
-> 定义、引用与调用者
-> 相邻测试和相似实现
-> 最小相关文件集搜索结果也不是事实终点。命中文件可能已废弃,注释可能过时,测试可能只覆盖旧路径。Agent 应用代码、运行行为和版本控制交叉确认。
4. 渐进披露让信息按需进入

全仓共同的命令和边界可以常驻 AGENTS.md;后端、前端、迁移可以使用路径规则;低频复杂流程放进 Skill;当前任务用到的文件通过搜索加载;遇到失败再加入相关日志和诊断。
这比一份巨型规则更可维护。Agent 开始时只知道“有什么能力以及何时读取”,真正需要数据库迁移流程时才加载详细步骤。信息越接近使用时机,越不容易过期或干扰其他任务。
渐进披露还适用于人类 Review。PR 描述先给目标、方案、验证和风险;需要深挖时再看 Diff、测试日志和设计文档。上下文工程并非 AI 专属,而是协作信息架构。
5. 上下文污染怎样形成错误轨迹

污染可能来自错误用户描述、旧文档、无关日志、Prompt Injection 或 Agent 自己的推断。如果错误假设进入计划,后续代码和测试会围绕它形成自洽结构。会话越长,模型越倾向维护已经建立的解释。
发现污染后不要只追加“请再仔细检查”。应定位错误首次出现的位置,删除或否定相关信息,加入权威证据,必要时回退到干净 Git 节点和新会话。让模型在充满错误历史的上下文中自我纠正,成本通常高于重建小上下文。
6. 压缩最容易丢失否定条件和例外

摘要容易保留目标和主结论,却可能省略“不要修改数据库”“PAID 不允许取消”“这个测试警告是预期行为”。这些条件字数少但风险高。关键约束应写进任务、计划、测试或规则文件,让后续会话可以重新读取,而不是只依赖自动摘要。
长任务可以主动创建 handoff:当前目标、已完成节点、关键决策、未解决问题、工作树状态、验证命令和下一步。Handoff 比让下一个会话从完整聊天历史猜测有效状态更可靠。
Context Debugging:调试 Agent 看到了什么

当结果异常时,按下面顺序排查:
- 它在哪一步首次偏离任务?
- 当时读取了哪些文件和工具结果?
- 是否有过期规则或错误用户假设?
- 关键非目标是否在压缩后消失?
- 工具描述是否让它选择了错误能力?
- 测试是否提供了错误或过弱反馈?
然后缩小上下文,加入权威证据,用一个小任务验证修正。例如只要求追踪创建订单调用链,不允许编辑;如果仍读错模块,问题在仓库地图或搜索,而不是实现 Prompt。
Context Debugging 还要检查工作目录。Monorepo 中 Agent 可能在根目录运行错误脚本,读取另一个模块的配置;命令本身成功,却验证了错误对象。每个验证证据都应带目录和目标模块。
上下文生命周期

信息先从任务和仓库创建,经搜索和规则选择,支持一次决策;环境反馈校正结论;稳定知识回写到测试、文档或规则;临时日志和错误候选退出。健康系统会持续清理和沉淀,而不是让会话无限增长。
不同信息的沉淀位置:
- 业务行为:测试和任务规格。
- 架构选择:设计记录。
- 构建命令:README 或 AGENTS.md。
- 高频错误:规则、Linter 或 Hook。
- 低频流程:Skill。
- 临时调查:任务笔记,完成后归档或删除。
一个具体实践:为订单服务准备上下文
根 AGENTS.md 只需要说明目录职责、mvn test、不增加数据库、状态规则在 Domain、HTTP 映射在 Advice。取消任务写在 docs/task-contract.md,包含状态和错误码。Agent 开始时读取目录和构建文件,再读取 Controller、Service、Order、Repository 和相关测试。支付配置虽在同一仓库,但非目标明确,不进入主要上下文。
实现后,测试结果进入反馈上下文;Review 发现状态规则在 Service,新增证据是领域对象应拥有不变量,于是计划和代码调整;最终稳定结论回写 AGENTS.md。编译失败日志和中间假设不需要永久保留,Git 标签足以复现过程。
大型仓库中的上下文策略
Monorepo 的难点不是文件数量本身,而是同名概念、多个构建系统和局部规则。Agent 首先需要确定工作子树、依赖方向和验证入口。根 AGENTS.md 只描述全局原则和模块地图,每个服务在近目录提供自己的命令和边界;路径规则随相关文件加载。这样修改前端组件时不会携带数据库迁移规范,修改基础库时又能读取更严格兼容要求。
代码索引和向量检索可以提高召回,但不应独立决定事实。语义相似可能找到旧版本、测试夹具或另一个领域的同名实现。检索后仍要沿符号定义、调用者、构建文件和 Git 历史确认。对于公共接口,搜索消费者比只读定义更重要;对于错误行为,读取失败测试和运行 Trace 比读取注释更重要。
大型仓库还需要限制命令输出。全量构建可能产生数万行日志,可以让脚本保留退出码、失败模块、第一处根因和报告文件路径。Agent 需要时再读取具体报告。工具输出越结构化,越不必消耗模型从噪声中做传统日志过滤。
RAG、长上下文和代码搜索不是三选一
长上下文允许一次携带更多内容;RAG 根据查询召回候选;符号搜索利用代码结构精确定位。三者可以组合:先用目录和符号缩小,再用语义检索发现概念相关文档,最后在足够窗口中比较实现与测试。直接依赖任何一种都会有盲点。
RAG 的数据也要维护版本。如果索引没有及时更新,Agent 可能引用已删除接口。关键任务可要求它在文件系统中重新读取命中文件,并用当前 Git 状态验证。检索结果是线索,不是不可变事实。
怎样衡量上下文质量
Token 使用量只能说明成本,不能说明质量。更有用的指标包括:首次搜索是否命中正确模块;为完成任务读取了多少无关文件;同一事实是否重复加载;工具选择错误率;上下文压缩后是否重复询问已确认问题;任务在第几轮首次偏离;人工纠偏发生在哪里。
团队可以定期查看失败轨迹,把问题分类为任务缺失、仓库说明缺失、检索错误、工具反馈不足、过期规则或模型推理错误。只有最后一类主要通过换模型解决。其余类别更适合修改任务模板、仓库地图、命令包装、Rule、Skill 或测试。
上下文优化应以任务结果为准。减少 Token 如果导致更多搜索和返工不一定划算;增加一份简短模块地图如果显著降低错误路径,通常很有价值。目标是最小充分,不是绝对最小。
会话切换的标准 handoff
长任务结束一轮前,应保存:当前目标与非目标、已读取的权威文件、已确认决策及理由、已修改文件、Git 状态、通过和失败的命令、未解决问题、下一步唯一建议。不要复制整段聊天,也不要只写“继续修复测试”。
接手会话先验证 Git 状态和关键命令,再信任 handoff。这样即使摘要遗漏或文件被其他人修改,真实环境仍能校正上下文。Handoff 是启动索引,不是替代检查。
失败模式
失败一:把整个仓库塞给模型
大上下文可以提高召回,却降低精度和成本效率。先用目录、符号和测试缩小范围,只有跨模块关系需要时才扩大。
失败二:复制整套风格指南到规则
格式和常见风格应由 Formatter、Linter 和现有代码表达。规则记录领域边界、特殊命令和真实陷阱。重复文档会过期并与工具冲突。
失败三:每次失败都追加 Prompt
追加内容不会删除错误假设,反而让上下文更长。错误轨迹应回退、清理和重新建立权威证据。
失败四:把 Memory 当事实数据库
自动记忆可能过期或缺少来源。关键事实必须在仓库或权威系统可验证;Memory 只作为检索提示。
失败五:忽略工具返回中的不可信文本
Web、Issue、日志和 MCP Resource 都可能包含指令样式内容。它们应被标记为数据,不能覆盖系统和用户目标。
失败六:上下文切换没有 handoff
新会话只得到“继续之前工作”时,会重新搜索或猜测状态。明确提交、测试、未完成项和下一动作,能显著减少重复和偏离。
生产边界
上下文可能包含源码、客户数据、日志、Secrets、设计稿和内部文档。进入模型或远程服务前必须遵守数据分类、最小化、保留期和区域政策。敏感值不应为了“上下文完整”直接粘贴;使用短期凭据、脱敏样本或受控工具。
上下文规则不是安全边界。即使规则写着“不要读取 .env”,客户端仍应拒绝访问;即使 Prompt 说“只读数据库”,账号也应只有只读权限。数据和动作权限必须由模型外系统执行。
实践清单
- [ ] 区分任务、仓库、代码、工具和反馈五层上下文。
- [ ] 常驻规则只保留稳定、高频、难以推断的信息。
- [ ] 使用搜索、符号和相邻测试渐进读取代码。
- [ ] 长日志提取根因、命令、环境和第一处失败。
- [ ] 关键否定条件写入持久文件或测试。
- [ ] 低频复杂流程按需加载为 Skill。
- [ ] 检查工具描述和数量是否造成选择噪声。
- [ ] 发现污染时清理和回退,不无限追加 Prompt。
- [ ] 长任务在会话切换前生成结构化 handoff。
- [ ] 敏感上下文遵循最小化、脱敏和权限策略。
读完之后,你应该能完成什么
- 能为任务构建最小充分上下文。
- 能选择搜索、索引、摘要或重新读取。
- 能识别上下文污染和压缩失真。
- 能把一次修正沉淀为可维护的仓库知识。
如果只能复述概念,却不能完成上述动作,说明还没有把内容转化成工程能力;可以回到对应机制图、失败模式和实践清单重新核对。
小结
Context Engineering 的目标不是让 Agent 知道一切,而是让它在每个决策点拥有足够、相关、可验证的信息。信息需要被选择、使用、反馈、沉淀和丢弃。掌握上下文生命周期后,AI 编程从提示词试错变成可以诊断和改进的工程系统。
