上下文工程的减法实践:5000 token检索为何胜过10万token摘要

上下文工程的减法实践:5000 token检索为何胜过10万token摘要
张文保 更新 29 分钟阅读 1,675 阅读
本文目录
  1. 为什么上下文越多,编码Agent反而越差?
  2. 及时检索在工程上对应哪个动作
  3. CodeScaleBench的对照组究竟赢在哪里?
  4. 一笔上下文交易划不划算,怎么算
  5. 上下文腐烂的退化曲线是什么形状?
  6. 退化非均匀:模型撞悬崖而不是滑坡
  7. 伤害大小取决于问题和目标的语义距离
  8. 长上下文的四种失效模式怎么区分?
  9. 现场排查按什么顺序走
  10. 卸载和摘要怎么做才不丢信息?
  11. 入参卸载:被漏掉的另一半规则
  12. 压缩到什么程度算过头
  13. 常驻开销是账单上最贵的一栏
  14. 工具定义
  15. 指令文件
  16. 上下文预算的三类科目怎么分配?
  17. 不同窗口尺寸的账要分开算
  18. 哪些流行的上下文工程做法在帮倒忙?
  19. 上下文工程在独立站运营里怎么落地?
  20. 站点审计:别把全站爬取结果一次喂完
  21. 批量改内容为什么跑到第十几篇就崩?
  22. 项目约定怎么沉淀进指令文件
  23. 跨会话的项目记忆该怎么分层
  24. 哪些任务不值得动用这一套?
  25. 三条要点
  26. 常见问题解答
  27. 上下文工程和提示词工程到底有什么区别?
  28. 5000 token打败10万token,这个结论可信吗?
  29. 上下文腐烂是不是就是越长越差?
  30. 卸载和摘要该按什么顺序做?
  31. 工具调用的入参也需要卸载吗?
  32. CLAUDE.md写多长算合适?
  33. 什么情况下不该做上下文工程?
  34. 权威参考资料
摘要:调教编码Agent最大的杠杆是删token,不是加token。Sourcegraph在370个真实企业代码库任务上测出来:拿5000 token精准检索的Agent,比拿10万token代码库摘要的表现更好;precision@5从0.140升到0.478。这个实验还有一个被广泛忽略的细节——赢的那一侧不是本地grep,是把源码整个搬走、只留13个检索工具的MCP方案。下面拆解腐烂机制、四种失效模式的辨认方法、先卸载后摘要的阈值打法,以及三个看着像进步的伪技巧。

大多数人调Agent的功夫都花在加法上:指令文件越写越长,可能用得上的文件统统塞进窗口,整个仓库挂上向量索引。背后是同一个直觉——喂得越饱,Agent越强。

2026年最硬的几组证据指向相反的方向。而且相反得毫不含糊:同一个任务、同一个模型、上下文多了20倍,结果反而更差。

这篇不再重复上下文工程的定义,只论证一件事:上下文窗口是一份要花的预算,不是一个要装满的桶,而预算里杠杆最大的那个动作几乎总是减法。顺带把几组被反复转述、在转述过程中已经变形的实验数据,还原成它们本来的样子。

为什么上下文越多,编码Agent反而越差?

先看最常被引用的那个结论。Sourcegraph的上下文工程指南里有一句原话:在同一个编码任务上,拿着10万token代码库摘要的Agent,表现比拿着5000 token精准检索的更差。

体积让了20倍的先手,还是输了。机制不复杂:10万token的摘要没有给模型更多可用信息,只给了更多可分心的东西;5000 token精准检索之所以赢,是因为里面每一个token都在承重。

决定要不要相信这个结论的,是它背后那组可复现的数字。Sourcegraph把实验做成了一个叫CodeScaleBench的基准,370个软件工程任务全部取自真实的企业级代码库。同一个编码Agent跑两种配置,结果是这样的:

指标基线(本地源码+grep/file/read)结构化代码检索
文件召回率0.1270.278
precision@50.1400.478
F1@50.0990.262

精度翻了三倍多,改的只是取什么,不是取多少。下游效果的差距更大:一个Kubernetes单体仓库的任务,基线撞上了两小时超时,换成结构化检索之后89秒完成、得分0.90;一次跨文件重构,基线用了96次工具调用、84分钟,换过来是5次调用、4.4分钟。

把96对5这组数字再读一遍。这是减法论证里最深的一层:精度不只改善答案,它直接压缩轮数;轮数少了,对话里堆积的垃圾就少,窗口给后面的轮次留得就干净。精度会复利。

膨胀也复利,方向相反。今天放进来的每个垃圾token,都会喂出一个更糊涂的轮次,明天生产更多垃圾。

及时检索在工程上对应哪个动作

结论好记,落地容易走样。及时检索要换的是决策权,不是换一个更聪明的搜索算法——把“读哪个文件”这个判断从你手上交回给Agent。

预加载的心智模型是:我先判断哪些文件相关,打包递给它。及时检索的心智模型是:我只给它一份目录和一个读取工具,它自己判断该拆哪个包。

差别在于你的判断是提问之前做的,它的判断是看过前几步结果之后做的。一行文件引用加一个读取工具,在Agent真正判定这个文件相关之前几乎零成本;而你预判错的每一个文件,都是全价买单还倒扣注意力。

有一个很实用的自查:如果你正在写“把下面这些文件的内容也一并附上”,先停三秒——你是真的知道它需要,还是只是不确定它不需要?后者就是分心的来源。不确定的东西应该做成它取得到的,而不是它必须看的。

另一件常被搞反的事:及时检索并不意味着次数越少越好。基线那96次工具调用糟糕在每次都取回一堆无关的东西,于是不得不再取一次。轮数是精度的结果,不是可以直接优化的目标——盯着轮数硬压,只会逼出一次性抓一大把的策略,正好回到加法那条路上。

CodeScaleBench的对照组究竟赢在哪里?

这一节是我在别处没见人写过的,也是这组数据被转述时最常丢掉的部分。

大多数二手引用把它概括成“结构化代码检索打败了grep”。这个说法不算错,但它把最有意思的那半掐掉了。翻CodeScaleBench的实验设置会发现,赢的那一侧的完整配置是:Agent不在本地持有源码,改成调用13个检索工具,而这13个工具是通过MCP暴露的。

所以2026年关于“上下文该做减法”的最硬一组实证,是靠MCP拿到的。

这个细节之所以重要,是因为同一年的舆论主线恰好是“MCP是不是该被CLI加Skill取代”。我在MCP、Skills、Hooks三大扩展机制怎么选那篇里拆过这场争论的来龙去脉。而这里出现了一个反直觉的交叉:被诟病“常驻吃上下文”的协议,在这个实验里恰恰是省上下文的那一方。

怎么理解这个矛盾?关键在于账算到哪一层。MCP的成本是工具定义常驻窗口,收益是把整个代码库挪出窗口。当代码库有几百万行、而13个工具定义只有几千token的时候,这笔交易的方向非常清楚。当你挂的是十几台各自带着几十个工具的服务、而要处理的只是一个单文件改动时,方向就反过来了。

所以真正的原语不是“MCP好”或者“MCP差”,而是:判断一个机制该不该用,得看它换掉了什么,而不是它本身占多少。只算成本不算它替你搬走了什么,会得出一堆看着严谨、方向却是错的结论。

一笔上下文交易划不划算,怎么算

把这条原语做成可算的式子并不难。任何一个占用常驻上下文的机制,划算与否取决于两个量的比:

  • 它的常驻成本:工具定义、指令片段每一轮都要付的那部分。
  • 它替你挪出窗口的量×这些内容原本被读到的频率。

13个工具定义大概几千token,换掉的是一个动辄百万行的代码库,这笔交易几乎不用算。而挂十几台服务、每台带几十个工具,常驻成本可能上万token,换回来的只是“万一要用”的可能性,这就是纯亏。

注意第二项里那个频率因子,它最容易被忽略。一个替你搬走了大量内容、但那些内容一次都用不到的机制,收益是零而不是很大——你只是把从来不会被读的东西,从窗口里换成了从来不会被调的工具。这种“看起来做了优化,其实两边都是死重”的情况,在堆了一堆集成的项目里非常常见。

实操上的粗判据:一台服务如果在最近十次任务里被调用不到两次,就该从常驻改成按需加载。这个数字没什么理论依据,但它足以砍掉大部分明显不划算的常驻项,执行成本只是翻一下调用日志。

上下文腐烂的退化曲线是什么形状?

“上下文腐烂”这个词现在满天飞,但绝大多数复述都把它讲成一条平滑的曲线:输入越长,效果越差,像电池慢慢没电。

Chroma那份原始研究说的不是这个。他们在18个前沿模型上做了受控实验,最重要的发现有两条,两条都比“越长越差”更有用。

退化非均匀:模型撞悬崖而不是滑坡

模型不会随输入变长而线性变差。它们是撞墙:有的模型在32K还好好的,到64K突然塌方;有的一路撑住,然后毫无预兆地垮掉。

这条对工程实践的意义很直接:你在8K上下文里跑通的验证,对64K完全没有预测力。那种“先小规模验证,成了再放大”的常规做法,在长上下文这件事上是失效的。要验就得在你真实的上下文长度上验。

伤害大小取决于问题和目标的语义距离

当要找的信息和提问之间语义相似度高时,长上下文的伤害小;相似度一低,退化速度立刻加快。

这条解释了一个很常见的困惑:为什么同样是塞满窗口,有时候Agent表现正常,有时候直接失智。区别不在你塞了多少,而在你要它找的东西和它手上的提问长不长得像。

落到做法上:如果任务本身就是“从一堆不相关的东西里找出那个隐含相关的”,比如排查一个症状和成因完全不像的线上问题,那这类任务对上下文洁净度的要求要比普通任务高一个量级。别在这种任务上省事。

研究里还测了干扰项的影响:语义上相似但实际无关的内容,会明显把模型带偏。所以“多塞点保险”这个直觉完全反了,这么做买到的不是保险,只是打了折的注意力。

长上下文的四种失效模式怎么区分?

知道会坏还不够,得能在现场认出是哪种坏法。Drew Breunig那篇长上下文失效模式给了一套至今没被超越的分类,四种,各有各的相貌:

失效模式机制现场症状该拉哪根杠杆
污染一个幻觉或错误进入了上下文,之后被反复引用Agent坚持一个不存在的函数名/接口,你纠正一次它下一轮又用回去开新会话,或把那段消息从历史里摘掉重来
分心上下文长到模型过度关注历史,反而忽略了训练里学到的东西前十轮很聪明,第三十轮开始机械重复前面的模式,不再想新办法压缩历史,保留意图和产物,丢掉过程
混淆上下文里多余的信息被模型拿去生成了低质量回答输出里混进了另一个模块的约定、另一个环境的配置收紧检索范围,把不相关的文件逐出
冲突新累积进来的信息或工具,和上下文里已有的内容互相矛盾Agent在两种做法之间反复横跳,或者在相似工具间犹豫不决砍工具集,消除重复;统一指令文件里打架的规则

这张表最大的用处是逼你先诊断再动手。四种失效对应四根完全不同的杠杆,用错了不但不解决问题,还会把成本推上去。

最容易搞混的是分心和混淆。判据是这样的:分心的Agent在重复自己,混淆的Agent在引用别人。前者要压缩,后者要收紧检索,反过来做两边都会更糟。

现场排查按什么顺序走

四种失效在真实会话里经常同时出现,所以顺序比清单重要。我实际用的排查路径是这样的:

  1. 先问是不是污染。成本最低、危害最大。判据是“我纠正过的东西有没有卷土重来”。只要出现一次回滚,后面所有诊断都不用做了,先把那段历史清掉,因为污染会伪装成另外三种。
  2. 再问是不是冲突。看Agent在不在两个方案之间反复横跳,或者在功能相近的工具间犹豫。这一步查的是你的配置,不是它的状态,所以可以离线做。
  3. 然后区分分心和混淆。用上面那条“重复自己还是引用别人”的判据。
  4. 最后才考虑加东西。如果前三步都排除了,问题很可能真的是信息不够,但按我的经验,走到第四步的概率不到三成。

把顺序反过来做,是这个领域最常见的时间浪费:一上来就补资料,补进去的东西被已有的污染带偏,症状加重,然后你以为是补得还不够多。加法在诊断阶段是有害的,因为它同时改变了症状和病因,让你没法归因。

卸载和摘要怎么做才不丢信息?

Agent跑得够长,再聪明的检索也挡不住对话被填满。减法从选修变成必修,问题只剩一个:怎么删而不毁掉信息。

2026年的生产框架已经收敛出一套带明确阈值的打法,LangChain在Deep Agents文档里给的方案是目前最干净的样本。三条规则,顺序不能乱:

  1. 任何单条超过2万token的工具返回,卸载到文件系统,在上下文里替换成一个文件路径加前10行预览。
  2. 会话越过模型窗口的85%,就把较早的工具调用截断成指向磁盘内容的指针。
  3. 只有当卸载已经不够用时才摘要——生成一份包含会话意图、产物、下一步的结构化摘要,同时把原始消息写到磁盘作为权威记录。

这个顺序本身就是课程。卸载是无损减法,内容还在,只是改用路径引用;摘要是有损的,而且失败方式很阴:摘要悄悄丢掉了那条唯一重要的约束,三轮之后Agent跑偏了,没人知道为什么。

入参卸载:被漏掉的另一半规则

关于卸载,绝大多数转述只讲了工具返回那一半。文档里还有对称的另一半:工具调用的入参也要卸载。

典型场景是写文件和编辑文件。你让Agent写一个800行的文件,这次工具调用的入参里就带着这800行的完整内容,然后它会一直躺在对话历史里。而这份内容已经落到磁盘上了,历史里那一份是纯冗余,一个字的信息量都没多出来,却要在接下来每一轮都被重新读一遍。

这一半为什么容易被漏掉?因为它反直觉:大家的心智模型里,“上下文膨胀”是Agent读进来的东西造成的,很少有人意识到Agent写出去的东西同样会在历史里留下等重的副本。跑重构、跑批量改文件的任务,这一项经常是最大的单一开销。

压缩到什么程度算过头

给一个可操作的判据:如果要压缩,就得让“大海捞针式恢复”可测试。当Agent后来发现需要那条被摘要掉的细节时,它还取得回来吗?取不回来,就是压狠了。

实操上可以这么验:压缩之后,故意问Agent一个只有被压掉那段才答得出的问题。答得出,说明摘要保住了要害;答不出,把摘要模板里的字段补一条。这个动作花不了五分钟,但它是压缩策略里唯一有反馈信号的环节。

摘要模板本身也值得固定下来。让模型自由发挥写摘要,它会写成一篇读后感;给它字段,它才会写成一份交接单。我用下来最稳的四个字段是:

  • 意图:这次会话到底要达成什么,用一句话。跑偏最先丢的就是这条。
  • 已产出:改了哪些文件、建了哪些东西,只列路径不贴内容。
  • 硬约束:过程中确认过的、不能违反的规则。这是最容易被摘掉又最致命的一类。
  • 下一步:当前卡在哪儿、下一个动作是什么。

缺了“硬约束”那一条,就是前面说的阴险失败:Agent接着干,语气还很自信,只是它已经不知道那个字段不能为空了。

常驻开销是账单上最贵的一栏

前面讲的都是工作集,它会变、会被逐出。但有两个科目每一轮都坐在窗口里,这让它们成为收益最高的下刀处。

工具定义

你暴露的每一个工具定义,每一轮都占着上下文;每一对功能近似的工具,都逼模型烧一轮去纠结选哪个。这项开销不算零头:带着相互冲突假设的臃肿工具集,是有据可查的浪费轮数、把Agent搞糊涂的根源,也正是前面那张表里“冲突”那一行的主要来源。

规则很简单:只暴露覆盖当前任务的、最小的一组无歧义工具,并按需动态加载工具组,而不是一次性挂上你拥有的每一台服务。Agent在写后端代码时,作用域里的设计稿工具纯粹是税。

指令文件

CLAUDE.md和AGENTS.md会被拼接进每一轮,是大多数团队预算里被纵容得最厉害的科目。400行的指令文件把整个架构重讲一遍,每一行都在每一轮被永久征税,不管当前任务碰不碰那个子系统。

精简原则只有一句:永远加载的文件里,只放稳定的、全项目通用的规则,也就是约定、硬约束、那几条“到处都别这么干”。所有任务相关的东西,推到Agent按需加载的文件里去。

一个短短的根文件写着“鉴权逻辑在src/auth/,动它之前先读src/auth/README.md”,胜过200行重述那个二十次任务里只碰一次的鉴权流程。更细的分层组织方式,我在CLAUDE.md记忆术的四级作用域拆解里写过一整套,同一套逻辑也支撑着持久记忆系统:常驻层保持极小,可检索层承载大头。

顺带说一句子代理。Skill和子代理的核心区别正是上下文归属:Skill共享主窗口,子代理拿的是独立窗口。把一个会产生大量中间输出的探索型任务丢给子代理,本身就是一次卸载,脏活在别的窗口里干完,回来的只有结论。这是减法思路的一个结构性用法,比任何压缩技巧都干净。

上下文预算的三类科目怎么分配?

减法是战略,预算是记账。把窗口当成一份有明细科目的账,你的工作就是分配:每一个花在过期堆栈上的token,都是从Agent真正要改的那个文件那里挪走的。

科目一共三类:

  • 固定开销:系统提示词、指令文件、工具定义。纯负担,压到最低。
  • 工作集:及时检索到的代码、最近N轮对话、已卸载内容的路径指针。保持精准,过期即逐出。
  • 预留余量:给下一个工具结果和推理留出的空间。

把它落成一张真实的账更有说服力。假设一个20万token的窗口,一个中等复杂度的重构任务,我会这么分:

科目预算里面装什么失控的信号
固定开销不超过1万系统提示词、精简后的指令文件、当前任务需要的那几个工具定义还没开始干活,窗口已经用掉8%以上
工作集12万到14万及时检索到的定义和调用点、最近若干轮对话、已卸载内容的路径指针里面出现了三轮之前就不再提及的文件
预留余量不低于3万留给下一个工具返回和这一轮的推理压缩总是在工具返回的瞬间被触发

右边那一栏比左边的数字更有用。预算是不是合理,不看你分了多少,看它以什么方式被突破。固定开销超标说明你在指令文件和工具集上偷懒;工作集里躺着老文件说明逐出策略没生效;压缩总在工具返回那一刻被触发,说明余量留少了。

余量为什么值得单列一栏?因为一个把窗口跑到99%满的Agent没有余地思考,下一个大的工具返回会逼它在最糟糕的时刻仓皇压缩,而仓皇压缩恰恰是最容易丢掉关键约束的时候。

预留余量这件事没法靠感觉,得能看见。给Claude Code装一个实时状态栏是成本最低的办法,上下文占比和token消耗直接摆在眼前;把黄色预警线提前到七成,而不是等它变红。看不见的预算是管不住的,这一条在任何领域都成立。

Anthropic在官方那篇为AI智能体做有效上下文工程里给的框架是同一套骨架,并且明确提出了结构化笔记模式:Agent把草稿写到上下文窗口之外的文件里,需要时再读回来,长期记忆在真正用到之前不占预算。这和前面那条“先卸载再摘要”是同一个原理的不同表达。

不同窗口尺寸的账要分开算

上面那张表按20万窗口算。但2026年常用的几档窗口差得很远,同一套比例直接套过去会出问题。

窗口越大,固定开销的占比越不值得优化,工作集的纪律反而越重要。1万token的指令文件在20万窗口里是5%,在100万窗口里是0.5%,后者你完全没必要为它花时间。但工作集不是这样:窗口翻五倍,Chroma测出的那道悬崖并不会跟着往后挪五倍,因为退化跟的是绝对长度和干扰项密度,不是你用掉了窗口的百分之几。

所以有一条很反直觉的推论:换了更大窗口的模型之后,该收紧的是工作集,而不是放松。大窗口给你的是“不会硬性截断”的安全感,不是“可以多塞”的许可证。100万token的窗口是容量上限,不是使用目标,把它当目标的人通常在第三十轮就会发现Agent开始胡说八道,然后归咎于模型不行。

还有一个容易被忽略的成本项:缓存。很多服务对命中缓存的输入按一折左右收费,而缓存命中的前提是前缀稳定。这意味着把变动频繁的内容放在上下文前部,会让后面所有稳定内容的缓存全部失效。顺序不只影响注意力,还直接影响账单,固定的放前面,易变的放后面,这个排序习惯几乎零成本,收益却是每一轮都在的。

哪些流行的上下文工程做法在帮倒忙?

2026年一些说得最自信的建议,其实在悄悄拖后腿。它们有个共同点:全是加法,而且全都让人觉得很有生产力。

伪技巧一:为了保险把窗口塞满。这是白交上下文腐烂税,用每个主流模型家族上都测到过的注意力退化,换一份不存在的保险。而且按Chroma的发现,你还不知道自己离那道悬崖还有多远。

伪技巧二:把整个仓库嵌入向量库,然后称之为上下文工程。散文可以,代码不行。代码有结构,定义、引用、调用图俱全,理解这种结构的检索会碾压把源文件当token袋子的检索,precision@5那组三倍多的差距就是证据。而且你还额外背上了一套要和不断变化的代码库保持同步的基础设施。

伪技巧三:不看状态、按固定节奏压缩。“每N轮压一次保持整洁”会扔掉Agent可能还需要的细节,还在窗口只用了30%的时候白白引入目标漂移风险。预算逼你压的时候再压,不要定时压。

顺便处理一个流传很广的数字:不少文章会引用“企业Agent失败中有65%源于上下文漂移”。这个数字我没能找到可核实的一手出处,多数引用都指向另一篇同样没给出处的二手文章。方向可能是对的,但把它当成论据写进技术方案,属于给自己埋雷。凡是找不到署名负责的一手来源的百分比,最好只当氛围不当依据。

上下文工程在独立站运营里怎么落地?

上面全是编码Agent的语境。但真正让保哥觉得这套方法值钱的,是它在内容和SEO这类活儿上同样成立,而且成立得更明显,因为这类任务的上下文天然更脏。

站点审计:别把全站爬取结果一次喂完

让Agent审一个几百页的站,最常见的错误做法是把全站爬取结果一次性喂给它。这是典型的“10万token摘要”,信息全在,但每一条的权重都被稀释了,模型会挑最显眼的几条讲,剩下的当没看见。

正确的形状是及时检索:先给它页面清单和一个查询工具,让它按判断去取。判据是——如果你发现自己在准备一份“它可能用得上”的资料包,那你多半正在制造分心。

批量改内容为什么跑到第十几篇就崩?

这是前面说的“入参卸载”最容易咬人的地方。一次性让Agent改30篇文章,每篇的原文和改写稿都会以工具入参的形式沉在历史里,跑到第十几篇的时候窗口就开始告急,而输出质量的下滑往往先于任何显式报错。

做法是把批量任务拆成独立会话,或者交给子代理,每篇改完只回传一个结果摘要。不要让第30篇的判断建立在前29篇的全文之上,那29篇对它没有任何帮助,只有干扰。

项目约定怎么沉淀进指令文件

做自养工具的人特别容易把指令文件写成项目说明书。我在用Vibe Coding重塑SEO工作流那篇里提过一个反复出现的现象:工具越用越顺手,指令文件也越写越长,然后某一天Agent开始忽略你写在第300行的那条规则。

保哥自己也栽过:给一个内容生产脚本写的指令文件从最初的40行长到280行,某天发现它开始忽略“标题不要用冒号拼接”这条,那条规则在第190行,前面堆着一大段和当次任务毫无关系的数据库字段说明。把无关部分挪进按需加载的文件之后,规则立刻又生效了,一个字都没改。

问题不在它不听话,而在那条规则已经被前面299行稀释掉了。指令文件的容量不是无限的,写第N条规则的时候,你其实在削弱前面N-1条的权重。这句话值得贴在每一个AGENTS.md的开头。

跨会话的项目记忆该怎么分层

做长期项目的人迟早会遇到这个需求:每开一个新会话都要把项目背景重讲一遍,很浪费。于是自然而然想到,把背景写进永远加载的那个文件里。

这正是把常驻层撑爆的最常见路径。正确的分层是常驻层只放索引,检索层承载内容:根文件里写“客户约定见docs/clients/,历史决策见docs/decisions/”,而不是把约定和决策本身抄进去。

判断标准很简单:问自己这条信息在十次任务里会被用到几次。十次里用到八九次的,进常驻层;只在特定任务里才碰的,进检索层。会犹豫的,一律进检索层,因为常驻层的每一行都是复利支出,而检索层的内容不用到就不花钱。

顺带一个反模式:把整个项目的历史决策记录塞进常驻层,理由是“怕它重复踩坑”。实际效果通常是它开始给出四个月前才成立的建议,因为那些记录里的时效性没人维护。过期的常驻上下文比没有上下文更危险,它会让Agent自信地做错事。

哪些任务不值得动用这一套?

取舍要诚实说清楚:对短的一次性任务,这套机制全都不值。

任务是“给这个函数加个空值检查”“把这段文案的语气改得客气一点”,那么一个带着那一个文件的朴素提示词,胜过任何检索流水线、压缩方案或记忆系统。你花在搭上下文管线上的时间,够你手动做完二十次。

上下文工程是给长时程Agent的纪律;在两轮的任务上,它纯是负担。让仪式感匹配时程——过度工程化在这个领域造成的浪费,一点不比上下文膨胀少。

判断门槛可以粗暴一点:Agent要跑超过10轮、或者会读超过5个文件,才值得动用这一套。低于这个量级,好好写提示词、把对的文件递给它,到此为止。想系统补齐整条主线的,Claude Code从安装到工作流的完整指南是更合适的入口,那篇讲的是骨架,这篇讲的是骨架上最容易断的那一节。

三条要点

第一,把上下文窗口当预算管,默认做减法:及时检索、代码优先用结构化检索、先卸载再摘要、工具集和指令文件都保持精简、永远预留余量。

第二,先诊断再施法。污染、分心、混淆、冲突四种失效对应四根不同的杠杆。一股脑同时上向量库、摘要流水线和300行指令文件然后祈祷,只会加成本、不解决问题。

第三,数据要读到实验设置那一层。“5K打赢100K”只是标题,底下那句“赢的一方把源码整个搬出了窗口”才是可迁移的原语。转述会磨掉细节,而工程判断恰恰活在细节里。

模型会一直变强,token预算永远有限。能不能判断哪些东西该留在预算之外,决定了你手上的Agent是能发布,还是只会空转。

常见问题解答

上下文工程和提示词工程到底有什么区别?

提示词工程优化的是一条消息的措辞,是施加在单轮上的手艺。上下文工程管的是整个循环里到底有哪些token进入了窗口:读一个文件进来800行,跑一次测试进来5000行堆栈,grep一把进来40个匹配,这些没有一个是谁写的提示词,它们是堆积出来的。提示词工程是上下文工程的子集。附赠一个免费诊断:Agent第一轮很稳、第三十轮崩掉,那不是提示词问题,是上下文管理问题。

5000 token打败10万token,这个结论可信吗?

可信,但要读到实验设置那一层。Sourcegraph的CodeScaleBench用了370个来自真实企业代码库的任务,基线是本地源码加grep、file、read这类标准工具,对照组是把源码搬出窗口、改用13个检索工具。结果是文件召回率从0.127升到0.278,precision@5从0.140升到0.478,F1@5从0.099升到0.262。需要注意的是,赢的那一侧不是笼统的结构化检索,而是一套通过MCP暴露的检索工具,这个细节在多数转述里被抹掉了。

上下文腐烂是不是就是越长越差?

不完全是。Chroma在18个前沿模型上的受控实验给出了两条更精确的结论:一是退化非均匀,模型是撞悬崖不是滑坡,有的在32K还正常、64K突然塌方;二是伤害大小取决于要找的信息和提问之间的语义相似度,相似度越低退化越快。实践含义是,短上下文里跑通的验证对长上下文没有预测力,要验就得在真实长度上验。

卸载和摘要该按什么顺序做?

先卸载,再摘要,顺序不能反。参考LangChain在Deep Agents里给的阈值:单条工具返回超过2万token就写到文件系统,上下文里只留路径加前10行预览;会话越过模型窗口的85%时截断较早的工具调用;只有当卸载已经腾不出空间了才摘要。原因是卸载无损而摘要有损,摘要一旦丢掉了那条唯一重要的约束,三轮之后Agent跑偏,没人知道为什么。

工具调用的入参也需要卸载吗?

需要,而且这一项经常被完全忽略。写文件、编辑文件这类操作,会把整份文件内容作为入参留在对话历史里,而这份内容已经落到磁盘上了,历史里那一份是纯冗余。跑重构或者批量改文件的任务时,这往往是最大的单一开销。大家的心智模型里上下文膨胀是读进来的东西造成的,很少有人意识到写出去的东西会在历史里留下等重的副本。

CLAUDE.md写多长算合适?

没有绝对行数,但有一条判据:只放稳定的、全项目通用的规则,任务相关的一律推到按需加载的文件里。因为这个文件会被拼接进每一轮,每一行都在被永久征税。一个短根文件写着“鉴权逻辑在src/auth/,动它之前先读src/auth/README.md”,胜过200行重述那个二十次任务只碰一次的流程。还有个反直觉的推论:写第N条规则的时候,你其实在削弱前面N-1条的权重。

什么情况下不该做上下文工程?

短的一次性任务全都不该。给一个函数加空值检查、改一段文案的语气,一个带着那一个文件的朴素提示词,胜过任何检索流水线、压缩方案或记忆系统。粗暴的门槛是:Agent要跑超过10轮、或者会读超过5个文件,才值得动用这一套。低于这个量级,过度工程化造成的浪费不比上下文膨胀少。

权威参考资料

分享到
标签
版权声明

本文标题:《上下文工程的减法实践:5000 token检索为何胜过10万token摘要》

本文链接:https://zhangwenbao.com/context-engineering-subtraction-practice.html

版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交