MCP实战高阶:借助LangChain快速打造MCP天气助手

本文将进一步升级我们的实战案例,介绍如何借助LangChain的新开源项目langchain-mcp-adapters,让MCP集成变得更加简单高效。

img

一、LangChain MCP适配器简介

最近,LangChain发布了一个新的开源项目langchain-mcp-adapters[1],该项目为开发者提供了一种便捷的方式,将MCP (Model Control Protocol) 服务器无缝集成到LangChain生态系统中。

MCP是一种通信协议,允许大语言模型与外部工具和服务进行交互。而LangChain则是构建LLM应用的流行框架。langchain-mcp-adapters的出现,极大地简化了两者之间的集成过程,让开发者可以更专注于业务逻辑的实现,而非底层通信细节。

二、LangChain的ReAct Agent简介

在深入代码实现之前,有必要了解本案例中使用的核心技术——ReAct Agent。

ReAct Agent

ReAct (Reasoning and Acting) 是一种AI代理架构,它将大语言模型的推理能力与工具调用能力结合在一起。简单来说,ReAct允许AI模型:

  1. 思考问题 (Reasoning)
  2. 决定使用什么工具 (Planning)
  3. 执行工具调用 (Acting)
  4. 观察结果并更新思考 (Observation)

在LangChain中,create_react_agent函数提供了一种便捷方式来创建这样的代理。它接收三个关键参数:

  • model:用于推理的语言模型
  • tools:可供代理使用的工具列表
  • prompt:引导代理行为的系统提示

这种方式构建的代理能够分析用户问题,规划并执行多步骤工具调用,最终整合信息为用户提供完整答案。

三、代码实现

下面,我们通过一个完整的天气信息助手案例,展示如何使用langchain-mcp-adapters和ReAct Agent构建智能应用。

1. 项目结构设计

本项目采用面向对象的设计思路,主要包含三个核心类:

  • Configuration:负责环境变量管理和配置验证
  • MCPServer:处理MCP服务器的连接与工具管理
  • MCPClient:整合DeepSeek模型与MCP服务,提供用户交互接口

2. 核心代码实现

首先导入必要的库:

import asyncio
import logging
import os
from contextlib import AsyncExitStack
from typing import List, Optional

from dotenv import load_dotenv
from langchain_core.messages import SystemMessage 
from langchain_core.tools import BaseTool
from langchain_mcp_adapters.tools import load_mcp_tools
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

配置类用于管理环境变量:

class Configuration:
    """配置管理类,负责管理和验证环境变量"""
    
    def__init__(self) -> None:
        """初始化配置并加载环境变量"""
        self.load_env()
        self._validate_env()
        
    @staticmethod
    defload_env() -> None:
        """从.env文件加载环境变量"""
        load_dotenv()
        
    def_validate_env(self) -> None:
        """验证必需的环境变量是否存在"""
        required_vars = ["DEEPSEEK_API_KEY"]
        missing_vars = [var for var in required_vars ifnot os.getenv(var)]
        if missing_vars:
            raise ValueError(f"缺少必需的环境变量: {', '.join(missing_vars)}")
    
    @property
    defapi_key(self) -> str:
        """获取 DeepSeek API 密钥"""
        return os.getenv("DEEPSEEK_API_KEY", "")
    
    @property
    defbase_url(self) -> str:
        """获取 DeepSeek API 基础 URL"""
        return os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com")
    
    @property
    defmodel(self) -> str:
        """获取 DeepSeek 模型名称"""
        return os.getenv("DEEPSEEK_MODEL", "deepseek-chat")

MCP服务器类处理与天气服务的通信:

class MCPServer:
    """MCP 服务器管理类,处理服务器连接和工具执行"""
    def__init__(self, server_path: str) -> None:
        """
        初始化服务器管理器
        
        Args:
            server_path: 服务器脚本路径
        """
        self.server_path = server_path
        self.session: Optional[ClientSession] = None
        self.exit_stack = AsyncExitStack()
        self._cleanup_lock = asyncio.Lock()

    asyncdefinitialize(self) -> None:
        """初始化服务器连接,包含重试机制"""
        max_retries = 3
        retry_delay = 1.0
        
        for attempt inrange(max_retries):
            try:
                ifnot os.path.exists(self.server_path):
                    raise FileNotFoundError(f"找不到服务器文件: {self.server_path}")
                
                server_params = StdioServerParameters(
                    command='python',
                    args=[self.server_path],
                    env=None
                )
                
                stdio_transport = awaitself.exit_stack.enter_async_context(
                    stdio_client(server_params)
                )
                stdio, write = stdio_transport
                
                self.session = awaitself.exit_stack.enter_async_context(
                    ClientSession(stdio, write)
                )
                awaitself.session.initialize()
                logger.info("成功连接到 MCP 服务器")
                break
                
            except Exception as e:
                logger.error(f"第 {attempt + 1}/{max_retries} 次尝试失败: {str(e)}")
                if attempt < max_retries - 1:
                    await asyncio.sleep(retry_delay)
                else:
                    raise

    asyncdeflist_tools(self) -> List[BaseTool]:
        """获取服务器提供的可用工具列表"""
        ifnotself.session:
            raise RuntimeError("服务器未初始化")
        # LangChain方式获取可用工具列表
        tools = await load_mcp_tools(self.session)
        logger.info(f"成功加载工具: {[tool.name for tool in tools]}")
        return tools

    asyncdefcleanup(self) -> None:
        """清理服务器资源"""
        asyncwithself._cleanup_lock:
            try:
                awaitself.exit_stack.aclose()
                self.session = None
                logger.info("服务器资源清理完成")
            except Exception as e:
                logger.error(f"清理过程中出错: {str(e)}")

客户端类整合模型与MCP服务:

class MCPClient:
    """MCP 客户端实现,集成了 DeepSeek API"""
    
    def__init__(self, config: Configuration) -> None:
        """
        初始化 MCP 客户端
        
        Args:
            config: 配置对象
        """
        self.config = config
        self.server: Optional[MCPServer] = None
        self.llm_client = ChatOpenAI(
            api_key=config.api_key,
            base_url=config.base_url,
            model=config.model
        )
        
    asyncdefinitialize(self) -> None:
        """初始化客户端并连接到服务器"""
        server_path = os.path.join(
            os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
            "server",
            "weather_server.py"
        )
        self.server = MCPServer(server_path)
        awaitself.server.initialize()
        
    asyncdefprocess_query(self, query: str):
        """
        处理用户查询,集成工具调用,支持多轮工具交互

        Args:
            query: 用户查询字符串

        Returns:
            处理后的响应结果
        """
        ifnotself.server:
            raise RuntimeError("客户端未初始化")

        # 创建提示模板
        prompt = SystemMessage(content="""你是一个专注于天气信息的助手...(详细系统提示内容)""")
        
        # 获取工具
        tools = awaitself.server.list_tools()

        # 创建ReAct Agent
        logger.info("正在创建agent...")
        agent = create_react_agent(
            model=self.llm_client,  
            tools=tools,
            prompt=prompt
        )
        logger.info("Agent创建成功")

        # 发送查询
        logger.info("正在发送天气查询...")
        agent_response = await agent.ainvoke({
            "messages": query
        })

        # 返回响应
        return agent_response

3. 核心技术要点解析

工具加载与集成

通过langchain-mcp-adapters提供的load_mcp_tools函数,我们可以将MCP服务器中的工具转换为LangChain可识别的BaseTool对象:

tools = await load_mcp_tools(self.session)

这行代码是整个集成的关键,它自动处理了MCP工具到LangChain工具的转换过程,使我们不必手动实现适配逻辑。

ReAct Agent的创建

使用create_react_agent函数创建代理:

agent = create_react_agent(
    model=self.llm_client,  
    tools=tools,
    prompt=prompt
)

这个函数接收三个关键参数:

  • model:我们使用的DeepSeek模型
  • tools:从MCP服务器加载的工具列表
  • prompt:引导代理行为的系统提示

创建的agent对象能够接受用户查询,分析需求,规划并执行工具调用,最终返回整合后的结果。

四、运行效果展示

下面是一个实际使用案例:

用户查询:

最近一周郑州有没有高温或大风预警?周末适合户外活动吗?

系统日志:

2025-05-04 19:10:36,485 - INFO - 成功加载工具: ['get_weather_warning', 'get_daily_forecast']
2025-05-04 19:10:36,485 - INFO - 正在创建agent...
2025-05-04 19:10:36,494 - INFO - Agent创建成功
2025-05-04 19:10:36,494 - INFO - 正在发送天气查询...

Agent响应:

### 郑州近期天气情况:

1. **天气预警**:
   - **大风蓝色预警**:河南省气象台于2025年5月4日发布大风蓝色预警,预计5月5日至6日郑州及周边地区将出现大风天气,阵风可达8-9级,局部10-11级,并伴有扬沙或浮尘。请注意防范。

2. **未来一周天气预报**:
   - **5月4日(今天)**:多云,最高27°C,最低18°C。
   - **5月5日(明天)**:多云转晴,最高31°C,最低17°C,风力较大(西风1-3级)。
   - **...(其他日期天气)**
   - **5月10日(周六)**:晴转多云,最高30°C,最低17°C。

### 周末户外活动建议:
- **周六(5月10日)**:天气晴朗,最高气温30°C,风力较小(西风1-3级),适合户外活动。但请注意防晒和补水。
- **周日(5月11日)**:未提供具体预报,建议关注后续更新。

**注意**:目前有大风预警,尤其是5月5日至6日风力较大,建议避免高空或水上活动,并注意防风防尘。周末天气较为稳定,适合安排户外活动。

从上述案例可以看出,系统成功地:

  1. 识别出用户询问的是天气预警和周末户外活动适宜性
  2. 调用get_weather_warning工具获取预警信息
  3. 调用get_daily_forecast工具获取未来天气预报
  4. 整合信息,分析天气状况,并给出周末户外活动建议

五、技术优势与应用场景

技术优势

  1. 简化的MCP集成langchain-mcp-adapters大幅简化了MCP与LangChain的集成流程,开发者无需手动处理协议转换。
  2. 灵活的Agent架构:ReAct模式使模型能够自主规划工具调用路径,处理复杂多步骤任务。
  3. 可扩展性:基于此架构,可以轻松添加新的工具和功能,而无需大幅修改核心代码。
  4. 可靠的异常处理:代码中包含完善的错误处理和重试机制,提高了系统的稳定性。

应用场景

  1. 智能客服系统:集成企业内部API,构建能够回答产品、订单、物流等问题的智能客服。
  2. 个人助理:连接日历、邮件、任务管理等工具,创建全功能个人助理。
  3. 数据分析助手:集成数据库查询、数据处理工具,构建交互式数据分析助手。
  4. 企业知识管理:连接企业内部知识库、文档系统,构建智能知识检索与问答系统。

六、总结与展望

通过本文的实践,我们不仅展示了如何利用langchain-mcp-adapters简化MCP服务的集成,更展示了如何基于ReAct模式构建智能代理系统。这种方法相比传统的固定流程工具调用,更加灵活和智能,能够根据用户需求动态规划执行路径。

未来,随着大语言模型能力的提升和工具生态的丰富,基于此架构的应用将变得更加强大。企业可以基于此框架,快速构建各类垂直领域的智能助手,提升服务效率和用户体验。

那么,如何系统的去学习大模型LLM?

作为一名从业五年的资深大模型算法工程师,我经常会收到一些评论和私信,我是小白,学习大模型该从哪里入手呢?我自学没有方向怎么办?这个地方我不会啊。如果你也有类似的经历,一定要继续看下去!这些问题啊,也不是三言两语啊就能讲明白的。

所以我综合了大模型的所有知识点,给大家带来一套全网最全最细的大模型零基础教程。在做这套教程之前呢,我就曾放空大脑,以一个大模型小白的角度去重新解析它,采用基础知识和实战项目相结合的教学方式,历时3个月,终于完成了这样的课程,让你真正体会到什么是每一秒都在疯狂输出知识点。

由于篇幅有限,⚡️ 朋友们如果有需要全套 《2025全新制作的大模型全套资料》,扫码获取~
在这里插入图片描述

👉大模型学习指南+路线汇总👈

我们这套大模型资料呢,会从基础篇、进阶篇和项目实战篇等三大方面来讲解。
在这里插入图片描述
在这里插入图片描述

👉①.基础篇👈

基础篇里面包括了Python快速入门、AI开发环境搭建及提示词工程,带你学习大模型核心原理、prompt使用技巧、Transformer架构和预训练、SFT、RLHF等一些基础概念,用最易懂的方式带你入门大模型。
在这里插入图片描述

👉②.进阶篇👈

接下来是进阶篇,你将掌握RAG、Agent、Langchain、大模型微调和私有化部署,学习如何构建外挂知识库并和自己的企业相结合,学习如何使用langchain框架提高开发效率和代码质量、学习如何选择合适的基座模型并进行数据集的收集预处理以及具体的模型微调等等。
在这里插入图片描述

👉③.实战篇👈

实战篇会手把手带着大家练习企业级的落地项目(已脱敏),比如RAG医疗问答系统、Agent智能电商客服系统、数字人项目实战、教育行业智能助教等等,从而帮助大家更好的应对大模型时代的挑战。
在这里插入图片描述

👉④.福利篇👈

最后呢,会给大家一个小福利,课程视频中的所有素材,有搭建AI开发环境资料包,还有学习计划表,几十上百G素材、电子书和课件等等,只要你能想到的素材,我这里几乎都有。我已经全部上传到CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费
在这里插入图片描述
相信我,这套大模型系统教程将会是全网最齐全 最易懂的小白专用课!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值