系列简介:从零搭建一个多 Agent AI 助手,覆盖原理、实现、部署全链路。不讲空话,每篇都有可运行的代码。
项目地址:https://github.com/CodeMomentYY/LangGraph-Agent
本篇目标:接入 MCP 工具生态,让 Agent 的能力不再受限于手写工具;回顾整个系列,我们来看看系统全景架构图。
前言
大家好,我是一名前端工程师。都说前端“已死”,那与其担心被 AI 替代,不如打入敌人内部,于是我开始折腾 Agent 开发。
折腾下来发现,Agent 的核心不是算法,而是“工程能力”(怎么设计架构、怎么串联服务、怎么把 LLM 的能力落地成产品)。这些恰好是我们擅长的事。
这个系列记录我从零搭建多 Agent 系统的完整过程。只聊技术知识和设计思路,代码交给 AI 写。如果你也想从应用层切入 AI,希望这个系列对你有帮助。
读完本篇你将学到:
- MCP 是什么,为什么 Agent 需要它;
- 用 langchain-mcp-adapters 接入语雀 MCP 服务器;
- 手写工具 vs MCP 工具,什么时候该用哪种;
- 从零到完整 Agent 系统的全景回顾;
背景与动机
前几篇我们给 Agent 加了多 Agent 协作、流式输出、记忆能力。但你会发现一个问题:Agent 只能访问我们几个手写工具提供的数据。
为什么可以查实时天气?因为我们写了get_weather。但如果我想让 Agent 帮我查语雀文档、读 GitHub 仓库、获取 Figma 设计稿呢?这些数据有两个共同特点:
- 在第三方平台上:语雀、GitHub、Figma、飞书等这些平台,数据都在各自平台的库中;
- 需要授权才能访问:这些数据不能随意爬取,你得有
ACCESS TOKEN授权才能读写;
如果每个平台都手写一个工具函数,工作量巨大,而且不具备拓展性。MCP 的出现就是为了解决这个问题:把“连接授权平台、获取私有数据”这件事标准化,让 Agent 通过统一协议就能触达各种平台的数据。
核心概念
MCP 是什么?
MCP =Model Context Protocol(模型上下文协议),由 Anthropic 在 2024 年底提出。通过MCP 来访问各个平台上的私有数据,究其本质也是用来增强上下文信息的。
LLM 的知识截止于训练时间,训练的也是一些公开信息,它不知道你的语雀文档写了什么、你的 GitHub 仓库有哪些 Issue、你的 Figma 设计稿长什么样。这些数据散落在各个平台,而且都需要授权才能访问。
MCP 做的事情是:定义一套标准协议,让 MCP Server 封装好平台的认证和 API 调用逻辑,Agent 只需要配一个 Token,就能通过统一接口读写这些平台的数据。
类比理解:MCP 就像 USB 接口标准——键盘、鼠标、U盘都用同一个口,你不需要为每个设备单独装驱动。MCP Server 就是“驱动”,帮你处理好和平台的对接细节。
架构上,MCP 采用 Client-Server 模式,通信方式支持 stdio(本地子进程,适合开发)和 HTTP SSE(远程服务,适合生产):
Agent 工具调度(Function Calling)
说到这里你可能会有个疑问:MCP Server 把工具暴露出来了,但Agent 怎么知道该调哪个工具?
答案是Function Calling。回忆一下第 1 篇,我们用 Prompt 约定格式(Action: get_weather(北京)),让 LLM 输出固定文本,然后自己解析字符串提取工具名和参数——这其实就是在“模拟” Function Calling。
现代 LLM(Claude、GPT、DeepSeek 等)把这个过程内置了:你把工具的名称、描述、参数格式传给 LLM,它判断需要调工具时直接返回 JSON 格式的调用指令,不需要你自己解析字符串。
手写工具 vs MCP 工具
我们项目里两种都有,什么时候该用哪种?
| 手写工具 | MCP 工具 | |
|---|---|---|
| 开发成本 | 高(写代码 + 测试) | 低(配置即用) |
| 灵活性 | 完全自定义 | 受限于 MCP Server 提供的能力 |
| 维护 | 自己维护 | 社区 / 官方维护 |
| 适合场景 | 定制逻辑、内部 API | 通用能力(文档、数据库、设计稿) |
我的建议:通用能力优先找 MCP Server,找不到或者需要定制逻辑时再手写。
动手实现
Step 1:安装依赖
pipinstalllangchain-mcp-adapterslangchain-mcp-adapters是 LangChain 官方提供的 MCP 适配器,能把 MCP 工具自动转成 LangChain Tool 格式,无缝接入我们的 Agent。
Step 2:接入语雀 MCP Server
因为之前我写过一个「语雀 MCP」,所以这里用语雀 MCP Server 作为示例——接入后 Agent 就能搜索、读取语雀文档。
""" 语雀 MCP 工具接入 通过 langchain-mcp-adapters 连接语雀 MCP 服务器 """importasynciofromlangchain_mcp_adapters.clientimportMultiServerMCPClient _mcp_tools=None# 全局缓存def_load_mcp_tools_sync()->list:"""加载 MCP 工具"""asyncdef_load():client=MultiServerMCPClient({'yuque':{'transport':'stdio','command':'npx','args':['-y','@momentyy/yuque-mcp-server'],'env':{'YUQUE_API_TOKEN':'your-token','YUQUE_BASE_URL':'https://www.yuque.com/api/v2',},}})returnawaitclient.get_tools()returnasyncio.run(_load())defget_yuque_mcp_tools()->list:"""获取语雀 MCP 工具列表(带缓存)"""global_mcp_toolsif_mcp_toolsisNone:_mcp_tools=_load_mcp_tools_sync()return_mcp_tools关键点:
transport: 'stdio':本地通过子进程启动 MCP Server;npx -y @momentyy/yuque-mcp-server:直接用 npx 运行,不需要全局安装;get_tools()返回的就是标准的 LangChain Tool 列表,和手写的@tool函数格式完全一样;
Step 3:注册到工具列表
MCP 工具加载后,和手写工具一起注册到 Agent:
# tools/__init__.pyfromapp.agent.tools.weatherimportget_weatherfromapp.agent.tools.recommendimportrecommend_activityfromapp.agent.tools.web_fetchimportfetch_webpagefromapp.agent.tools.mcp_yuqueimportget_yuque_mcp_tools ALL_TOOLS=[get_weather,# 手写工具recommend_activity,# 手写工具fetch_webpage,# 手写工具]+get_yuque_mcp_tools()# MCP 工具(自动追加)就这么简单——MCP 工具和手写工具在 Agent 眼里没有任何区别,都是“可调用的函数”。Dispatcher 分流到 tools 路径后,LLM 会根据用户问题自动选择调哪个工具。
Step 4:新增 MCP 工具
MCP 的核心价值在于即插即用。假设明天你想让 Agent 能读取 Figma 设计稿,不需要写任何业务代码,只需要在配置里多加一个 Server:
client=MultiServerMCPClient({'yuque':{'transport':'stdio','command':'npx','args':['-y','@momentyy/yuque-mcp-server'],'env':{'YUQUE_API_TOKEN':'...'},},# 新增:Figma MCP Server,一行配置搞定'figma':{'transport':'stdio','command':'npx','args':['-y','@xx/figma-mcp-server'],'env':{'FIGMA_ACCESS_TOKEN':'...'},},})加完这几行,Agent 就自动获得了 Figma 的能力(读取设计稿、获取组件信息、导出切图)。不需要改 Agent 代码,不需要改路由逻辑,不需要改前端——工具层的变化对上层完全透明。
这就是“即插即用”的含义:MCP 生态里有上千个现成的 Server,你想用哪个就配哪个,Agent 的能力边界由你决定。
Step 5:验证效果
接入后,Agent 自动获得了语雀相关的能力,大致流程如下:
# 读取语雀文档用户:"读一下这个文档 https://xxx.yuque.com/xxx/xxx/xxx"Agent → 调用 yuque_get_doc → 返回文档内容 → 总结回复Web 端验证效果:
注意:我们没有为这些能力写任何业务代码——全部由 MCP Server 提供,Agent 只是“调用”。
多端交互
除了 Web 界面,项目里面我还接入了钉钉机器人(Stream 模式),让 Agent 能在群聊里直接使用。这里就就不展开讲了,感兴趣的小伙伴可以自己尝试一下。
代码位置:https://github.com/CodeMomentYY/LangGraph-Agent/blob/main/server/app/dingtalk_bot.py
系列回顾
6 篇文章,我们从零搭建了一个完整的多 Agent 系统。回顾一下整个系列的内容:
| 篇 | 主题 | 核心能力 |
|---|---|---|
| 第 1 篇 | Agent 的本质 | LLM + 工具 + 循环 |
| 第 2 篇 | 三种工作模式 | ReAct、Plan-and-Solve、Reflection |
| 第 3 篇 | 多 Agent 协作 | Dispatcher + 专业 Agent + 串行/并行 |
| 第 4 篇 | 全栈产品化落地 | FastAPI + SSE 流式 + Vue3 前端 |
| 第 5 篇 | 上下文记忆能力 | 短期 JSON + 长期 ChromaDB RAG |
| 第 6 篇 | Agent 工具生态 | Agent 工具调度 + MCP 接入 |
系统全景架构图:
刨根问底
| 序号 | 问题 |
|---|---|
| 1️⃣ | Q:MCP 和 Function Calling 有什么区别? |
| A:Function Calling 是 LLM 层面的能力——LLM 决定调什么函数、传什么参数。MCP 是工具层面的标准——定义工具怎么暴露、怎么被发现、怎么被调用。两者是互补的:LLM 通过 Function Calling 决定调哪个工具,MCP 负责把工具标准化地接进来。 | |
| 2️⃣ | Q:MCP Server 是怎么运行的? |
A:stdio 模式下,Agent 启动时会 fork 一个子进程运行 MCP Server(比如npx @momentyy/yuque-mcp-server),通过标准输入输出通信。Server 常驻内存,Agent 需要调工具时发请求,Server 执行后返回结果。 |
本篇小结
- MCP 是 AI 工具的标准化协议,让工具像 USB 设备一样即插即用;
langchain-mcp-adapters一行代码把 MCP 工具转成 LangChain Tool,无缝接入;- 手写工具适合定制逻辑,MCP 适合通用能力,两者互补;
写在最后
6 篇文章写完,回头看这个系列的核心观点只有一个:Agent 开发的门槛不在 AI,在工程。
LLM 是现成的(调 API 就行),真正需要你动手的是:怎么设计多 Agent 协作架构、怎么做流式输出、怎么管理记忆、怎么接入工具生态、怎么让它在多个端上跑起来。
这些全是工程问题,而工程能力恰好是我们每天都在练的。
如果你跟着这个系列走了一遍,你会发现:从零搭一个能用的 Agent 系统,没有想象中那么难。难的不是某个技术点,而是把所有东西串起来的那个过程。
希望这个系列对你有帮助。如果有问题或者想法,欢迎在评论区交流 🌹🌹🌹。