第 06 章

Context Engineering · 长任务的核心挑战

agent 的 context 每步都在涨,「塞进更大窗口」会撞墙 —— 不是装不下,是模型用不好长上下文。这一章把 context window 当作 agent 的 RAM 来工程化:它为什么有限(三个退化机制 + 实证)、管理它的四个策略(写出去 / 选进来 / 压缩 / 隔离)、compaction 怎么做、什么时候该卸载而非压缩,以及你喂的每个观测本身就是一次 context 决策。前置:Ch2-5;#1 Ch3。

约 2.5 小时
开篇 · 管理 agent 的工作记忆

这是 Agent 工程路书的第 6 章,约 2.5 小时,纯 Mode A,也是第三站的第一章。前两站你搭好了一个能跑、能用工具、安全、抗劫持的 harness。但它现在只扛得住短任务。一旦任务变长,几十上百步跑下去,一件新的事会压垮它:context 会爆炸,模型会在越来越长的上下文里丢三落四、质量衰减。这一章讲怎么管理 agent 的工作记忆,让它在长程任务里始终带着真正需要的那部分上下文,而不是被自己积累的历史压垮。

读完后,你能解释为什么"给更大的窗口就行"会撞墙(三个不同的退化机制 + 实证),能用写出去、选进来、压缩、隔离这四个策略管理一块有限的 context,知道 compaction 该怎么做、什么时候该 offload 而不是 compact,能为长任务设计一个运行时的 context 预算调度,并且理解一件容易被忽略的事:你喂给模型的每一个观测,本身就是一次 context 工程决策。

7 节:0 context 是 agent 的有限工作记忆 · 1 为什么 context 有限(三机制 + 实证)· 2 六个策略其实是四个 · 3 Compaction 深挖 · 4 动态 context 预算 · 5 Observation engineering · 6 边界。

边界 hard line:#1 基础 Ch3 已教 token、context window、RAG 检索这些词汇,这一章不重教,只把 context 当作 agent 的工作记忆引擎来工程化。RAG 的生产管线(多阶段检索、重排、chunking、向量库运维)归数据工程路书,这一章只讲"按需检索作为一种 context 策略"。持久 memory 架构 + 自我改进闭环归下一章 Ch7。attention 为什么会衰减的模型内部机制归 #1 / #4,这一章只引用结论。

0. 你的 agent 不是健忘,是被自己的历史压垮

先看 agent 和聊天机器人的一个根本差异。你在 #1 基础里学过 context window 是模型的工作记忆上限,一块装得下多少 token 的空间。聊天机器人用它,一问一答,context 增长得很慢。但 agent 不一样:agent 的 context 每跑一步都在增长。它读一个文件、context 多一段;调一个工具、context 多一段返回值;再想一步、又多一段推理。Manus 团队实测过一个惊人的比例,agent 的输入对输出大约是 100 比 1,也就是说每生成一个简短的工具调用,背后是不断累积、越堆越高的上下文。任务越长,这堆东西越大。

于是 2025 年有一个很自然的直觉:既然 context 会涨,那就把窗口做得更大,把所有东西都塞进去不就行了?这个直觉撞了墙。撞墙的原因不是装不下,1M token 的窗口 2026 年已经有了。撞墙的原因是,模型用不好这么长的 context。把十万 token 一股脑喂进去,模型反而找不准、记不牢、被噪声带偏。所以 agent 工程要回答的不是"窗口够不够大",而是一个更精细的调度问题:在每一步,把哪个最小、信噪比最高的 token 集合喂给模型,让长任务不崩。这门学科有个名字,叫 context engineering。Anthropic 给的定义很精确:它是在模型推理过程中,策划并维护那个最优 token 集合的一整套策略;核心准则是"找到能最大化你想要结果的、最小的高信噪比 token 集合"。

有一个心智模型能把这件事钉死,是 Karpathy 提的,LangChain 反复引用。把大模型想成 CPU,把它的 context window 想成 RAM,也就是工作记忆。RAM 是有限的,而且越满越慢、装太多反而拖累。于是 context engineering 就成了操作系统级的调度学:在每一步,该把什么调进 RAM、什么调出去、什么压缩、什么留在外面。这一章后面所有的策略,本质上都是这个调度的具体手法。这门学科 2025 年才从零散技巧结晶成一个有名字的工程领域,正是因为"更大窗口就行"这个直觉被现实反复证伪,而下一节就是这个证伪的实证弹药。

1. 为什么 context 有限:三个机制

"context 是有限资源"不是一句口号,它背后有三个不同的退化机制,各有一手实证。把这三个讲清楚,你才会真正相信"更大窗口不等于更好",而不只是听过这句话。这三个机制常被混为一谈,但其实是正交的,分清它们是这一章的第一个素养。

1.1 Context rot:越长越掉(被动退化)

第一个机制叫 context rot。定义很朴素:输入的 token 越多,模型从中准确召回、推理的能力就越差,即使任务本身没变难。这是一种被动的退化,不是模型变笨了,是注意力被摊薄了。根因这里只引用结论(展开属 #1 / #4):transformer 让每个 token 都要关注其他每个 token,n 个 token 就有 n² 对关系,context 越长,模型捕捉这些两两关系的能力就被拉得越稀;加上训练数据里短序列偏多,模型对超长依赖本来就缺经验。

把这件事从口号变成数据的,是 Chroma 2025 年的一份技术报告。他们测了 18 个主流模型,核心发现一句话:模型不会均匀地使用它的 context。性能随输入变长越来越不可靠,连最简单的任务都是如此。这份报告最有价值的地方是它隔离了变量:以前的 benchmark 常把"输入长"和"任务难"混在一起,Chroma 固定任务难度、只变长度,证明了退化就来自长度本身。它还有几个反直觉的子发现都很值得记:哪怕只加入一个干扰项,模型也会掉点,而且不均匀,某些干扰项掉得特别狠;模型在被打乱的上下文上,表现反而比在逻辑连贯的上下文上更好;最极端的一个,GPT-3.5 在长输入下的拒答率高达 60%,而 Claude Opus 4 只有不到 3%。长 context 会触发模型的退化行为。

如果说 Chroma 证明了"长就掉",那 NoLiMa 这项研究证明了"非词面任务掉得更狠"。过去测长 context 常用"大海捞针",在一堆文本里藏一句话再让模型找,但这只测词面匹配,模型常拿满分,造成"长 context 已经解决了"的错觉。NoLiMa 故意让要找的那句话和问题在字面上几乎不重叠,逼模型做语义关联。结果很扎心:13 个号称支持 128K 以上的模型,在短上下文下表现很好,但到 32K 时,其中 11 个就掉到了短上下文基线的一半以下,连 GPT-4o 都从 99.3% 掉到了 69.7%。这引出一个 Ch6 该用的关键指标,叫有效长度:模型能维持基线 85% 分数的最长 context。结论是,模型宣称的 context window,远大于它真正有效的 context window。

context 长度(token · log)→准确率 ↑1K4K16K32K64K128K100%85%50%有效长度阈值(85% 基线)↑ 有效 window声称 128K更大的 window ≠ 更好 —— 喂全 ≠ 喂准
Figure · context rot:输入越长,模型准确召回 / 推理的能力越掉(即使任务没变难)· 横轴 context 长度(log)· 纵轴准确率 · 虚线是 NoLiMa「有效长度」阈值(维持 ≥85% 基线的最长 context)· 声称的 128K window ≫ 有效 window(此处约 16K 就跌破)· 曲线为示意趋势,绝对数字随模型迭代(NoLiMa 实测 32K 时多数模型已腰斩)· 对应正文 第 1.1 节

1.2 Lost in the middle:中间的会被忽略(位置偏置)

第二个机制是位置偏置,有个很形象的名字叫"迷失在中间"。Liu 等人 2023 年发现,相关信息放在 context 的开头或结尾时,模型性能最高;放在中间,性能显著下降,整条曲线呈一个 U 形。连 GPT-4 都逃不掉这个 U 形,它绝对分最高,但中间照样塌陷。这个机制的根源其实和人的记忆有共通之处,对应心理学里的系列位置效应:人自由回忆一串东西时,最记得头和尾。后续研究证实,模型的注意力分布也是 U 形的,首尾高、中间低,正好和性能曲线吻合。

这里要诚实标注一个 recency:新模型在简单任务上正在克服这个偏置,有研究发现某些新模型在"大海捞针"上几乎不受位置影响。所以这一章的准确说法是:迷失在中间是一个经典失败模式,机制根植于 attention;新模型在简单任务上有所缓解,但复杂、多跳、长任务仍然受整体的 context rot 拖累,别赌模型替你解决了它。而这个机制有一个特别干净的工程对策,正好把机制接到策略上:Manus 的"复述"做法,不断把目标和进度重写到 context 的末尾(比如维护一个 todo.md),主动把关键信息推进 attention 的高区,对治中间塌陷。这是从机制跳到策略最自然的一跳。

1.3 Context collapse:反复重写会侵蚀(主动退化)

第三个机制和前两个正交,也是最常被和 context rot 混淆的一个,必须钉精确。前两个机制是 context 变长导致的被动退化,而这个机制是主动造成的:当你为了省空间而反复重写、压缩 context 时,每一次摘要都会丢掉一点细节,累积起来,context 就被侵蚀了。这个现象 ACE 那篇论文给了个名字,叫 context collapse:迭代式的重写会随时间侵蚀细节。它还有个伴生的毛病叫简洁偏见,为了让摘要更简洁,把领域里那些关键的洞察也一并丢了。

把两个机制对照着记最清楚。Context rot 的触发是 context 变长,机制是 n² 注意力被摊薄,失败的样子是长上下文里召回变差、幻觉增多、对干扰项敏感,对策方向是减少喂进去的量。Context collapse 的触发是 context 被反复重写压缩,机制是每次摘要丢一点、累积侵蚀,失败的样子是摘要越来越笼统、那些"事后才显出重要"的关键细节被抹掉,对策方向是让压缩可逆、用增量更新而不是整体重写。Anthropic 在 compaction 的语境里点出了同一个洞见:过于激进的压缩会丢掉那些微妙但关键、其重要性只在事后才显现的 context。Claude Code 自己也诚实标注,它的压缩摘要在设计上就是有损的,精确值和硬约束会在压缩中被悄悄抹掉。

ACE 给的解法是把 context 当作一个不断演化的 playbook,用结构化的增量更新(合并、去重、裁剪)而不是昂贵且破坏性的整体重写,从而保住细节,效果是 agent 任务上提升了约 10 个百分点,而且不需要重新训练模型。但要划清边界:这一章借 ACE 立起 context collapse 这个概念,以及"增量优于重写"这个原则;而 ACE 作为一个完整的自我改进闭环(它怎么生成、反思、策划)属于下一章 Ch7。这条接缝必须在这里说清楚,否则两章会重叠。

1.4 还有钱和延迟:成本曲线

context 有限,不只体现在质量上,还体现在钱和延迟上——这是它经济维度的有限性,得并列讲。前面说 agent 的输入对输出是 100 比 1,这意味着成本几乎全在读 context(prefill)这一头,而不在生成(decode)那一头。context 翻倍,成本就差不多翻倍。这里最大的一根杠杆叫 KV-cache:相同的前缀可以命中缓存,大幅降低首字延迟和成本。在 #1 基础讲过的 prompt cache 就是这个东西,缓存命中的 token 价格只有未命中的十分之一。Manus 说得很直接:如果只能选一个指标来优化,那就是 KV-cache 命中率。

要吃到这个缓存,有三条纪律,它们也接回了第二章 agent loop 对 prompt 稳定性的要求。第一,保持前缀稳定,千万别在 system prompt 顶部放一个时间戳,一个 token 变动就会让下游整段缓存全部失效。第二,只追加不修改,永不改动之前的 action 和 observation,序列化也要确定,连 JSON 的 key 顺序都会影响缓存。第三,在该断的地方显式设缓存断点。把这条接上开篇的 100 比 1,你会发现省 context 不只是省准确率,还直接是省钱。值得补一句,2026 年 1M token 的窗口正式可用了,这改变了具体的算计,但没有取消有限性:rot 照样发生,只是阈值往后挪了。

2. 六个策略,其实是四个

知道了 context 为什么有限,接下来是怎么管理它。市面上各家讲 context 策略,数目从四个到六个不等,容易让人以为有个标准的"N 分法"要背。这里先帮你把账对清楚,免得记错。

2.1 别自创分类:对齐一手 taxonomy

诚实地说,各家的 canonical 集并不统一。Anthropic 的 context engineering 博客根本不用固定的 N 操作分类法,它直接列具体技术(compaction、结构化笔记、子 agent、按需检索、工具设计等);网上很多二手把它总结成"选择/压缩/排序/隔离/格式化五操作",但原文里没有这个五元组,引用时别张冠李戴。真正给出最小完备集的是 LangChain,它明确分四类:写出去(Write)、选进来(Select)、压缩(Compress)、隔离(Isolate)。这四类是个好骨架。本章就以这四类为骨架来讲——按需检索归入"选进来"(它是按需的 select),把大块内容卸载到文件归入"写出去"(写到文件再用指针引用),这样既覆盖全,又对齐一手,不自创分类。

2.2 四个策略,以及它们各治一种病

先给个对治关系。Drew Breunig 总结了 context 会得的四种病:context 中毒(幻觉进了 context 并被反复引用)、context 分心(context 太长淹没了推理)、context 混淆(冗余信息影响输出)、context 冲突(context 内部互相矛盾)。下面四个策略就是治这些病的药,你可以病药对照着看。

写出去,是把信息存到 context window 之外。一种是草稿纸,任务进行中把笔记持久化到一个工具或状态字段里,Manus 的 todo.md 复述就属于这类,还顺手治了迷失在中间。另一种是写到跨会话的持久 memory,但 memory 的架构是下一章的事,这里只点一句"写出去的一个去处是持久 memory"。选进来,是把相关信息按需拉进 context,核心范式叫按需检索:不预先把所有东西载入,而是维持轻量的标识符(文件路径、URL、查询),等当前这一步真的需要时,才用工具去拉。这很像人的认知,你不会把整个文件系统背在脑子里。Claude Code 就是典型,它不把整个代码库载进 context,而是用工具按需探文件。

压缩,是只留必要的 token。主要手法是摘要(跨整段轨迹做递归或层次化摘要,这就是 compaction 的核心,下一节深挖)和裁剪(用启发式删掉旧消息)。但压缩有它固有的风险,就是上一节讲的 context collapse,压缩有损。所以最安全的轻量压缩,是 Anthropic 说的"清掉工具结果"——工具的原始输出用完就清掉,但不动推理链。隔离,是把 context 的管理负载拆开。一种是多 agent,每个 agent 有自己独立的 context window,子 agent 把发现压成精炼的摘要再返回(深入归 Ch8,这里只讲它作为 context 隔离这一面)。另一种是用 sandbox 环境,让工具的大块输出留在 LLM 的 context 之外。

Context Window= agent 的 RAM有限 · 越满越不准Write 写出去scratchpad / 持久 memory(→Ch7)Select 选进来just-in-time · 留指针Compress 压缩摘要 / 裁剪 · 有损(collapse 风险)sub-agentIsolate 隔离各自 window(→Ch8)策略=药,治 4 种病:poisoning / distraction / confusion / clash(Breunig)
Figure · context window = agent 的 RAM(有限);四个策略是管理这块 RAM 的四个方向 —— Write 把信息写到窗外(scratchpad/memory)· Select 按需把相关信息选进来(just-in-time,留指针不预载)· Compress 压缩历史只留必要(有损,警惕 collapse)· Isolate 拆给子 agent 各自的窗 · 对应正文 第 2.2 节

2.3 用哪个:决策框架与信噪比

把这四个策略从并列的名词变成"按情况选"的判断,才是真本事。大致是这样:信息现在就要用、量也不大,直接放进 context,别折腾;信息可能要用、量大或不确定,用选进来(留指针,按需拉);历史太长、要保连贯,用压缩(但警惕 collapse,压缩要可逆或增量);遇到大块的工具输出(网页、PDF、长日志),卸载到文件(留路径,可回读)再加隔离;子任务可以并行或需要独立探索,用隔离(各自的 context window);要跨会话复用,写到 memory(这归 Ch7)。

贯穿所有选择的,是一条比"用哪个策略"更根本的准则:信噪比比总信息量更重要。LangChain 引过一个案例,精选过、结构化的相关数据能让准确率超过 95%,而把全部文档语料一股脑喂进去,准确率反而远低于此。这条准则其实就是开篇那句 Anthropic 准则的实践版——找最小的高信噪比 token 集合。喂全,远不如喂准。

3. Compaction:长任务连贯性的第一杠杆

上一节的"压缩"值得单独深挖,因为它是 2026 年最该讲透的 context 策略,也是第二章 agent loop 里点过名、说"深入留 Ch6"的那个 primitive 的兑现点。

3.1 什么是 compaction

Anthropic 给的定义:当一段对话快到 context window 上限时,把它的内容摘要掉,然后用这份摘要重新初始化一个新的 context window。它是长任务连贯性的第一杠杆。以 Claude Code 的范式为例,压缩时保留架构决策、未解决的 bug、关键实现细节,丢掉冗余的工具输出和消息,之后带着压缩后的 context 加上最近访问过的几个文件继续。这里有一条直接可教的调参原则:先最大化召回(确保把所有相关信息都抓全),再迭代提升精度(删冗余)——先全后精。而最轻量的压缩形态,就是上一节说的只清工具结果,不碰推理。

2026 年,Anthropic 把 compaction 做成了 API 层的 primitive(目前是 beta)。机制是:API 检测到输入 token 超过设定阈值,就生成一份摘要,造一个压缩块,用压缩后的 context 继续响应;后续请求会自动丢掉压缩块之前的所有消息,从摘要续上。还有一个很实用的开关,允许在压缩完成后先暂停,让你追加内容(比如把最近几条关键消息或硬约束再注入一遍)再继续——这正是为了对治"压缩把刚才那条关键约束也压没了"。

3.2 Claude Code 的三层 compaction

Claude Code 是"生产级 compaction 长什么样"的最好范本,它从轻到重分三层。最轻的一层叫微压缩,其实是把大的工具输出早早卸载到磁盘,context 里只留路径;机制是一个热尾加冷存的设计——最近一小窗的工具结果全部可见(热尾),其余的按路径引用(冷存),人能审计、agent 能回读。注意,这一层本质是卸载,不是摘要,正好印证了卸载和压缩是两回事。第二层是自动压缩,输入 token 超过阈值时,生成一份结构化的多段摘要。第三层是手动触发,在自然的任务边界上由开发者主动压缩,还能带聚焦指令(比如"聚焦 API 改动,保留数据库 schema 决策")——开发者比系统更懂哪里是安全的压缩点。

阈值的实况演进很快,引用前务必 pin 版本:大致是自动压缩在约 83% 占用时触发,留约 33K token 的缓冲给输出。社区的最佳实践反而是别等到 95%,在 60% 左右就压,大代码库留更多回读余量。还有一条很重要:把约定、架构决策、安全规则放进 CLAUDE.md 这类每轮重读的文件里,压缩压不掉它们——compaction 管的是本会话的工作窗,持久 memory 管的是跨会话的存活。

还有一个比阈值更深的问题:摘要既然有损,怎么不让它滑向上一节那个 context collapse?生产级 compaction 专门和这件事较劲,Claude Code 的三个做法值得记。一是保住近端原文,最近几条消息不进摘要、原样留着,摘要还被要求带上最近工作的直接引用,因为任务意图最怕在一次次转述里悄悄漂掉。二是给有损留条回头路,摘要末尾附一个指向完整对话存档的指针,被压没的细节事后还能捞回来,有损但可恢复。三是别让失败滚雪球,连续压缩失败到一定次数就停手(Claude Code 设的是三次),宁可降级也不陷进反复重摘的死循环,曾经真有会话卡在连环压缩失败里空烧调用。这三招合起来,正是上一节"让压缩可逆、增量优于整体重写"那条抽象原则,在一个真系统里落地的样子。

3.3 三家同一个问题,三种答案

Compaction 没有标准答案,这一点看三家主流系统的对照最清楚。Codex CLI 走的是服务端加密:压缩成一个用户不可读的加密块,但保留结构化元数据和推理轨迹,压完自动回读最近编辑过的几个文件。Claude Code 走的是大模型摘要:人可读,支持聚焦指令,但靠 CLAUDE.md 兜底,因为"摘要在设计上有损"。OpenCode 走的是模型自决:没有固定阈值,让模型按任务完成的边界自己决定何时压,只有当能回收足够多的 token 时才剪,并护住最近的一窗。同一个问题,加密保真、人可读可控、模型自决时机三种取舍,这和第四章里隔离机制阶梯"各有取舍、无标准答案"是同构的——工程的成熟,常常体现在知道自己在哪个维度上做了取舍。

3.4 何时 compact、何时 offload、何时 isolate

这是这一章该给的最实用的一个判断。三个动作有明确的优先级。卸载,针对大块、可回读、现在不一定要用的内容(网页、PDF、日志、大工具输出),做法是写到文件、context 只留指针;它是无损的(原文还在磁盘),所以优先用它。隔离,针对可并行、可独立探索的子任务,交给子 agent,那部分 context 根本不进主窗;它比压缩更好,因为压根没让那些 token 占用主窗。压缩,针对长对话历史本身——这部分没法靠"留指针"解决,因为历史就是要连贯;它是有损的(有 collapse 风险),所以是最后手段,而且用的时候务必配持久 memory 兜底关键约束。

优先级:无损有损Offload 卸载无损 · 首选触发:大块可回读(网页 / 日志 / PDF)做法:写文件,context 只留指针Isolate 隔离不进主窗触发:可并行 / 可独立探索的子任务做法:交 sub-agent,根本不进主窗Compact 压缩有损(collapse 风险)· 最后手段触发:长对话历史本身(要连贯)做法:摘要替换历史
Figure · context 满了,先 offload 再 isolate,最后才 compact —— 能无损就别有损,能不进主窗就别进 · offload 把大块内容写文件留指针(原文还在磁盘,可回读)· isolate 交 sub-agent 不占主窗 · 只有「长历史的连贯性」真正需要有损 compact,且要配 CLAUDE.md 兜底关键约束 · 对应正文 第 3.4 节

一句话总结:能无损就别有损(offload 优于 compact),能不进主窗就别进(isolate 优于让它占窗),只有"长历史的连贯性"才真正需要有损的 compaction。

4. 动态 context 预算:把策略串成调度循环

前面的策略是一个个的手法,这一节把它们串成一个运行时的调度——也就是动态 context 预算。它其实是三个可操作的工程问题:预算怎么分配、满了驱逐谁、什么时候动手。

预算分配,是把一块 200K(或 1M)的窗口看成预算,有四大消费者在互相挤占。一是 system prompt 加工具定义,最稳定,但也能很贵,50 多个 MCP 工具能吃掉约 72K token,而 上一章讲的工具搜索(defer_loading) 能把它压到约 8.5K,省 85%;它放最前面(对 KV-cache 友好)。二是对话历史,随轮次线性增长,是压缩的主要对象。三是检索和工具结果,大块、易爆,是卸载的主要对象。四是工作草稿(todo、复述),小,但放在末尾(attention 高区,治迷失在中间)。分配的原则就是:稳定的放前(吃缓存),易变大的能卸载就卸载,目标和计划放末尾,再给输出留一块安全缓冲。

驱逐策略,是窗口满了之后换出谁,很像操作系统的页面置换。Deep Agents 的实证是:会话 context 超过 85% 就截断旧的工具调用、换成文件指针;工具结果超过 20K token 就卸载、只留预览。Claude Code 的热尾冷存本质上是 LRU——最近用的留在 context,旧的踢到磁盘但可召回。驱逐有优先级:先驱逐冗余的工具输出,再旧消息,再实现细节;而架构决策、未解决的 bug、硬约束绝不驱逐(它们进压缩摘要或 CLAUDE.md)。这里有个关键认识:好的驱逐不是删除,而是移到一个可召回的外部(文件或 memory),呼应前面"卸载无损"那条。

触发阈值,是什么时候动手。可以用百分比(比如约 83% 触发,或更激进的 60%),可以用绝对 token 数(工具结果超过 20K 就卸载),但最优的往往是任务边界——OpenCode 让模型按完成边界自决,Claude Code 建议在"合并完一个功能、重构完、调完一个 bug"这类自然停顿点手动压缩。所谓"动态",真义就在这里:不是固定地删第 N 条,而是按当前的 context 占用、任务所处的阶段、内容的类型,实时决定调进什么、调出什么。这就把前两节的策略,串成了一个运行时的调度循环:每一步都问一句,还差多少预算?该卸载、压缩还是隔离哪一部分?

5. Observation engineering:你往 RAM 里灌什么

最后一个维度,容易被忽略但极重要:你喂给 agent 每一步的那个观测,本身就是一次 context 工程决策。前面四节管的都是"已经在 context 里的东西怎么调度",这一节管的是输入端——决定什么表征进 context。

5.1 一个 reframe:观测工程是 context 工程的输入端

把这件事想清楚的关键 reframe 是:observation engineering 是 context engineering 的一个子集,它问的是"agent 每一步感知到的环境,该用什么表征塞进 context"。注意,这不是视觉或感知的质量问题(那归多模态 #7),而是"喂给循环什么 token"的问题。它补上了前四节缺的输入端:如果一开始就往 RAM 里灌噪声,再好的压缩也救不回来。坏的表征,是从源头制造 context rot。

5.2 GUI 观测:同一个网页,三种表征

最干净的入口例子是 GUI agent。上一章 Ch3 在讲图形界面工具时 已经立过一个观测的分叉:同一个网页,你可以喂给模型三种表征。一种是标记截图(在像素图上叠加编号框),每张约 765 token,什么网站都能跑。一种是无障碍树(语义化的元素树加引用 ID),每次约 200 到 400 token,但原始 DOM 是 15000 token 以上的噪声海,而且现实里很多网站的无障碍标记是坏的,所以脆。还有混合(无障碍树为主、视觉兜底),是 2026 年的主流。

Ch6 在这个事实上深挖的是"为什么这是一个纯粹的 context 决策"。同一个网页的三种表征,等于三种 context 占用,乘以三种信噪比,乘以三种鲁棒性。选无障碍树,是用约 400 token 换"依赖站点标记干净";选像素,是用 765 以上的 token 换"什么都能跑但更贵更慢"。这个选择会层层传导到一切:速度、成本、准确率、哪些网站能跑、改版会不会崩。而且它直接连回第一节:把 15000 token 的原始 DOM 塞进 context,等于主动制造 context rot(一片干扰项的海);而无障碍树的几百 token,就是一次高信噪比的"选进来"。观测格式的选择,本身就是选进来和压缩这两个策略在输入端的应用。

5.3 泛化:所有观测都要做表征工程

把这个分叉从 GUI 泛化到 agent 的所有观测,是 Ch6 超出 Ch3 的部分。工具结果的截断是最常见的一类:bash 吐出一万行日志、SQL 返回十万行,不能原样进 context,你得做表征选择:截断(留头尾)、摘要、卸载留指针,或者结构化抽取(只回成功或失败加几个关键字段)。Anthropic 写工具的指南里有一条正是这个:工具返回要优先给上下文相关的语义,而不是底层的技术标识符(给语义,别给一长串 UUID)。还有"引用而非倾倒"——大文档不整篇进 context,而是留引用和路径、按需回读相关段;Anthropic 的多 agent 系统里,子 agent 把发现压成精炼的摘要加引用再返回,而不是把原始检索结果全倒回来。

再有,结构化优于自由文本:同样的信息,用表格或 JSON schema 字段表达,比散文更省 token、信噪比更高;但要小心一个陷阱,Manus 提醒,如果 context 里的模式太均匀,模型会盲目模仿(被自己的少样本带跑偏),所以要引入一点结构化的变化破除这种脆性。还有一个承接第二章的取舍:错误的观测要不要留?Manus 的经验是"把出错的留在 context 里",因为模型看到自己犯了错会更新内部信念、减少重犯;但要权衡——错误要留成明确的错误信号,而不是含糊的输出,否则就和第二章警惕的"语义空返回骗进展"撞上了。这是观测表征上"保真还是噪声"的取舍。多模态的观测也一样:模型怎么从像素里读懂界面归 #7,但喂哪种分辨率、要不要附无障碍树、截图多频繁,这些是 context 决策,归这一章。

6. 边界

边界 · Ch6 教 context 调度,不教检索管线、不教 memory 闭环、不教 attention 内部

这一章最容易越界的地方是 RAG。Ch6 拥有的是"按需检索作为一种 context 策略"——何时按需拉而不是预载、留指针还是灌全文、检索结果怎么塞进有限的窗口(引用而非倾倒、压缩、截断)。数据工程路书(#3)拥有的是 RAG 的生产管线本身:多阶段检索、重排、chunking 策略、embedding 选型、向量库运维、混合检索、检索质量评估。一句话分工:Ch6 是"作为 context 工程师,我何时检索、检索结果怎么塞进有限窗口";#3 是"检索管线本身怎么造得准、快、可扩"。

另外两条边界:写出去的一个去处是持久 memory,但 memory 架构(分层、跨会话、何时增删改)+ Skills 工程 + 自我改进的完整闭环(ACE 的生成-反思-策划怎么跑)归下一章 Ch7——这一章只借 ACE 立起 context collapse 这个概念。context rot、迷失在中间这些机制的模型内部原因(n² attention、训练序列分布)归 #1 / #4——这一章只引用结论做"为什么有限"的论据,不展开 transformer 内部。

综合 · context 工程 = agent 的内存管理

回头看这一章。你先接受了一个心智模型:context window 是 agent 的 RAM,有限,而且越满越不准;agent 的 context 每步都在涨(100 比 1),所以"塞更大窗口"会撞墙,真正的工程是在每一步喂最小的高信噪比 token 集合。你学了 context 为什么有限的三个正交机制——被动的 context rot(越长越掉,Chroma 和 NoLiMa 实证)、位置的迷失在中间(U 形偏置)、主动的 context collapse(反复重写侵蚀),外加成本这第四维(KV-cache 是头号杠杆)。你拿到了管理这块 RAM 的四个策略(写出去、选进来、压缩、隔离),以及"信噪比胜过总量"这条贯穿准则。你深挖了 compaction(三层、三家、API primitive),并拿到了那个最实用的判断:能 offload 就别 compact,能 isolate 就别进主窗。你把这些串成了一个动态预算的运行时调度循环。最后你理解了观测工程是 context 工程的输入端,喂什么表征本身就是往 RAM 灌什么。

把这一章和前面合起来,你那台 harness 又长出了关键的一层。它本来能跑、能用工具、安全、抗劫持,但只扛得住短任务;现在它有了内存管理,能在长程任务里始终带着最该带的那部分上下文,而不被自己的历史压垮。这是第三站"让 agent 扛住长任务"的第一块基石。

但 context 工程管的是单次会话内的工作记忆,会话一结束,RAM 就清空了。一个真正能长期干活、还能越干越好的 agent,需要的是跨会话的持久记忆、可复用的技能、以及一套在运行中自我改进的闭环——这正是下一章的主题。合上书,去动手:给你前几章那个 agent 接一个会读大文件的工具,先看它把整份文件灌进 context 后怎么开始答非所问(亲手制造一次 context rot),再改成"只留路径、按需回读相关段",对比一下准确率和成本;然后给它加一个 todo.md,让它每步把进度复述到末尾,体会一下复述怎么对治迷失在中间。带着"context = RAM"这张图,进 Ch7。

本章关键术语

下面按本章顺序复习。加粗是术语,后面是一句话解释;带链接的词可点进术语表看更完整的解释。

为什么有限

  • Context Engineering 在每一步策划并维护最优 token 集合的一整套策略;Karpathy 类比:context window = agent 的 RAM,这门学科是 OS 级的内存调度
  • Context Rot 被动退化:输入越长,模型召回 / 推理越差(即使任务没变难);根因 n² attention 摊薄;声称的 window ≫ 有效 window
  • 迷失在中间(lost in the middle) 位置偏置:信息在 context 首尾召回最好、中间最差,呈 U 形;对策是把关键信息复述到末尾
  • Context Collapse 主动退化:反复重写 / 压缩每次丢一点细节,累积侵蚀;对策是可逆 + 增量 delta,别整体重写
  • KV-cache 相同前缀命中缓存,价格约 1/10;agent 的头号成本杠杆;三纪律:稳定前缀 / 只追加 / 显式断点

策略与调度

  • 六策略其实是四类 Write 写出去 / Select 选进来 / Compress 压缩 / Isolate 隔离(LangChain 一手骨架);各治一种病(中毒 / 分心 / 混淆 / 冲突)
  • 按需检索(just-in-time retrieval) 不预载,留轻量指针(路径 / URL / query),到需要时才用工具拉
  • Compaction 把近上限的对话摘要掉、用摘要重开窗口;先召回后精度;有损,关键约束另存 CLAUDE.md
  • Offload 卸载 把大块可回读内容写文件、context 只留指针;无损,优先于有损 compact
  • 动态 context 预算 运行时按占用 + 阶段 + 类型决定调进 / 调出;四大消费者互挤;驱逐 ≠ 删除(移到可召回外部)

输入端

进阶词汇(memory 架构 / Skills / 自我改进闭环等)归后续章节,完整术语见术语表 /glossary

参考文献

Mode A · 引用出处(正文 inline,集中列在此)

深 dive 资源(可选 · 想往下走再看)

说明:Context engineering 是 2025-26 刚结晶成学科的前沿,本章纯 Mode A,由 Anthropic / LangChain / Manus doctrine + Chroma / NoLiMa / ACE 一手实证扛起。核心机制(context rot / 迷失在中间 / 四策略)概念稳定;但具体数字(NoLiMa 32K、Chroma 18 模型、compaction 阈值 83.5% / 33K buffer、API beta header)演进快,引用前 pin 版本。

下一章

下一章(Ch7)是第三站的第二块 · Memory + Skills + 自我改进工程。这一章你把单次会话内的工作记忆管好了,但会话一结束 RAM 就清空。Ch7 讲怎么给 agent 跨会话的持久记忆(memory 的读写改忘四操作 + 几种具名架构)、可复用的技能(Skills 与渐进披露),以及最有意思的一块——不更新模型权重、纯靠 harness 的自我改进闭环(ACE 的完整生成-反思-策划机制、把轨迹蒸馏成技能),让 agent 越干越好。那条无梯度的自我改进归 #8,而更新权重的强化学习归后训练 #6,两章在那里交接。