一、先说一个真实感受

学 MCP 之前,我对 Agent 工具通信的认知大概是这样的:

"模型输出一个函数名和参数 → 我的代码执行 → 把结果塞回 Prompt → 完事"

听起来没问题,对吧?Function Calling 不就是这么干的吗

但后来我自己搭 Agent 系统的时候才发现一个问题:

        接入成本长得完全不合理

                接 GitHub,写一套 JSON Schema、构造请求、解析返回值、处理错误

                接数据库,又写一套

                接飞书、接 Jira、接 Sentry、接公司内部日志平台……

        每一套都要自己定义格式、自己写适配层、自己维护

更要命的是,这些工具写完不是只给一个产品用的。Claude Desktop 要用,Cursor 要用,公司内部 Agent 要用,可能过两个月产品那边也要接——你给我一个工具,我难道给每个宿主都写一套插件?

这时候我才意识到一个之前没想过的问题:

Agent 工具接入这件事,本质上是一个 N×M 问题。N 个 AI 应用 × M 个工具系统 = N×M 套胶水代码

如果没有统一协议,这个乘积只会越来越大

MCP 就是来解决这个问题的。它不是在 Function Calling 上加一层——它是在"工具从哪来、怎么发现、怎么连、怎么通信"这个层面上建立标准。它的目标是让每一个工具只写一次,每个 AI 应用只实现一次 MCP 支持,然后他们就能互联

这个动机我理解了之后,再看 MCP 的架构设计就不再是"背三个角色四条方法",而是"每一个设计都是在解决一个具体问题"


二、MCP 在我的 Agent 知识体系里到底放在哪

这是我自己理解 MCP 最关键的一步。因为之前我脑子里的 Agent 技术栈是糊的——模型、框架、工具调用、权限控制,全搅在一起。

后来我把 Agent 系统拆成了四层:

MCP 卡在模型层和框架层之间,它做的事情非常专一:把外部能力以标准化的方式接入 AI 应用

它不替模型做推理(那是模型层的事),也不替应用做编排(那是框架层的事),更不替用户做交互(那是应用层的事)。它只做"连接标准化"这一件事

把层分清楚之后,很多之前觉得模糊的东西突然就清晰了:

  • Function Calling 和 MCP 的区别:不在一个层。Function Calling 在模型层,管"模型这次输出什么函数、什么参数";MCP 在协议层,管"工具从哪来、怎么发现、怎么连接"。它们的关系是上下游——MCP 发现工具 → 转成 Function Calling 格式 → 模型选择调用。不是替代,是串在一起的

  • MCP 和 Agent 框架的区别:也不在一个层。框架管编排、状态管理、多 Agent 协作;MCP 只管"怎么把外部能力接进来"。你用 LangChain 可以用 MCP 获取工具,你自研框架也可以用。它不绑定任何框架

  • MCP 和 Agent 本身的关系:Agent 是一个"围绕目标持续行动的系统",它需要工具,但工具从哪来、怎么管理,是 MCP 的活。Agent 的能力上限由工具质量决定,但工具接入的效率由 MCP 决定

这四层一分,我再也不把 MCP 叫"更高级的 Function Calling"了——因为它们根本不在同一个维度上


三、Host-Client-Server:架构里藏着设计思想

MCP 的架构就三个角色:Host、Client、Server。看起来简单,但这里面的设计思想值得琢磨

我理解下来,这套设计有两个核心理念:

第一,能力与交互分离。 Host 负责跟用户聊天、调用模型、做决策。Server 只管暴露能力——它不知道当前对话上下文,不参与"用户最终要怎么回答"的判断。Server 就是提供能力的,Host 才是做决策的。这个边界很重要,因为它意味着你可以独立升级 Server(加工具、改实现)而不影响 Host 的交互逻辑,反之亦然

第二,隔离大于打通。 一个 Host 可以连多个 Server,但每个 Server 不应该看到其他 Server 的数据,也不应该看到全部对话历史。Host 在中间做权限控制和上下文分发——传给文件系统 Server 的是文件路径,传给数据库 Server 的是查询请求,各管各的。MCP 的设计不是让所有工具互相打通,而是让 Host 在可控边界内组合多个能力源

多说一句:我把 Client 理解成"连接器"而不是"中间层"。它是一个 Server 在 Host 内部的投影——建立连接、协商协议版本、收发消息、维护安全边界。一个 Server 一个 Client,这样每个连接的职责边界非常清晰


四、数据层和传输层:MCP 的"里子"和"面子"

如果只把 MCP 理解成"一个调工具的协议",那等于只看了面子没看里子

MCP 实际上是两层结构,这是我学完之后觉得最值得记住的东西:

数据层(语义层)——MCP 基于 JSON-RPC,定义了一套标准的方法名和消息结构:

方法 作用 属于哪类能力
tools/list 发现这个 Server 有哪些工具 Tools
tools/call 调用一个具体工具 Tools
resources/read 读取一个资源的内容 Resources
resources/list 列出可用的资源 Resources
prompts/get 获取一个提示模板 Prompts
initialize 建立连接、协商版本和能力 生命周期

注意,这不是"随便起了几个 HTTP 接口名"。每类方法有自己的请求结构、响应结构、错误码——它是一个完整的 RPC 协议,不是 REST

传输层(通信层)——JSON-RPC 消息怎么送过去?两种方式:

  • stdio:标准输入输出,Host 启动一个子进程,跟它通过 stdin/stdout 通信。适合本地工具——文件系统、代码搜索、Git 操作。好处是零网络开销、不需要鉴权(进程边界就是安全边界),坏处是只能本机用

  • Streamable HTTP:通过 HTTP 传输,支持流式响应和标准鉴权(OAuth 等)。适合远程服务——公司的知识库、监控平台、SaaS 工具。好处是集中部署、多人共享,代价是网络延迟、需要处理认证授权

我个人理解这个双层设计的好处是:语义和传输解耦。 同一个数据层协议可以跑在 stdio 上,也可以跑在 HTTP 上。将来如果有更好的传输方式(比如 WebSocket、gRPC),换传输层就行,语义层不用动


五、三类能力:我用一个例子彻底搞懂了 Tools / Resources / Prompts

这是 MCP 里我最容易搞混的地方,也是面试官最爱追问的地方

MCP Server 不是只能暴露"工具"。它暴露三类东西,每一类回答一个不同的问题:

  Tools Resources Prompts
回答的问题 Agent 能做什么 Agent 能看到什么 Agent 按什么套路做?
调用方式 模型主动触发 Host 按需读取 用户或 Host 选择使用
本质 动作(有副作用) 上下文(只读数据) 模板(可复用的引导)
举例 查订单、发消息、改文件 数据库 Schema、API 文档、退款规则 "按公司规范写 PR 描述"

我彻底理解这三者的区别,是通过一个订单客服的例子:

做订单客服 Agent 时:

  • 把"查询订单""创建退款草稿""校验退款资格"做成 Tools——它们是 Agent 要主动执行的动作

  • 把"退款政策文档""物流状态说明""订单状态流转图"做成 Resources——它们不是动作,但 Agent 需要看到这些信息才能正确判断。别把所有业务知识塞进 System Prompt! 把它们做成 Resources,按需加载,Prompt 简洁了,准确率反而上去了

  • 把"标准客服开场白""退款拒绝话术模板""升级工单的提示模板"做成 Prompts——保证不同客服场景下 Agent 的行为一致性,不需要每次都靠 Prompt Engineering 现编

这个例子让我明白了一件事:MCP 不是你有一堆 API 就全塞进 Tools 里。 好的 MCP 设计,是把"动作""数据""引导"分开思考。哪些是 Agent 要执行的操作、哪些是它需要看到的信息、哪些是引导它按规范做事的模板——分清楚了,Agent 的行为才稳定。


六、一次调用串起来之后,我更清楚 MCP 的边界在哪

用一个具体的故障排查场景串一下整个流程,会更容易理解 MCP 到底在整个链路里干了什么、没干什么:

用户问:"支付服务昨晚为什么变慢了?"

看完这个流程,我想强调两个容易被忽略的点:

第一,MCP Server 不参与决策。 它收到 tools/call 就执行并返回结果,不问"你为什么查这个""用户原话是什么"。决策完全在 Host 和模型那一侧。所以别把 MCP Server 当成 Agent——它只是一个标准化能力提供者

第二,MCP 只负责"接入",不负责"用好"。 工具描述准不准确、返回值结不结构化、错误信息能不能驱动下一步——这些问题全在设计工具的人手里。MCP 提供了标准化的通道,但通道里跑的东西是好是坏,仍然是工具设计的问题


七、关于安全和错误处理:我最想补充的两件事

Host 管权限、Server 要克制、高风险动作要确认和审计

我最想补充的两件事:

第一,安全不是"加一层权限检查"就完了。 MCP 的安全模型实际上是一套纵深防御体系

第一层:Server 注册时的白名单 → 不是谁都能连

第二层:工具级别的权限声明 → Server 声明每个工具的敏感度

第三层:Host 的运行时确认 → 高风险操作弹窗让用户确认

第四层:审计日志 → 每次调用谁、什么时候、调了什么、结果是什么

只靠模型自觉是最薄弱的防御。真正靠谱的安全是让每一层都有防线

第二,错误处理不是"try-catch 就完了"。 工具调用失败的时候,返回给模型的错误信息质量直接决定了 Agent 能不能自己恢复。一个好的 MCP Server 应该在返回错误时告诉模型:发生了什么、可能是什么原因、你可以尝试什么。把错误信息设计成能驱动下一步的信息,而不是一条"调用失败"的字符串


八、MCP 不是银弹——这可能是全文最重要的一句话

学完 MCP,最容易犯的错误是把它当成"Agent 的万能解药"

但 MCP 只解决了一个问题:连接标准化

它不解决:

  • ❌ 工具描述怎么写才不会被模型误调

  • ❌ 参数 Schema 怎么设计才能约束模型的幻觉参数

  • ❌ 返回值怎么结构化才能驱动下一步推理

  • ❌ 多个工具之间怎么编排才高效

  • ❌ 工具调失败了怎么恢复

  • ❌ 用户没给权限怎么优雅降级

这些全是你自己的工程活

MCP 的意义在于:它让你不用每次做这些工程活的时候都从头写一套连接代码。但活本身不会消失

正因如此,我觉得 MCP 真正让我佩服的不是它"统一了工具接入"——而是它没有越界。它很清楚自己能解决什么、不能解决什么。设计上克制,协议层面做减法,把"怎么用好工具"留给 Agent 工程师,把"怎么发现和连接工具"标准化

这种克制的设计,比一个大而全的"统一 Agent 框架"靠谱得多


九、总结:我的 MCP 知识框架

学完之后,我脑子里 MCP 的知识结构大概是这样的:

最后的最后,三句话:

  • Function Calling 是模型调用工具的方式——管"按下哪个按钮"

  • MCP 是工具接入 AI 应用的协议——管"设备怎么插上电视"

  • Agent 是围绕目标持续行动的系统——管"整件事怎么做完"

三个东西不在一个层面,互不替代,串在一起才完整

把这层关系想清楚,面试官就知道你是真懂,不是背的

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐