ARTICLE DETAIL

资讯详情

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

一文掌握MCP、LangChain和LangGraph:构建大模型应用的完整指南,建议收藏

一文掌握MCP、LangChain和LangGraph:构建大模型应用的完整指南,建议收藏 1. 先把三个概念摆到同一张桌子上MCP、LangChain、LangGraph 这三个词经常被放在一起讲但很多人第一次接触时会懵它们到底是竞争关系还是协作关系我该先学哪个能不能只用其中一个就把大模型应用跑起来先把结论说清楚MCP 解决的是“模型怎么拿到外部数据和工具”LangChain 解决的是“怎么把模型、工具、提示词组装成一条链”LangGraph 解决的是“多条链、多个智能体之间怎么按状态流转和条件分支”。三者不是替代关系而是从下到上的三层协作。打个比方。MCP 像是统一的 USB-C 接口标准任何数据源只要实现这个协议模型就能插上就用LangChain 像是主板上的各种插槽和排线把 CPU模型、内存记忆、外设工具连起来LangGraph 则是整台机器的控制逻辑决定什么时候调用哪个模块、失败了走哪条分支、多个智能体怎么交接。适合谁看这篇如果你已经能跑通一个简单的 LLM 调用但面对“接数据库、接文件、接多个工具、还要多步推理”时不知道从哪下手那这篇就是给你梳理选型和落地路径的。我会给出可复制的 MCP 配置骨架、LangChain 与 LangGraph 的最小集成示例以及一套逐步验证连通性的操作清单。实测下来按这个顺序走能少踩不少“工具注册了但模型看不见”的坑。2. TaoToken 前置准备把模型入口先打通在折腾 MCP 和 LangGraph 之前得先有一个稳定的模型调用入口。因为后面所有链路最终都要落到“模型能不能正常返回”这件事上。我习惯先把模型入口单独验证通过再去接工具和编排否则出问题时根本分不清是模型的问题还是工具的问题。TaoToken 在这里扮演的是统一模型接入层的角色。你不需要在代码里为每个模型厂商写一套不同的鉴权逻辑而是通过一个兼容常见接口规范的入口来调用。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。第一步去控制台创建一个 API Key。打开 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 登录后在 API Keys 页面新建一个密钥复制保存好。这个 Key 后面会写进环境变量不要硬编码在代码里。第二步如果你只是想先确认模型能不能通可以直接用模型对话页面发一条消息试试 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。这一步能快速排除网络和鉴权问题。第三步如果你打算长期做编码类或 Agent 类项目建议了解一下 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。它更适合高频调用场景成本结构比按次调用更可控。把 Key 拿到手后先写一个最小的连通性测试。我用的是 OpenAI 兼容风格的调用方式Python 环境先装好依赖pip install openai然后写一个测试脚本import os from openai import OpenAI client OpenAI( api_keyos.environ[TAOTOKEN_API_KEY], base_urlhttps://taotoken.net/api ) resp client.chat.completions.create( modelgpt-4o-mini, messages[{role: user, content: 只回复两个字通了}] ) print(resp.choices[0].message.content)运行前设置环境变量export TAOTOKEN_API_KEY你刚才复制的Key python test_llm.py如果输出“通了”说明模型入口没问题。这一步看起来简单但它是后面所有工作的地基。我见过太多人跳过这步结果在 LangGraph 里调了半天最后发现是 Key 没配对。3. MCP 配置骨架让模型看见外部世界模型本身只能基于训练数据回答要让它读你的文件、查你的数据库、调你的 API就需要 MCP。MCP 的核心思路是把外部能力抽象成“工具”和“资源”通过标准协议暴露给模型。你不需要改模型本身只需要写一份配置文件告诉客户端去哪里找这些 Server。先给一份可复制的 MCP 配置骨架。这份配置通常放在项目根目录命名为mcp_config.json{ mcpServers: { filesystem: { command: npx, args: [ -y, modelcontextprotocol/server-filesystem, /Users/yourname/projects/data ] }, dbhub: { command: npx, args: [ -y, bytebase/dbhub, --dsn, postgresql://user:passwordlocalhost:5432/mydb ] }, http-api: { command: npx, args: [ -y, mcp-server-http, --base-url, https://api.example.com ], env: { API_TOKEN: your_token_here } } } }这份配置里定义了三个 Server文件系统、数据库、HTTP API。每个 Server 的command和args决定了怎么启动它。filesystem那个参数是你要暴露给模型的目录路径建议只暴露项目内的数据目录不要暴露整个用户目录。配置写好后怎么验证 Server 能正常启动可以用 MCP 的命令行客户端手动测一下npx modelcontextprotocol/inspector这个 Inspector 会启动一个本地界面让你选择配置文件、连接 Server、查看它暴露了哪些工具。如果能看到read_file、list_directory这类工具名说明 Server 侧没问题。接下来是 LangChain 侧的适配。LangChain 官方提供了langchain-mcp-adapters作用是把 MCP 工具自动转换成 LangChain 的 Tool 对象。安装pip install langchain-mcp-adapters langchain-openai langgraph然后写一个最小集成示例把 MCP 工具加载进来并交给模型import asyncio from langchain_mcp_adapters.client import MultiServerMCPClient from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent async def main(): client MultiServerMCPClient({ filesystem: { command: npx, args: [-y, modelcontextprotocol/server-filesystem, ./data], transport: stdio } }) tools await client.get_tools() print(已加载工具, [t.name for t in tools]) llm ChatOpenAI( modelgpt-4o-mini, api_key你的TaoToken Key, base_urlhttps://taotoken.net/api ) agent create_react_agent(llm, tools) result await agent.ainvoke({ messages: [{role: user, content: 列出 data 目录下的所有文件}] }) print(result[messages][-1].content) asyncio.run(main())这段代码做了三件事通过MultiServerMCPClient连接 MCP Server 并拿到工具列表用 TaoToken 的入口初始化模型用 LangGraph 的create_react_agent把模型和工具组装成一个能自主决定调用哪个工具的智能体。注意transport参数写的是stdio意思是客户端通过标准输入输出和 Server 进程通信。这是本地开发最常用的方式。如果你把 Server 部署在远端可以换成sse或streamable_http。4. LangGraph 编排从单次调用到多步工作流LangChain 的 Agent 能解决“模型自己决定调哪个工具”的问题但当你需要“先查数据库再根据结果决定要不要查文件最后汇总”这种带条件分支的流程时就需要 LangGraph 了。LangGraph 的核心是状态图你定义一个状态结构然后定义节点和边节点负责处理状态边决定下一步走哪里。下面是一个最小但完整的工作流示例。场景是用户提问后先判断问题类型如果是数据类问题走数据库查询分支如果是文档类问题走文件检索分支最后统一汇总回答。from typing import TypedDict, Literal from langgraph.graph import StateGraph, END from langchain_openai import ChatOpenAI class AgentState(TypedDict): question: str category: str context: str answer: str llm ChatOpenAI( modelgpt-4o-mini, api_key你的TaoToken Key, base_urlhttps://taotoken.net/api ) def classify(state: AgentState) - AgentState: prompt f判断这个问题属于 data 还是 doc只回复一个词{state[question]} result llm.invoke(prompt).content.strip().lower() state[category] data if data in result else doc return state def query_db(state: AgentState) - AgentState: state[context] 数据库查询结果本月订单量 1200 单 return state def search_doc(state: AgentState) - AgentState: state[context] 文档检索结果产品手册第 3 章提到退货政策 return state def summarize(state: AgentState) - AgentState: prompt f根据以下信息回答问题。\n问题{state[question]}\n信息{state[context]} state[answer] llm.invoke(prompt).content return state def route(state: AgentState) - Literal[query_db, search_doc]: return query_db if state[category] data else search_doc graph StateGraph(AgentState) graph.add_node(classify, classify) graph.add_node(query_db, query_db) graph.add_node(search_doc, search_doc) graph.add_node(summarize, summarize) graph.set_entry_point(classify) graph.add_conditional_edges(classify, route, { query_db: query_db, search_doc: search_doc }) graph.add_edge(query_db, summarize) graph.add_edge(search_doc, summarize) graph.add_edge(summarize, END) app graph.compile() result app.invoke({question: 这个月卖了多少}) print(result[answer])这段代码的关键点在于add_conditional_edges它根据classify节点的输出决定走哪条分支。这就是 LangGraph 相比普通 Chain 的核心优势——流程不再是线性的而是可以根据运行时状态动态选择路径。把 MCP 工具接进 LangGraph 节点也很直接。你可以在query_db节点里调用前面加载好的 MCP 工具而不是写死一个假结果。这样整条链路就串起来了LangGraph 控制流程LangChain 提供工具抽象MCP 提供实际的数据访问能力。5. 逐步验证清单每一步都确认再往下走链路一长出问题时就容易抓瞎。我的习惯是分层验证每层都确认通过再进下一层。下面这份清单可以直接照着做。第一层模型入口验证。用第 2 节的test_llm.py确认模型能返回。如果报 401检查 Key如果报连接超时检查 base_url 是否写成了https://taotoken.net/api。第二层MCP Server 单独验证。用npx modelcontextprotocol/inspector连接你的mcp_config.json确认每个 Server 都能启动并列出工具。如果某个 Server 启动失败先单独在终端跑它的command和args看报什么错。常见问题是npx包名写错或路径不存在。第三层MCP 工具加载验证。运行第 3 节里client.get_tools()那几行打印工具名列表。如果列表为空说明配置里的 Server 没连上如果报transport相关错误检查是否写了transport: stdio。第四层LangChain Agent 调用验证。用第 3 节的完整示例问一个必须调工具才能回答的问题比如“列出 data 目录下的文件”。如果模型直接编造答案而没调工具说明工具没正确绑定到 Agent检查create_react_agent的第二个参数是不是工具列表。第五层LangGraph 流程验证。用第 4 节的示例分别问一个 data 类问题和一个 doc 类问题确认走了不同分支。可以在每个节点里加print确认执行路径。第六层端到端验证。把 MCP 工具真正接进 LangGraph 节点跑一个完整流程。这时候如果出错根据前面五层的经验能快速定位是哪一层的问题。这套清单看起来繁琐但比“一把梭然后到处 debug”快得多。我试过在没做分层验证的情况下直接跑完整链路结果一个transport拼写错误查了半小时。6. 常见报错与排查报错一ModuleNotFoundError: No module named langchain_mcp_adapters包名和导入名不一致是常事。安装时用pip install langchain-mcp-adapters导入时用from langchain_mcp_adapters.client import MultiServerMCPClient。注意是下划线不是连字符。报错二MCP Server 启动后立即退出大概率是args里的路径不对。modelcontextprotocol/server-filesystem要求传入一个存在的目录路径。如果路径不存在Server 会直接退出。先用ls确认路径存在。报错三模型返回“我没有访问文件系统的能力”这说明工具没绑定成功。检查两点get_tools()返回的列表是否非空create_react_agent是否传入了tools。另外有些模型对工具调用的支持程度不同如果某个模型不返回tool_calls可以换一个对 function calling 支持更好的模型试试。报错四LangGraph 报InvalidUpdateError通常是节点函数没有返回完整的状态字典。LangGraph 要求每个节点返回的字典包含你要更新的字段。如果你只返回{answer: ...}其他字段会保留原值这是可以的但如果你返回了一个状态里不存在的字段就会报错。检查AgentState的定义和节点返回值是否对齐。报错五异步调用报RuntimeError: no running event loopMultiServerMCPClient的get_tools()是异步方法必须在async函数里用await调用。如果你在同步代码里直接调就会报这个错。用asyncio.run(main())包起来。报错六连接 TaoToken 返回 404检查base_url是否写成了https://taotoken.net/api不要多加/v1或结尾斜杠。有些兼容库会自动拼接路径多写反而会 404。排查时的一个通用思路把链路拆成“模型调用”和“工具调用”两部分分别用最小示例验证。模型部分用第 2 节的脚本工具部分用 Inspector。两部分都通了再合起来。7. 接下来怎么走按场景选入口如果你现在的目标是快速验证模型能力先把模型对话跑通就够了 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。在这里可以直接对比不同模型的返回效果不用写代码。如果你要开始写接入代码先去 API Keys 页面创建密钥 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。创建后配合接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里的示例把第 2 节的测试脚本跑通。如果你打算长期做编码类或 Agent 类项目调用频率会比较高建议看看 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。它的计费方式更适合持续开发场景。如果你用的是 Claude Code 这类工具可以参考 Anthropic 兼容接入的说明 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 。整条链路搭起来之后你会发现 MCP 负责“能拿到什么”LangChain 负责“怎么组装”LangGraph 负责“按什么顺序走”。三者各司其职缺一不可。先把模型入口和 MCP 工具加载这两步做扎实后面的编排就是水到渠成的事。
返回列表