背景:MCP 工具调用的问题

2024 年 11 月,Anthropic 开源 Model Context Protocol(MCP)后,社区热情高涨,几个月内涌现出数千个 MCP 服务器。但随着实际应用深入,一个根本性的矛盾暴露出来:

MCP 的工具越多,Agent 越傻。

传统 MCP 的工作流是这样的:

LLMLLM

这里有两个致命的 Token 黑洞:

问题一:工具定义开销爆炸

每个工具都需要在系统提示或上下文中描述清楚——名称、参数、类型、含义。接入 5 个 MCP 服务器,每个 20 个工具,光工具定义就能吃掉十几万 Token,模型还没开始干活。

Cloudflare 给出了一个极端案例:其 API 有 2,500+ 个端点,如果全量转化为 MCP 工具,需要 1,170,523 个 Token——超过当前最先进模型的整个上下文窗口。

问题二:中间结果污染上下文

Agent 调用工具获取数据,结果必须经过上下文"传送"给下一轮推理。一份会议纪要、一张电子表格,动辄几万字,全塞进去,效率直接崩了。

Anthropic 的实测数据:一个包含转录文本传输的工作流,仅中间数据就多消耗了约 50,000 Token

这就是为什么 2025 年底,Cloudflare 和 Anthropic 几乎同时,从不同角度提出了同一个解法:让 Agent 写代码,而不是喊话。


两条殊途同归的路

维度Cloudflare Code ModeAnthropic Code Execution with MCP
发布时间2026 年 2 月2025 年 11 月
核心思路服务端封装,2 个工具代替 2500 个客户端文件系统,按需加载定义
执行环境Cloudflare Dynamic Worker(V8 Isolate)客户端沙箱(可插拔)
语言JavaScriptTypeScript / Python
工具发现方式search() + 内嵌 OpenAPI spec文件系统目录树浏览
认证方式OAuth 2.1 + Worker BindingMCP Client 持有 Token
适用场景大规模 API 访问(Cloudflare 生态)通用多服务器编排
Token 节省99.9%(vs 全量 MCP)98.7%(vs 传统工具加载)
开源状态@cloudflare/codemode 实验性设计模式,非框架

两者的交集在于一个核心洞察:LLM 写代码比调用 JSON 格式的工具更擅长,因为它见过的代码比见过的 tool_call 格式多出几个数量级。


Cloudflare Code Mode:服务端的极简主义

设计哲学

Code Mode 的核心是一种服务端封装策略:把庞大的 API 文档锁在服务器端,只给 Agent 两把钥匙:

  • search():让 Agent 用 JavaScript 代码在 OpenAPI spec 里检索端点
  • execute():让 Agent 用 JavaScript 代码调用找到的端点

API 规格说明永远不进入模型上下文——Agent 只拿到它需要的那一片段的结果。

架构全景

writeNNEADooxgJyteSCnfeenClainrtlcomlvnoouieaSuddcsvludefyapflWsrfelaotieraArreatvrIsekmbcieeMelhsAaCMrae(oAgrPCc)rPecPLclInhPoeebht(rSasalo()oedskol2treacd,oovrgks5rceee0or(dc0elVr+x8beeydecIenusdndtoetpelfio(aaai)tulnelst)ts)

实际运行示例:DDoS 防护配置

一个要"给 origin 配置 DDoS 防护"的 Agent,完整流程只需 4 次工具调用:

第一步:用代码搜索相关端点

// Agent 调用 search(),传入过滤逻辑代码
spec.paths
  .filter(
    (path) =>
      path.includes("/zones/") &&
      (path.includes("firewall/waf") || path.includes("rulesets")),
  )
  .map((path) => ({ path, operations: spec.paths[path] }));

服务器执行这段代码,返回匹配的端点列表(不是完整 spec)。

第二步:用代码执行配置

// Agent 调用 execute()
const rulesets = await cloudflare.request("GET", "/zones/{zone_id}/rulesets");
const ddosRuleset = rulesets.find((r) => r.phase === "ddos_l7");
await cloudflare.request(
  "PUT",
  `/zones/{zone_id}/rulesets/${ddosRuleset.id}/rules`,
  {
    action: "execute",
    action_parameters: { id: "ddos_protection" },
  },
);

整个过程,上下文中只有代码和执行结果,永远不会出现 2MB 的 OpenAPI 文档。

Dynamic Worker Loader:沙箱技术核心

Code Mode 的执行引擎是 Cloudflare 2026 年初推出的 Dynamic Worker Loader API,核心特性:

// 动态实例化一个 Worker 来执行 Agent 生成的代码
let worker = env.LOADER.get(id, async () => {
  return {
    compatibilityDate: "2025-06-01",
    mainModule: "agent_code.js",
    modules: { "agent_code.js": agentGeneratedCode },
    env: {
      // 只注入 MCP 服务绑定,不注入任何 secret
      CLOUDFLARE_API: mcpServerBinding,
    },
  };
});

const result = await worker.run();

每次代码执行都在独立的 V8 Isolate 中运行,执行完即销毁(disposable model)。


Anthropic Code Execution with MCP

设计哲学

Anthropic 的方案更像一套系统架构指导原则,核心是重新设计 Agent 与工具的接口方式:

把工具变成文件,把调用变成 import。

不再在 prompt 里声明所有工具,而是把工具定义组织成文件系统目录:

servegsgroaisltgehliglsiuquiceneifnpubnr-dtsodde/dedeDtrearearxoFcxtyxti.cie.eR.evtultRetPesmesecsR/esco.n.ortttrds.sdst..sttss##

Agent 像一个程序员一样:先 ls 看看有什么,再按需 read 定义,最后写代码调用。

工作流对比

传统 MCP 调用流程:

LLML1tL5oM0o,l0_0c+0a5.l0.tl,.o0kJ0eS0nOsNtokens

Code Execution with MCP 流程:

Agent2,000tokens

典型代码示例

// Agent 生成的代码(在沙箱中执行)
import * as gdrive from "./servers/google-drive";
import * as salesforce from "./servers/salesforce";

// 获取会议记录(数据留在沙箱,不进 LLM 上下文)
const transcript = (
  await gdrive.getDocument({
    documentId: "abc123",
  })
).content;

// 在沙箱内处理:提取关键决议
const actionItems = transcript
  .split("\n")
  .filter((line) => line.startsWith("ACTION:"));

// 只把精炼结果写回给 LLM
await salesforce.updateRecord({
  objectType: "SalesMeeting",
  recordId: "00Q5f000001abcXYZ",
  data: { ActionItems: actionItems.join("\n") }, // 不是原始 transcript!
});

console.log(`Updated ${actionItems.length} action items`);

原始转录文本(可能几万字)在沙箱内处理,只有 actionItems 的摘要最终返回给模型。


核心设计理念:为什么是代码,而不是 JSON

这是两个方案最值得玩味的共同洞察,也是整个范式转变的哲学基础。

LLM 的训练数据分布

LLM 在预训练阶段接触了大量真实世界的代码——GitHub 上的亿级代码库、Stack Overflow 的问答、技术博客。但"MCP tool call JSON"这种格式,在训练数据里几乎是零。

API:(Ptyotohlo_nc/aTlylpeJSScOrNipt/JS)

这意味着:

  • 让 LLM 写代码 → 它有海量参考,表现稳定
  • 让 LLM 输出 tool_call JSON → 它在猜测一种罕见的格式,容易出错

Cloudflare 工程师在博客中直接点明:

“LLMs have seen a lot of code. They have not seen a lot of ’tool calls’ in real-world contexts, making code generation substantially more reliable than direct tool invocation.”

类型系统提供隐式文档

当工具被转换为 TypeScript 接口时,类型签名本身就是文档:

// 这比 JSON schema 更直观,LLM 更熟悉
async function createDnsRecord(params: {
  zoneId: string; // The Zone ID
  name: string; // DNS record name (e.g., "example.com")
  type: "A" | "AAAA" | "CNAME" | "MX";
  content: string; // IP address or hostname
  ttl?: number; // Time to live (default: 3600)
  proxied?: boolean; // Enable Cloudflare proxy (default: false)
}): Promise<DnsRecord>;

JSDoc 注释 + TypeScript 类型 = LLM 最熟悉的 API 文档形式。


沙箱安全模型对比

代码执行的安全性是最关键的问题。两种方案都选择了 V8 Isolate(而非容器),但侧重点不同。

V8 Isolate vs 容器:选择的逻辑

维度V8 Isolate容器 (Docker)
启动时间毫秒级秒级
内存占用几 MB几百 MB
隔离级别内存级别(同进程不同 Isolate)进程/内核级别
支持语言JavaScript / WebAssembly任意
成本极低较高
适合场景高频、短时、轻量代码长时运行、需要完整系统调用

对于 Agent 生成的短时工具调用代码,V8 Isolate 是完美选择。

Cloudflare 的安全层次

第一层:网络隔离

// Wrangler 配置中,外部网络完全封锁
const executor = new DynamicWorkerExecutor({
  loader: env.LOADER,
  globalOutbound: null, // null = 完全禁止外部 fetch()
});

不是"过滤",而是"不存在"。Isolate 里根本没有 Internet 连接。

第二层:Binding 访问控制

认证信息不注入到 Isolate 的代码环境中,而是通过 Binding 对象提供:

// Agent 的代码只能调用 binding 提供的方法
// 无法通过 process.env 或任何方式泄露 API Key
const result = await cloudflare.request("GET", "/zones");
// cloudflare 是一个 Binding 对象,不是真实的 fetch

即使 Agent 写了恶意代码 console.log(process.env.CF_API_KEY),也拿不到任何东西,因为环境变量根本不在 Isolate 里。

第三层:Agent Supervisor 授权

AgVcre8lenoqtIuusdeSofsulltpaa(etr.ree.v..i)sorAgentSAuPpIerTvoikseonrToken

所有对 Cloudflare API 的请求先经过 Supervisor,由 Supervisor 添加认证头。AI 永远看不到真实的 Token。


Token 效率

Cloudflare API 场景的 Token 对比

方案Token 消耗占 200K 上下文的比例
原始 OpenAPI Spec~2,000,000977%
完整 MCP(含 Schema)1,170,523585%
精简 MCP(最小参数)244,047122%
Code Mode1,0690.5%

Code Mode 比"精简 MCP"还节省 99.6%

Anthropic 场景的实测数据

指标传统 MCPCode Execution节省
工具定义加载 Token150,0002,00098.7%
含数据传输的完整工作流771,000165,00078.5%

Agent Skills:从工具调用到能力积累

Anthropic 方案中最具前瞻性的概念之一是 Skill(技能),这让 Agent 从单次任务执行进化到能力持续积累。

Skills 的工作原理

/skicsblryalentsacc/t-hem--eujesiteriran--gpf-rrnooovmti-esasil.oetnrsitn.gt.sts###

当 Agent 成功完成一项复杂任务后,可以把核心逻辑提炼成 Skill 保存起来。下次面对类似任务,Agent 先扫描 skills 目录,直接复用而不是从头推理。


架构权衡与适用场景

代码执行的代价

可靠性风险

LLM 写的代码不保证语法正确,也不保证逻辑正确。需要完善的错误捕获和重试机制。

基础设施成本

你需要一个安全的代码执行环境:Cloudflare Code Mode 依赖 Dynamic Worker Loader(目前是 closed beta)。

适用场景矩阵

场景推荐方案理由
访问单一大型 API(如 Cloudflare、Stripe)Code Mode服务端封装,简单接入
多服务编排(CRM + 云存储 + 通知)Code Execution客户端灵活组合
需要处理敏感 PIICode Execution数据不出沙箱
简单问答、单工具调用传统 MCP无需引入额外复杂度

行业意义与未来展望

两个独立团队的趋同验证

Cloudflare 和 Anthropic 在几乎相同的时间窗口内,基于各自的实践经验,独立得出了同一个结论:代码是 AI Agent 调用工具的更好抽象

这种趋同(convergence)本身就是强信号——它说明这不是一家公司的特定偏好,而是工程实践揭示的客观规律。

MCP 本身的进化方向

Code Mode 并非要取代 MCP,而是在 MCP 之上的一种使用范式的进化:

MMCCPP12..00::

可以预见,未来 MCP 规范可能会纳入代码执行相关的标准——比如沙箱接口、类型定义导出格式等。


总结:一场正在发生的范式迁移

旧范式(传统 MCP 工具调用)新范式(代码执行)
LLM 输出 tool_call JSONLLM 输出可执行代码
工具定义全量加载按需发现和加载
中间数据过上下文中间数据留在沙箱
串行工具调用并发代码执行
无状态(每次从零开始)有状态(技能积累,进度持久化)
隐私依赖模型服务商隐私可控(PII 不进模型)
Token 消耗随工具数量线性增长Token 消耗接近常数

AI Agent 正在从"一个会按按钮的机器人",进化为"一个会写程序的工程师"。

这不仅是工程效率的提升,更是 Agent 自主能力的质变——当工具调用变成代码,Agent 就获得了组合、抽象、复用的能力,而这正是软件工程的本质。


参考资料

  1. Code Mode: give agents an entire API in 1,000 tokens — Cloudflare Blog
  2. Code execution with MCP: building more efficient AI agents — Anthropic Engineering
  3. Cloudflare MCP Server — GitHub
  4. Code Mode: the better way to use MCP — Cloudflare Blog
  5. Codemode API Reference — Cloudflare Agents Docs
  6. Dynamic Worker Loaders — Cloudflare Workers Docs

调研日期:2026-03-06 关联话题:MCP, AI Agent, 代码执行, 沙箱安全, Token 效率