**模型上下文协议(MCP)**是一个用于将智能体连接到外部系统的开放标准,由Anthropic于2024年11月发布。传统上,将智能体连接到工具和数据需要为每对组合进行自定义集成,这会造成碎片化和重复劳动,使得真正连接的系统的扩展变得困难。MCP 提供了一个通用协议——开发者在其智能体中实现一次 MCP,就能解锁整个集成生态系统。
理想很丰满,现实很骨感。MCP 发布的整整一年来,尽管加入开发 MCP 协议的大厂络绎不绝,但整体市场情况可以用下图来概括:

半个月前,Anthropic 在发布了更轻量级的工具调用标准 Skills ,业界普通认为该标准很可能会威胁到他们自己在一年前发布的MCP协议。为了避免煮豆燃豆萁的风险,于是Anthropic 发布了一篇名为《Code execution with MCP: Building more efficient agents》的文章,指导用户有效解决利用 MCP 协议来构建智能体时 token 消耗量大的问题,来巩固(抢救) MCP 协议的地位。
直接调用工具会消耗用于定义和结果的上下文。智能体通过编写代码来调用工具,反而能实现更好的扩展性。以下是该机制与MCP的协同工作方式。
自 2024 年 11 月推出 MCP 以来,其采用速度一直很快:社区已经建立了数千个 MCP 服务器,SDK 适用于所有主流编程语言,业界已将 MCP 作为连接智能体与工具和数据的事实标准。 如今,开发者通常会构建能够访问数十个 MCP 服务器上数百或数千个工具的智能体。然而,随着连接工具数量的增长,预先加载所有工具定义并将中间结果通过上下文窗口传递,会降低智能体的速度并增加成本。
本文将探讨代码执行如何使智能体更有效地与 MCP 服务器交互,处理更多工具,同时使用更少的 token。
一、工具带来的过度 token 消耗导致智能体效率低下
随着 MCP 使用规模的扩大,有两种常见的模式会增加智能体的成本和延迟:
- 工具定义使上下文窗口过载;
- 中间工具结果消耗额外的 token。
1. 工具定义使上下文窗口过载
大多数 MCP 客户端会预先将所有工具定义直接加载到上下文中,使用直接的工具调用语法将它们暴露给模型。这些工具定义可能如下所示:
gdrive.getDocument 描述:从 Google Drive 检索文档 参数: documentId (必需, 字符串): 要检索的文档 ID fields (可选, 字符串): 要返回的特定字段 返回:包含标题、正文内容、元数据、权限等的文档对象
``````plaintext
salesforce.updateRecord 描述:更新 Salesforce 中的记录 参数: objectType (必需, 字符串): Salesforce 对象类型 (潜在客户, 联系人, 客户等) recordId (必需, 字符串): 要更新的记录 ID data (必需, 对象): 要更新的字段及其新值 返回:包含确认信息的更新后的记录对象
工具描述占据了更多的上下文窗口空间,增加了响应时间和成本。在智能体连接到数千个工具的情况下,它们在读取请求之前需要处理数十万个 token。
2. 中间工具结果消耗额外的 token
大多数 MCP 客户端允许模型直接调用 MCP 工具。例如,用户可能会要求智能体:“从 Google Drive 下载我的会议记录,并将其附加到 Salesforce 潜在客户。”
模型将进行如下调用:
TOOL CALL:gdrive.getDocument(documentId: "abc123") → returns “讨论了 Q4 目标...\n[完整的记录文本]” (加载到模型上下文中)TOOL CALL:salesforce.updateRecord( objectType: "SalesMeeting", recordId: "00Q5f000001abcXYZ", data: { "Notes": "讨论了 Q4 目标...\n[写入完整的记录文本]" } ) (模型需要再次将完整的记录写入上下文)
每个中间结果都必须通过模型。在这个例子中,完整的会议记录流经了两次。对于一个 2 小时的销售会议,这可能意味着需要额外处理 50,000 个 token。更大的文档甚至可能超过上下文窗口限制,导致工作流中断。
对于大型文档或复杂的数据结构,模型在工具调用之间复制数据时可能更容易出错。
MCP 客户端将工具定义加载到模型的上下文窗口中,并编排一个消息循环,在该循环中,每个工具的调用及其结果,都在不同操作之间通过模型传递。
二、通过MCP执行代码可提高上下文效率
随着代码执行环境在智能体中日益普及,一种解决方案是将 MCP 服务器作为代码 API(而非直接的工具调用)来提供。然后,智能体就可以编写代码来与 MCP 服务器交互。这种方法解决了上述两个挑战:智能体可以仅加载它们需要的工具,并在将结果传回模型之前,先在执行环境中处理数据。
实现这一点有多种方式。一种方法是根据已连接的 MCP 服务器生成所有可用工具的文件树。以下是一个使用 TypeScript 的实现示例:
servers├── google-drive│ ├── getDocument.ts│ ├── ... (其他工具)│ └── index.ts├── salesforce│ ├── updateRecord.ts│ ├── ... (其他工具)│ └── index.ts└── ... (其他服务器)
然后每个工具对应一个文件,示例如下:
// ./servers/google-drive/getDocument.tsimport { callMCPTool } from "../../../client.js";interface GetDocumentInput { documentId: string;}interface GetDocumentResponse { content: string;}/* 从 Google Drive 读取文档 */export async function getDocument(input: GetDocumentInput): Promise<GetDocumentResponse> { return callMCPTool<GetDocumentResponse>('google_drive__get_document', input);}
上文那个 Google Drive 到 Salesforce 的示例就变成了如下代码:
// 从 Google Docs 读取记录并添加到 Salesforce 潜在客户import * as gdrive from './servers/google-drive';import * as salesforce from './servers/salesforce';const transcript = (await gdrive.getDocument({ documentId: 'abc123' })).content;await salesforce.updateRecord({ objectType: 'SalesMeeting', recordId: '00Q5f000001abcXYZ', data: { Notes: transcript }});
智能体通过浏览文件系统来发现工具:列出 ./servers/ 目录以查找可用的服务器(如 google-drive 和 salesforce),然后读取它需要的特定工具文件(如 getDocument.ts 和 updateRecord.ts)来解析每个工具的接口。这使得智能体仅需加载当前任务所需的定义。这将 token 使用量从 150,000 个 token 减少到 2,000 个 token——节省了 98.7% 的时间和成本。
Cloudflare 也发布了类似的研究结果,将使用 MCP 的代码执行称为“代码模式”。其核心见解是相同的:LLM 擅长编写代码,开发者应该利用这一优势来构建能更有效地与 MCP 服务器交互的智能体。
三、通过MCP执行代码的好处
通过MCP执行代码,智能体能够按需加载工具、在数据到达模型前进行过滤,以及在单个步骤中执行复杂逻辑,从而更有效地利用上下文。这种方法在安全性和状态管理方面也具有优势。
1.渐进式披露
模型非常擅长浏览文件系统。将工具以代码形式存放在文件系统中,允许模型按需读取工具定义,而不是一次性预先加载所有定义。
或者,可以向服务器添加一个 search_tools 工具来查找相关定义。例如,在使用上文假设的 Salesforce 服务器时,智能体搜索 “salesforce”,并仅加载当前任务所需的那些工具。在 search_tools 工具中包含一个“细节级别”参数,允许智能体选择所需的细节级别(例如仅名称、名称和描述,或包含模式的完整定义),这也有助于智能体节省上下文并高效地查找工具。
2.工具结果的上下文效率
在处理大型数据集时,智能体可以在返回结果之前,先在代码中对结果进行过滤和转换。以获取一个包含 10,000 行的电子表格为例:
// 不使用代码执行 - 所有行都流经上下文TOOL CALL:gdrive.getSheet(sheetId: 'abc123') → 在上下文中返回 10,000 行,等待手动过滤// 使用代码执行 - 在执行环境中过滤const allRows = await gdrive.getSheet({ sheetId: 'abc123' });const pendingOrders = allRows.filter(row => row["Status"] === 'pending');console.log(`找到了 ${pendingOrders.length} 个待处理订单`);console.log(pendingOrders.slice(0, 5)); // 仅记录前 5 行以供审查
智能体最终看到的只有 5 行,而不是 10,000 行。类似的模式也适用于聚合、跨多个数据源的连接或提取特定字段——所有这些都不会导致上下文窗口膨胀。
3.更强大、上下文效率更高的控制流
循环、条件判断和错误处理可以使用熟悉的代码模式来完成,而无需串联调用单个工具。例如,如果需要在 Slack 中接收部署通知,智能体可以编写如下代码:
let found = false;while (!found) { const messages = await slack.getChannelHistory({ channel: 'C123456' }); found = messages.some(m => m.text.includes('部署完成')); if (!found) await new Promise(r => setTimeout(r, 5000));}console.log('收到部署通知');
这种方法比通过智能体循环交替执行 MCP 工具调用和休眠命令要高效得多。
此外,能够编写一个可一次性执行的条件逻辑块也节省了**“首个 token 时间”(Time to First Token, TTFT)**的延迟:智能体不必等待模型来评估 if 语句,而是可以让代码执行环境来完成这项工作。
4.隐私保护操作
当智能体使用 MCP 执行代码时,中间结果默认保留在执行环境中。这样,智能体只能看到被显式记录或返回的内容,这意味着不希望与模型共享的数据可以流经整个工作流,而无需进入模型的上下文。
对于更敏感的工作负载,智能体执行 harness(管理程序)可以自动对敏感数据进行 token 化。例如,假设需要将客户联系方式从电子表格导入 Salesforce。智能体编写:
const sheet = await gdrive.getSheet({ sheetId: 'abc123' });for (const row of sheet.rows) { await salesforce.updateRecord({ objectType: 'Lead', recordId: row.salesforceId, data: { Email: row.email, Phone: row.phone, Name: row.name } });}console.log(`更新了 ${sheet.rows.length} 个潜在客户`);
MCP 客户端会在数据到达模型之前拦截数据,并对 PII(个人身份信息)进行 token 化:
// 如果智能体记录了 sheet.rows,它将看到的内容:[ { salesforceId: '00Q...', email: '[EMAIL_1]', phone: '[PHONE_1]', name: '[NAME_1]' }, { salesforceId: '00Q...', email: '[EMAIL_2]', phone: '[PHONE_2]', name: '[NAME_2]' }, ...]
然后,当这些数据在另一次 MCP 工具调用中共享时,MCP 客户端会通过查找将其反 token 化。真实的电子邮件地址、电话号码和姓名从 Google Sheets 流向 Salesforce,但绝不会通过模型。这可以防止智能体意外记录或处理敏感数据。也可以使用这种机制来定义确定性的安全规则,选择数据可以流入和流出的位置。
5.状态持久化与技能
具有文件系统访问权限的代码执行允许智能体跨操作维护状态。智能体可以将中间结果写入文件,使其能够恢复工作并跟踪进度:
const leads = await salesforce.query({ query: 'SELECT Id, Email FROM Lead LIMIT 1000'});const csvData = leads.map(l => `${l.Id},${l.Email}`).join('\n');await fs.writeFile('./workspace/leads.csv', csvData);// 之后的执行会从上次中断的地方继续const saved = await fs.readFile('./workspace/leads.csv', 'utf-8');
智能体还可以将其自己的代码持久化为可重用函数。一旦智能体为某个任务开发了可工作的代码,它就可以保存该实现以供将来使用:
// 在 ./skills/save-sheet-as-csv.ts 中import * as gdrive from './servers/google-drive';export async function saveSheetAsCsv(sheetId: string) { const data = await gdrive.getSheet({ sheetId }); const csv = data.map(row => row.join(',')).join('\n'); await fs.writeFile(`./workspace/sheet-${sheetId}.csv`, csv); return `./workspace/sheet-${sheetId}.csv`;}// 之后,在任何智能体执行中:import { saveSheetAsCsv } from './skills/save-sheet-as-csv';const csvPath = await saveSheetAsCsv('abc123');
这与“技能”(Skills)的概念密切相关——“技能”是指可重用指令、脚本和资源的文件夹,用于模型提高在专门任务上的性能。向这些保存的函数添加一个 SKILL.md 文件,会创建一个模型可以引用和使用的结构化技能。随着时间的推移,这允许智能体构建一个更高级别能力的工具箱,不断发展其高效工作所需的辅助框架。
请注意,代码执行也引入了其自身的复杂性。运行智能体生成的代码需要一个安全的执行 environment,具备适当的沙盒化(sandboxing)、资源限制和监控。这些基础设施需求增加了运营开销和安全考量,而这些是直接工具调用所能避免的。在权衡时,应充分考量代码执行带来的好处(减少 token 成本、降低延迟和改进工具组合)与这些实现成本。
总结
MCP 为智能体连接众多工具和系统提供了一个基础协议。然而,一旦连接的服务器过多,工具定义和结果就会消耗过量的 token,从而降低智能体的效率。
尽管这里的许多问题——如上下文管理、工具组合、状态持久化——看似是新问题,但它们在软件工程中已有成熟的解决方案。代码执行将这些成熟的模式应用于智能体,让它们得以使用熟悉的编程结构,更有效地与 MCP 服务器交互。如果开发者实施了这种方法,我们鼓励其向 MCP 社区分享研究结果。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。
这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费】

1368

被折叠的 条评论
为什么被折叠?



