|
随着大语言模型(LLM)能力不断增强,我们逐渐发现一个事实:
真正有价值的,不是模型“会说话”,而是模型“能做事”。
因为再强大的LLM,其核心优势仍然在于语言理解与推理能力,而非实时计算或外部状态获取。, 在某些简单事情上, 例如 查询当前时间, 当前地区的天气, 进行一个简单的数学运算, 其实都不是大模型擅长的事情, 我们也不需要大模型全知全能, 这不是一个正确的路线.
大模型应该像人类的大脑, 他只需要足够的聪明, 可以判断出做某些事情,需要什么工具. 就像人类大脑不会拣树枝, 但是可以使用手臂做这件事.
例如在查询天气这件事上, 我们不需要给大模型本身上报各种数据库, 而是需要大模型在判断需要查询天气的时候,调用一个外部的接口即可. 做数学运算时,调用一个计算器接口, 等等
而“做事”,就绕不开 工具调用、Agent 协作、以及标准化协议。
Tool Calling(函数调用) 是大模型的一种能力:
模型在推理过程中,不直接给出最终答案,而是返回一个结构化 JSON,表示“我需要调用某个工具”。
JavaAI 框架, 例如Spring AI 等, 对于ToolCalling都有实现, 注册工具,告诉大模型可以执行该工具的条件和参数,大模型在决策需要调用时, 返回调用指令, 本地框架反射执行函数, 再将结果返回到上下文, 大模型继续决策.
从系统角度看,Tool Calling 做了三件事:
- 模型 → 输出结构化指令
- 框架 → 解析指令
- 本地代码 → 执行真实逻辑
Tool Calling 的局限
Tool Calling 虽然重要,但它有明显边界:
- 工具调用的决策和编排只存在于单个 Agent 的推理循环中
- 不同框架(Spring AI / LangChain)工具定义不通用
- 缺乏统一的权限、发现、生命周期管理
这就引出了下一阶段。
2. MCP:Agent 世界的“HTTP 协议”
MCP(Model Context Protocol,模型上下文协议) ,2024年11月底,由Anthropic 推出的一种开放标准。旨在为大语言模型(LLM)提供统一的、标准化方式与外部数据源和工具之间进行通信。
一句话:
MCP 是 Agent 与外部世界交互的统一协议层。
如上图所示, 在传统的大模型调用外部工具, 例如访问数据库,访问互联网数据的能力, 我们需要针对每一个框架, 每一个外部工具,都需要实现一套单独的调用函数, 函数的调用和代码完全耦合,
而有了MCP协议,在AI的世界里, 不管是调用方还是被调用方, 大家只需要都实现这套协议, 就可以无障碍,无沟通的进行联系,就像硬件世界的USB
MCP 和 HTTP.TCP/IP协议的类比:
| 特征 |
MCP |
TCP/IP、HTTPS |
| 本质 |
协议(Protocol) |
协议(Protocol) |
| 作用 |
标准化 AI 模型与上下文来源/工具之间的数据交互方式 |
标准化 设备之间的网络通信方式 |
| 目标 |
让不同 AI 应用 / Agent 以统一方式访问外部资源和工具 |
让不同设备、系统可以互通数据 |
| 好处 |
消除碎片化集成、形成生态闭环 |
解决设备互联、实现互联网基础 |
2.1 MCP协议的两种实现方式: stdio和SSE
在上文中, 我们知道了MCP是一种协议, 是规范Agent如何调用工具, 工具如何响应的规范, 而工具在这是作为Server. Agent作为Client, 他们的通信是如何实现的, 有哪些实现方式.
官方参考实现中,主要提供了 stdio 方式,同时也支持基于 HTTP/SSE(实验 & 可选) 的远程实现。 分别对应本地调用和远程调用的使用.
2.1.1 SSE(Server-Sent Events)
SSE 是一种基于 HTTP 的单向流式通信方式:
- 客户端发起 HTTP 请求
- 服务器保持连接不断开
- 服务器可以持续往客户端推送消息
SSE是实现Client远程调用Server的方式. Server部署在云端, 具体的工作流程如下: - Client
- │
- │ HTTP POST /agent/run (这里就已经把请求发完了)
- ▼
- Server
- │
- │ 200 OK
- │ Content-Type: text/event-stream
- │
- │ 开始SSE
- │ data: ...
- │ data: ...
- │ data: ...
复制代码注意, Client发送HTTP请求Server提出问题的流程,并不是SSE协议的部分, 这只是一个普通的HTTP请求. 只需要遵循相应的请求规范.
但是此时客户端将会与Server建立一个基于HTTP协议的长链接,一直监听Server对于此问题的回答,此时才是SSE所描述的Server-Sent Events流程.
网上对于SSE的描述,都是说SSE是一个单向流式输出的通道, 但不是理解成 SSE 是一个“只能服务器说话,客户端不能说话”的通道
正确理解
SSE 是一次普通 HTTP 请求 + 一个不断写数据的响应
下面是一个天气预报查询的示例, 展示通过SSE协议, Agent作为Client 如何与天气预报Server交互
- 客户端 → Server(普通 HTTP 请求)
- POST /agent/run
- Content-Type: application/json
- {
- "input": "杭州今天天气怎么样?"
- }
复制代码这一步 不是 SSE
只是一个普通 HTTP POST。
- Server 内部
- 接收请求
- ↓
- Server 调用天气 API(这是 Server → 外部)
- ↓
- 拿到结果
复制代码
- Server → Client(SSE 开始推送)
- data: {"type":"thinking","content":"需要查询天气"}
- data: {"type":"tool_call","name":"weather","args":{"city":"杭州"}}
- data: {"type":"observation","content":"晴 26℃"}
- data: {"type":"final","content":"杭州今天晴,26℃"}
复制代码客户端从头到尾只发了一次请求
SSE的优缺点:
优点:
- 基于 HTTP,简单
- 浏览器原生支持
- 适合流式 AI 输出
缺点:
- 单向(Server → Client),
- 连接数多时压力较大
2.1.2 stdio
stdio 的本质
stdio = 标准输入 / 标准输出 - stdin → 程序输入
- stdout → 程序输出
- stderr → 错误输出
复制代码这是 一个基于操作系统级别的进程通信方式。
所以基于stdio实现的Server都是通过本地进程的, 因为Client和Server 只能通过OS级别的通道进行交互
MCP 官方和目前大部分Server大部分都是使用 stdio. 这是一个设计取舍问题
原因 1:安全
原因 2:本地工具友好,可以实现更多样化的功能
- Git
- FileSystem
- SQLite
- Docker
对于stdio本地通信的理解:
stdio 只能“本地部署”
不等于:只能访问本地数据
真正含义是:通信通道是本机进程级的. 具体的功能可以访问外部数据
stdio的工作流程如下: - Agent需要调用某个工具
- ↓
- 启动这个进程
- ↓
- 通过 stdin 发送 JSON
- ↓
- 通过 stdout/stderr 接收 JSON/
复制代码
所以当我们需要使用某个工具时, 需要在Agent本机部署一个对应Server即可, 网上有很多这样的实现, 例如https://github.com/modelcontextprotocol/servers 下载需要的服务即可.
例如一个天气预报的调用方式: - LLM Agent
- │ stdio
- ▼
- MCP Server
- │
- │ HTTP 请求
- ▼
- 天气 API(公网)
复制代码本机的Server封装了对远程HTTPAPI的调用
对比:
| 对比项 |
SSE |
stdio |
| 层级 |
网络(HTTP) |
操作系统 |
| 是否流式 |
✅ |
✅ |
| 通信方向 |
单向(推送) |
双向 |
| 是否跨机器 |
✅ |
❌(本地) |
| 适合场景 |
Web / 云服务 |
本地工具 |
| MCP 常用 |
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
|