[控场AI]
· 12 分钟阅读· 6,194 字

MCP图解:AI Agent如何连接你的应用

MCP图解:AI Agent如何连接你的应用

MCP用公共集成边界把AI与工具的M×N连接压缩为M+N,但不提供记忆与安全。

文章从电商客服机器人的真实场景出发,解释为什么在已有 REST API、GraphQL 和 SDK 的情况下仍需 MCP。直连集成会陷入 M×N 困境:每个 AI 应用都要为每个工具写定制连接器,换模型、换工具版本或多团队复用时成本急剧上升。让 LLM 直接调用 REST 接口同样不现实,冗长响应浪费 token、污染上下文,422 之类的错误码对模型也不友好。MCP 在 API 前加一层翻译,对外暴露带 schema 校验的高层工具,并通过动态发现把工具定义挪到 server 端。但协议本身不提供对话记忆、访问控制或凭证保护,这些必须在 host、server 和后端各层显式实现。文章最后拆解 M、C、P 三个字母、Host/Client/Server 三层架构与一次请求的完整路径,并给出是否自建 server 的判断标准。

为什么有了API还需要MCP?

大多数工程师第一次听说 MCP(Model Context Protocol)时,反应都差不多:我们已经有 REST API、GraphQL 和 SDK,服务之间连了这么多年,为什么 AI 一来就要发明一个新协议?

这个问题不能靠背定义回答。用一个电商客服机器人的场景走一遍,答案自然就出来了。假设你要给公司做一个 AI 客服,用户的问题是「我的订单 12345 到哪了?能退款吗?」。LLM 本质上是训练数据里泡大的语言模型,它知道怎么写礼貌的回复,但对你的订单库、支付网关、工单系统一无所知。要让它真正干活,就得把这些系统接进来。

API 就像餐厅的点单柜台:你发一个定义好的请求,系统返回一个定义好的响应。订单查 ERP 或 Shopify,退款走 Stripe,工单记到 Zendesk,物流问 FedEx,紧急情况再拉个 Slack 通知人工。问题不在于能不能接,而在于怎么接、接多少个、以后怎么维护。

直连集成的隐性成本:M×N 问题

用传统 API 的做法很直接:在应用后端给每个服务写集成代码。读 Stripe 文档、拉 SDK、写 wrapper 函数,再为 LLM 的 function calling 定义一个 schema;Postgres 写一套连接和查询逻辑;Zendesk 和 Slack 把同样的流程再重复一遍,各自处理认证、解析 JSON、写工具定义。

接三四个工具,工作量虽然繁琐但还扛得住。真正的麻烦在于规模化和变化:

  • 换模型:从 GPT 切到 Claude,或者换成本地开源模型,各家 tool calling 的格式和 SDK 不一样,迁移意味着改代码加测试。
  • 换工具版本:Zendesk 新增一个 check_warranty_status 工具,或某个接口加了必填参数,硬编码在应用里的旧 schema 就会让请求失败。
  • 多团队重复:另一个团队也要接同样的系统,只能重写一遍,或者勉强复用共享库。

把视角拉到整个行业:M 个 AI 应用(Claude Desktop、Cursor、各家自研 chatbot)× N 个工具和数据源(GitHub、Slack、Postgres、Stripe),就形成了经典的 M×N 集成困境。每个 AI 应用开发者都在为每个工具写定制连接器,代码重复、脆弱、难维护。MCP 要解决的就是把它压缩成 M+N:定义一层公共集成边界,应用和工具各自对协议负责。

为什么不直接让LLM调用REST API?

一个合理的反问是:REST API 已经是标准了,让 LLM 直接调 HTTP 接口不行吗?

技术上可以,但体验上很糟糕。以从 Stripe 或 Shopify 拉一个订单为例,真实响应往往有上百个字段:内部数据库 UID、嵌套 metadata、分页游标、弃用标记、各种时间戳、系统级配置。这些字段对 LLM 来说全是噪音,带来三个实际后果:

  1. Token 消耗与延迟:冗长的响应烧掉大量 token,成本上升,响应变慢。
  2. 上下文污染:无关字段挤占 context window,模型更容易困惑甚至幻觉。你可以把 context window 想成模型的工作桌面,放相关文件有用,堆满杂物就是负担。
  3. 错误语义不友好:REST 面向开发者,返回 422 之类的 HTTP 状态码和晦涩的错误码。人类工程师查文档能懂,但运行时 LLM 需要的是自然语言解释——「什么错了、该怎么修正」,而不是一个数字。

MCP 的思路是在 API 前面加一层翻译。MCP server 内部照样调 Stripe 的 REST API 或查 SQL 数据库,但对外暴露的是 AI 原生语义的高层工具,比如「查询订单退款资格」这种把订单状态和物流信息组合好的操作,并附带 schema 校验(订单 ID 必填、类型为字符串,格式不对直接拒绝)。协议本身不是 AI 大脑,也不提供魔法权限——真正的实现和权限,仍然要靠 server 背后的 API、数据库和文件系统。

function calling 是理解这一节的前提:它是主流 LLM 提供的一种结构化输出能力,开发者把可用的工具(名称、用途描述、参数 schema)随 prompt 一起交给模型,模型在需要时不再生成自然语言,而是返回一个符合 schema 的调用意图,例如 {"name": "get_order_status", "arguments": {"order_id": "12345"}}。模型本身并不执行任何函数,真正调用由宿主应用完成,再把结果回填给模型继续推理。正因为 function calling 的输入是文本化的工具定义与 JSON 参数,工具描述的冗长程度、参数 schema 的严格程度、错误信息的可读性都会直接影响调用准确率——这正是原始 REST 响应在 LLM 场景下表现糟糕的根本原因。

工具发现与状态管理:MCP改变了什么

直连集成里,工具定义写死在应用代码中。MCP 把这些定义挪到了 server 端,通过动态发现机制解决维护问题。兼容的 client 可以向 server 请求能力列表,拿到每个工具的确切名称、自然语言描述(告诉 LLM 这个工具做什么、什么时候该调用)、以及精确的输入 schema。server 在上线新能力后,工具列表刷新就能看到。

但这不意味着零改动。host 的审批策略和兼容性测试依然必要。这里适合用 USB 类比:共享接口让设备能连上,但每个设备的版本和能力并不会自动兼容。

另一个常见误解是把「连接」当成「记忆」。MCP 的连接和对话是两回事——线连着,不代表 chatbot 记得上一句话。真实的客服场景是多步工作流:用户说键盘坏了,AI 查到订单 987,核对退货政策,用户要求换货并寄到新地址,AI 再发起换货、生成退货标签、更新工单。中间选中的订单、确认的地址、流程进度,都需要应用自己显式存储。据该视频对协议演进的说明,2026 年 7 月的修订版中请求模型有变化,旧教程里的初始化握手和 session 概念可能已过时,实现时务必核对协议版本。部分 server 会实现工作流存储和通知,但 MCP 本身不自动提供对话记忆。

JSON-RPC 是 MCP 消息格式的骨架,理解它有助于看懂动态发现为何可行。它是一种轻量远程调用协议:每条请求包含 jsonrpc 版本、唯一 id、method 和 params,服务端返回带有相同 id 的 result 或 error,因此同一连接上可以并发多个请求而不串号。MCP 在此之上定义了工具列表、调用工具、读取资源等具体 method,并借 initialize 阶段交换协议版本与双方能力声明。动态发现本质上就是 client 发送一次列举工具的请求,server 返回当前可用工具及其 schema;由于 method 是标准的,任何兼容 client 都能与任何兼容 server 对话,无需为每个工具预先写死代码。

安全边界:认证、授权与凭证放置

当工程师意识到要把生产数据库、Stripe 账户和 Slack workspace 交给 LLM 时,警报立刻响起:模型会看到数据库密码吗?Stripe 的 secret key 会被塞进 prompt 发给模型厂商的服务器吗?

答案取决于设计。凭证不应该出现在模型 prompt 里,而应放在受保护的 host 或 server 环境中。host 可能持有授权 token,后端服务自己保管数据库凭证。MCP 并不保证 secret 永不泄漏——工具结果、日志和配置中的敏感数据,需要开发者主动约束并测试。

当 LLM 决定查订单时,它输出的只是一个结构化意图:「调用 get_order_status,参数 order_id 12345」。server 负责验证调用方权限、使用受保护的凭证、显式移除未授权字段。这些都是实现层面的选择,不是协议自带的魔法。

几个具体的安全抓手:

  • 区分认证与授权:认证回答「你是谁」,授权回答「你能做什么」,两者边界不同。
  • 防 prompt injection:返回的文档内容不应被赋予指令权限。权限要在 host、server 和后端三层强制,光在 prompt 里写「不要退款」不构成可靠访问控制。
  • 数据库层兜底:配置正确的只读数据库角色能从边界上阻断写操作。但要审计实际的 grant 和暴露的函数,别只信「只读」这个标签。
  • 高风险操作走人工:例如金额超过 50 美元的退款进入人工审批队列,金额与归属校验在 server 端完成,不交给模型的判断;改变状态的操作前,host 可以要求用户确认,即便确认了,server 仍要执行自己的策略检查。

prompt injection 是指攻击者把指令藏在模型会读到的数据里,例如订单备注、工单正文、网页内容或工具返回的文档,诱导模型偏离原任务去执行攻击者意图,比如把数据发往外部地址或调用高权限工具。它与传统注入的区别在于没有清晰的数据与指令分隔:对模型而言,工具返回的文本和系统提示可能同处一个上下文。防御重心不在提示词措辞,而在架构——对返回内容做来源标记与清洗、限制工具权限到最小集合、对不可信内容禁止触发副作用操作、在高风险动作前引入人工确认,并假定模型可能被说服而由 server 侧独立校验每次调用。

MCP三个字母拆开看

M(Model):核心的 LLM,比如 Claude、GPT、Gemini 或 Llama,擅长推理和生成,但孤立于你的私有系统。

C(Context):让模型真正有用的那部分信息。MCP 把它标准化为 server 能提供的三类原语:Tools(可调用函数,模型提出调用,应用批准后路由执行)、Resources(只读数据源,比如退款政策文档、客户档案、日志、数据库 schema)、Prompts(可复用指令模板,比如客服升级话术的结构;选模板不会自动执行整个工作流)。

P(Protocol):两端通信的规则与消息格式,类似 Web 的 HTTP 或邮件的 SMTP。MCP 消息采用 JSON-RPC 风格——可以理解成带编号的信封,请求 ID 与响应匹配,method 说明要做什么。通信还需要兼容的协议版本、声明的能力和授权。

三层架构与一次请求的完整路径

每个 MCP 部署都由三层组成:

  • Host:用户面对的应用,比如 Claude Desktop、Cursor、Windsurf、VS Code + Copilot,或自研客服系统。它负责和 LLM 对话、管理 UI、编排整个应用。
  • Client:host 内部的协议连接器,你通常不会直接接触。host 为每个连接的 server 启动一个 client 实例,形成一对一关系,负责 JSON-RPC 通信、工具发现、把 host 的工具执行请求转发给 server,再把响应带回。
  • Server:坐在具体数据源前面的轻量程序,比如 GitHub MCP server、Postgres MCP server、Stripe MCP server,把 MCP 请求翻译成原生 API 调用、SQL 查询或本地文件操作。

用订单 550 的退款查询走一遍:

  1. 应用把用户问题和已发现的工具列表、schema 一起发给 LLM。
  2. LLM 读完问题,不执行任何操作,只回一个意图:需要调用 get_order_status 和 check_refund_status,参数 order_id 550。
  3. host 做策略检查,通过对应的 MCP client 把工具调用发给 server。
  4. server 用自己安全存储的凭证查询 Postgres、调用 Stripe API。
  5. server 精选相关事实返回——已入仓、退款已处理。过滤逻辑由开发者实现。
  6. host 把结果交给模型,模型基于事实生成回复。遇到错误或不确定,应当诚实处理,而不是猜测。

传输层方面,本地 server 通常走 stdio,作为 host 同机的子进程运行,不需要网络端口,适合访问本地文件、跑本地 git 命令、查本地 SQLite,或让 AI 编码助手操作本地开发环境;远程 server 常用 streamable HTTP,适用于生产 Web 应用、几十名工程师或大量用户共享的中心化 server,以及云端 SaaS 集成。旧教程中的 HTTP+SSE 方案与当前版本不同,不要混淆。

stdio 与 streamable HTTP 是当前两种主流传输方式,选择它们取决于部署形态而非功能差异。stdio 指标准输入输出:host 把 server 作为子进程启动,双方通过管道按行交换 JSON-RPC 消息,天然没有网络监听端口,凭证和文件访问都局限在本机,适合个人开发工具与本地数据源,代价是无法被多台机器共享。streamable HTTP 则是面向远程的标准做法,client 向单一端点 POST 请求,服务端可用流式响应逐步回传结果,并支持会话标识以维持跨请求状态,便于放在反向代理、网关和统一鉴权之后,适合多用户共享的中心化 server。旧方案 HTTP+SSE 使用两个独立端点分别承担请求与事件推送,已在新版规范中被取代,迁移时需注意端点与握手方式都已变化。

要不要自己写Server?

多数情况下不必。开放标准的意义正在于此:Postgres、Slack、GitHub、Stripe 等大量服务已有官方或社区维护的 MCP server。但每一份列表都不自动可信,使用前要检查发布方、维护状态、权限范围和协议兼容性,理解清楚再运行配置中的命令。

值得自建的场景有两类:一是公司内部的专有微服务或内部 API,比如自研的遗留库存系统、内部部署流水线;二是需要把多个内部业务规则和 API 调用组合成带护栏和数据过滤的、经过策展的高层工具时。官方提供 Python、TypeScript、Java、Go 的 SDK。

回到最初的疑问:传统 API 不会消失,它仍是软件系统通信的骨干。MCP 只是在应用和 server 之间加了一层公共边界,减少重复的集成劳动,而后端集成、测试和安全这些工作依然要做。它不是万能适配器——host 决定问什么,server 实现被允许做的事。用一句话复盘:发现能力、发起工具请求、强制执行权限、返回有用结果;至于记忆、过滤和安全,都得靠实现。

#MCP#Model Context Protocol#AI Agent#LLM集成#REST API#工具调用#AI应用架构
分享:

相关推荐