如何使用LangGraph搭建一个智能体应用,需要mcp和工具调用
下面是一份从零开始、基于LangGraph 框架开发智能问答系统的完整实战教程涵盖API 工具调用和MCP 服务调用两大核心能力。一、什么是 LangGraphLangGraph 是由 LangChain 团队开发的低级别编排框架专门用于构建、管理和部署长期运行、有状态的 AI 智能体工作流。核心设计理念传统 LangChain 的 Chain 是线性链式调用A→B→C而 LangGraph 采用有向图结构支持循环、条件分支、并行执行更贴合真实业务中反复推理-执行-判断的 Agent 行为。四大核心组件组件作用类比State状态贯穿整个工作流的共享数据结构全局变量Node节点工作流中的原子执行单元纯函数函数Edge边定义节点间的流转逻辑普通/条件/并行if-else / 路由Graph图将节点和边组装成可执行的工作流程序入口为什么用 LangGraph 而不是 LangChain Agent精细控制可以精确控制每一步的流转逻辑而非黑盒执行状态持久化内置 Checkpoint 机制支持断点续传和故障恢复人机协同支持在任意节点暂停等待人工审核多智能体协作支持子图嵌套实现复杂的多 Agent 编排二、整体架构设计用户提问 │ ▼ ┌──────────────────────────────────────────┐ │ LangGraph 智能体图工作流 │ │ │ │ ┌─────────┐ ┌──────────┐ │ │ │ LLM节点 │◄──►│ 工具节点 │ ← 循环调用 │ │ └─────────┘ └────┬─────┘ │ │ │ │ │ ┌────────────┼────────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │ │自定义工具 │ │ RAG检索 │ │MCP工具 │ │ │ │(API调用) │ │(知识库) │ │(外部) │ │ │ └──────────┘ └──────────┘ └────────┘ │ └──────────────────────────────────────────┘ │ ▼ 输出回答三、环境搭建3.1 创建项目mkdirlanggraph-qa-systemcdlanggraph-qa-system python-mvenv venv# Windowsvenv\Scripts\activate# macOS/Linuxsourcevenv/bin/activate3.2 安装依赖# LangGraph 核心框架pipinstalllanggraph langchain-core langchain-openai# MCP 集成pipinstalllangchain-mcp-adapters mcp fastmcp# 向量数据库RAGpipinstallchromadb langchain-chroma# 文档加载pipinstallpypdf python-docx# HTTP 请求pipinstallhttpx# 环境变量pipinstallpython-dotenv3.3 配置环境变量创建.env文件OPENAI_API_KEYsk-xxx # 如使用通义千问等国内模型 # DASHSCOPE_API_KEYyour_key四、接入大语言模型importosfromdotenvimportload_dotenv load_dotenv()fromlangchain_openaiimportChatOpenAI# 方式一OpenAIllmChatOpenAI(modelgpt-4o,temperature0)# 方式二通义千问兼容 OpenAI 接口# llm ChatOpenAI(# modelqwen-plus,# api_keyos.getenv(DASHSCOPE_API_KEY),# base_urlhttps://dashscope.aliyuncs.com/compatible-mode/v1# )五、定义自定义工具API 调用工具是智能体的手脚让它能执行搜索、计算、调用外部 API 等操作。fromlangchain_core.toolsimporttoolfromdatetimeimportdatetimeimporthttpxtooldefget_current_time(city:str)-str:获取指定城市的当前时间。当用户询问时间、几点钟等问题时调用。nowdatetime.now().strftime(%Y-%m-%d %H:%M:%S)returnf{city}当前时间是{now}tooldefquery_weather_api(city:str)-str:通过 API 查询指定城市的天气信息。当用户询问天气时调用。geocode_urlhttps://geocoding-api.open-meteo.com/v1/searchweather_urlhttps://api.open-meteo.com/v1/forecastwithhttpx.Client(timeout10)asclient:rclient.get(geocode_url,params{name:city,count:1,language:zh})r.raise_for_status()datar.json()[results][0]lat,londata[latitude],data[longitude]rclient.get(weather_url,params{latitude:lat,longitude:lon,current_weather:true})r.raise_for_status()weatherr.json()[current_weather]returnf{city}当前温度{weather[temperature]}°C风速{weather[windspeed]}km/htooldefcalculate(expression:str)-str:计算数学表达式。当用户需要数学计算时调用。try:resulteval(expression,{__builtins__:{}},{})returnf{expression}{result}exceptExceptionase:returnf计算出错:{e}custom_tools[get_current_time,query_weather_api,calculate] 工具的docstring 非常关键大模型依赖它来判断何时调用哪个工具。六、构建 RAG 知识库fromlangchain_community.document_loadersimportPyPDFLoaderfromlangchain.text_splitterimportRecursiveCharacterTextSplitterfromlangchain_openaiimportOpenAIEmbeddingsfromlangchain_chromaimportChroma# 加载文档loaderPyPDFLoader(your_document.pdf)documentsloader.load()# 切割文本text_splitterRecursiveCharacterTextSplitter(chunk_size500,chunk_overlap50)chunkstext_splitter.split_documents(documents)# 向量化存储embeddingsOpenAIEmbeddings()vectorstoreChroma.from_documents(documentschunks,embeddingembeddings,persist_directory./chroma_db)retrievervectorstore.as_retriever(search_kwargs{k:3})# 封装为工具tooldefsearch_knowledge_base(query:str)-str:从私有知识库中检索相关信息。当用户询问专业知识、文档内容时调用。docsretriever.invoke(query)ifnotdocs:return知识库中未找到相关信息。return\n\n.join([doc.page_contentfordocindocs])七、编写 MCP Server外部服务调用7.1 创建 MCP Server创建文件news_mcp_server.pyfrommcp.server.fastmcpimportFastMCP mcpFastMCP(NewsService)mcp.tool()defsearch_news(keyword:str)-str:根据关键词搜索最新新闻。当用户询问新闻资讯时调用。# 示例实际项目中替换为真实 API 调用mock_news[{title:f关于{keyword}的最新报道1,summary:这是第一条新闻摘要...},{title:f关于{keyword}的最新报道2,summary:这是第二条新闻摘要...},]return\n.join([f{n[title]}:{n[summary]}forninmock_news])mcp.tool()defget_stock_price(symbol:str)-str:查询股票实时价格。当用户询问股价、行情时调用。returnf{symbol}当前价格为 150.25 元涨幅 2.3%if__name____main__:# stdio 模式本地开发mcp.run(transportstdio)# 生产环境改用 HTTP 模式# mcp.run(transportstreamable-http, host0.0.0.0, port8005)八、用 LangGraph 构建智能体核心这是整个教程的核心部分。LangGraph 提供两种构建方式预构建快捷方式和手动图编排。方式一使用预构建的create_react_agent推荐入门importasynciofromlangchain_openaiimportChatOpenAIfromlangchain_mcp_adapters.clientimportMultiServerMCPClientfromlanggraph.prebuiltimportcreate_react_agentasyncdefmain():# 1. 加载 MCP 工具mcp_config{news-server:{transport:stdio,command:python,args:[/你的绝对路径/news_mcp_server.py]# 必须用绝对路径}}clientMultiServerMCPClient(mcp_config)mcp_toolsawaitclient.get_tools()# 2. 合并所有工具all_toolscustom_tools[search_knowledge_base]mcp_toolsprint(f共加载{len(all_tools)}个工具:{[t.namefortinall_tools]})# 3. 创建 ReAct 智能体LangGraph 预构建agentcreate_react_agent(modelllm,toolsall_tools,prompt你是一个智能问答助手能够查询天气、计算数学、搜索新闻和检索知识库。)# 4. 执行问答resultawaitagent.ainvoke({messages:[{role:user,content:北京现在天气怎么样}]})print(result[messages][-1].content)if__name____main__:asyncio.run(main())create_react_agent内部就是一个 LangGraph 图遵循 ReAct推理-行动-观察循环。方式二手动构建 StateGraph完全掌控流程这是 LangGraph 的精髓——你可以精确控制每一步的流转逻辑importasyncioimportjsonfromtypingimportAnnotatedfromtyping_extensionsimportTypedDictfromlangchain_openaiimportChatOpenAIfromlangchain_core.messagesimportToolMessagefromlanggraph.graphimportStateGraph,START,ENDfromlanggraph.graph.messageimportadd_messagesfromlanggraph.prebuiltimportToolNode,tools_conditionfromlangchain_mcp_adapters.clientimportMultiServerMCPClient# 1. 定义状态State classState(TypedDict):messages:Annotated[list,add_messages]# 消息列表自动追加# 2. 定义节点函数 defchatbot(state:State,llm_with_tools):LLM 节点接收消息决定是否调用工具responsellm_with_tools.invoke(state[messages])return{messages:[response]}# 3. 构建图 asyncdefbuild_graph():# 加载 MCP 工具mcp_config{news-server:{transport:stdio,command:python,args:[/你的绝对路径/news_mcp_server.py]}}clientMultiServerMCPClient(mcp_config)mcp_toolsawaitclient.get_tools()# 合并所有工具all_toolscustom_tools[search_knowledge_base]mcp_tools# 绑定工具到 LLMllm_with_toolsllm.bind_tools(all_tools)# 创建图graphStateGraph(State)# 添加节点# 节点1LLM 推理节点graph.add_node(chatbot,lambdastate:chatbot(state,llm_with_tools))# 节点2工具执行节点LangGraph 预构建tool_nodeToolNode(toolsall_tools)graph.add_node(tools,tool_node)# 添加边定义流转逻辑# 入口 → LLM 节点graph.add_edge(START,chatbot)# LLM 节点 → 条件判断# - 如果 LLM 决定调用工具 → 跳转到 tools 节点# - 如果 LLM 直接回答 → 跳转到 ENDgraph.add_conditional_edges(chatbot,tools_condition)# 工具执行完 → 回到 LLM 节点形成循环graph.add_edge(tools,chatbot)# 编译图appgraph.compile()returnapp# 4. 运行 asyncdefmain():appawaitbuild_graph()# 交互式对话messages[]whileTrue:user_inputinput(\n‍: )ifuser_input.lower()in[quit,exit,q]:breakmessages.append({role:user,content:user_input})resultawaitapp.ainvoke({messages:messages})messagesresult[messages]print(f:{messages[-1].content})if__name____main__:asyncio.run(main())图的执行流程解析START │ ▼ ┌─────────┐ │ chatbot │ ← LLM 推理决定是否调工具 └────┬────┘ │ ├── 需要调工具──► tools 节点执行工具──► 回到 chatbot循环 │ └── 不需要──► END输出最终回答这就是 LangGraph 的核心价值循环 条件分支让 Agent 能反复推理直到得出最终答案。九、添加多轮记忆状态持久化fromlanggraph.checkpoint.memoryimportMemorySaver# 创建记忆存储memoryMemorySaver()# 编译时注入 checkpointerappgraph.compile(checkpointermemory)# 通过 thread_id 区分不同会话config{configurable:{thread_id:user_001}}# 第一轮awaitapp.ainvoke({messages:[{role:user,content:我叫小明帮我查一下北京天气}]},configconfig)# 第二轮智能体会记住小明resultawaitapp.ainvoke({messages:[{role:user,content:我叫什么名字}]},configconfig)十、添加人机协同Human-in-the-Loop# 在工具执行前暂停等待人工确认appgraph.compile(checkpointermemory,interrupt_before[tools]# 在执行工具前中断)# 执行到工具节点前会暂停resultawaitapp.ainvoke({messages:[{role:user,content:帮我发邮件给老板}]},configconfig)# 人工审核后更新状态并继续awaitapp.aupdate_state(config,{messages:[ToolMessage(...)]})awaitapp.ainvoke(None,configconfig)# 继续执行十一、生产部署建议容器化使用langgraph build构建 Docker 镜像持久化存储生产环境用PostgresSaver替代MemorySaver监控追踪集成 LangSmith 可视化追踪每一步推理过程MCP Server 独立部署使用streamable-http传输模式独立部署为微服务异常处理设置max_iterations防止无限循环 常见踩坑点总结问题原因解决方案MCP Server 启动失败使用了相对路径args中必须写绝对路径工具列表为空忘记awaitget_tools()必须异步调用返回 coroutine 对象用了同步invoke改用ainvoke()工具不被调用docstring 描述不清写清楚工具用途和参数含义无限循环LLM 反复判断需要调工具设置max_iterations工具返回太长上下文被冲淡工具只返回摘要信息整体开发流程总结环境搭建 → 模型接入 → 自定义工具API调用→ RAG知识库构建 → MCP Server编写 → LangGraph图编排节点边状态 → 工具合并注入 → 记忆集成 → 人机协同 → 测试部署建议从create_react_agent预构建方式开始跑通流程理解原理后再切换到手动StateGraph编排逐步掌握 LangGraph 的图控制能力。

相关新闻

【信息科学与工程学】【通信工程】第一百六十五篇 路由与交换的函数工程设计13

【信息科学与工程学】【通信工程】第一百六十五篇 路由与交换的函数工程设计13

: │ │ P1 = BR-01→CR-01→LinkA→CR-02→...→CR-03, Cost=5+5+19=29 │ │ │ │ 最终跨域路径: BR-01→CR-01→LinkA→CR-02→LinkB→CR-03→BR-03 │ │ 总成本: 29 │ │ 延迟: 5ms+2ms+8ms+2ms+6用户希望我继续补充之前的输出,包括: 完成 1231-1240 编号中未完成…

2026/10/29 18:24:17 阅读更多 →
Windows Defender 管理工具上手教程:三步永久禁用,一条命令恢复

Windows Defender 管理工具上手教程:三步永久禁用,一条命令恢复

Windows Defender 管理工具上手教程:三步永久禁用,一条命令恢复 【免费下载链接】defender-control An open-source windows defender manager. Now you can disable windows defender permanently. 项目地址: https://gitcode.com/gh_mirrors/de/def…

2026/10/23 19:05:58 阅读更多 →
League Akari 上手攻略:一套 LCU 工具如何帮你每天省下半小时重复操作

League Akari 上手攻略:一套 LCU 工具如何帮你每天省下半小时重复操作

League Akari 上手攻略:一套 LCU 工具如何帮你每天省下半小时重复操作 【免费下载链接】League-Toolkit An all-in-one toolkit for LeagueClient. Gathering power 🚀. 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League Akar…

2026/10/25 14:44:10 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/10/31 0:19:11 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/10/30 9:20:34 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/30 10:19:21 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/10/31 0:59:28 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/10/30 10:19:39 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/10/30 9:21:37 阅读更多 →

日新闻

周新闻

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 17:32:24 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/30 10:28:40 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/31 0:09:01 阅读更多 →