48
48 / 50

MCP 的 Code Execution 模式:把工具当代码库调用

⏱️ 25分钟

当 MCP server 从 3 个增长到 30 个,直接工具调用的主要成本会从“模型思考”变成“工具定义和中间结果占满 context”。Code Execution 模式把 MCP 暴露为可浏览的代码接口,让 Agent 按需读定义、在执行环境处理数据,只把结论送回模型。


两种数据路径

直接 MCP 调用
定义全部进 context → 模型调用 → 结果全部进 context → 模型再过滤

Code Execution with MCP
文件系统发现接口 → 沙箱代码调用 → 本地过滤/聚合 → 结论进 context
维度直接调用Code Execution 模式
工具发现预加载 schema按需浏览文件或搜索
中间数据进入模型 context留在执行环境
组合逻辑多轮模型判断循环、条件、函数
状态对话历史文件或执行环境变量
基础设施MCP client 即可还需要安全沙箱和资源限制

Anthropic 官方示例把同类任务从 150,000 token 降到 2,000 token。这个数字是特定任务的结果,不是每个系统都能复制的承诺;真正应测的是你自己的定义体积、结果大小和调用链长度。


把 MCP server 映射为代码目录

一种清晰的目录约定如下:

servers/
├── google-drive/
│   ├── getDocument.ts
│   └── getSheet.ts
├── salesforce/
│   ├── findProspect.ts
│   └── updateRecord.ts
└── index.ts

每个文件只暴露类型、用途和包装后的调用函数:

import { callMCPTool } from '../../client';

export interface GetDocumentInput {
	documentId: string;
}

export interface GetDocumentResponse {
	content: string;
	modifiedAt: string;
}

/** Read one Google Drive document. Do not use for folders. */
export async function getDocument(input: GetDocumentInput): Promise<GetDocumentResponse> {
	return callMCPTool('google_drive__get_document', input);
}

Agent 不需要读取整个 MCP catalog。它先列出 servers/,再打开与任务有关的文件,这就是 progressive disclosure。


示例:从会议记录更新 CRM

import * as drive from './servers/google-drive';
import * as crm from './servers/salesforce';

const transcript = await drive.getDocument({ documentId: 'doc-123' });
const summary = transcript.content
	.split('\n')
	.filter(line => line.startsWith('Decision:') || line.startsWith('Owner:'))
	.join('\n');

await crm.updateRecord({
	objectType: 'SalesMeeting',
	recordId: 'meeting-456',
	data: {
		Notes: summary,
		SourceModifiedAt: transcript.modifiedAt
	}
});

完整 transcript 没有进入模型。需要模型判断的只有“应该提取哪些信息”;机械过滤和写入由代码完成。


安全边界必须先于 token 优化

Agent 生成的代码不应直接运行在应用服务器主进程里。最低控制包括:

控制最低要求
文件系统临时工作目录;默认只读;显式输出目录
网络只允许必要 MCP endpoint;拒绝任意出站
凭证短时、最小权限;不把长期密钥放入环境变量
资源CPU、内存、执行时间、输出大小上限
工具权限按任务授权;读写工具分离;高风险写入需审批
审计保存代码、工具调用、结果摘要和最终写操作

不要把“中间数据没有进入 LLM”误写成“数据绝对安全”。数据仍然经过执行环境、MCP server 和日志系统,必须分别做数据分类与保留策略。


错误处理与幂等

批处理代码最容易把一次错误扩大成 500 次错误。写入工具至少需要:

type WriteResult = {
	idempotencyKey: string;
	status: 'created' | 'already_applied' | 'rejected';
	evidenceId?: string;
};

执行策略:

  1. 先读、后算、最后写。
  2. 写入前生成 idempotency key。
  3. 高风险操作先输出 dry-run diff。
  4. 限制单次批量大小。
  5. 部分失败时记录成功项,不盲目全量重跑。

何时不要使用

  • 只有 3–5 个工具且结果很小。
  • 模型必须逐条阅读中间结果才能判断。
  • 团队暂时没有可信的代码沙箱。
  • 工具包含不可撤销写操作,却没有审批和幂等设计。
  • 省下的 token 少于执行环境的固定运维成本。

上线验收

  • 工具定义可以按需发现,不需要全量预载。
  • 10,000 行数据先在执行环境过滤,再进入模型。
  • 沙箱超时后任务能明确失败,不会无限等待。
  • 写操作支持 dry run、审批和幂等。
  • Trace 能关联生成代码、MCP 调用和业务结果。
  • 用真实任务比较 token、P95 延迟、正确率和运维成本。

动手练习

选择一个“从表格找出逾期客户并创建 CRM follow-up”的流程:

  1. 为 Sheet 与 CRM 建立最小 TypeScript wrapper。
  2. 在代码里过滤逾期超过 14 天且金额大于阈值的行。
  3. 输出 dry-run JSON,不直接写 CRM。
  4. 加入人工批准后再执行批量写入。
  5. 验证重复执行不会创建重复任务。

相关阅读

参考资料

📚 相关资源

常见问题

点击问题,查看本章对应的实践答案。

Code execution 模式和传统 MCP 工具调用的核心区别是什么?

传统方式把全部工具定义预载进上下文、每个中间结果都流经模型;code execution 把 MCP server 呈现为文件系统里的代码 API,Agent 按需读定义、写代码调用,数据在执行环境流转,模型只看最终结果。

Token 降幅 150k → 2k 的数据出处是哪里?

Anthropic 官方工程博客《Code execution with MCP》(2025-11-04)的实测数据:同类任务 token 消耗从 150,000 降到 2,000,节省 98.7%。

什么场景不值得上 code execution 模式?

工具少、返回数据小的场景直接调用更简单;模型确实需要对中间数据做推理时数据本来就该进上下文。该模式要求自建沙箱、资源限制和监控,这些运维成本要和 token 节省对着算。

Code execution with MCP 和 Programmatic Tool Calling 是一回事吗?

前者是需要自建执行环境的架构模式;PTC 是 Claude Developer Platform 的 API 产品化实现——Claude 在托管沙箱里写 Python 编排工具,官方实测复杂研究任务 token 平均降 37%(43,588 → 27,297)。