2026年7月2日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

Claude Code 意外开源后,我终于看清了 Agent 里“延迟曝光”的真正价值

发布日期:2026-04-01 09:40:01 浏览次数: 2397
作者:土猛的员外

微信搜一搜,关注“土猛的员外”

推荐语

Claude Code意外开源揭示Agent设计的精妙之处:延迟曝光机制如何优化多轮交互成本。

核心内容:
1. Claude Code源码意外泄露暴露的"延迟曝光"设计模式
2. 前缀缓存(prefix cache)对Agent性能的关键影响
3. 主流编码智能体采用相似架构的深层原因

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家


一、一个被很多人忽略的问题:Agent 的成本,很多时候不是模型能力,而是“前缀”

事情的起点,其实有点戏剧性。

原本只是一个再普通不过的工作日,但开发者圈突然被一件事刷屏——
Claude Code 的源码,被“意外公开”了。

不是官方开源,也不是技术发布,而是一个很典型的工程事故:
npm 包里误带了 source map 文件。

这种文件本来只是用来调试的,但一旦放出来,就等于把压缩后的代码“反编译”回了原始实现。于是短短时间内,几十万行 TypeScript 代码被完整还原,整个工程细节几乎被摊在桌面上。

一时间TorchV的办公室里,同事们奔走相告,coding-agent和数字员工们被指派进行了深度的源码挖掘。大家纷纷对自己Focusing的方面开始了探索


说回来,这件事为什么会炸? 因为大家第一次有机会,看到公认的全球Top级“顶级 Agent”到底是怎么做的。 很快,讨论就集中在几个非常熟悉的话题上:

  • 它到底有多少工具?(答案:很多,而且很复杂)
  • Agent loop 是怎么跑的?
  • 多 agent 协同是怎么做的?
  • 有没有什么“隐藏能力”(比如后台常驻、自动执行等)

这些都很正常,也确实很有意思。


但如果我们把这些代码多翻一会儿,会慢慢注意到一个不那么起眼、甚至一开始很容易忽略的点:

👉 工具并不是一开始就全部给模型的。

而且不仅如此,它们:

  • 有一部分是“延迟”的
  • 有一部分只以“线索”形式存在
  • 有一部分甚至被刻意放在不同的上下文结构里

这件事初看很像是某种 prompt 技巧,甚至有点“工程细节味太重”。

但再往深一点想,就会意识到:

这很可能不是技巧,而是一个被精心设计过的结构。


更有意思的是,当我们把视角从 Claude Code 稍微拉开一点,会发现:

这并不是它一家在这么做。

同样是顶级的编码智能体Codex,在开源代码中也能找到相同的做法,被称之为: delayed exposure

这时候,一个问题就变得值得认真对待了: **为什么这些系统都在做同一件事?


原因其实不在“能力”,而在一个很多人一开始不会注意到的地方:

多轮Agent的成本和速度,很大程度由 Context 的结构决定的。

更具体一点说,是由——

👉 前缀(prefix)是否稳定决定的。

而 Claude Code 这次“意外开源”,恰好让我给大家带来一段颇有意思的分享:

延迟曝光机制,和前缀缓存(prefix cache)有什么关系?


二、prefix cache 是什么,以及它为什么会成为 Agent 的核心约束

很多人真正开始关注 prefix cache,其实是从 2024 年的一次“价格变化”开始的。 当时 DeepSeek 在 API 里上线了一个能力:上下文硬盘缓存。

官方给出的描述很直接:

  • 很多请求,其实有大量重复前缀
  • 这些前缀可以缓存下来
  • 下次再用,不需要重新计算

更关键的是价格:

👉 命中缓存的部分,成本可以降到原来的 0.1 倍


这事之所以重要,不仅因为“便宜了”,而是因为它首次将cache的复用做到了工程化中,让这个相对隐性的知识被知晓:

模型推理,并不是每次都必须从头计算。

prefix cache,本质上在复用“已经算过的前缀”

要理解这件事,需要稍微回到一点点模型原理。

以 Transformer 为例(现在几乎所有大模型都是这个架构),推理过程大致是这样的:

  • 输入被拆成一串 token
  • 模型一层一层处理这些 token
  • 每一层都会产生一组中间结果(KV cache)
  • 后续 token 会不断依赖前面所有 token 的计算结果

换句话说:

模型在处理第 N 个 token 时,前面 N-1 个 token 的计算结果是已经存在的。


于是就有一个很自然的优化:

如果下一次请求的前缀完全一样,那这些中间结果(KV cache)其实可以直接复用。

也就是说:

  • 不需要重新跑 attention
  • 不需要重新算 embedding
  • 直接从缓存继续往后生成

DeepSeek 做的事情,本质上就是把这套机制“工程化”了:

  • 把前缀的计算结果缓存到磁盘(而不是只存在内存)
  • 在分布式系统中复用这些缓存
  • 自动识别请求前缀是否一致

而且它还有一个非常严格的条件:

只有从第 0 个 token 开始完全一致的前缀,才会命中缓存。

中间哪怕有一点不同:

👉 都不会命中


这件事为什么会对 Agent 产生巨大影响

在普通单轮问答里,这个机制已经很有价值了:

  • 长 prompt(system prompt / few-shot)
  • 重复调用
  • 数据分析类任务

都可以明显降成本。 但在 Agent 里,这件事的影响是被放大的。 因为 Agent 的调用方式是这样的:

  • 每一轮都会把“历史对话 + 新输入”一起发给模型
  • 上下文单调递增,这是一个非常适合缓存的结构

如果一切都按理想情况发展,每一轮只是往后 append,前面的内容完全不变 那么:

👉 prefix cache 命中率会非常高
👉 推理成本接近“增量计算”


但现实情况下,模型提供商在收到消息后会这样格式化输入:

┌───────────────────────────────┐
│         System / Instructions │  ← 稳定前缀(基本不变)
├───────────────────────────────┤
│         Tool List / Schema    │  ← 稳定前缀(最容易被破坏)
├───────────────────────────────┤
│   Environment / Context Info  │  ← 通常稳定(但可能变化)
├───────────────────────────────┤
│                               │
│   ┌───────────────────────┐   │
│   │ User Message (turn 1) │   │
│   ├───────────────────────┤   │
│   │ Assistant (reasoning) │   │
│   ├───────────────────────┤   │
│   │ Tool Call + Output    │   │
│   ├───────────────────────┤   │
│   │ User Message (turn 2) │   │
│   ├───────────────────────┤   │
│   │ Assistant ...         │   │
│   └───────────────────────┘   │
│                               │
│        (持续 append)           │  ← 可增长后缀
└───────────────────────────────┘

很多系统,会在不知不觉中破坏这一点。 最典型的,就是前面提到的:

👉 前缀被改写了。


而改写前缀的“重灾区”,往往就是工具列表,这会带来一个非常实际的结果:

同一个 Agent,随着对话轮次增加,成本和延迟不断“重算”。

也正是因为这个原因,prefix cache 在 Agent 里,从一个“可选项”,变成了一个必做项

  • 你可以让上下文变长
  • 但尽量不要让“前面的结构”发生变化

换句话说: DeepSeek 把这件事“显性化”了——用价格告诉你缓存有多重要;
而 Agent 系统,则必须把这件事“结构化”——从一开始就围绕缓存去设计上下文。


接下来,我们就可以回到最开始那个问题:

如果工具本身是动态的,那该怎么让它“不破坏前缀”?

答案就是——延迟曝光


三、Claude Code 意外“开源”,让一个原本模糊的机制变清晰了

如果只停留在表层,Claude Code 做的事情其实并不新鲜:

  • 有工具
  • 支持 Tool Search
  • 模型可以按需调用

但源码一旦被还原出来,有一件事会变得非常明显——它的重点根本不在“工具调用”,而在另一件更底层的事情:

工具是如何进入上下文的。


Claude Code 从一开始就把工具可见性,当成一个和缓存边界绑定的问题来处理。

它的基本思路可以用一句话概括:

工具不是一次性给模型,而是分阶段、分位置、分承载方式进入上下文。


首先,它在系统层面就把工具分成两类:

一类是立即可见的,模型从第一轮就可以直接调用;另一类则是延迟的,这部分工具不会在初始 prompt 里展开完整 schema。

这一步本身不复杂,但关键在于后面的处理方式。

对于这些延迟工具,Claude Code 并不是“什么都不给”,而是先给模型一个“线索层”:

  • 告诉模型有哪些工具存在
  • 告诉它们来自哪个来源(比如 MCP)
  • 但不会给出完整参数定义

这样,模型在第一轮看到的上下文,是一个轻量且稳定的前缀,而不是一整套庞大的工具 schema。


接下来,当模型真正需要某类能力时,它才会通过 Tool Search 去拿完整定义。

这一点和很多系统类似,但 Claude Code 的关键区别在于:

👉 “拿到定义”这件事之后,这些信息会以什么形式进入上下文。


如果只是简单实现,很容易走到一种直觉方案: 将搜索到的工具重新加入工具列表

这种方式简单直接,但有一个致命问题:
前缀变了,cache 直接失效。


Claude Code 的处理方式明显更“克制”。

它没有依赖单一表达,而是根据不同路径,把“延迟工具的存在”放在不同的承载层里。

有时候,它确实会用类似上面的提示块,让模型知道有哪些工具;但在另一条路径下,这些信息会变成一种 system-reminder 风格的消息,不再是直接拼在 prompt 前部的文本。

再往后,你会看到更进一步的做法:它会把这些变化整理成一种增量结构,比如:

  • 普通提示块示例:

    <available-deferred-tools>
    Read
    Edit
    Grep
    </available-deferred-tools>
  • 系统提醒类信息示例:

    Deferred tools appear by name in <system-reminder> messages.
  • 更稳定的增量附加信息示例:

    deferred_tools_delta:
      - tool: Read
      - tool: Edit
      - tool: Grep

这种形式的本质,不再是“每轮重写一段文本”,而更像是:

👉 把工具池的变化,当作一次可追加的状态更新。


进一步看源码里的开关逻辑,这件事就更清晰了。

是否使用 <available-deferred-tools> 这种前置块,并不是固定的,而是取决于类似 isDeferredToolsDeltaEnabled() 这样的路径判断:

  • 如果没有启用更稳定的机制,就退回到“前置提示块”
  • 如果启用了 delta attachment,就不再每轮 prepend
  • 而是把变化整理成附加信息,进入会话历史

再往深一层看,还有一个更容易被忽略的点:

它在 cache 判断上,是有明确取舍的。

延迟工具的变化,本质上是“系统能力的变化”,但 Claude Code 的策略是:

👉 **这种变化不应该直接影响 prefix cache **

换句话说,它在做两件事:

  • 让模型“看到工具”
  • 但尽量不让“工具变化”成为 cache 的扰动源

把这些拼在一起,就可以得到一个非常清晰的结构:



它不是在解决“模型如何选工具”,而是在解决“工具系统如何不破坏前缀”。


四、再看 Codex:另一种实现,但在解决同一个问题

如果只看 Claude Code,或许以为这是 Anthropic 的一套“特殊技巧”。

但当你再去看 OpenAI Codex CLI 的实现,会发现一个很有意思的现象:

它走的是相对不同的路径,但目标几乎一样。


Codex 的切入点不是“工具怎么放”,而是:

把“工具发现”这件事,变成一次正式的会话事件。


它的做法可以简单理解成三步:

第一步,初始阶段不暴露全部工具
模型一开始只看到:

  • 少量基础工具
  • 一个叫 tool_search 的入口

其他工具,并不在顶层完整出现。


第二步,需要时让模型自己去搜
当模型判断需要某类能力时,它不会直接调用工具,而是:

👉 先调用 tool_search

这个动作的意义在于:

  • 明确当前有哪些工具
  • 拿到完整 schema
  • 确认命名空间和调用方式

第三步,也是最关键的一步:

👉 搜索结果会写入会话历史

也就是说,这不是一段临时提示,而是一个正式存在的历史项:

  • 有 call
  • 有 output
  • 有配对关系

从这一刻开始,这些工具就“存在于对话里”了。


这一步的工程价值非常大,但很容易被忽略。

因为它带来一个直接结果:

工具定义不需要反复出现在前缀里了。

后续轮次发生的事情是:

  • 模型直接基于历史里的工具定义调用
  • 系统通过“命名空间 + 短名”解析回真实工具
  • 整个顶层工具集合保持稳定

也就是说,Codex 做了一件和 Claude Code 本质类似的事情:

👉 把变化往“后面”移动,而不是改前面


如果你把两者放在一起看,会发现一个非常清晰的共识:


Claude Code
Codex
切入点
工具信息的承载位置
工具发现的生命周期
关键手段
delta / reminder / 非前缀注入
tool_search + 历史写入
本质目标
不污染 prefix
不重写 prefix

路径不同,但答案是一致的:

不要让“工具全集”成为一个每轮都会变化的 prompt 前缀。

而这,也正是“延迟曝光机制”真正要解决的问题。

五、为什么“延迟曝光”会在 Agent 中变成一个几乎必选的结构

如果只看 Claude Code 或 Codex,很容易把延迟曝光理解成一种“高级优化”。

但一旦你把视角从“某个实现”切换到“Agent 系统整体演进”,就会发现:

这其实不是优化,而是规模上来之后的必然结果。


先看一个趋势变化。

早期的 Agent,工具通常是这样的:

  • 数量很少(2~5 个)
  • 来源固定(本地 + 少量 API)
  • 生命周期稳定(基本不会变)

在这种情况下,把所有工具一次性塞进 prompt,完全没问题,甚至更简单


但现在的 Agent,工具形态已经完全变了:

  • 工具数量:几十甚至上百
  • 工具来源:
    • 本地工具
    • 平台内置工具
    • MCP 工具
    • 子agent工具
  • 工具可见性:可能在运行过程中动态变化

尤其是 MCP 这一类能力,本质上是:

工具集合是“运行时生成”的,而不是静态配置的。


这时候,如果你还用“全量工具直接暴露”的方式,会发生什么?

第一层问题,是成本问题

  • prompt 变得很重
  • 每一轮都要重新发送完整 schema
  • token 消耗显著上升

但更致命的是第二层问题:

👉 prefix cache 开始频繁失效


这时候,延迟曝光就不再是“优化”,而是一个结构性解法

  • 工具不再一次性暴露
  • 可见性分层(基础工具 / 延迟工具)
  • 能力通过搜索或线索按需获取
  • 工具定义尽量只出现一次(进入历史或稳定层)

这样做的直接结果是:

  • 首轮更轻,按需加载
  • 中间轮次更稳定
  • prefix 更容易保持一致
  • cache 命中率显著提高

换句话说:

当工具系统开始“动态化 + 大规模化”,延迟曝光几乎是唯一不会把系统拖垮的方案。


好,这一章我帮你做一次压缩 + 强化 TorchV 部分 + 收尾更有力,去掉重复表达,让节奏更干净。


六、延迟曝光真正保护的不是“工具数量”,而是“前缀不被改写”

如果把前面的分析收敛成一句话,其实就是:

延迟曝光真正保护的,不是“工具少一点”,而是“前缀稳定不被改写”。


可以把一次模型请求简单拆成两部分:

  • 前缀(prefix):instructions、工具定义、环境信息
  • 后缀(suffix):用户输入、工具调用结果、对话历史

prefix cache 的规则非常简单,也非常严格:

👉 只有前缀完全一致,缓存才会命中。


延迟曝光本质上做了一件事:

把原本会进入前缀的变化,转移到后缀或更稳定的附加层。

这其实就是把“只追加、不修改”的设计,从对话内容,扩展到了工具系统本身——也就是一种更完整的 Append-Only Prompt 模式


这个问题在真实系统里并不抽象。

在 TorchV 的 Agent 实践中,我们遇到过一个很典型的场景:有状态的沙箱工具

  • agent 先发起连接
  • 连接成功后,系统才返回一组新的可操作工具

如果直接把这些工具“刷新进前缀”,很容易出现:

  • 每轮工具列表都在变化
  • prefix 不再稳定
  • cache 命中率迅速下降

我们的调整方式其实和前面两家的思路是收敛的:

  • 初始只暴露稳定能力
  • 动态工具通过“事件 / 附加信息”进入上下文
  • 严格避免回写或重排前缀
  • 所有变化尽量表现为 append,而不是 rewrite

这件事在 RAG 和企业知识库场景里尤为关键。

因为:

  • prompt 本身很长(知识上下文 + system 约束)
  • Agent 运行链路更长(检索 → 推理 → 调用 → 再检索)
  • 工具来源更多且更动态

如果前缀不稳定:

👉 每一步几乎都在“重新算一遍”

而一旦前缀稳定:

👉 系统会明显进入“增量执行”的状态(速度和成本都会下来)


也正因此,在我们新的 Agent 产品线 Workstation 里,这一点被明确提炼成一个设计原则:

能力可以动态变化,但前缀必须尽量静态。


回头看 Claude Code 和 Codex,其实路径不同,但本质完全一致:

  • Claude Code:通过承载层设计,隔离工具变化
  • Codex:通过 tool_search,把工具展开变成历史追加
  • TorchV:在动态工具与长上下文之间,强制“只追加不回写”

当 Agent 还很简单时,这件事不明显;
但当工具变多、链路变长、上下文变重时,

👉 谁能控制“变化发生在哪里”,
👉 谁的系统才能真正跑得稳、跑得久、跑得起。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅