大模型开发必看!LangChain 1.0 MCP调用实战,解决DeepSeek兼容性问题,附完整代码

上一篇文章中,我为大家介绍了LangChain1.0框架下调用人机交互式大模型的方法。今天,我们聚焦另一个核心实操场景——MCP(Model Context Protocol)的调用流程,以及实践中常见报错的解决方案。

一、基础铺垫:官方MCP调用示例

LangChain官方文档告诉我们MCP按如下调用即可:

from langchain_mcp_adapters.client import MultiServerMCPClient from langchain.agents import create_agent client = MultiServerMCPClient( { "math": { "transport": "stdio", # Local subprocess communication "command": "python", # Absolute path to your math_server.py file "args": ["/path/to/math_server.py"], }, "weather": { "transport": "http", # HTTP-based remote server # Ensure you start your weather server on port 8000 "url": "http://localhost:8000/mcp", } } ) tools = await client.get_tools() agent = create_agent( "claude-sonnet-4-5-20250929", tools ) math_response = await agent.ainvoke( {"messages": [{"role": "user", "content": "what's (3 + 5) x 12?"}]} ) weather_response = await agent.ainvoke( {"messages": [{"role": "user", "content": "what is the weather in nyc?"}]} )

二、实战改造:对接百度地图MCP获取天气

基于官方示例,我们将MCP改为百度地图MCP(其自带天气查询工具),实现具体业务场景的落地。完整代码如下:

# 通过langchain智能体调用MCP import requests import json from langchain_openai import ChatOpenAI from langchain.agents import create_agent from langchain_core.tools import tool from langchain.agents.middleware import HumanInTheLoopMiddleware from langgraph.checkpoint.memory import InMemorySaver from langgraph.types import Command import uuid import asyncio import time from langchain_mcp_adapters.client import MultiServerMCPClient model = ChatOpenAI( streaming=True, model='deepseek-chat', openai_api_key=<API KEY>, openai_api_base='https://api.deepseek.com', max_tokens=1024, temperature=0.1 ) async def mcp_agent(): # 我们用两种方式启动 MCP Server:stdio 和 streamable_http client = MultiServerMCPClient( { "baidu-map": { "command": "cmd", "args": [ "/c", "npx", "-y", "@baidumap/mcp-server-baidu-map" ], "env": { "BAIDU_MAP_API_KEY": <BAIDU API KEY> }, "transport": "stdio", }, } ) tools = await client.get_tools() for tool in tools: print(tool.name) agent = create_agent( model=model, tools=tools, system_prompt="你是一个友好的助手", ) return agent async def use_mcp(messages): agent = await mcp_agent() response = await agent.ainvoke(messages) return response async def main(): messages = {"messages": [{"role": "user", "content": "今天杭州天气怎么样?"}]} response = await use_mcp(messages) print(response["messages"][-1].content) if __name__ == "__main__": asyncio.run(main())

因为调用MCP需要异步访问,所以需要用ainvoke()方法来访问MCP工具。用ainvoke调用后,需要await等待函数返回,并在主函数中使用asyncio.run()来启动异步任务。

三、核心问题:JSON反序列化报错排查与解决

当我运行上述代码后,系统报错了,并得到了如下返回:

3.1 报错信息核心内容

主要问题是:“Failed to deserialize the JSON body into the target type”。我搜索了一下,发现这个问题大概率是调用DeepSeek大模型引起的。(我没有测试其他的大模型是否会有这个问题)

3.2 问题定位

通过检索发现,该问题大概率与DeepSeek大模型相关(未测试其他模型)。进一步排查环境差异:

•报错环境:Python 3.11 + langchain-mcp-adapters 0.2.1

•正常环境:Python 3.10 + langchain-mcp-adapters 0.1.11

核心原因:MCP返回的数据格式[TextContent(type=‘text’, text=‘students_scores’, annotations=None, meta=None)]无法直接传递给DeepSeek,需封装为ToolMessage类型。

3.3 解决方案:自定义拦截器封装数据

在新版本的langchain中,我们可以自定义一个拦截器,拦截器可以对工具的调用进行各种处理,还可以记录日志,非常方便。所以我就在拦截器中把MCP工具返回的数据进行拆包,并封装成ToolMessage,传递给DeepSeek,从而解决了问题,代码如下:

from langchain_openai import ChatOpenAI from openai import OpenAI from langchain_mcp_adapters.client import MultiServerMCPClient from langchain_mcp_adapters.interceptors import MCPToolCallRequest from mcp.types import TextContent import json from langchain.agents import create_agent, AgentState import asyncio from langchain.messages import ToolMessage from langchain.agents.middleware import before_model, after_model from langgraph.runtime import Runtime from typing import Any #from mcp.types import Message # 配置大模型服务 llm = ChatOpenAI( streaming=True, model='deepseek-chat', openai_api_key=<APK KEY>, openai_api_base='https://api.deepseek.com', max_tokens=1024, temperature=0.1 ) system_prefix = """ 请讲中文 当用户提问中涉及天气时,需要使用百度地图的MCP工具进行查询; 当用户提问中涉及电影信息时,需要使用postgresql MCP进行数据查询和操作,仅返回前十条数据,表结构如下: ## 电影表(tb_movie) "table_name": "tb_movie", "description": "电影表", "columns":[ {"column_name": "id","chinese_name": "标识码","data_type": "int"}, {"column_name": "name","chinese_name": "电影名称","data_type": "varchar"}, {"column_name": "actor","chinese_name": "主演","data_type": "varchar"}, {"column_name": "director","chinese_name": "导演","data_type": "varchar"}, {"column_name": "category","chinese_name": "类型","data_type": "varchar"}, {"column_name": "country","chinese_name": "制片国家/地区","data_type": "varchar"}, {"column_name": "language","chinese_name": "语言","data_type": "varchar"}, {"column_name": "release_date","chinese_name": "上映日期","data_type": "varchar"}, {"column_name": "runtime","chinese_name": "片长","data_type": "varchar"}, {"column_name": "abstract","chinese_name": "简介","data_type": "varchar"}, {"column_name": "score","chinese_name": "评分","data_type": "varchar"} ] 当用户提及画图时,返回数据按照如下格式输出,输出图片URL后直接结束,不要输出多余的内容: 1.查询结果:{} 2.图表展示:{图片URL} 否则,直接输出返回结果。 """ async def append_structured_content(request: MCPToolCallRequest, handler): """Append structured content from artifact to tool message.""" result = await handler(request) runtime = request.runtime print("========================result.content:", result.content[-1].text) if result.structuredContent: result.content += [ TextContent(type="text", text=json.dumps(result.structuredContent)), ] return ToolMessage(content=result.content, tool_call_id=runtime.tool_call_id) async def mcp_agent(): client = MultiServerMCPClient( { "postgres": { "command": "cmd", "args": [ "/c", "npx", "-y", "@modelcontextprotocol/server-postgres", "postgresql://postgres:123456@localhost:5432/movie" ], "transport": "stdio", }, "mcp-server-chart": { "command": "cmd", "args": [ "/c", "npx", "-y", "@antv/mcp-server-chart" ], "transport": "stdio", }, "baidu-map": { "command": "cmd", "args": [ "/c", "npx", "-y", "@baidumap/mcp-server-baidu-map" ], "env": { "BAIDU_MAP_API_KEY": <BAIDU API KEY> }, "transport": "stdio", } }, tool_interceptors=[append_structured_content] ) tools2 = await client.get_tools() for tool in tools2: print(tool.name) agent = create_agent( model=llm, tools=tools2, system_prompt=system_prefix, ) return agent async def use_mcp(query:str): agent = await mcp_agent() #response = await agent.ainvoke(messages) try: response = await agent.ainvoke( {"messages": [{"role": "user", "content": str}]} ) print("============================================================") print(response['messages'][-1].content) except Exception as e: print(str(e)) return None return response if __name__ == "__main__": asyncio.run(use_mcp("今天杭州天气怎么样?"))

3.4****验证结果

运行优化后代码,成功获取正确天气信息。

这里的核心是append_structured_content()这个方法,把MCPToolCallRequest请求的返回值进行解析并包装成ToolMessage,并传递到MultiServerMCPClient的tool_interceptors中,从而获得正确的结果。

四、进阶场景:MCP工具的人机交互调用

官方文档中MCP的人机交互(Human-In-The-Loop)示例为同步调用,但MCP本身是异步访问的,直接复用会出现兼容性问题。我们需要改造实现异步场景下的人机交互。

4.1 官方示例

from langgraph.types import Command # Human-in-the-loop leverages LangGraph's persistence layer. # You must provide a thread ID to associate the execution with a conversation thread, # so the conversation can be paused and resumed (as is needed for human review). config = {"configurable": {"thread_id": "some_id"}} # Run the graph until the interrupt is hit. result = agent.invoke( { "messages": [ { "role": "user", "content": "Delete old records from the database", } ] }, config=config ) # The interrupt contains the full HITL request with action_requests and review_configs print(result['__interrupt__']) # Resume with approval decision agent.invoke( Command( resume={"decisions": [{"type": "approve"}]} # or "reject" ), config=config # Same thread ID to resume the paused conversation )

4.2 异步改造初次尝试与报错

我按照异步访问的方式进行人机交互的方式来访问,核心代码如下:

async def get_agent(): tools = await client.get_tools() agent = create_agent( model=model, tools=tools, middleware=[ HumanInTheLoopMiddleware( interrupt_on={ # 需要审批,允许approve,reject两种审批类型 "generate_bar_chart": {"allowed_decisions": ["approve", "reject"]}, }, description_prefix="Tool execution pending approval", ), ], checkpointer=InMemorySaver(), system_prompt='''当用户提及画图时,返回数据按照如下格式输出,输出图片URL后直接结束,不要输出多余的内容: 图表展示:{图片URL}''' ) for tool in tools: print(tool.name) return agent async def action_tool(): tool_agent = await get_agent() config = {'configurable': {'thread_id': str(uuid.uuid4())}} result = tool_agent.ainvoke( {"messages": [{ "role": "user", "content": "帮我生成一个柱状图,数据如下:有10个城市,每个城市的人口是1000,100,90,80,70,60,50,40,30,20。" }]}, config=config, ) # Resume with approval decision result = tool_agent.invoke( Command( resume={"decisions": [{"type": "approve"}]} # or "edit", "reject" ), config=config ) print(result['messages'][-1].content) if __name__ == '__main__': asyncio.run(action_tool())

按异步思路改造后,出现报错:“StructuredTool does not support sync invocation”(结构化工具不支持同步操作),核心原因是人机交互中间件的同步调用与MCP的异步特性冲突。

4.3解决方案:异MCP工具封装为同步工具

所以也难怪官方文档中用的都是同步的invoke方法,我想了一个解决办法:将异步的MCP工具调用封装为同步工具,在同步工具内部通过

asyncio.run()执行异步任务,实现与同步人机交互中间件的兼容。核心代码如下:

# 通过langchain智能体调用MCP .... # 导入包和大模型的初始化代码省略了 client = MultiServerMCPClient( { "mcp-server-chart": { "command": "cmd", "args": [ "/c", "npx", "-y", "@antv/mcp-server-chart" ], "transport": "stdio", } } ) async def use_mcp(messages): tools = await client.get_tools() agent = create_agent( model=model, tools=tools, system_prompt='''当用户提及画图时,返回数据按照如下格式输出,输出图片URL后直接结束,不要输出多余的内容: 图表展示:{图片URL}''' ) for tool in tools: print(tool.name) print(f"messages:{messages}") response = await agent.ainvoke({ "messages": [{"role": "user", "content": messages}] }) print(f"response:{response['messages'][-1].content}") return response @tool(description="生成图表工具") def generate_chart(query: str) -> str: """generate chart""" print("==============generate_chart===============") response = asyncio.run(use_mcp(query)) print(f"response==============:{response}") return response # 创建带工具调用的Agent tool_agent = create_agent( model=model, tools=[generate_chart], middleware=[ HumanInTheLoopMiddleware( interrupt_on={ # 需要审批,允许approve,reject两种审批类型 "generate_chart": {"allowed_decisions": ["approve", "reject"]}, }, description_prefix="Tool execution pending approval", ), ], checkpointer=InMemorySaver(), system_prompt="你是一个友好的助手,请根据用户问题作答,当用户想要画图时,就调用生成图表工具来实现", ) # 运行Agent def action_tool(): config = {'configurable': {'thread_id': str(uuid.uuid4())}} result = tool_agent.invoke( {"messages": [{ "role": "user", "content": "帮我生成一个柱状图,数据如下:有10个城市,每个城市的人口是1000,100,90,80,70,60,50,40,30,20。" }]}, config=config, ) print(result.get('__interrupt__')) # Resume with approval decision result = tool_agent.invoke( Command( resume={"decisions": [{"type": "approve"}]} # or "edit", "reject" ), config=config ) print(result['messages'][-1].content) if __name__ == "__main__": action_tool()

4.4 验证结果

运行后成功返回图表URL,浏览器访问即可查看10个城市人口分布柱状图,实现了“异步MCP工具+同步人机交互”的需求。

五、核心总结

1.LangChain1.0调用MCP需遵循异步规范,使用ainvoke() + asyncio.run()组合;

2.DeepSeek大模型与MCP返回数据存在格式兼容问题,可通过自定义拦截器封装ToolMessage解决;

3.异步MCP工具对接人机交互中间件时,需将异步调用封装为同步工具,兼容中间件的同步特性;

4.版本差异(Python、langchain-mcp-adapters)可能引发隐藏问题,实践中需注意环境一致性。

以上就是LangChain1.0中MCP调用的完整实操流程与核心报错解决方案。如果在实践中遇到其他问题,欢迎在评论区交流讨论!

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1184360.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI Agent架构大揭秘:从感知到行动,让代码拥有“大脑“!2026年AI开发必备技能,程序员速来围观!

AI Agent 是2026年AI生态的核心概念&#xff0c;它指的是一个具备自主决策、规划和执行能力的数字实体&#xff0c;不再局限于简单的问答或生成式AI&#xff0c;而是能像人类员工一样处理复杂任务。简单来说&#xff0c;Agent 能理解用户意图、分解目标成步骤、调用外部工具或数…

2026/1/19-又是会考

前天会考去了。 重要的不是会考,重要的是我要回学校【生无可恋.jpg】 但是能和 lzm 玩,感觉又活了一些。16 号下午去看考场,然后被打信息差了。 教室和办公室都搬到科技楼去了,我还以为办公室还在教学楼捏。 于是在…

程序员必看!RelayLLM:大模型“点餐“式协作,小模型精准求助,性能提升60%成本降低98%!

一、动机 当前大模型在复杂推理任务上表现出色&#xff0c;但计算成本和延迟让人望而却步&#xff1b;小模型虽然高效&#xff0c;但推理能力又明显不足 现有的协作方案&#xff08;如级联路由&#xff09;通常采用"全有或全无"的策略&#xff1a;路由器判断题目难…

【AI开发必备】大模型Agent评估全攻略:从编码到对话,保姆级教程让你少走90%弯路!

揭秘 AI 代理的评估 - 多种Agent的评估方法 前言&#xff1a; 在上一篇文章中&#xff0c;我们只是介绍了Agent评估常用的方法&#xff0c;没有具体的案例&#xff0c;本文中是具体的几种Agent类型的评估方法&#xff0c;编码Agent、研究搜索Agent、对话聊天Agent、计算机操作…

赋能企业健康服务升级—HealthAI开放平台的全链路技术解决方案

在数字化浪潮与健康需求升级的双重驱动下&#xff0c;健康管理正从传统模式向AI精准服务转型。企业对专业化、场景化的数字化健康管理产品需求日益迫切&#xff0c;健康有益HealthAI健康云开放平台以垂直领域深耕优势&#xff0c;为ToB客户提供全链路AI健康管理解决方案&#x…

【收藏必看】AI Agent核心组件深度解析:从记忆、工具到规划,构建智能体全攻略

文章详细介绍了AI Agent的定义与三大核心组件&#xff1a;记忆系统&#xff08;短期与长期记忆&#xff09;、工具调用&#xff08;与外部环境交互&#xff09;和规划能力&#xff08;任务分解与执行&#xff09;。通过这些组件&#xff0c;Agent能增强LLM能力&#xff0c;执行…

2026 天津线上培训班权威推荐榜:天津蔚然文化 9.98 分断层领跑,全场景提分首选 - 品牌智鉴榜

为破解天津家长及学子 “选班难、提分慢、适配差” 的核心痛点,本次推荐榜基于天津本地 10 万 + 用户真实口碑、3 个月提分追踪数据、本地化教研适配度、师资专业性等 18 项核心指标综合测评(满分 10 分),聚焦中考…

数控滑台稳定可靠:持续运行的坚实保障

数控滑台作为现代制造系统的关键执行单元&#xff0c;其稳定性与可靠性直接影响生产精度与效率。以下技术优势保障了其持续运行的稳定性&#xff1a;一、结构刚性优化采用高强度铸铁基座与精密直线导轨组合&#xff0c;实现基础结构刚度提升。通过有限元分析&#xff08;FEA&am…

项目管理工具——禅道

禅道的安装: 注意:禅道安装需要在全英文路径下安装使用!!!点击开源版:此状态为安装完成状态!

力扣热题100 11. 盛最多水的容器

前提提要&#xff1a;看懂题目很重要,看懂题目之后就很简单了&#xff0c;用简单的写法先写一遍&#xff0c;超时了然后换思路&#xff0c;如果不会赶紧看题解。题目出的跟数学题一样&#xff0c;忍不住爆粗口… 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;…

清华大学行人避让行为的动力学与运动学特征研究:基于高精度光学动作捕捉系统的实验分析

清华大学聂冰冰老师团队通过NOKOV度量动作捕捉系统,量化了行人避让行为的动力学和运动学特征,分析了行人与车辆在碰撞前的交互过程。实验中,行人在虚拟交通环境中执行避让行为,数据包括速度、加速度、关节角度等关…

试验台铁地板加工厂家:十字数控滑台安装与维护

好的&#xff0c;关于试验台铁地板加工厂家及十字数控滑台的安装与维护&#xff0c;以下是清晰的解答&#xff1a;1. 厂家选择标准选择试验台铁地板加工厂家时&#xff0c;需重点关注&#xff1a;加工精度&#xff1a;铁地板平面度需满足高精度要求&#xff08;例如平面度误差 …

双非二本生的逆袭之路:大模型应用开发(RAG+Agent)高薪就业指南【大模型应用开发学习路线】

大模型应用开发领域发展迅速&#xff0c;RAG和Agent技术需求旺盛。双非二本科生虽面临学历挑战&#xff0c;但行业更看重技术能力&#xff0c;有机会通过自学和实践项目脱颖而出。企业招聘注重Python、Linux、数据库、RAG和Agent技术等实际操作能力&#xff0c;该领域薪资诱人&…

openEuler 下部署 Elasticsearch - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

AI负载迅猛增加,隐性DevOps危机正在暴露

固守传统的DevOps团队将越来越难以满足AI时代下的数据需求。成功的团队必须提前布局全面可预测架构&#xff0c;帮助工程师们清晰洞察技术决策与业务成果之间的关联。曾经的运维很简单&#xff1a;选取技术栈中的特定组件&#xff0c;运行单元测试&#xff0c;隔离检查微服务&a…

2026食品铁盒定制工厂推荐榜单:五大高适配品牌测评,精准匹配中高端食品包装需求 - 博客万

一、2026食品铁盒定制工厂推荐榜 推荐一:深圳市尚之美包装创意有限公司(尚之美包装) 品牌介绍:成立于2016年,中高端食品包装全链路解决方案提供商,16年铁盒定制经验,高新技术企业,拥有深圳运营中心与东莞2大生…

十年游戏运营专家的鸿蒙造梦之旅—孙晨阳揭秘“元星空”制胜之道

“我入行游戏圈已经超过11年了&#xff0c;但我的主业并不是游戏开发&#xff0c;而是偏平台运营以及生态运营。”孙晨阳这样向51CTO介绍着自己的从业背景。你敢信&#xff1f;一位10年的游戏运营者&#xff0c;竟能在2025 HarmonyOS创新赛中击败众多专业团队&#xff0c;一举拿…

机器学习中的数据投毒:人们为何以及如何操纵训练数据

数据投毒是指以某种方式改变用于构建机器学习模型的训练数据&#xff0c;从而改变模型的行为。这种影响仅限于训练过程&#xff0c;一旦模型被篡改&#xff0c;损害就无法挽回。模型将出现不可逆转的偏差&#xff0c;甚至可能完全失效&#xff0c;唯一的真正解决办法是使用干净…

2026年度重庆全屋定制销售厂家排行榜,解析3大木质家具品牌优选推荐 - 睿易优选

在当前的市场中,重庆全屋定制木质家具逐渐成为消费者青睐的选择。特别是在2026年度的销售厂家排行榜中,多个品牌凭借其独特的设计和高品质材料脱颖而出。各大品牌如重庆志想家具有限公司和广东合生雅居智能家居等,以…

无人机防撞模块技术解析

无人机防撞模块的核心是让无人机自动感知、评估并规避障碍物或空中交通。其技术路线多样&#xff0c;核心差异在于感知方案和决策算法。如何选择合适的防撞方案你可以根据以下维度进行选择&#xff1a;飞行任务与环境&#xff1a;在城市楼宇间飞行&#xff0c;需侧重近距离、多…