ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MCP+LangChain实战:从零搭建AI Agent工具调用架构

MCP+LangChain实战:从零搭建AI Agent工具调用架构 2026年了如果你还在用“提示词模型”的方式写 AI 应用基本等于还在用记事本写代码。这一两年 AI 开发范式最大的变化就是 MCPModel Context Protocol的快速普及。这个协议把 AI 应用从“模型Prompt”变成了“模型工具总线”所有数据源、API、文件系统、数据库都能以统一方式接进大模型。这次我们直接进入实战不铺垫概念。文章核心围绕三件事MCP Server 怎么搭、LangChain 怎么集成 MCP、Agent 怎么真正把工具用起来。全文按“环境准备 → Server 端实现 → LangChain 接入 → Agent 实战 → Debug 排查 → 工程化建议”展开代码可以直接复制路径和端口按你的环境调整。如果你是做 AI 应用开发、Agent 开发或者打算把 LangChain 项目升级到工具调用架构这篇文章建议收藏。下面直接开始。1. MCP 核心能力速览先快速判断这东西适不适合你现在学。MCP 是 Anthropic 在 2024 年底开源的开放协议目标是统一大模型应用和外部工具/数据源之间的通信方式。它解决的不是“模型聪明不聪明”的问题而是“模型怎么稳定地调用工具”的问题。能力项说明协议类型开放标准基于 JSON-RPC 2.0通信方式本地 stdio、远程 Streamable HTTP/SSE核心原语Tools工具、Resources资源、Prompts提示词模板对模型的影响让模型通过工具获取实时数据、执行写操作、读取业务系统与 LangChain 关系LangChain 通过适配层直接连接 MCP Server工具注册进 Agent是否需要高配显卡不需要MCP 是协议层和本地推理、云端 API 均可配合支持批量任务支持批量取决于 Agent 编排逻辑和上游接口限流适合读者AI 应用开发者、Agent 开发者、LangChain/LangGraph 用户当前生态热度2025 年到 2026 年增长极快几乎所有主流 AI 框架都已支持从这张表可以得出一个结论MCP 不是框架、不是模型、不是 SDK它是“接口标准”。就像 HTTP 定义了 Web 如何通信MCP 定义了 AI 应用如何发现和调用工具。学 MCP核心是掌握三件事Server 端暴露什么、Client 端怎么连、Agent 怎么选工具。2. 适用场景与使用边界MCP 的定位非常明确解决 AI 应用接入外部系统时的碎片化问题。在它出现之前每接一个数据源都要写一套私有函数调用每换一个 Agent 框架又要重新适配一遍。MCP 把这些收敛成统一协议工具即插即用。适合的场景包括让 Agent 读取本地文件、数据库、网页内容。让 Agent 调用内部 API比如查询订单、创建工单、发送消息。让 Agent 操作开发者工具比如 GitHub、Figma、浏览器自动化。让 Agent 在执行任务过程中动态选择多个工具组合调用。不适合的场景也要说清楚。MCP 不负责模型能力提升不负责工具内部逻辑的正确性也不负责权限安全——这些都需要你自己在 Server 端和周边系统里控制。如果你只是做单轮问答、不需要外部数据MCP 属于过度设计。使用边界方面只要涉及读取业务数据、写入系统、操作第三方账号就必须要鉴权、限流、审计。尤其是调用线上 API 或操作真实业务数据时建议先在测试环境验证身份体系和数据范围。3. MCP 协议关键概念Tools、Resources、Prompts动手敲代码之前先把协议层的三个核心原语理清楚。很多人在这一步就卡住了因为网上资料常把这三者混在一起讲。3.1 Tools工具Tools 是 MCP 里最常用的原语对应模型可执行的函数。每个 Tool 有名称、描述、输入参数 Schema。模型根据用户的自然语言请求决定是否调用某个 Tool并按照 Schema 生成参数。例如一个get_weather工具Schema 里声明city字符串参数。Agent 收到“北京明天天气如何”时会调用get_weather并把city填成“北京”。3.2 Resources资源Resources 是静态或动态数据源类似文件的虚拟化。比如把某个数据库查询结果、某个配置文档暴露成resource://orders/daily。模型不会直接“调用”资源而是通过上下文读取。这适合给 Agent 注入背景信息、知识库片段、配置文件。3.3 Prompts提示词模板Prompts 是服务端预定义的提示词模板客户端可以拉取并填入参数快速生成结构化任务指令。比如定义一个review_code模板接收language和code_path就可以让 Agent 快速进入代码评审模式。理论部分到这里就够了。接下来直接搭建环境跑一个真实的 MCP Server。4. LangChain MCP 环境准备与前置条件关于操作系统Windows、macOS、Linux 都可以跑通 Stdio 模式的 MCP Server。如果你在 Linux 服务器上做 AI 开发建议优先考虑稳定性优先的 Server 版本Python 环境管理会更干净。桌面版不是不能做开发只是服务器版在依赖隔离和后台进程管理上更省心。4.1 安装 Python 与虚拟环境管理推荐 Python 3.10 以上版本。Ubuntu 环境下面给出示例命令Windows/macOS 请使用对应安装方式。# Ubuntu / Debian 系列 sudo apt update sudo apt install -y python3 python3-venv python3-pip创建独立项目目录和虚拟环境mkdir -p mcp-langchain-demo cd mcp-langchain-demo python3 -m venv .venv source .venv/bin/activate # Windows 用 .venv\Scripts\activate4.2 安装 MCP SDK、LangChain 与适配层核心依赖是MCP Python SDK、LangChain、langchain-mcp-adapters。适配层的作用是把 MCP Server 暴露的工具“翻译”成 LangChain 能识别的工具。pip install --upgrade pip pip install mcp langchain langchain-openai langchain-mcp-adapters需要说明的是langchain-mcp-adapters是官方维护的适配包当前主流用法是通过McpServerClient连接 MCP Server再把 tools 转成 LangChain 工具列表。更早的 0.1.x 版本有load_mcp_tools之类的函数式写法如果你在别的教程里看到注意版本差异。pip show langchain-mcp-adapters4.3 模型服务准备LangChain Agent 需要一个大模型来决策是否调用工具。这里用 OpenAI 兼容接口为例无论你用的是官方 API、第三方中转还是本地部署的模型服务只要暴露 OpenAI 兼容接口都可以通过ChatOpenAI接入。# 需要设置环境变量 # 如果使用本地或其它兼容服务改成对应地址即可 export OPENAI_API_KEYyour-api-key export OPENAI_API_BASEhttps://api.example.com/v1如果使用本地模型服务比如 vLLM 或 LM Studio则把OPENAI_API_BASE指向本地端口具体配置以你部署的服务为准。5. 从零搭建一个 MCP Server文件查询与天气查询实战这一节我们写一个真正的 MCP Server。它会暴露两个工具read_local_file读取本地文本文件内容。get_weather根据城市名返回模拟天气数据。选择这两个工具的原因很直接read_local_file能验证 Agent 与本地文件系统的交互能力get_weather能验证模型对工具参数 Schema 的遵循程度。5.1 创建 Server 文件创建一个weather_server.pyfrom mcp.server.fastmcp import FastMCP from typing import Optional mcp FastMCP(demo-server) mcp.tool() async def get_weather(city: str) - str: 根据城市名查询实时天气。 # 这里仅作演示返回模拟数据 weather_data { 北京: 晴气温 18℃北风 3 级, 上海: 多云气温 22℃东风 2 级, 广州: 小雨气温 26℃南风 2 级, } return weather_data.get(city, f抱歉没有 {city} 的天气数据) mcp.tool() async def read_local_file(file_path: str) - str: 读取本地文本文件内容返回纯文本。 if not file_path.endswith(.txt): return 仅支持读取 .txt 文本文件 try: with open(file_path, r, encodingutf-8) as f: content f.read() return content[:2000] or (文件为空) except FileNotFoundError: return f文件不存在: {file_path} except Exception as e: return f读取失败: {str(e)} if __name__ __main__: mcp.run(transportstdio)关键点装饰器mcp.tool()把普通函数变成 MCP 工具。函数类型注解和文档字符串会被自动提取成工具描述和参数 Schema。所以描述要写清楚“什么时候该调用、参数代表什么”。transportstdio表示通过标准输入输出通信这是 LangChain 本地集成最稳定的方式。5.2 手动运行测试 Server先启动 Server确保没报错python weather_server.py如果能看到进程挂起、没有任何错误输出说明 Stdio 模式初始化成功。注意此时该进程是在等待客户端连接所以终端会一直停留。5.3 用 MCP Inspector 调试MCP 官方提供网页调试工具mcp-inspector可以单独验证 Server 的注册工具和调用结果。npx modelcontextprotocol/inspector python weather_server.py启动后根据控制台提示打开地址一般是http://localhost:6274在页面里能看到Tools 列表里有两个工具。点击get_weather输入city为“北京”能直接看到返回结果。点击read_local_file输入一个本机存在的.txt路径能读取到文件内容。这一步相当重要。先确认 Server 本身没问题再去接 LangChain否则后面出错时很难定位是协议问题还是框架适配问题。6. LangChain Agent 集成 MCP完整代码与启动流程Server 已经能跑了现在把它接进 LangChain Agent。6.1 创建 LangChain 集成脚本创建agent_demo.pyimport asyncio import os from pathlib import Path from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_mcp_adapters.client import McpServerClient async def run_agent(): # 固定 MCP Server 路径按你的实际目录调整 server_script str(Path(__file__).parent / weather_server.py) # 连接本地 MCP Server async with McpServerClient( commandpython, args[server_script], encodingutf-8, ) as client: # 获取工具列表转成 LangChain 工具格式 tools await client.get_tools() print(f成功加载工具数量: {len(tools)}) for t in tools: print(f - {t.name}: {t.description}) llm ChatOpenAI( modelgpt-4o-mini, temperature0, openai_api_keyos.getenv(OPENAI_API_KEY), openai_api_baseos.getenv(OPENAI_API_BASE), ) prompt ChatPromptTemplate.from_messages( [ (system, 你是一个可以调用本地工具的助手。需要工具时就调用工具。), (human, {input}), MessagesPlaceholder(variable_nameagent_scratchpad), ] ) agent create_openai_tools_agent(llm, tools, prompt) executor AgentExecutor(agentagent, toolstools, verboseTrue) # 测试 1天气查询 result await executor.ainvoke( {input: 查询一下北京的天气情况} ) print( 天气查询结果 ) print(result[output]) # 测试 2读取本地文件 test_file Path(__file__).parent / demo.txt test_file.write_text(hello from mcp langchain agent, encodingutf-8) result await executor.ainvoke( {input: f读取本地文件 {test_file} 的内容} ) print( 文件读取结果 ) print(result[output]) if __name__ __main__: asyncio.run(run_agent())6.2 启动并观察日志运行脚本python agent_demo.py正常流程会分几步McpServerClient拉起本地weather_server.py子进程。客户端自动完成 MCP 握手获取工具列表。LangChain 把工具包装成 Agent 可调用的BaseTool。用户提问后LLM 决定调用哪个工具Agent Executor 执行并把结果返回给 LLM。LLM 根据工具结果生成最终回复。verboseTrue的 Agent 会打印详细的中间步骤这是新手最重要的调试窗口。可以看到 LLM 的工具调用请求参数、工具返回结果、最终答案内容。6.3 两个测试用例的预期结果测试 1 中输入“查询一下北京的天气情况”理想情况是 LLM 先调get_weather(city北京)再基于返回结果给出“北京天气晴气温 18℃”之类的回答。测试 2 中输入“读取本地文件 /path/to/demo.txt 的内容”Agent 会调read_local_file(file_path...)并把文件内容回复给用户。如果工具名、参数描述写得足够清晰LLM 基本能准确选对工具。如果描述太模糊模型可能会出现“没有调用工具直接编造答案”“选错工具”“参数格式错误”三种典型问题这一点在后面的排查章节展开。7. MCP Server 的更多连接方式远程 MCP 与多工具组合Stdio 模式适合本地开发但真实业务里MCP Server 多半部署在远端通过 HTTP 暴露。这一节给出远程 MCP 的对接思路和代码模板。7.1 通过 URL 连接远程 MCP Serverlangchain-mcp-adapters也支持直接通过urllib连接远程 MCP Server。前提是远端已经启动了 Streamable HTTP 模式的 MCP 服务并暴露了可访问的 URL。from langchain_mcp_adapters.client import McpServerClient client McpServerClient(urlhttp://your-server:8000/mcp) tools await client.get_tools()这种模式适合前后端分离、多 Agent 共享同一批工具的场景。需要注意的是远程模式必须确认接口鉴权和网络白名单。工具数量多时工具描述和 Schema 会占不少上下文 Token建议服务端精简描述。远程 MCP 的延迟比本地 stdio 高一个量级对延迟敏感的场景要评估。7.2 多 MCP Server 组合Agent 不需要只连一个 Server。你可以同时连接“数据库 MCP Server”和“文件系统 MCP Server”把两边的工具一起注册进 Agent。server1 McpServerClient(commandpython, args[db_server.py]) server2 McpServerClient(commandpython, args[file_server.py]) async with server1 as s1, server2 as s2: tools await s1.get_tools() await s2.get_tools()这种组合方式非常实用比如一个 Agent 既需要读取数据库里的用户信息又需要把结果写入日志文件两个 Server 各司其职。8. 接口 API 化与批量任务设计MCP 本身是 Agent 与工具之间的协议不是给外部系统直接调用的 HTTP API。但真实业务里你需要把“MCP Server 的查询能力”封装成可供其他系统调用的 API。常见做法是用 FastAPI 包一层。8.1 用 FastAPI 封装 MCP 工具查询from fastapi import FastAPI from pydantic import BaseModel import asyncio app FastAPI() class QueryRequest(BaseModel): user_input: str app.post(/agent/run) async def run_agent(req: QueryRequest): from agent_demo import run_agent_once result await run_agent_once(req.user_input) return { output: result[output], intermediate_steps: str(result[intermediate_steps]), }注意这里依赖run_agent_once是你自己写的、能接收字符串并返回结果的函数。实际项目建议把 Agent 初始化逻辑独立出来避免每次请求都重新拉起 MCP Server 子进程。8.2 批量任务队列设计批量任务场景下不要直接并发拉太多 MCP 连接要设置信号量和重试机制。下面是一个简单的批量处理模板import asyncio from asyncio import Semaphore async def batch_process(user_inputs: list[str], max_concurrency: int 3): sem Semaphore(max_concurrency) async def process_one(text: str): async with sem: # 这里替换成你自己的 Agent 调用函数 return await run_agent_once(text) results await asyncio.gather(*[process_one(t) for t in user_inputs]) return results批量任务的核心注意事项控制并发数防止上游 LLM API 限流。记录每个任务的输入、输出、耗时和错误信息方便失败重放。如果 Agent 内部有状态需要确认多任务之间是否有状态污染。9. 资源占用与性能观察MCP 是协议层本身不跑模型所以显存占用可以忽略不计。真正占资源的是 LLM 推理服务和 MCP Server 所在进程的开销。以下观察点值得关注。9.1 如何观察性能启动时间McpServerClient拉起本地 Python 子进程需要一个握手周期Linux 下通常比 Windows 快一些具体以本机测试为准。工具调用延迟LLM 决策 工具执行 LLM 总结三段耗时。工具执行如果涉及网络请求会显著增加总时长。Token 消耗Agent 的中间步骤会消耗大量 Token尤其是工具描述过长、多轮调用时。建议用verboseTrue观察每一轮的 Token 变化。9.2 降低开销的技巧精简工具描述不要写冗长的历史背景。参数 Schema 只保留必要字段减少生成参数时的错误。如果 Agent 只需要 1 个工具不要注册 10 个工具避免干扰决策。批量任务使用异步并发但并发数不要超过 LLM 接口的 RPM 限制。9.3 进程残留问题Stdio 模式下如果 Python 脚本异常退出子进程可能残留。排查时用系统进程命令检查ps aux | grep weather_server.py # Linux / macOS tasklist | findstr weather_server.py # Windows如果发现残留直接终止对应 PID否则端口无关的 stdio 子进程会累积占用内存。10. 常见问题与排查方法这一节整理我实践中比较高频的坑。每个问题都按现象、原因、排查、解决四步列出。问题现象可能原因排查方式解决方案get_tools()返回空列表MCP Server 没把工具注册成功或当前连接模式未启用工具能力用 MCP Inspector 单独测试 Server检查装饰器是否遗漏mcp.tool()确认工具函数有mcp.tool()装饰器重启 Server启动 Agent 后报connection closed错误stdio 模式下 Python 子进程崩溃或脚本路径错误先手动执行 Server 脚本观察是否有报错检查args里的路径是否绝对路径修正脚本路径在 Server 代码外层加try-except输出日志Agent 不调用工具直接编造答案工具描述不清晰系统提示词中没有强调工具使用查看verboseTrue的中间输出检查工具名称是否与意图匹配改写工具描述明确说明“什么时候调用该工具”在系统提示词里加上“如果需要工具信息请先调用工具”工具参数传入错误LLM 对参数 Schema 理解偏差参数名或枚举值不明确检查工具函数的参数命名和 docstring使用更明确的参数名在 docstring 中列举可选枚举值工具调用后最终回答没有使用工具结果Agent 编排问题或模型没有读到工具返回值观察AgentExecutor中间输出确认工具返回值是否有内容检查工具返回是否为合法字符串调整提示词要求基于工具输出回答问题远程 MCP 连接超时网络不通、鉴权失败、服务未启动用curl测试 MCP 端点是否响应确认服务状态、网络策略和鉴权 Header批量任务跑到一半卡住并发过高触发 LLM 接口限流或某个工具调用长时间阻塞在工具函数里加超时和日志降低并发数给网络请求设置timeout增加失败重试模型反复重试同一个工具工具返回了空字符串或错误提示模型误以为还能再试检查工具的返回内容确认没有死循环逻辑让工具在数据不存在时返回明确的“无数据”信息在 Agent 层级限制最大迭代轮数Agent 上下文越来越长Token 消耗剧增工具描述太多太长多轮对话历史累积审查注册的工具数量和描述长度精简工具描述必要时用agent_scratchpad控制历史记录长度11. Agent 工具选择的工程化经验很多人第一次跑通 MCP Agent 后会陷入一个困惑既然 LLM 能选工具是不是工具越多越好不是。工具数量增加会带来三个问题第一工具描述占据上下文窗口。一个工具的描述如果写 200 Token50 个工具就是 10000 Token模型用于推理的空间被压缩工具选择准确率反而下降。第二模型在“相似工具”之间容易选错。比如get_weather和get_temperature描述相似模型可能错误调用。除非有必要否则把功能相近的工具合并成一个工具内部用参数区分。第三调试变难。工具多中间步骤就多定位问题更耗时间。建议第一版只注册核心工具跑通后再逐步扩充。另外创建 Agent 时一定要限制最大迭代次数防止模型在工具调用中死循环。AgentExecutor有max_iterations参数建议起步设为 3 到 5。12. 最佳实践与合规提醒到这里整个 MCP LangChain Agent 的链路已经跑通。最后给几条工程化建议。12.1 代码与配置管理所有工具函数写独立文件不要堆在 Agent 启动脚本里。MCP Server 的启动命令、模型 API Key、Base URL 全部用环境变量或配置文件管理不要硬编码。工具函数内部不要打印敏感数据日志级别要可控。12.2 架构与部署建议本地开发用 stdio 模式部署到服务器后优先考虑远程 MCP 模式便于多个 Agent 共享。如果多个 Agent 需要调用同一批工具建议把 MCP Server 独立部署成服务不要每个 Agent 都拉一个子进程。对耗时较长的工具调用比如爬网页、跑数据分析建议改成异步任务Agent 先返回“正在处理”结果通过异步回调或轮询获取。12.3 安全与合规工具调用如果涉及读取数据库或文件系统必须做路径白名单和权限校验防止 Agent 被诱导访问未授权文件。MCP Server 暴露到公网时必须加鉴权建议使用 API Key 或 OAuth 方式禁止裸奔。如果 Agent 操作的是真实业务系统比如发送邮件、修改订单、删除文件建议先实现“预执行确认”逻辑也就是让 Agent 先生成操作预览由人工确认后再执行。涉及第三方平台的自动化操作比如 GitHub、Figma、浏览器控制必须保证有授权并且只在允许的范围内执行不突破权限边界。13. 总结与下一步MCP 不是新语言也不是新框架它是 AI 应用开发里“工具链统一”的答案。这篇文章的核心链路是本地 Stdio 模式启动 MCP Server通过langchain-mcp-adapters把工具接进 LangChain Agent让 LLM 自主选择工具并返回结果。整个过程不依赖高配显卡不依赖特定模型服务只要模型支持 OpenAI 兼容的工具调用接口就能跑。环境方面Windows、macOS、Linux 都能开发部署到服务器时建议用稳定优先的 Linux 发行版。最先要验证的功能建议按这个顺序来先单独跑weather_server.py再用 MCP Inspector 确认工具注册最后才接 LangChain。最容易踩的坑有三个工具描述写得太含糊导致模型选错或乱编、McpServerClient的args路径写错导致子进程启动失败、以及批量任务并发过高被 LLM 接口限流。这三个坑分别对应 Schema 设计、环境调试、并发控制三个层面的能力也是 MCP 工程化最核心的经验。下一步可以扩展的方向很多把 MCP Server 部署成远程 HTTP 服务、接入 LangGraph 做有状态 Agent、结合 RAG 给 Agent 注入私域知识或者用 MCP 对接更多内部系统。最推荐的做法是先以一个真实工具为目标把它完整跑通并部署再复用这套流程去接第二个、第三个工具。工具一多你就能明显感受到统一协议的价值。
返回列表