📑 本页目录(点开跳转)
08 · MCP:接入外部世界
⏱ 44 分钟 | ⭐ 核心
🎯 一句话
MCP(Model Context Protocol)解决 M×N 问题:M 个 Agent × N 个系统, 不再需要 M×N 个定制集成,而是各自实现一次标准协议。它是 Agent 世界的 USB 接口。
🔌 一、没有 MCP 之前的痛
每个 Agent 接每个系统都要单独写:
认证怎么做?工具怎么暴露?返回格式怎么定?错误怎么处理?
Agent A ──定制──► Slack 3 个 Agent × 4 个系统
Agent A ──定制──► GitHub = 12 套定制集成
Agent B ──定制──► Slack 每次加一个系统,所有 Agent 都要改 💥
...
MCP 的答案:定一个标准协议,工具提供方实现一次 MCP Server, 任何支持 MCP 的 Agent(Client)都能即插即用。
MCP Server 能暴露三类东西
| 类型 | 是什么 | 例子 | 谁触发 |
|---|---|---|---|
| Tools | 可调用的操作 | create_issue() |
模型(用得最多)⭐ |
| Resources | 可读取的数据 | 一份文档、一张表 | 应用/用户 |
| Prompts | 预置的提示模板 | 「代码审查」模板 | 用户 |
日常 90% 的场景用的是 Tools。
🧱 二、三层协议:Function Calling / MCP / A2A 各在哪一层
读完第 7 章(工具怎么设计)和上一节(MCP 解决 M×N), 几乎所有人都会冒出同一个疑问:Function Calling 和 MCP 到底是不是一回事?
不是。它们根本不在一层上,加上 Agent 之间的 A2A,一共三层:
| Function Calling | MCP | A2A | |
|---|---|---|---|
| 连的是谁和谁 | 模型 ↔ 工具 | 工具 ↔ 宿主程序 | Agent ↔ Agent |
| 解决什么 | 模型怎么把「我要调这个」说出口 | 工具怎么被接进来、被发现 | 两个自主系统怎么互相托付任务 |
| 谁在实现它 | 模型厂商(训练 + API 格式) | 工具提供方 + Agent 宿主 | 双方的 Agent 平台 |
| 没有它会怎样 | 模型只能吐散文,你得自己正则解析 | 每接一个系统写一次定制集成(M×N) | 只能把对方当成一个工具来调 |
| 换掉它意味着 | 换模型 | 换适配层 | 换协作方 |
🔑 一句话记住三层: Function Calling 是「怎么说」,MCP 是「怎么接」,A2A 是「怎么托付」。 ⭐ 三者是叠加不是替代——一次 MCP 工具调用,底下走的仍然是 Function Calling。
① Function Calling:模型和工具之间的接口约定
它只约定两件事:
① 你怎么把工具告诉模型 名字 + 描述 + 参数 schema(第 7 章讲的就是这个的内容)
② 模型怎么把调用意图说出来 一个结构化的 tool_use 块,而不是一段散文
⭐ 关键认知:它不负责执行。 模型只是「说出」它想调什么,真正去调的是你的代码—— 第 1 章那个循环里的分支。
这也正是「Function Calling ≠ Agent」的原因:它只提供了一次往返的格式, 而循环、状态、错误处理、什么时候停,全都还在你这儿(第 1 章 + 第 12 章)。
💡 模型为什么知道该输出 tool_use 而不是散文:这是训练出来的,不是提示词技巧。 所以不同模型的工具调用可靠性差别很大——参数漏填、该并行调却串行调、该停不停, 都是模型能力问题而不是协议问题(选型见第 2 章)。
⚠️ 一个容易混的邻居:Structured Outputs / JSON mode 和 Function Calling 长得很像 (都是让模型吐结构化数据),但目的不同:前者是「输出要有格式」,后者是「我要调外面的东西」。 见 16c · 接进真实产品。
② MCP:工具和宿主之间的传输与发现协议
MCP 比 Function Calling 高一层:它压根不关心模型怎么表达调用意图(那是上一层的事), 它关心的是——工具从哪来、怎么被发现、怎么连上。
三个角色(上一节只讲了 Server 和 Client 两端,还差最重要的 Host):
| 角色 | 是谁 | 干什么 |
|---|---|---|
| Host(宿主) ⭐ | 用户面对的那个应用:IDE、聊天客户端、你自己的 Agent 服务 | 决定接哪些 Server、谁有什么权限、把工具交给模型、拿回返回值。信任边界在这里 |
| Client(客户端) | Host 内部为每个 Server 开的一条连接 | 一对一维护会话、协商双方支持哪些能力 |
| Server(服务端) | 工具提供方写的那个进程或服务 | 声明自己有哪些 Tools / Resources / Prompts,被调时执行 |
⭐ 为什么必须把 Host 单拎出来说:因为权限和审计只能做在 Host 上。 Server 是别人写的,Client 只是一根管子。你想做「这个 Server 只允许只读」 「这个工具必须人工确认」,唯一的实现位置就是 Host—— 这正是第 15 章说的「确定性的环境层边界」落地的地方。
两种 Transport:
| stdio | HTTP(含流式) | |
|---|---|---|
| 怎么连 | Host 把 Server 当子进程拉起来,走标准输入输出 | 网络请求 |
| 天然形态 | 一对一,随宿主进程生死 | 一对多,独立部署、独立扩容 |
| 认证 | 靠操作系统的进程边界,通常没有额外认证 | 必须自己做(见本章第五节 ④) |
| 适合 | 本地工具、桌面开发、要读本机文件 | ⭐ 生产主流:多用户、要审计、要独立发版 |
| ⚠️ 坑 | 谁拉起进程谁就给了它全部权限;Server 挂了 Host 不一定感知得到 | 长连接的超时与重连要自己扛,跨网络多一个攻击面 |
🔑 判断口诀:Server 和用户在同一台机器上 → stdio;不在 → HTTP。 别拿 stdio 去做多用户共享——它根本没有租户的概念。
还有一半价值容易被忽略:发现。Server 能自报家门(我有哪些工具、参数长什么样), 所以 Host 可以在运行时把工具列表拿到再交给模型。 ⭐ 这正是上一节 Tool Search 能成立的前提:工具是运行时可枚举的,才谈得上延迟加载。
③ A2A:Agent 和 Agent 之间的协作协议
一个很自然的反问:既然 MCP 什么都能接进来,把另一个 Agent 也包成一个 MCP Server 不就行了?
能,但会丢掉三样东西:
| 丢掉什么 | 为什么 |
|---|---|
| 对方是自主的 | 工具调用的心智模型是「我给参数,你返回结果」。而另一个 Agent 会自己规划、可能反问你、可能中途需要人批准——包成工具,你只能拿到最后那个返回值 |
| 过程可见 | 跑几十分钟的长任务需要中间状态、进度、可取消。工具调用是一问一答 |
| 能力发现是跨组织的 | 你接一个 MCP Server 是因为你决定接它;跨组织协作时,你得先知道对方能做什么、以什么形式交付 |
所以 A2A 这一层要定义的东西和 MCP 完全不同:对方是谁、能干什么(能力描述)、 一个任务的生命周期(提交 / 进行中 / 需要补充输入 / 完成 / 失败)、 交付物长什么样(结构化的产物,而不是一段文本)、长任务怎么推送进度。
⭐ 它和 MCP 是互补不是替代。 一个典型的企业形态是:
A2A 横着连 团队A的Agent ←→ 团队B的Agent ←→ 供应商的Agent
MCP 竖着连 每个 Agent ↓ 接自己那堆系统(Jira / 数据库 / 内部服务)
⚠️ 给这一层泼一盆冷水:跨组织的 Agent 协作目前还没跑出规模化的成功案例,协议本身也在动。 你应该知道这一层要解决什么问题(那是稳定的),但不必记它今天的字段名(那会过期)—— 这就是 16b · 框架这层皮 那条判据:框架会过期,原理不会。
⚠️ 三、MCP 的甜蜜陷阱:工具定义撑爆上下文
接上 5 个 MCP Server = 58 个工具
→ 光工具定义就吃掉 55K token
→ Agent 还没干活,注意力预算先被"工具菜单"花光了(第 4 章)
三个官方解法,按你的瓶颈选:
| 瓶颈 | 解法 | 实测效果 |
|---|---|---|
| 工具定义太多 | Tool Search:工具标记延迟加载,初始只给一个搜索工具(约 500 token),用时再取 | token 省 85%;准确率反而升(Opus 4.5:79.5% → 88.1%)⭐ |
| 中间结果污染上下文 | 程序化调用:模型写代码编排工具,中间数据在沙箱流转,只有最终结果进上下文 | token 省 37% |
| 参数总用错 | 工具示例:input_examples 给最小/部分/完整三类调用样例 |
复杂参数准确率 72% → 90% |
💡 注意 Tool Search 那一行:减少上下文的同时准确率上升了。 这再次印证第 4 章的核心命题——上下文不是越多越好,工具菜单也是噪声。
🚀 四、更激进:代码执行 + MCP
把「工具调用」改造成「写代码」:
传统:每次工具调用都往返一次模型,中间结果全过上下文
模型 → 调 read_sheet() → 【1万行数据进上下文】💀
→ 模型 → 调 filter() → 结果又进上下文
→ 模型 → 调 write() → ...
代码执行:MCP 工具变成代码 API(沙箱里的模块)
模型写一段代码:
rows = await gdrive.sheets.read(...) # 1万行
filtered = rows.filter(r => r.amount > 100) # 沙箱里过滤
await salesforce.update(filtered) # 只写回结果
→ 上下文里只有【这段代码】+ 最终摘要 ✅
📌 官方案例:150,000 token 降到 2,000(省 98.7%)。
三个红利:
| 红利 | 说明 |
|---|---|
| 渐进式披露 | 模型用 ls/read 按需探索工具定义,不用预载(第 4 章) |
| 数据不过模型 ⭐ | 大数据集在沙箱里处理,既省 token 又保隐私 |
| 控制流免费 | 循环、重试、条件分支用代码写,不烧模型轮次 |
代价:需要一个安全的代码沙箱(第 15 章)。
🏭 五、生产接入的六条经验
① 远程 Server 是主流形态
本地 stdio Server → 只适合桌面开发场景
远程 HTTP Server → Web/移动/云部署都能用 ⭐
(两种 Transport 各自的机制和坑,见本章第二节 ②。)
② ⭐ 按意图分组,别镜像 API
这是第 7 章原则 ① 的 MCP 版,也是最常被违反的一条:
❌ 把 REST API 的端点一比一暴露
GET /issues, POST /issues, GET /users, POST /comments...
→ 模型要「从这个讨论串创建一个 issue」得调 4 次
✅ 按用户意图设计
create_issue_from_thread(thread_url, assignee_hint)
→ 一次搞定,内部自己调那 4 个 API
③ 大接口面用代码编排
📌 Cloudflare 的做法:用两个工具覆盖约 2,500 个 API 端点 ——一个搜文档、一个执行代码。
思路:当端点多到无法一一暴露时,别暴露端点,暴露"查文档 + 执行"的能力。
④ 认证要标准化
OAuth 流程、token 刷新交给平台层(Vaults 等),别让每个 Server 自己造。
⑤ ⚠️ 「审计过的连接器 ≠ 审计过的数据」
MCP Server 本身可信(你审过代码)
≠
它取回来的内容可信(那是外部数据)
→ 从 MCP 读到的网页/邮件/工单,都可能携带提示注入
🔗 这是第 15 章的核心议题。MCP 扩大了攻击面—— 每接一个 Server,就多一个外部内容入口。
⑥ 工具返回也要控制体积
MCP 工具和自己写的工具一样,返回内容会永久占据上下文(第 7 章原则 ④)。 接第三方 Server 时,先看它的返回有多大——有些 Server 的默认返回非常臃肿。
🧭 六、什么时候用什么(决策表)
| 场景 | 建议 |
|---|---|
| 本地开发,接文件系统/git | 内置工具或 CLI 就够,别为用 MCP 而用 MCP |
| 接一两个内部 API,只有你自己用 | 直接写工具函数更简单 |
| 多个 Agent 要共用同一批系统 | ⭐ MCP,一次实现处处可用 |
| 接第三方 SaaS(Slack/GitHub/Jira…) | 用现成的官方 MCP Server,别重复造 |
| 工具超过 20 个 | 上 Tool Search |
| 数据量大 / 编排复杂 | 代码执行 + MCP |
| 需要给外部团队提供能力 | MCP(这正是它的设计目标) |
🔑 一个判断原则:MCP 的价值随「Agent 数量 × 系统数量」增长。 只有一个 Agent 接一个系统时,它是纯开销。
🕳️ 七、六个常见坑
| 坑 | 症状 | 修 |
|---|---|---|
| 以为 MCP 取代了 Function Calling ⭐ | 概念错位,出问题时找错层:明明是模型参数填错(上层),却去改 Server(下层) | 三层是叠加的——MCP 工具调用底下走的仍是 Function Calling |
| 一比一镜像 API ⭐ | 一个简单意图要调四五个工具 | 按意图重新分组 |
| 接太多 Server | 上下文被工具定义吃掉一大半 | Tool Search / 只接真正需要的 |
| 第三方返回臃肿 | 几轮就烧光预算 | 包一层做裁剪,或用代码执行 |
| 把 MCP 数据当可信 | 提示注入 | 外部内容一律当不可信(第 15 章) |
| 为用而用 | 单 Agent 单系统还搭 MCP | 直接写工具函数 |
📚 延伸阅读
✅ 检查点
- MCP 解决什么问题?用一个类比说明。
- MCP Server 能暴露哪三类东西?哪类用得最多?
- 58 个工具会带来什么问题?首选解法是什么?效果如何?
- 代码执行 + MCP 为什么能省 98% 的 token?三个红利是什么?
- 「按意图分组,别镜像 API」什么意思?Cloudflare 怎么处理 2500 个端点的?
- 「审计过的连接器 ≠ 审计过的数据」什么意思?
- 什么时候不该用 MCP?
- Function Calling、MCP、A2A 分别连接谁和谁?三者是替代关系吗?
- MCP 的 Host / Client / Server 各干什么?为什么权限和审计只能做在 Host 上?stdio 和 HTTP 怎么选?
- 把另一个 Agent 包成一个 MCP Server 来用,会丢掉哪三样东西?
👀 答案
- M×N 集成爆炸——M 个 Agent 接 N 个系统本需 M×N 套定制集成。MCP 让两边各实现一次标准协议。类比 USB。
- Tools(可调用操作,模型触发,用得最多)、Resources(可读数据)、Prompts(预置模板)。
- 工具定义吃掉几万 token,注意力预算先被工具菜单花光。首选 Tool Search:延迟加载,省 85% token,且准确率反而上升(79.5%→88.1%)。
- 中间数据在沙箱里用代码处理不经过上下文。三红利:渐进式披露(按需探索工具定义)、数据不过模型(省 token + 保隐私)、控制流免费(循环重试用代码不烧模型轮次)。
- 一个工具对应一个用户意图(内部可以调多个 API),而不是把 REST 端点原样暴露。Cloudflare 用两个工具(搜文档 + 执行代码)覆盖 2500 个端点。
- MCP Server 本身可信不代表它取回的内容可信——外部网页/邮件/工单可能携带提示注入。每接一个 Server 就多一个攻击面。
- 单 Agent 接单系统时(直接写工具函数更简单)、本地开发接文件系统/git 时(内置工具够用)。MCP 的价值随「Agent 数 × 系统数」增长。
- Function Calling=模型 ↔ 工具(一次调用的格式约定,「怎么说」);MCP=工具 ↔ 宿主(传输与发现,「怎么接」);A2A=Agent ↔ Agent(任务托付,「怎么托付」)。三者叠加不是替代——一次 MCP 工具调用底下走的仍然是 Function Calling。
- Host 是用户面对的那个应用,决定接哪些 Server、给什么权限、把工具交给模型并执行返回值;Client 是 Host 为每个 Server 开的一条一对一连接;Server 是工具提供方那个进程,声明并执行 Tools/Resources/Prompts。权限只能做在 Host 上,因为 Server 是别人写的、Client 只是一根管子。Transport 口诀:Server 和用户在同一台机器上就 stdio,不在就 HTTP——stdio 是子进程、一对一、没有租户概念,生产主流是 HTTP。
- ①对方是自主的(会自己规划、会反问、可能要人批准,包成工具只能拿到最后一个返回值)②过程可见(长任务要中间状态/进度/可取消,而工具调用是一问一答)③跨组织的能力发现(你得先知道对方能做什么、以什么形式交付)。
🛑 可以停在这里
⚡ 走神救援
MCP=Agent 的 USB,解 M×N 集成爆炸(3 个 Agent × 4 个系统就要 12 套定制集成,加一个系统所有 Agent 都得改;有了协议,加系统只写一个 Server,加 Agent 什么都不用写);Server 暴露 Tools(最常用,日常 90% 场景)/Resources/Prompts。⭐三层协议别混:Function Calling=模型↔工具(「怎么说」,只是一次往返的格式约定,它不负责执行,所以 Function Calling≠Agent——循环/状态/何时停还在你这儿)、MCP=工具↔宿主(「怎么接」)、A2A=Agent↔Agent(「怎么托付」);三者叠加不是替代——一次 MCP 工具调用底下走的仍然是 Function Calling。MCP 的三个角色是 Host/Client/Server:⭐权限和审计只能做在 Host 上(Server 是别人写的,Client 只是一根管子);两种 Transport 的口诀是在同一台机器上就 stdio、不在就 HTTP——stdio 是子进程、一对一、⚠️没有租户概念且谁拉起进程谁就给了它全部权限,生产主流是 HTTP。MCP 另一半价值是发现:工具运行时可枚举,才谈得上 Tool Search 那种延迟加载。A2A 那层解决的是「把另一个 Agent 包成 MCP Server 会丢掉的三样东西」:对方是自主的、过程要可见、跨组织的能力发现;⚠️它和 MCP 互补不是替代(A2A 横着连各团队 Agent,MCP 竖着连各自的系统),但知道它解决什么问题就够了,别背今天的字段名。甜蜜陷阱:接 5 个 Server = 58 个工具吃掉 55K token,Agent 还没干活,预算先被"工具菜单"花光 → Tool Search 省 85% 且准确率反升(79.5→88.1,初始只留一个约 500 token 的搜索工具)/程序化调用省 37%/工具示例把参数准确率从 72% 提到 90%。⭐Tool Search 那行要单记:上下文变少的同时准确率上升了,说明工具菜单本身也是噪声。更激进:代码执行+MCP,数据在沙箱流转,150K→2K(省 98.7%),三红利是渐进式披露、数据不过模型(省 token 又保隐私)、控制流免费;⚠️代价是要有安全的代码沙箱。生产六课:远程 HTTP Server 才是主流(本地 stdio 只够桌面开发)、按意图分组别镜像 API(「从讨论串建 issue」不该调四次端点;端点太多时别暴露端点,暴露"查文档+执行"的能力——Cloudflare 用 2 个工具盖 2500 端点)、认证交给平台层、连接器可信≠数据可信(每接一个 Server 多一个攻击面)——取回的网页邮件工单都可能带提示注入、控制返回体积。判断原则:MCP 价值随「Agent 数×系统数」增长,超过 20 个工具就上 Tool Search,单对单时是纯开销。
下一节 👉 09-计算机与浏览器使用.md