本地模型接入本地MCP实践!保姆教程来了

 Datawhale干货 

作者:牧小熊,Datawhale成员

mcp最近很火,但在实际的应用环境中,并没有详细的资料讲解如何使用如何部署,增加初学者的学习成本,本文希望直观的展示mcp工具的具体使用实践。

一、mcp是什么?

大语言模型,例如DeepSeek,如果不能联网、不能操作外部工具,只能是聊天机器人。除了聊天没什么可做的。而一旦大语言模型能操作工具,例如:联网/地图/查天气/函数/插件/API接口/代码解释器/机械臂/灵巧手,它就升级成为智能体Agent,能更好地帮助人类。今年爆火的Manus就是这样的智能体。

在以前,如果想让大模型调用外部工具,需要通过写大段提示词的方法,实现“Function Call”,这样其实就非常的不友好。

Anthropic公司(就是发布Claude大模型的公司),在2024年11月,发布了Model Context Protocol协议,简称MCP。MCP协议就像Type-C扩展坞,让海量的软件和工具,能够插在大语言模型上,供大模型调用。

总的来说,mcp就是一个框架,能帮助大模型调用工具

更多MCP介绍可以看:Dify MCP 保姆级教程来了!

二、mcp协议通信

MCP采用客户端-服务器的分布式架构,它将 LLM 与资源之间的通信划分为三个主要部分:客户端、服务器和资源

  • MCP Hos:Hosts 是指 LLM 启动连接的应用程序,像Cursor、Claude、Desktop、Cline 这样的应用程序。
  • MCP Client:客户端是用来在 Hosts 应用程序内维护与 Server 之间 1:1 连接。一个主机应用中可以运行多个MCP客户端,从而同时连接多个不同的服务器。
  • MCP Server(服务器):独立运行的轻量程序,通过标准化的协议,为客户端提供上下文、工具和提示,是MCP服务的核心。

目前配置 MCP服务主要有种模式:

  • Stdio 模式: 这个主要是用来连接你本地电脑上的软件或文件。比如你想让 AI 控制 Blender 这种没有在线服务的软件,就得用 Stdio,它的配置相对复杂一些。
  • SSE 模式: 这个用来连接线上的、本身就有 API 的服务。比如访问你的谷歌邮箱、谷歌日历等等。SSE 的配置超级简单,基本上就是一个链接搞定。

在 MCP 框架中,SSE 模式是为了支持流式生成(如 LLM 的分词响应)而设计的一种 模型响应协议形式,其主要特征如下:

特点:

  • 服务端推送:服务端可以不断发送生成的 token,客户端实时接收并显示。
  • 兼容 Chat Completions 接口:通常和 OpenAI 的 stream=True 接口兼容。
  • 性能更高:相比于完整生成后一次返回,流式响应能提升用户体验和响应速度。

sse模型一般是推荐使用异步函数,那么为什么 SSE 模型要用异步函数?

1. SSE 本质是“流式”通信,需要持续等待数据SSE 是服务端持续推送数据,客户端需要一直监听这个连接,直到服务端关闭或中止。这种长时间等待、读取的过程非常适合用 async 实现,而不是阻塞式的 requests.get()。如果用同步函数,会卡住整个线程,阻塞后续逻辑或 UI。

2. 异步 I/O 更高效,占用资源更少 在异步模式下,await 会在数据没到的时候挂起任务,释放执行权给其他协程,而不是死等。这对于聊天机器人、Web 服务或多用户同时请求来说,性能提升非常明显。

三、mcp实践

为了方便演示,我写了一个mcp的工具demo

from fastmcp import FastMCP
# 创建一个FastMCP应用实例,名称为"demo"# 这将作为所有工具的统一服务入口app = FastMCP("demo")
# 定义一个名为"weather"的工具,用于查询城市天气# 该工具接收一个字符串类型的城市名称作为参数@app.tool(name="weather", description="城市天气查询")def get_weather(city: str):    # 定义一个包含部分城市天气信息的字典    # 实际应用中这里可能会调用真实的天气API    weather_data = {        "北京": {"temp"25"condition""晴"},        "上海": {"temp"28"condition""多云"}    }    # 返回对应城市的天气信息,如果城市不存在则返回错误信息    return weather_data.get(city, {"error""未找到该城市"})
if __name__ == "__main__":    # 启动应用,使用标准输入输出作为传输方式    # 这意味着可以通过命令行与工具进行交互    app.run(transport="stdio")

run(transport="stdio") 以子进程方式等待客户端通过标准输入输出发送调用指令

这里为了演示方便,我们直接调用阿里的api接口进行模型与mcp工具的交互

(文:Datawhale)

发表评论