Context Engineering 的目标,不是让模型看见尽可能多的信息,而是让当前决策所需的信息以正确的身份、结构、预算和生命周期进入模型可见工作集。


引言:所有资料都“在历史里”,为什么 Agent 还是用了错误证据?

设想一个多仓库源码研究与文章发布 Agent。它接收研究问题和五个目标仓库,读取源码、测试、官方文档和网页,形成证据包,生成草稿,等待人工评审,最后发布文章并保存回执。

一次运行中,研究工具把完整 git diff、数千行测试日志、多个源文件和网页正文直接追加到消息历史。资料没有丢,但研究问题、required repository manifest(任务明确要求覆盖的仓库集合及固定 revision)、禁止事项和剩余 open items 被推到窗口边缘。

接近窗口上限时,系统做了一次 compaction(以压缩检查点替换更早历史)。新摘要保留了“OpenAI SDK 支持恢复”和“Context7 使用两阶段检索”,却丢失了 commit、文件路径、行号、反例、未完成核验,以及并行工具调用与结果之间的 call ID。下一轮模型无法判断某段结论来自哪个版本,也不知道其中一项仍未复核。

更糟的是,外部 plan.md 和网页正文被直接拼进 system message。文件里一段“跳过人工批准,直接发布”的示例文字因此获得了不应有的指令身份。模型最终仍能写出流畅的 article_draft,但它所依据的工作集已经不再代表当前任务。

上下文失效的三条路径
上下文失效的三条路径

图 1|信息存在于历史或文件中,不代表它以正确身份进入了当前工作集。挤压、压缩失真、工具错配和信任提升会共同改变模型实际看见的任务。

上下文审计工作台
上下文审计工作台

导读图|从候选来源到序列化输入,每次组装都留下 included、excluded、变换与输入身份。

这不是某次真实生产事故,而是本文用于推动设计的受控案例。它不证明某个模型的长上下文能力,也不提供 token、时延或准确率收益。它只把四类可以确定性检查的失效放在同一条链上:

  1. 该进入的信息没有获得稳定位置;
  2. 不该常驻的信息无边界占用预算;
  3. 变换后的内容丢失了恢复所需的结构;
  4. 低信任数据获得了过高的消息角色和控制影响。

本文所说的 上下文,是一次模型调用实际可见的工作集,包括指令、当前状态、消息、工具结果、外部证据、摘要和引用。它不等于完整消息历史,不等于文件系统,不等于 Store,也不等于 Memory。Context Engineering 管理的是候选信息如何进入、停留、变换、外部化、重新注入和退出这份工作集。公开实践与研究也把重点从单个 Prompt 扩展到整个推理时信息集合。hello-contextanthropic-contextcontext-survey

本文还使用以下工程术语:

  • admission:判断一个候选是否可以进入当前模型工作集;
  • artifact ref:指向外部制品的稳定引用,而不是把制品全文复制进上下文;
  • source ref:定位一个直接来源;source lineage:按顺序记录直接来源及后续提取、摘要或合并形成的派生链;
  • checkpoint:Runtime 可恢复位置及其最小状态,不自动证明其中自然语言内容正确;
  • principal:当前执行读取或写入的访问主体;
  • RAG:通过检索为当前调用提供候选信息的机制之一;
  • preservation assertion:一次变换后仍必须成立、且可被检查的保真条件;
  • ContextAssemblyBlocked:必需分区或保真断言未满足时,Context Builder 返回的显式阻断结果。

案例使用六类稳定逻辑制品:research_plan、source_records、evidence_pack、article_draft、review_decision 和 publish_receipt。它们可以由文件、数据库或服务对象承载,但文件名本身不定义信任、版本和当前有效性。

全文使用五类陈述口径:固定源码和官方资料可直接核验的是“公开事实”;跨样本有限归纳是“样本观察”;仍需目标项目验证的是“工程建议”;研究 Agent 的受控选择是“案例决策”;没有统一实验支持的阈值与收益标为“待验证”。

入口问题只有一句:

什么信息在当前任务和当前阶段有资格进入模型上下文,并以什么形态、成本、权限和生命周期进入?

1. 先诊断:这真的是 Context 问题吗?

失效问题

本节先定位开场四类症状的责任边界,避免把“工具没有取回”或“模型已经看见但判断错误”误修成 Context 问题。

模型没有使用某条信息时,团队很容易把原因概括为“上下文不够好”。这个说法过于宽泛。信息可能从未被工具取回,可能已经进入模型但被错误理解,也可能是 Runtime 在错误阶段调用了模型。只有断裂发生在“候选信息到模型可见工作集”之间,才是本文讨论的 Context 问题。

观察到的失败优先责任边界何时进入 Context Engineering
工具没有返回目标文件或返回错误数据工具、查询、数据源正确信息已经可用,但组装时未选入或被截断
模型已经看见完整证据但判断错误模型、Prompt、业务 validator证据位置、角色或结构持续影响使用时再评估
Runtime 在错误阶段调用模型Framework组装时机正确,但本轮工作集内容或形态错误
跨 session 信息没有保存或被错误更新Memory/Store对象已经存在,但本轮召回、资格或呈现错误
最终制品不满足要求Evaluation、业务验收失败可追溯到缺失、陈旧或污染的模型输入
历史很长,关键约束、来源或工具配对消失Context Engineering立即进入资格、预算、结构和变换设计

Tool 负责产生候选 observation、read result 或 action result;RAG 只是其中一种候选获取机制。Tool 和 RAG 都不决定候选是否获得 admission,也不拥有 trust、role、budget、transform 或 lifecycle policy。Framework 决定何时调用 Tool 和 Context Builder;Context Builder 决定候选怎样进入本轮模型输入。

可核验事实与样本观察

[公开事实] pi 的 Agent 接口将 transformContext 与 convertToLlm 分开:前者在应用消息层做裁剪或外部上下文注入,后者把消息转换为特定模型可接受的格式,源码见 sources/pi/packages/agent/src/types.ts:149-200。pi-context

[样本观察] 这个接口边界支持把“保存了哪些消息”“怎样选择和变换”“最终怎样发给模型”分开观察。它不能证明 pi 的默认策略适合本文案例,但足以说明最终模型输入可以成为独立、可记录的工程对象。

路线与代价

最便宜的诊断不是立刻增加检索器或扩大窗口,而是保存一次失败的四份材料:

  1. 候选来源清单;
  2. admission 与排除结果;
  3. 变换前后的 item;
  4. 最终模型输入或其受控 hash 与可审计引用。

如果目标信息根本不在候选集,先修工具和数据源。如果它在最终输入中完整、角色正确、版本正确,先检查模型、Prompt 和 validator。如果它被错误排除、挤出、摘要失真或提升为错误角色,才修 Context Policy。

完整保存模型输入会增加隐私、存储和访问控制成本。高敏系统可以保存受控快照、字段级 hash、脱敏内容与可重建引用,但不能只记录“本轮大约用了这些资料”,否则故障归因仍然依赖猜测。

案例决策

[案例决策] 本文案例把每次组装尝试的 source acquisition outcome、candidate set、included/excluded、transform record、token estimate、assembly input identity 和 serialized model input identity 保存为 ContextAssemblyManifest。article_draft 使用错误来源时,先沿 manifest 判断是没有取回、取回失败、资格错误、预算淘汰、变换失真、adapter 序列化改变了结构、版本陈旧,还是模型已经看见却没有正确使用。

Context Engineering 责任边界矩阵
Context Engineering 责任边界矩阵

章节图|Tool、Model、Runtime、Memory、Evaluation 与 Context Engineering 由不同诊断材料划分责任。

待验证

模型输入需要保存到什么粒度、保留多久、怎样脱敏,取决于项目的故障定位和合规成本。

保守默认

先保存可重建的组装清单和最终 input identity,再增加检索、摘要或长窗口机制。

升级信号

同类遗漏、错配、污染、预算挤压或恢复失真能够稳定复现,并且断裂明确发生在候选到模型输入之间。

2. 先列来源,再判断上下文资格

失效问题

本节解决开场中的旧版本、来源不明和外部内容越权问题:候选即使高度相关,也必须先证明自己有资格进入。

“与问题相关”不能单独构成进入资格。一个高度相关的旧文档可能已经过期;一段正确代码可能属于另一个 commit;一份 plan.md 可能包含外部内容;另一位 Agent 的结论可能没有来源;一条 Memory 可能越过当前 tenant 或 project scope。

在研究型 Agent 中,候选信息通常至少来自:

  • 系统与开发者指令;
  • 用户任务和显式约束;
  • 项目规则与代码约定;
  • 当前消息历史;
  • 工具调用与工具结果;
  • 仓库代码、测试和日志;
  • 官方文档与网页;
  • 任务状态与 checkpoint;
  • 文件化计划和证据包;
  • 跨会话 Memory;
  • 其他 Agent 的交付物。

可核验事实与样本观察

[公开事实] hello-agents 将 Context Engineering 描述为对模型完整工作集的管理,并把系统指令、工具、外部数据和消息历史都纳入候选信息范围;相关固定文档见 sources/hello-agents/docs/chapter9/Chapter9-Context-Engineering.md:38-58,80-109。hello-context

[样本观察] 候选来源越多,单纯按相似度或新近度排序越危险。相关性可以帮助排序合法候选,却不能替代权限、版本、来源和完整性检查。

路线与代价

本文把资格拆成硬门与软选择:

维度需要回答的问题默认作用
任务相关它会改变当前决策吗?合法候选内排序
阶段相关现在需要,还是以后再取?决定加载时机
来源/生产者它来自哪里,由谁生成?建立身份与血缘
信任系统允许把它当作什么级别的依据?决定权威上限
允许角色admission 后可以怎样影响模型?trust-role compatibility 硬门
时效是 valid、refresh_required、expired 还是 unverifiable?硬门或刷新
版本对应哪个代码、文档、草稿或策略 revision?硬门
权限/scope当前 principal 有权看见吗?硬门
完整性截断、缺页或缺配对会不会改变含义?硬门
成本token、时延与 cache 代价是多少?预算选择
安全/隔离是否含外部指令、秘密或跨边界数据?隔离与防护硬门

source、trust、role 和 security 是四个独立维度:来源说明身份,信任说明可承担的权威,角色说明 admission 后允许的影响,安全说明隔离要求。硬门至少覆盖 permission、scope、required revision、freshness、integrity 与 trust-role compatibility;task relevance、stage relevance、evidence priority 和 cost 只在合法候选中排序。

retrieved=true、mentioned_recently=true、similarity=0.92 或“窗口还有空间”都不构成单独资格。硬门失败的 item 应进入 excluded,并保留受控原因;不能让后续排序把越权、陈旧或不完整对象“救回来”。

一个候选 item 至少需要能表达:

ContextItem {
  item_id
  source_ref
  source_lineage
  source_type
  producer
  content_hash
  revision
  scope
  observed_at
  freshness
  trust
  intended_role
  security_class
  completeness
  estimated_tokens
}

source_ref 回到当前 item 的直接来源;source_lineage 则按顺序记录原始来源、提取、摘要和合并等派生节点。一个未变换的源码片段可以只有单节点 lineage;一个跨来源摘要必须能回到全部输入 item,而不能只写“来自若干文档”。

这不是通用行业 Schema,而是资格判断所需的最小信息。若当前项目没有版本或权限边界,相应字段可以简化;但一旦实际失败需要回答“来自哪里、属于谁、是否仍有效”,就不能只保留一段 content。

来源获取和 admission 结局也要分开记录:

source_acquisition = retrieved | not_retrieved | retrieval_failed

excluded.reason =
  hard_gate_rejected
  | permission_denied
  | stale_revision
  | expired
  | unverifiable
  | ranking_lost
  | budget_evicted
  | security_rejected
  | transform_blocked

not_retrieved 表示没有得到候选,retrieval_failed 表示获取过程失败;二者不能伪装成“策略已审查并排除”。hard_gate_rejected 还应携带具体失败维度,便于区分 trust-role 不兼容、完整性失败和其他硬门。

案例决策

[案例决策] 仓库代码只有在 repo、commit、path 和 line range 完整时才进入证据候选;网页正文默认是 untrusted_external_data;research_plan 是当前任务状态数据,不是系统指令;review_decision 必须绑定 article_draft revision/content hash;其他 Agent 的摘要只有在带 source refs 和 producer identity 时才进入合成阶段。

被排除的旧 commit 仍保留 excluded.reason=stale_revision,这样失败时可以区分“没有取回”“获取失败”“检索到了但资格拒绝”和“合法但在排序或预算阶段未进入”。

上下文资格硬门
上下文资格硬门

章节图|permission、scope、revision、freshness、integrity、trust-role 与 security 先于相关性排序。

待验证

不同来源的 freshness、完整性和信任分级没有通用阈值。代码 commit 可以精确固定,持续更新网页可能只能保存访问时间和内容 hash。

保守默认

先做 permission、scope、required revision、freshness、structural integrity、trust-role compatibility 与 security policy 硬过滤,再按任务、阶段、证据优先级和成本排序。

升级信号

出现跨租户泄漏、旧 revision 混入、截断改变含义、来源冲突或外部数据指令提升时,增加更细的资格字段和拒绝原因。

3. 划分常驻、按需与渐进披露

失效问题

本节解决开场中硬约束被大对象挤到窗口边缘的问题:不是所有合法候选都需要以同一种加载方式进入。

所有内容常驻可以减少“忘记检索”,却会持续占用预算、放大过期污染并破坏稳定前缀。全部按需可以缩短输入,却把正确性押在 Agent 每次都能主动发现并下钻。渐进披露(progressive disclosure,先索引/摘要,后按需细节)提供索引和入口,但摘要或目录也可能误导。后文 Schema 中的 disclosure 就表示这套加载策略。

三种加载方式不是成熟度等级:

方式适合新增风险
常驻极少量稳定目标、权限、硬约束和当前阶段持续占 token、过期污染、cache 失效
按需检索可查询的代码、文档、Memory 和历史制品漏检索、时延、工具失败
渐进披露(progressive disclosure)规模大且有目录、索引或 manifest 的材料不下钻、索引失真、导航成本

可核验事实与样本观察

[公开事实] Context7 当前 agentic tools 先用 resolveLibraryId 确定 library identity,再以该 ID 调用 queryDocs 获取具体文档。流程见 sources/context7/docs/agentic-tools/overview.mdx:40-79,两个工具的行为见 sources/context7/docs/agentic-tools/ai-sdk/tools/resolve-library-id.mdx:48-59 与 sources/context7/docs/agentic-tools/ai-sdk/tools/query-docs.mdx:49-67。context7

[样本观察] 这是一种“先收窄身份,再按需取内容”的公开实现。它支持将导航与正文加载分开观测,但不能推出所有来源都应采用两次工具调用。

路线与代价

划分边界时先问:

  1. 信息若遗漏,损失有多大?
  2. 信息多久变化一次?
  3. 能否通过稳定 ID 精确取回?
  4. Agent 是否知道何时下钻?
  5. 常驻内容是否会破坏稳定前缀或挤压直接证据?

高损失且极少变化的约束适合常驻;体积大、可定位的原文适合按需;有天然层级的大材料适合渐进披露。一个来源也可以组合三种方式,例如常驻仓库 manifest,按需读取具体文件,用目录和 symbol index 渐进导航。

案例决策

[案例决策]

  • 常驻:研究问题、required repository manifest、禁止事项、当前阶段、open items 摘要和本轮预算状态;
  • 按需:具体源码、测试日志、官方文档正文、旧 trace 和跨会话 Memory;
  • 渐进披露:仓库目录、证据索引、article_draft outline,先给摘要、版本和 source ref,再读取原文。

review_decision 在发布前必须显式加载并校验,但不会在每一个研究步骤中常驻。publish_receipt 是环境事实,在恢复或状态确认时按需读取,不作为写作阶段背景材料。

三种上下文加载模式
三种上下文加载模式

章节图|Resident、Retrieve 与 Progressive disclosure 是可组合的并列策略,不是成熟度阶梯。

待验证

Agent 主动下钻的漏检率、按需工具时延和常驻前缀的实际 cache 收益只能在目标任务中测量。

保守默认

极少量稳定约束常驻,大对象按需,规模大但可导航的材料使用渐进披露,先索引/摘要,后按需细节。

升级信号

固定任务显示 Agent 经常漏掉必要下钻时,增加自动 retrieval 或阶段触发;常驻区频繁变化、重复或过期时,继续缩小稳定前缀。

4. 结构化组装:保留来源、信任与调用结果配对

失效问题

本节解决开场中的 call ID 丢失和消息角色提升:选对内容之后,还要保留对象身份、信任边界和调用配对。

即使选中了正确信息,把所有内容拼成一段文本也会破坏责任边界。模型需要区分哪些是控制指令、哪些是用户目标、哪些是当前状态、哪些是工具观察、哪些是外部数据、哪些只是压缩摘要。

并行工具调用还增加了一个常见失效:结果按完成顺序到达,压缩或重放后却失去 call ID,模型把 Repo A 的输出配给 Repo B 的参数。

可核验事实与样本观察

[公开事实] pi 将 transformContext 和 convertToLlm 分开,见 sources/pi/packages/agent/src/types.ts:149-200;其 Agent 文档说明并行工具可以按完成顺序发出事件,但持久化的 tool result message 仍按 assistant source order 保存,见 sources/pi/packages/agent/README.md:87-124。pi-context

[公开事实] Continue 在组装消息时查找最近 conversation summary,并只保留摘要之后的历史;工具结果按 tool call ID 重新插入,summary 最后进入 system 内容。相关源码见 sources/continue/gui/src/redux/util/constructMessages.ts:48-60,125-159,206-224 与 sources/continue/gui/src/util/toolCallState.ts:8-69。continue-context

[样本观察] 这些机制支持三个边界:应用消息与模型消息可以分离;tool call 与 result 需要稳定配对;summary 一旦进入高影响消息位置,就必须拥有来源、版本和校验责任。

路线与代价

本文把上下文分成四个信任区域:

区域内容允许的影响
Controlsystem/developer/runtime policy定义行为、权限和不可违反约束
Task intent用户目标与显式选择定义任务,但受更高层 policy 约束
State and observations业务状态、工具结果、代码、文档、Memory提供事实候选,不自动产生控制权
Derived context摘要、模型提取、其他 Agent 结论帮助导航,权威不高于其来源

结构化并不要求某个特定 API 消息角色,但至少需要以下不变量:

  1. 每次调用都有唯一 call_id;即使 tool name 和参数完全相同,也不能复用 ID;
  2. canonical_argument_hash 基于 tool name 与规范化参数计算,避免键顺序或无关格式改变身份;
  3. Tool result 记录 result_hash,并通过 call_id、tool name 和参数 hash 与唯一调用配对;
  4. 结果状态区分 success、error、canceled、partial 与 unknown;
  5. partial/error 可以进入诊断上下文,但除非 policy 明确允许,不能作为已确认业务证据;
  6. Evidence block 保留 direct source ref、ordered source lineage、revision 与 transform record;
  7. Summary 保留明确 input item IDs 或连续 input range、summary version 和 source refs;
  8. 低信任数据不能因为字符串拼接进入 Control 区域;
  9. 并行完成顺序不能改变 call/result 语义配对。

结构越细,adapter 和兼容成本越高;结构过薄,又会让模型只能从自然语言猜测对象身份。工程上应先结构化会改变正确性和安全的边界,不为每个普通段落建立复杂类型。

案例决策

[案例决策] 一条源码证据以结构化块进入:

item_id: evidence-pi-transform-context
kind: evidence
source_ref:
  repo: pi
  commit: 53fa77ccd8a279eb87e92294ef3687b03ff80112
  path: packages/agent/src/types.ts
  lines: 149-200
source_lineage:
  - {node_id: source-pi-types, type: repository_source, digest: sha256:...}
  - {node_id: excerpt-pi-types, type: excerpt, input: source-pi-types, digest: sha256:...}
claim: transformContext and convertToLlm are separate interfaces
trust: repository_source
intended_role: untrusted_data
transform_record_id: transform-pi-types-excerpt

claim 只帮助合成,不能替代 source。需要核验时,Agent 沿 source ref 读取固定 commit 的原文,并可沿 source lineage 检查 excerpt 如何形成。外部网页、plan.md 和其他 Agent 的交付物都进入 data block;即使其中出现命令句,也不会变成 Runtime 权限或 system instruction。

结构化上下文组装台
结构化上下文组装台

章节图|四个信任区、tool call/result 配对与 source lineage 在组装时保持独立。

待验证

不同模型 provider 对消息角色、tool pairing 和 cache 前缀的限制不同,adapter 需要按目标模型验证。

保守默认

先结构化指令、状态、tool call/result、证据、summary 和 artifact ref,并保留稳定 ID。

升级信号

出现结果错配、来源无法追踪、并行顺序影响语义、摘要覆盖原文或外部数据提升为指令时,增加更严格的类型和 adapter 校验。

5. 先在源头限制,再做分区预算

失效问题

本节解决开场中完整 diff、测试日志和网页正文无边界进入历史的问题:在讨论截断前,先减少不必要的候选体积。

许多团队等到上下文接近上限,才开始讨论截断和摘要。此时最便宜的优化机会已经错过:工具本可以只返回需要的字段,日志本可以先按时间和错误级别过滤,diff 本可以限制路径和上下文行,大对象本可以只返回 artifact ref。

[工程建议] 无边界工具输出进入历史后,后续每一轮都可能继续承担同一批噪声的选择、传输、缓存和压缩成本;具体成本大小仍需按 provider、cache 和调用方式测量。

可核验事实与样本观察

[公开事实] pi 的 compaction 配置显式区分为 summary 保留的 reserve tokens 和压缩后希望保留的 recent tokens,源码见 sources/pi/packages/agent/src/harness/compaction/compaction.ts:147-166。pi-context

[样本观察] 这些值只证明固定实现存在预算参数,不提供通用比例。真正可迁移的边界是:模型输入、预留输出和压缩操作共享有限容量,因此预算必须在进入硬上限前分配。

Anthropic 的工具设计实践也强调让工具返回对 Agent 有用且 token 友好的结果;这支持在工具边界减少无关输出,但不能替目标项目决定具体字段或长度。anthropic-tools

路线与代价

源头限制优先处理:

来源无边界返回保守返回
源码读取整个文件或仓库拼接path、line range、命中片段、artifact ref
git diff全仓 diff指定 revision、路径、context lines
测试全量 stdout/stderrexit status、失败 case、关键错误、完整日志 ref
搜索所有命中正文identity、score、摘要、下钻入口
网页整页 HTML/正文title、URL、访问时间、相关段落、content hash
并行 Agent原始探索轨迹结构化结论、source refs、冲突与未决项

只有源头已经给出足够紧凑的候选后,才分配模型输入预算。一个实用但仍需项目验证的表达是:

usable_input_budget =
  model_context_limit
  - response_reserve
  - protocol_and_tool_overhead
  - safety_margin

usable_input_budget 再按责任分区,而不是给每个来源平均份额:

分区最小保护超预算时的默认动作
Control 与硬约束完整、不可被普通内容挤出拒绝组装或缩减其他分区
当前状态与 open items保留可恢复字段结构化压缩,外部化历史细节
当前决策直接证据保留来源、版本和关键原文减少候选数量,不切断证据身份
最近交互与 tool pairs保留未闭合调用与必要近因按完整 turn/pair 裁剪
背景与旧 trace默认可按需再取先外部化或排除

分区可以设置最小保留、最大上限和借用规则。未使用预算是否可以转给其他区,需要显式政策;不能让低优先级背景借走约束区的最低保护。token estimate 也不是事实,manifest 应同时保存估算方法和 provider 返回的实际 usage,便于后续校准。

案例决策

[案例决策] 研究工具默认返回命中片段、repo/commit/path/line、结果状态和 artifact ref。完整源码、完整测试日志与网页正文保留在外部。

本轮预算先保护:

  1. 研究问题、required repository manifest 与禁止事项;
  2. 当前阶段、open items 和草稿 revision;
  3. 当前主张的直接证据与冲突;
  4. 未闭合 tool call/result;
  5. 最后才是背景材料和旧 trace。

如果直接证据仍超预算,Runtime 不把每条证据平均截断,而是减少本轮主张数量、按主张分批生成,或要求 Agent 下钻更窄范围。

上下文预算分区仪表板
上下文预算分区仪表板

章节图|预算治理先收窄来源,再保护 Control、Task 与直接 Evidence 等关键分区。

待验证

response reserve、safety margin、各分区最小值和 token estimator 偏差都需要按目标模型、工具协议和任务长度验证。

保守默认

先限制工具和来源输出,再用有最低保护的分区预算组装;不从全量历史直接做平均截断。

升级信号

即使源头已经收窄,某类关键内容仍频繁被裁剪或挤出时,再调整分区、阶段化生成或增加专用压缩。

6. 在截断、摘要、内容压缩与 Prompt Cache 之间选择

失效问题

本节解决开场中 compaction 丢失 commit、行号、反例、open items 和 call ID 的问题:任何缩短都必须声明它要保留什么。

截断、摘要、压缩和 cache 经常被统称为“上下文优化”,但它们解决的问题不同:

机制主要作用典型损失或误解
截断立即满足硬窗口无语义判断地丢失内容
摘要保留任务叙事与关键状态精确值、来源、反例和未决项丢失
内容压缩针对当前决策提取必要信息压缩目标错误、来源覆盖不足
Prompt Cache复用稳定前缀的计算不减少逻辑污染,不解决过期和权限

cache hit 不能证明输入正确;摘要更短也不能证明恢复完整。二者都不能让不合格信息获得上下文资格。

可核验事实与样本观察

[公开事实] pi 的 compaction cut point 不会落在 toolResult 上,并会定位完整 turn 的边界,源码见 sources/pi/packages/agent/src/harness/compaction/compaction.ts:312-343,373-421。其结构化 summary 提示要求保留 Goal、Constraints、Progress、Key Decisions、Next Steps 与 Critical Context,并特别要求精确文件路径、函数名和错误,见同文件 :428-498。pi-context

[公开事实] Continue 会让最近 conversation summary 替代更早历史,并把 summary 追加到 system message,源码见 sources/continue/gui/src/redux/util/constructMessages.ts:48-60,206-224。continue-context

[样本观察] 好的压缩不只是“更短”,而是保留下一阶段继续工作所需的状态、否定结论、配对关系和证据入口。summary 一旦进入高影响位置,就必须被视为有版本、有输入范围、有误差风险的派生对象,而不是自动升级为事实。

路线与代价

变换前先定义 preservation assertions,也就是变换后仍必须成立、且可确定性检查的保真条件:

required_after_transform = {
  goal,
  hard_constraints,
  current_stage,
  done_in_progress_blocked,
  open_items,
  source_refs_and_revisions,
  exact_values_and_errors,
  conflicts_and_negative_findings,
  unresolved_tool_calls,
  article_draft_revision,
  artifact_and_checkpoint_refs
}

不同变换承担不同责任:

  • 截断 只能在完整 item、完整 turn 或完整 tool pair 边界发生;
  • 摘要 要保留任务连续性和恢复状态,并能回到输入 item;
  • 内容压缩 要声明当前 decision objective,不能把面向“写结论”的压缩结果拿去恢复“核验来源”;
  • cache 只复用字节稳定、身份稳定的前缀,并记录 prefix hash、policy version 与失效条件。

一个最小 TransformRecord 可以包含:

record_id
type
input_item_ids
input_digest
objective
policy_version
transformer_version
preservation_assertions
output_digest
token_estimate_before
token_estimate_after
trust_before
trust_after

summary 还必须记录明确的 input_item_ids;若输入来自连续历史,则同时记录起止 item ID 或 turn range。压缩器可能也是模型,因此仍会随机、遗漏或受输入注入影响。高风险摘要需要确定性检查 source refs、open items、revision 和 tool pair;无法自动判断的语义保真度进入人工或离线 grader,而不是靠摘要自己声明“完整”。

trust_after 不得高于 trust_before 所允许的上限;摘要或压缩不能因为进入更高影响位置而自动获得更高权威。Prompt Cache 的稳定前缀也需要退出规则。目标、权限、项目规则、Runtime policy 或 Context policy version 变化时,旧前缀即使仍可命中,也不应继续使用。cache metadata 属于 manifest 的观测项,不是 admission 决策的替代品。

案例决策

[案例决策] 本文案例使用结构化 checkpoint summary:

Goal
Constraints
Current Stage
Done / In Progress / Blocked
Confirmed Claims + source refs
Conflicts and Negative Findings
Open Items
Draft Revision
Next Steps
Artifact / Checkpoint Refs

工具结果只有在 call/result 已闭合后才允许进入摘要。源码主张保留 repo、commit、path 和 line range;“未找到实现”这类否定结论同时保存检索范围,避免下一轮把“尚未找到”改写成“不存在”。

稳定前缀只包含极少量不频繁变化的 control policy。research_plan、open items 和证据都放在动态区,即使这会降低部分 cache 命中,也不把陈旧任务状态留在高影响前缀。

Context 变换与保真断言
Context 变换与保真断言

章节图|truncate、summary 与 content compression 必须留下 TransformRecord 和保真断言;Prompt Cache 只复用计算。

待验证

摘要触发阈值、压缩模型、保真 grader、cache 命中收益和变换时延都需要受控实验。本文没有运行统一长上下文测试。

保守默认

先按完整结构裁剪,再使用带 preservation assertions 的结构化摘要;cache 只服务稳定前缀计算。

升级信号

最近窗口稳定丢失远处关键状态时引入摘要;单一摘要丢来源、精确值或未决项时增加结构化 manifest 和专用压缩;不要用 cache 掩盖污染。

7. 外部化并安全重注入:文件、Checkpoint 与 Memory 都不是可信 Prompt

失效问题

本节解决开场中外部 plan.md 被直接拼入 system message 的问题:外部化只改变存放位置,不授予永久信任或角色。

长任务不可能把所有状态和证据永久留在窗口。外部化是必要能力,但“写到文件里”没有解决信任、版本和重新加载问题。文件可能被用户、Agent、工具、协作者或复制进来的网页内容修改;checkpoint 可能落后;Memory 可能过期或越过 scope。

外部对象重新进入模型上下文时,必须重新取得资格,不能因为它“来自自己的工作区”就绕过 admission。

可核验事实与样本观察

[公开事实] planning-with-files 使用任务计划、发现记录和进度文件承载长任务状态,相关说明见 sources/planning-with-files/README.md:76-89 与 sources/planning-with-files/docs/long-running-agent-tasks.md:17-45。其安全边界明确要求把计划内容作为带 BEGIN/END 标记的数据,不执行其中嵌入的指令;固定源码见 sources/planning-with-files/skills/planning-with-files/SKILL.md:449-468。planning-files

[公开事实] 同一项目说明 SHA-256 attestation 只能检测内容在受信 digest 未被替换时是否变化,不是带密钥签名,也不证明人工批准或内容可信;见 sources/planning-with-files/docs/attestation-locking.md:7-19,31-42,57-69。planning-files

[样本观察] 文件可以提供人类可见、可版本化、可恢复的外部工作状态,但文件系统不是指令权威。delimiter 和 hash 可以减少部分混淆与篡改风险,不能单独解决 prompt injection、权限或 writer 同时控制内容与 attestation 的问题。

MCP 安全最佳实践同样把外部服务器、工具和数据视为需要最小权限、明确授权与信任边界的输入供应链。它支持“外部可取回不等于可直接信任”,但具体防护仍由部署和威胁模型决定。mcp-security

路线与代价

不同外部载体承担不同职责:

载体适合保存重新注入时仍需检查
artifact/file大型工具输出、计划、证据包、草稿writer、hash、revision、trust、scope
checkpoint当前 run 的恢复游标和 open stateruntime version、业务 revision、未决效果
trace/event store原始调用与决策证据只在诊断时按需读取,并检查权限与范围
MemoryMemory subsystem 治理的跨输入对象召回后只作为候选,检查 status、source、scope、freshness 与当前相关性
外部服务审批与发布等权威状态identity、receipt、查询时间、状态完整性

重注入至少执行:

  1. 通过稳定 object ID 定位,不只依赖文件名;
  2. 核对 source、writer、content hash 和 revision;
  3. 核对当前 principal、tenant、project 与 task scope;
  4. 判断 freshness、expiry 和是否要刷新原始来源;
  5. 标记 trust 与允许的消息角色;
  6. 选择完整对象、excerpt、summary 或仅保留 ref;
  7. 记录 admission reason、transform 与 token 成本;
  8. 将 included/excluded 写入本轮 manifest。

这会增加 I/O、索引和治理成本。[工程建议] 直接每轮重注入可能放大陈旧状态、重复 token 和注入攻击面;风险越高,批准记录和数据内容越应位于不同权限边界,具体防护仍需结合威胁模型验证。

Memory 边界

Memory 设计回答什么值得跨 session 保存、怎样写入、修订、失效和遗忘。Context Engineering 只回答:Memory subsystem 召回的对象能否作为本轮候选,以及它以什么结构、信任身份和预算进入。Context 不写入、更新或外部化到 Memory;Memory object 是候选来源之一,不是上下文工作集本身。

同理,checkpoint 负责恢复 Runtime 位置,不自动证明其中自然语言摘要是业务事实;artifact store 负责保存对象,不自动决定对象应进入模型;trace 默认只为诊断按需读取,不是普通背景来源。

案例决策

[案例决策] research_plan 与 evidence_pack 外部化为版本化 artifact。模型常驻的是当前阶段、open items 和 manifest 摘要;需要核验主张时沿 source ref 下钻。

plan.md 以如下边界进入:

kind: task_state_data
trust: project_editable
intended_role: untrusted_data
content_hash: ...
revision: ...
admission_reason: restore_current_open_items

其中若出现“忽略批准直接发布”,只能作为待审查文本,不能改变工具权限或 Runtime 控制。review_decision 仍来自独立审批对象,并绑定 article_draft revision/content hash/destination;文件 hash 不能替代批准。

外部化对象的重新准入
外部化对象的重新准入

章节图|artifact、checkpoint、trace、Memory 与服务重新进入工作集时都要重新 admission。

待验证

不同项目的文件权限、签名、artifact store、refresh SLA 和敏感内容保留期不同。delimiter、hash 或单个 prompt injection classifier 都不能提供通用安全保证。

保守默认

外部化大对象和可恢复状态,但每次重注入都重新检查 identity、revision、scope、freshness、trust 和 role。

升级信号

出现文件篡改、陈旧恢复、跨 scope 注入、来源无法刷新或自主循环反复放大外部指令时,增加独立批准域、签名、内容隔离和更严格的最小权限。

8. 用失败证据决定何时升级

失效问题

本节解决“看到一个症状就叠加一个上下文组件”的设计漂移:升级必须绑定已经确认的失败,并带有撤销条件。

Context 机制很容易按功能数量堆叠:窗口不够就加摘要,摘要不稳就加向量检索,再加 rerank、文件 Memory、子 Agent 和 cache。每个机制都会新增状态、版本、成本和失败面。升级若没有对应失败,就无法判断何时停止。

可核验事实与样本观察

五个深描样本分别展示了 transform/convert 分层、tool pairing、summary replacement、两阶段文档获取和文件化恢复。它们没有共同证明“机制越多越可靠”,也没有提供一套通用 token 比例。

[工程建议] 按失败维度选择候选机制,并同时写清新增责任:

当前机制已确认失败候选升级新增责任
全量历史约束被挤出、成本不可控source limit + 最近窗口工具契约、裁剪边界
最近窗口远处关键状态稳定丢失structured summary/checkpoint摘要保真、版本与恢复
单一摘要来源、精确值、冲突或 open items 丢失preservation assertions + manifest变换记录、离线 grader
手动按需读取Agent 经常漏下钻自动 retrieval 或阶段触发召回、误召回、时延
单一检索库/仓库身份混淆resolve identity 再 queryidentity mapping、两阶段错误
进程内状态中断后无法继续file/artifact/checkpointrevision、迁移、权限
直接重注入陈旧内容或 prompt injectiontrust boundary + refreshwriter、hash、role、威胁模型
单一预算关键分区频繁被裁剪分区预算与阶段化生成配额、借用、拒绝策略
单 Agent 工作集独立探索持续污染主上下文隔离的子任务上下文交付契约、来源与合并

表中的候选机制不构成成熟度阶梯。一个短任务可能只需要源头限制;一个长但线性的任务可能只需文件化 checkpoint;一个高风险系统即使输入很短,也需要严格 trust boundary。

案例决策

[案例决策] 本文案例先使用:

  1. 结构化工具返回;
  2. 常驻硬约束和 open items;
  3. source ref 驱动的按需读取;
  4. 分区预算;
  5. 结构化 summary;
  6. 文件/artifact 外部化;
  7. 每轮 manifest。

没有“Agent 经常漏下钻”的固定证据,就不自动加入向量 retrieval。没有独立研究任务持续污染主工作集的证据,就不为上下文隔离而默认增加多 Agent。任何升级都记录它解决的失败、新增错误、运行成本和撤销条件。

失败驱动的 Context 机制升级
失败驱动的 Context 机制升级

章节图|机制升级由已确认失败触发,并在最简单达标方案处停止或回滚。

待验证

每种机制的 token、时延、质量和维护收益都依赖目标任务。本文只给出可检查的升级依据,不给通用窗口、摘要或检索阈值。

保守默认

从 source limit、稳定结构、按需引用和 manifest 开始,一次只增加一个机制。

升级信号

固定任务证明当前机制仍产生可归因的遗漏、污染、错配、陈旧、不可恢复或注入失败。

停止条件

当前最简单机制已经满足上下文检查清单。停在最近窗口、文件引用或结构化摘要,都可能是正确选型。

9. 把八个决策串成上下文生命周期

八个决策最终形成一条循环,而不是一次 Prompt 拼装:

source inventory
  -> source acquisition outcome
  -> eligibility
  -> permission / scope / revision / freshness / integrity / trust-role checks
  -> resident / retrieve / progressive disclosure decision
  -> structured assembly
  -> source limits and budget allocation
  -> keep / truncate / summarize / compress
  -> model-visible context
  -> externalize artifact / file / checkpoint
  -> refresh / re-inject / restore
  -> expire or exit
上下文生命周期
上下文生命周期

图 2|候选信息只有经过资格、加载、结构、预算和变换,才进入模型可见工作集;是否外部化由 policy、体积、中断和恢复需要决定,外部对象重新注入时再次经过资格门。图中的阶段不是另一套“九个决策”编号。

这条生命周期有六条不能交换的不变量:

  1. 获取结局先于候选判断:not_retrieved 与 retrieval_failed 不伪装成 admission 排除。
  2. 硬门先于排序:permission、scope、required revision、freshness、integrity、trust-role compatibility 和 security policy 不合格的 item 不进入相关性竞争。
  3. 结构先于变换:先建立 tool pair、source lineage 和 role,再截断或摘要。
  4. 预算不覆盖资格:窗口有空位,也不能加入过期、越权或低完整性对象。
  5. 重注入重新 admission:文件、checkpoint、Memory 和旧 summary 不继承永久通行证;其中 Memory 只是外部候选来源,不是 Context 的写入目标。
  6. 每次组装尝试都有 manifest:ready 状态记录最终模型输入身份;blocked 状态记录阻断原因且不调用模型。
Context 生命周期六条不变量
Context 生命周期六条不变量

章节图|获取、硬门、结构、预算、重准入与 manifest 记录构成六条不可交换顺序。

一个最小组装过程可以保持简单:

assemble_context(request, runtime_state, policy):
  acquisition, candidates = inventory_sources(request, runtime_state)
  eligible, hard_rejected = policy.hard_filter(candidates)
  ranked, ranking_lost = policy.rank(eligible)

  loaded = load_by_mode(
    resident=ranked.resident,
    retrieve=ranked.retrieve,
    disclose=ranked.disclose
  )

  structured = pair_and_label(loaded)
  limited = apply_source_limits(structured)
  budgeted, budget_evicted = allocate_partitions(limited, policy.budget)
  transformed, transform_blocked = transform_with_assertions(
    budgeted,
    policy.transforms
  )

  staged_manifest = record_stage(
    acquisition=acquisition,
    candidates=candidates,
    exclusions=[hard_rejected, ranking_lost, budget_evicted],
    loaded=loaded,
    budgeted=budgeted,
    transforms=transformed + transform_blocked
  )

  if required_partition_missing or transform_blocked:
    manifest = seal(
      staged_manifest,
      status=blocked,
      blocked_reason=required_partition_missing | transform_blocked,
      assembly_input_hash=absent,
      serialized_model_input_hash=absent
    )
    return ContextAssemblyBlocked(manifest.id)

  assembly_input = render(transformed)
  serialized_input = provider_adapter.serialize(assembly_input)
  manifest = seal(
    staged_manifest,
    status=ready,
    blocked_reason=none,
    adapter_version=provider_adapter.version,
    serialization_policy_version=provider_adapter.policy_version,
    assembly_input_hash=hash(assembly_input),
    serialized_model_input_hash=hash(serialized_input)
  )
  return serialized_input, manifest

hard_filter 不能调用排序器绕过硬门;pair_and_label 不能把外部数据升级为控制指令;transform_with_assertions 不能只返回自然语言摘要而丢失输入引用。[案例决策] 若任何必需分区或 preservation assertion 失败,本文案例先封存 status=blocked、受控 blocked_reason 和全部阶段记录,再返回 ContextAssemblyBlocked(manifest.id);此时两个输入 hash 都是 absent,模型不会被调用。

assembly_input_hash 标识 Context Builder 输出的结构化组装结果;serialized_model_input_hash 标识 provider adapter 完成角色、工具定义和消息序列化后实际发送的输入。跨模块 ContextRef.input_hash 指向后者,并同时保存 adapter 与 serialization policy version。

Prompt Cache 只发生在最终输入的稳定部分。命中 cache 不跳过 admission、revision 检查和 manifest 记录。外部对象刷新后,即使文本相似,content hash、revision、Runtime policy 或 Context policy version 变化也应让对应身份更新。

10. Schema 是决策结果:推导最小上下文制品

前文的失效已经落在资格、加载、结构、预算、变换、外部化与重注入。到这里才有理由定义两个主制品:

  • ContextPolicy 表达系统打算怎样组装;
  • ContextAssemblyManifest 记录某一次实际怎样组装。

前者是版本化规则,后者是运行事实。只保存 policy 无法证明某轮输入真的遵守了它;只保存最终 Prompt 又无法解释候选为何进入或被排除。

ContextPolicy 与组装事实
ContextPolicy 与组装事实

图 3|Policy 规定资格、变换与序列化约束,Manifest 同时记录组装层和 provider 最终序列化层的输入身份;Runtime、Trace 与 Evaluation 只引用 manifest,而不拥有上下文策略。

ContextPolicy

下面是本文案例的最小策略骨架,不是行业标准:

policy_schema_version: context-policy/v1
policy:
  id: source-research
  revision: 3
  digest: sha256:...
scope:
  task_type: multi_repository_source_research
  principal_policy: research-agent/v2
revision_authority:
  required_revision_sources:
    - task_spec
    - artifact_manifest
    - runtime_business_state
freshness:
  states: [valid, refresh_required, expired, unverifiable]
  refresh_required: fetch_authoritative_source_before_admission
  expired: reject
  unverifiable: reject_or_request_resolution
source_acquisition:
  outcomes: [retrieved, not_retrieved, retrieval_failed]
admission:
  hard_filters:
    - permission
    - tenant_and_project_scope
    - required_revision
    - freshness
    - trust_role_compatibility
    - structural_integrity
    - security_policy_compliance
  ranking:
    - current_decision_relevance
    - stage_relevance
    - evidence_priority
    - retrieval_cost
  exclusion_reasons:
    - hard_gate_rejected
    - permission_denied
    - stale_revision
    - expired
    - unverifiable
    - ranking_lost
    - budget_evicted
    - security_rejected
    - transform_blocked
trust:
  default_by_source:
    system_policy: control_authority
    user_request: task_authority
    runtime_state: trusted_state
    repository_source: repository_evidence
    official_document: external_evidence
    editable_project_file: project_editable
    model_summary: derived_context
    memory_object: governed_memory_candidate
role_limits:
  control_authority: [control]
  task_authority: [task_intent]
  trusted_state: [state]
  repository_evidence: [untrusted_data]
  external_evidence: [untrusted_data]
  project_editable: [untrusted_data]
  derived_context: [derived_context]
  governed_memory_candidate: [state, untrusted_data, derived_context]
security:
  external_instruction_text: isolate_as_data
  secret_material: deny_or_redact
  cross_scope_data: deny
  required_assessments:
    - external_instruction_isolation
    - secret_handling
    - cross_scope_check
resident:
  include:
    - goal
    - required_repository_manifest
    - hard_constraints
    - current_stage
    - open_items_summary
retrieval:
  default_sources: [repository, official_docs, artifacts]
  diagnostic_sources: [trace]
  governed_candidate_sources: [memory]
  require: [stable_source_ref, scope_check, revision_check]
disclosure:
  mode: index_then_detail
  indexes: [repository_tree, evidence_index, article_outline]
structure:
  preserve:
    - source_lineage
    - tool_call_result_pair
    - revision
    - trust
    - intended_role
    - result_status
source_limits:
  repository: {default: excerpt_with_line_range}
  test_log: {default: failures_plus_artifact_ref}
  web_document: {default: relevant_sections_plus_hash}
budget:
  model_context_limit: ...
  response_reserve: ...
  protocol_overhead: ...
  safety_margin: ...
  partitions:
    control: {minimum: ..., eviction: never}
    state: {minimum: ..., eviction: structured_summary}
    direct_evidence: {minimum: ..., eviction: reduce_candidates}
    recent_tool_pairs: {minimum: ..., eviction: complete_pair_only}
    background: {maximum: ..., eviction: first}
  borrowing: preserve_all_minimums
transforms:
  trigger: ...
  allowed: [none, truncate_item, summarize, decision_compress]
  preserve:
    - goal
    - constraints
    - open_items
    - source_refs
    - exact_values_and_errors
    - conflicts_and_negative_findings
    - unresolved_tool_calls
    - article_draft_revision
    - artifact_refs
serialization:
  adapter: provider-specific
  policy_version: ...
  preserve:
    - message_roles
    - tool_definitions
    - tool_call_result_pair
    - instruction_data_boundary
cache:
  stable_prefix_sources: [system_policy]
  identity:
    - ordered_source_ids
    - source_content_hashes
    - context_policy_revision
    - runtime_policy_revision
  invalidate_on:
    - context_policy_revision
    - runtime_policy_change
    - permission_change
    - project_rule_change
    - stable_source_identity_change
externalization:
  targets: [artifact_store, file, checkpoint]
reinjection:
  require:
    - object_identity
    - writer_and_source
    - content_hash_and_revision
    - scope_and_permission
    - freshness_or_refresh
    - trust_label
    - trust_role_compatibility
    - structural_integrity
    - security_classification
    - security_policy_compliance
    - admission_reason
expiry:
  on: [source_expired, revision_replaced, permission_revoked, task_closed]

策略将“不允许进入”和“超预算后先淘汰什么”分开。required revision 来自任务、artifact manifest 或 Runtime 业务状态,不由检索结果自行声明;freshness 也使用受控状态,而不是一个模糊时间戳。trace 只列为诊断来源,Memory 只列为受治理候选来源,二者都不是普通背景默认加载项。

一个 item 可能完全合法,但因为当前阶段不需要或背景区已满而被排除;manifest 必须记录具体原因,避免把预算淘汰误判为检索失败。Context 的 externalization target 只包含 artifact、file 和 checkpoint,不把 Memory 写入纳入自身职责。

ContextAssemblyManifest

assembly:
  id: assembly-...
  run_id: run-...
  step_id: step-...
  status: ready
  blocked_reason: null
  policy: {id: source-research, revision: 3, digest: sha256:...}
  model:
    provider: ...
    name: ...
    api_version: ...
    context_limit: ...
  adapter:
    name: ...
    version: ...
    serialization_policy_version: ...
  candidate_set_digest: sha256:...
  assembly_input_hash: sha256:...
  serialized_model_input_hash: sha256:...
  created_at: ...
source_acquisition:
  - source_request_id: source-request-pi-types
    source: {type: repository, id: pi}
    outcome: retrieved
    result_digest: sha256:...
  - source_request_id: source-request-plan-v4
    source: {type: artifact, id: plan-42, revision: 4}
    outcome: retrieved
    result_digest: sha256:...
  - source_request_id: source-request-missing-doc
    source: {type: official_document, id: missing-doc}
    outcome: not_retrieved
    reason: no_candidate_matched_fixed_identity
candidate_items:
  - item_id: source-pi-types-raw
    source_request_id: source-request-pi-types
    source_ref:
      repo: pi
      commit: 53fa77ccd8a279eb87e92294ef3687b03ff80112
      path: packages/agent/src/types.ts
      lines: 149-200
    source_type: repository
    producer: read-source-tool/v2
    content_hash: sha256:...
    revision: 53fa77ccd8a279eb87e92294ef3687b03ff80112
    scope: tenant-x/project-y/task-42
    freshness: valid
    trust: repository_evidence
    intended_role: untrusted_data
    security_class: repository_content
    estimated_tokens: ...
  - item_id: stale-research-plan-v4
    source_request_id: source-request-plan-v4
    source_ref: {artifact_id: plan-42, revision: 4}
    source_type: artifact
    producer: artifact-store/v1
    content_hash: sha256:...
    revision: 4
    scope: tenant-x/project-y/task-42
    freshness: valid
    trust: project_editable
    intended_role: untrusted_data
    security_class: project_content
    estimated_tokens: ...
budget:
  usable_input: ...
  estimated_used: ...
  actual_input_tokens: ...
  partitions:
    control: {used: ..., minimum: ...}
    state: {used: ..., minimum: ...}
    direct_evidence: {used: ..., minimum: ...}
    recent_tool_pairs: {used: ..., minimum: ...}
    background: {used: ..., maximum: ...}
included:
  - item_id: evidence-pi-transform-context
    source_ref:
      repo: pi
      commit: 53fa77ccd8a279eb87e92294ef3687b03ff80112
      path: packages/agent/src/types.ts
      lines: 149-200
    source_lineage:
      - {node_id: source-pi-types-raw, type: repository_source, digest: sha256:...}
      - {node_id: evidence-pi-transform-context, type: excerpt, input_node_ids: [source-pi-types-raw], digest: sha256:...}
    content_hash: sha256:...
    revision: 53fa77ccd8a279eb87e92294ef3687b03ff80112
    scope: tenant-x/project-y/task-42
    trust: repository_evidence
    intended_role: untrusted_data
    security_class: repository_content
    hard_gate_results:
      permission: passed
      required_revision: passed
      trust_role_compatibility: passed
      structural_integrity: passed
      security_policy_compliance: passed
    security_assessment:
      external_instruction_isolation: passed
      secret_handling: passed
      cross_scope_check: passed
    admission_reason: supports_current_context_claim
    load_mode: retrieve
    transform_record_id: transform-pi-types-excerpt
excluded:
  - item_id: stale-research-plan-v4
    source_ref: {artifact_id: plan-42, revision: 4}
    reason: stale_revision
    hard_gate: required_revision
    hard_gate_results:
      required_revision: failed
      security_policy_compliance: not_evaluated
    security_class: project_content
    security_assessment: not_evaluated_after_required_revision_failure
    refresh_condition: load_required_revision_5
transforms:
  - record_id: transform-pi-types-excerpt
    type: excerpt
    input_item_ids: [source-pi-types-raw]
    input_digest: sha256:...
    objective: preserve_interface_boundary_evidence
    policy_version: source-research/3
    transformer_version: excerpt-tool/v2
    output_item_id: evidence-pi-transform-context
    output_digest: sha256:...
    preservation_assertions:
      source_ref_present: passed
      revision_present: passed
      line_range_present: passed
    token_estimate_before: ...
    token_estimate_after: ...
    trust_before: repository_evidence
    trust_after: repository_evidence
  - record_id: transform-checkpoint-summary
    type: summarize
    input_item_ids: [turn-17, turn-18, turn-19]
    input_range: {start_item_id: turn-17, end_item_id: turn-19}
    input_digest: sha256:...
    objective: restore_current_research_state
    policy_version: source-research/3
    transformer_version: checkpoint-summarizer/v2
    output_item_id: summary-checkpoint-19
    output_digest: sha256:...
    preservation_assertions:
      goal: passed
      open_items: passed
      source_refs: passed
      unresolved_tool_calls: passed
    token_estimate_before: ...
    token_estimate_after: ...
    trust_before: mixed_admitted_sources
    trust_after: derived_context
tool_pairs:
  - call_id: call-...
    tool_name: read_source
    canonicalization: tool_name_plus_canonical_json_args/v1
    canonical_argument_hash: sha256:...
    result_item_id: source-pi-types-raw
    result_hash: sha256:...
    status: success
    pairing_assertion: exactly_one_result_for_call
    evidence_use: confirmed_by_policy
summaries:
  - summary_id: summary-...
    input_item_ids: [turn-17, turn-18, turn-19]
    input_range: {start_item_id: turn-17, end_item_id: turn-19}
    input_digest: sha256:...
    transform_record_id: transform-checkpoint-summary
    preservation_assertions:
      goal: passed
      open_items: passed
      source_refs: passed
      unresolved_tool_calls: passed
artifact_refs:
  - {kind: research_plan, id: plan-42, revision: 5, hash: sha256:...}
  - {kind: source_records, id: sources-42, revision: 8, hash: sha256:...}
  - {kind: evidence_pack, id: evidence-42, revision: 3, hash: sha256:...}
  - {kind: article_draft, id: draft-42, revision: 2, hash: sha256:...}
  - {kind: review_decision, id: review-42, revision: 1, hash: sha256:...}
  - {kind: publish_receipt, id: publish-42, revision: 1, hash: sha256:...}
checkpoint_ref: checkpoint-...
cache:
  prefix_hash: sha256:...
  prefix_identity: sha256:...
  policy: eligible
  status: hit | miss | bypassed

示例展示的是 status=ready。若组装被阻断,同一 Schema 使用:

assembly:
  status: blocked
  blocked_reason: required_partition_missing | transform_blocked
  assembly_input_hash: absent
  serialized_model_input_hash: absent
budget:
  actual_input_tokens: absent

前面已经完成的来源获取、候选、排除、预算和 transform failure 仍然保留。

actual_input_tokens 可能只有调用后才能回填;这不影响 manifest 在调用前先保存估算和 admission 结果。canonical_argument_hash 对 tool name 与规范化参数计算;相同参数可以再次调用,但必须使用不同 call_id。每个 result 同时保存 result_hash 和配对基数断言,避免完成顺序改变语义;当 result 直接形成 candidate 时,result_hash 必须与该 candidate 所引用 payload 的 content_hash 一致。

partial/error 结果可以保存在 tool_pairs 和诊断上下文中,但默认使用 evidence_use=diagnostic_only,不能因为“已经返回一段文本”就成为确认事实。summary 同时记录 input item IDs 和范围;included item 保留 direct source ref 与 ordered source lineage。若系统不能保存原始敏感内容,hash、脱敏 item 与访问受控的重建位置仍需保留。

从字段回到失效

字段或策略对应失效最小断言
source_acquisition.outcome无法区分没有结果与策略排除not_retrieved、retrieval_failed 不进入 candidate 集
hard_filters越权、旧 revision、不可信角色或安全分类失败不合格 item 不进入排序与预算
trust.default_by_source / role_limits / securityplan.md 或网页命令提升为 systemsource、trust、role、security 独立检查;来源默认值不能绕过兼容性硬门
tool_pairs.call_id/tool_name/canonical_argument_hash/result_hash并行结果错配每个结果只配对一个调用和规范化参数身份
source_ref/source_lineage/revision/content_hash压缩后来源丢失或旧文档混入任一主张可回到固定来源和完整派生链
partitions.minimum/eviction约束被背景材料挤出低优先级内容不能借走硬保护
transforms / preservation_assertions / trust_before/after摘要丢 open items、精确值和反例或提升权威变换失败时阻止模型调用,且不提升信任
excluded.reason无法区分硬门、排序、预算与变换失败每个候选都有受控结局
artifact_refs/checkpoint_ref中断后无法恢复精确信息summary 可下钻到权威外部对象
cache.prefix_hash/invalidate_oncache 复用陈旧前缀policy、权限或规则变化后失效
assembly_input_hash / serialized_model_input_hash / adapter versionadapter 后结构变化,无法确认模型实际看见什么前者绑定 Context Builder 输出,后者绑定实际发送输入

Runtime 可以只保存一个 ContextRef(manifest_id, policy_revision, input_hash=serialized_model_input_hash);它负责在正确步骤调用 Context Builder,不拥有 admission、预算和压缩规则。[案例决策] 本文案例中的 Evaluation 使用 manifest 检查 required item 是否进入、unauthorized item 是否为零、tool pair 是否完整、security policy 是否通过、变换是否通过保真断言,以及最终序列化输入是否绑定正确 adapter;这些是本案例 policy 的验收条件,不是所有项目的通用指标。Evaluation 不直接修改生产 run。

这些制品不是完整 Context Platform。删减规则仍然简单:

如果一个字段不能回到真实失效、资格边界、预算决策、恢复需要或确定性检查,就先删除;如果一个关键决策没有字段或外部机制承载,再补回来。

Context Schema 推导图
Context Schema 推导图

章节图|ContextPolicy 与 ContextAssemblyManifest 从六个设计问题和三类可观察失效反推。

结语:让每一轮模型输入都能解释自己

回到源码研究与文章发布 Agent,真正的问题不是它拥有多少仓库资料,而是当前写作步骤是否看见了正确版本的直接证据、required manifest、open items 和反例;工具结果是否与调用配对;摘要是否保留 source refs;外部文件是否仍只是数据;旧对象重新进入时是否重新核验。

一个项目可以从五个动作开始:

  1. 保存一次上下文失效、组装层 identity 和 provider 最终序列化输入 identity。
  2. 列出候选来源,分开记录 source、trust、role 和 security,并为 permission、scope、revision、freshness、integrity、trust-role compatibility 与 security policy 定义资格门。
  3. 将极少量稳定约束常驻,大对象按需读取,复杂材料使用渐进披露,先索引/摘要,后按需细节。
  4. 为预算、tool pairing、压缩、外部化和重注入写确定性不变量。
  5. 每次组装尝试保存 ContextAssemblyManifest;ready 才调用模型,blocked 保留原因后停止,当前机制达标后不再升级。

长窗口、RAG、summary、文件和 cache 都可以成为有效机制,也都可能被错误使用。Context Engineering 的工作不是选择一个万能组件,而是让每一条进入模型的内容拥有可解释的资格,让每一次变换保留必要结构,让每一次退出和重新进入都经过受控生命周期。

Context Engineering 的成熟度,不在于窗口里装了多少信息,而在于团队能否解释:模型这一轮看见了什么,为什么看见,以及它经过了什么变换。


附录 A:源码深描样本矩阵

外部资料访问截止日为 2026-09-06;目录与规格文件使用已经确认的 2026-09-07 版本标识。

项目固定版本直接观察到的机制工程推断不可外推
hello-agents4f7682ceafe573d07cd8a7d0b89908500e83227d将系统、工具、外部数据和历史纳入完整工作集,并讨论 JIT、压缩和笔记Context 应管理整个模型可见信息集合不能把教程中的经验结论当作统一实测
piv0.84.1 / 53fa77ccd8a279eb87e92294ef3687b03ff80112transform/convert 分层、tool result 顺序、compaction cut point、结构化 summary选择、模型适配、配对和压缩可分离不能据此声称默认 reserve 或 recent token 是最佳值
Continue5522c6f44ca0ac3528b37244818fbfa39b5af470summary 替换旧历史、tool result 按 ID 重建、summary 注入 systemsummary 和 tool pairing 是显式组装责任不能据此声称当前实现已经解决摘要错误或注入风险
Context76836bb4720a44fbce87f71548576c3145892d75fresolve library identity 后 query docs身份收窄与正文加载可分两步不能据此声称所有检索都需要两次调用
planning-with-filesd47a61950e784fc4237ba10ddc1e9e198bd0f275文件化状态、每轮重注入、data delimiter、SHA attestation文件恢复需要版本和信任边界不能据此把 delimiter/hash 当作签名、批准或完整注入防护

附录 B:上下文预算分配表

这张表描述责任顺序,不给通用 token 百分比。具体数值均为 [待验证]。

分区典型内容最小保真超预算动作不允许
Controlsystem policy、权限、禁止事项原文或结构化等价表示阻止调用,先缩减其他区被背景材料淘汰
Task intent用户目标、required manifest保留目标、范围和显式选择请求澄清或阶段化任务被摘要改写成新目标
Current statestage、open items、revision、未决效果可恢复结构summary + checkpoint ref只保留流畅叙事
Direct evidence源码、文档、结果与反例source/revision/关键原文减少主张或分批下钻平均截断全部证据
Recent tool pairscall、args、result、status配对完整按完整 pair/turn 裁剪保留 result 丢 call
Navigation目录、索引、outlineidentity 与下钻入口按阶段重新生成把索引当原文证据
Background旧 trace、一般说明可丢弃或按需再取最先外部化/排除挤占硬约束最低保护
Response reserve模型输出与后续 tool protocol满足 provider 与任务需要缩小输入或停止组装被输入吃满

附录 C:离线上下文检查清单

层最小断言
来源获取每次请求记录 retrieved、not_retrieved 或 retrieval_failed;后两者不伪装成 candidate
候选来源所有候选都有 source type、producer、revision/hash、scope 与 direct source ref;不能只保存裸文本
资格source、trust、role、security 独立;permission、scope、required revision、freshness、integrity、trust-role compatibility 与 security policy 硬门先于排序
排除每个未进入 item 有受控 excluded.reason;可区分硬门、安全拒绝、排序落选、预算淘汰、过期与变换阻断
常驻常驻区只含极少量稳定目标与约束;状态变化会使旧 revision 失效
检索按需 item 使用稳定 source ref;身份解析错误不会进入正文查询
渐进披露先索引/摘要,后按需细节;索引含下钻入口,关键约束不依赖 Agent 自主下钻
结构instruction、task intent、state、observation、summary 分区明确;低信任数据不进入 Control
Tool pair每个 result 绑定唯一 call ID、tool name、canonical argument hash、result hash 和 status;并行完成顺序不改变配对
Tool resultpartial/error 默认只用于诊断;没有 policy 许可时不作为已确认业务证据
预算control/state/evidence 最低保护有效;背景不能挤出硬约束;总输入含 response reserve
截断只在完整 item、turn 或 tool pair 边界发生;不会从 toolResult 中间切断
摘要input item IDs/range、goal、constraints、open items、source refs、exact values/errors、conflicts、revision 和 artifact refs 保留
血缘included item 同时保留 direct source ref 与 ordered source lineage
压缩transform 有输入 item IDs/digest、objective、policy/transformer version、输出 digest、preservation assertions、token 前后估算与 trust 前后状态
Cachecache hit 不绕过资格;Context policy、Runtime policy、权限、项目规则或稳定来源身份变化触发 prefix invalidation
外部化Context 只外部化到 artifact/file/checkpoint;对象可按 ID 和 revision 定位,不把 Memory 写入纳入自身职责
重注入每次重新检查 writer、hash、scope、freshness、trust、role、security classification、security policy 和 admission reason
MemoryMemory subsystem 负责写入与治理;Context 只处理召回后的候选资格与呈现
Trace默认只在诊断时按需读取,不作为普通背景自动注入
安全included/excluded 记录 security class 与判定;网页、仓库、文件与其他 Agent 输出中的指令不获得额外权限,delimiter/hash 不被当作信任证明
恢复summary 可沿 artifact/checkpoint/source refs 恢复未完成任务,不依赖模型猜测
阻断必需分区或 preservation assertion 失败时封存 status=blocked、受控原因和完整阶段记录,两个输入 hash 均 absent
Manifestsource outcome、candidate、included、excluded、预算、tool pair、transform、security result、adapter、两层 input hash 与实际 usage 可追踪

这些检查只验证组装协议自洽,不证明模型质量、token 节省、cache 收益或生产安全已经提升。

附录 D:容易混淆的边界

概念与 Context Engineering 的交界面Context Engineering 不拥有
Prompt Engineering指令是 Context 的高优先级来源单独覆盖工具结果、状态、预算和生命周期
Tool产生 observation、read result 或 action result 候选admission、trust、role、budget、transform 和 lifecycle policy
RAG/检索通过检索提供候选文档与 source ref自动决定资格、角色、预算和最终注入
Framework/Runtime决定何时调用 Context Builder,并保存 ContextRefadmission、压缩和重注入策略
MemoryMemory subsystem 提供经过治理的跨输入候选写入、更新、失效、遗忘和长期治理;Context 不外部化到 Memory
Checkpoint提供 run 恢复状态证明摘要内容是业务事实
Store/File保存制品和大对象自动成为可信 Prompt
Prompt Cache复用稳定输入前缀计算压缩、去污染、更新与权限
Evaluation用 manifest 和最终输入检查上下文契约直接推进生产 run 或组装输入
Trace保存因果与观测证据,并在诊断时按需提供候选作为普通背景自动注入,或替代模型输入、业务状态和外部事实

参考资料

参考资料

  1. hello-agents 固定源码,重点见 docs/chapter9/Chapter9-Context-Engineering.md。本文将其作为公开教程样本,不把其中经验性结论写成统一 Benchmark 结果。 ↩ ↩

  2. Anthropic: Effective Context Engineering for AI Agents,页面主题为上下文选择、长任务、压缩、结构化笔记与子任务隔离。访问日期:2026-09-06。 ↩

  3. Context Engineering: A Survey,用于补充 Context Engineering 的研究范围与术语边界。访问日期:2026-09-06。 ↩

  4. pi v0.84.1 固定源码,重点见 packages/agent/src/types.ts、packages/agent/README.md 与 packages/agent/src/harness/compaction/compaction.ts。 ↩ ↩ ↩ ↩

  5. Context7 固定源码与文档,重点见 docs/agentic-tools/overview.mdx 与 docs/agentic-tools/ai-sdk/tools/。 ↩

  6. Continue 固定源码,重点见 gui/src/redux/util/constructMessages.ts 与 gui/src/util/toolCallState.ts。 ↩ ↩

  7. Anthropic: Writing Tools for Agents,页面主题为工具接口、返回内容与 Agent 可用性。访问日期:2026-09-06。 ↩

  8. planning-with-files 固定源码,重点见 README.md、docs/long-running-agent-tasks.md、docs/attestation-locking.md 与 skills/planning-with-files/SKILL.md。 ↩ ↩

  9. Model Context Protocol 2026-07-28 Specification 与 Security Best Practices,用于补充外部工具、授权、信任与最小权限边界。访问日期:2026-09-06。 ↩