掘金 人工智能 7小时前
LangGraph + MCP + Ollama 实战教程:打造强大的多智能体聊天机器人
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文介绍了如何利用模型上下文协议 (MCP) 、LangGraph 和 Ollama 构建一个强大的多智能体聊天机器人。MCP 作为开放标准,简化了 AI 工具与外部系统的连接。教程详细讲解了 MCP 的优势,以及函数调用与 MCP 的区别,并提供了代码示例,展示了如何使用 GitHub、Slack 等主流服务,实现 AI 自动搜索、生成报告和数据可视化等功能。通过该教程,读者可以深入理解 MCP 的应用,构建更灵活、强大的智能体应用。

🛠️ MCP 是一种开放标准,它简化了 AI 工具与外部系统的连接,提供标准化的接口,减少了集成代码的编写工作。

💡 函数调用模式适合定义明确、结构化的任务,而 MCP 模式更适合需要更大灵活性、多功能工具和跨交互上下文的复杂任务。

💻 本教程演示了如何结合 LangGraph、MCP 和 Ollama 构建多智能体聊天机器人,实现 AI 自动搜索信息、生成报告和编写数据可视化代码等功能。

⚙️ 系统架构的核心组件包括 LangGraph (管理智能体状态和工作流程)、MCP (标准化 AI 与外部工具的交互) 以及异步处理机制 (提升响应速度)。

✅ 教程详细介绍了代码实现,包括 agent.py、nodes.py 和 server.py 等模块,并阐述了消息流处理、错误处理和容错机制,确保系统的稳定性和可靠性。

最近,模型上下文协议 (Model Context Protocol, MCP) 在 AI 开发圈引起了不小的关注。这个由 Anthropic 推出的开放标准,被一些开发者称为"专为 AI 打造的 Zapier",也有人质疑它只是给 API 调用增加了不必要的复杂性。

实际上,MCP 解决了一个很实际的问题:在 MCP 出现之前,每当我们想让 AI 工具连接外部系统,都需要单独编写集成代码,每个 API 都要重新适配一遍。而 MCP 提供了标准化的接口,让这个过程变得简单很多。

虽然 MCP 相对较新,但发展势头很猛。LangChain 最近的一次社区投票显示:40.8% 的开发者认为 MCP 会成为未来标准,25.8% 认为它只是昙花一现,33.4% 还在观望。

目前 MCP 已经支持 GitHub、Slack、PostgreSQL 等众多主流服务,而且作为开放标准,它能与任何大语言模型 (Claude、OpenAI、Gemini 等) 配合使用。

本教程将手把手教你如何结合 LangGraph、MCP 和 Ollama,构建一个功能强大的多智能体聊天机器人。我们会通过实际案例展示这套技术栈的威力——比如让 AI 自动搜索最新信息生成报告,或者根据需求编写数据可视化代码。

学完这个教程,你将理解 MCP 和函数调用 (Function Call) 的区别、何时使用哪种方案,以及如何用 LangGraph、MCP 和开源工具创建强大的智能体聊天机器人。

MCP 和函数调用有什么区别?

在函数调用模式中,AI 就像一个按照严格脚本工作的熟练工人——它能填写表格、调用预定义工具,但只能使用已获得的工具,而且只能逐个调用。

而在 MCP 模式中,AI 更像一个拥有完整工具箱的智能体:它能在工具箱里翻找 (发现新工具)、组合使用不同工具、处理更复杂的任务,拥有更大的自主权。

函数调用与模型提示紧密绑定,需要开发者管理执行顺序,这让它很好控制但灵活性有限。

MCP 通过开放协议实现松散耦合,具有高度的灵活性和可扩展性,但需要精心设计来管理复杂性和确保安全性。接下来我们会深入介绍如何用 MCP 构建智能体,以及如何应对这种灵活性带来的挑战。

何时选择函数调用,何时选择 MCP?

选择哪种方案主要看具体用例:

选择函数调用的情况:

选择 MCP 的情况:

需要注意的是,这两种方法并不互斥——它们可以相互补充。比如,在 MCP 客户端内部可以使用函数调用来处理模型的结构化输出。

从概念上讲,函数调用专注于以可控方式将自然语言转换为函数执行,而 MCP 旨在为 AI 提供更广泛的接口来探索和操作环境。

开始编程实现

现在让我们逐步探索 MCP 应用的创建过程。首先安装必要的依赖库:

pip install -r requirements.txt

接下来导入相关库,这些库的重要性会在后续实现中逐渐体现:

langchain_mcp_adapters 负责将 MCP 工具转换为 LangChain 工具,提供客户端实现,让用户能连接多个 MCP 服务器并加载工具。

MCP 是标准化应用程序为大语言模型提供上下文的开放协议。

Googlesearch-python 是便于进行 Google 搜索的工具包。

# agent.pyfrom langchain_core.messages import AIMessage, ToolMessage, HumanMessagefrom langgraph.graph import StateGraph, START, END, MessagesStatefrom nodes import create_chatbotimport asyncioimport osimport dotenvfrom langchain_mcp_adapters.client import MultiServerMCPClient# main.pyimport streamlit as stimport asynciofrom agent import create_agentfrom langchain_core.messages import HumanMessage# nodes.pyfrom server import get_toolsfrom langgraph.graph import MessagesStatefrom langchain_openai import ChatOpenAIfrom langchain_ollama import ChatOllamafrom langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplatefrom datetime import datetimeimport os# server.pyfrom mcp.server.fastmcp import FastMCPfrom langchain_experimental.utilities import PythonREPLimport ioimport base64import matplotlib.pyplot as pltfrom openai import OpenAIfrom pydantic import BaseModel, Fieldimport osfrom dotenv import load_dotenvimport asynciofrom googlesearch import search

Agent.py 模块实现

在这个模块中,我们实现智能体的核心逻辑。create_agent 函数是一个异步过程,用于构建 AI 智能体。它接受可选的 docs_info 参数,为聊天机器人提供相关文档数据。

函数使用 MultiServerMCPClient 在异步上下文管理器中工作,确保与 MCP 服务器的无缝通信。服务器地址为 http://localhost:8000/sse,使用服务器发送事件 (SSE) 传输,超时设为 30 秒。

通过调用 client.get_tools() 获取 MCP 工具,启用高级功能。使用 MessagesState 构建 StateGraph 来管理对话状态,然后用 create_chatbot(docs_info) 创建聊天机器人节点。

async_tool_executor 负责动态处理工具调用。它接收包含对话消息列表的状态,提取最后一条消息检查工具调用。如果没有工具调用则直接返回,否则处理每个工具调用,提取工具名称、参数和 ID。

系统会搜索对应的工具,如果找不到就生成错误信息。找到工具后,判断是否为异步函数,相应地使用 await 或直接调用执行。所有错误都会被捕获并生成详细的错误信息。

async def create_agent(docs_info=None):    async with MultiServerMCPClient({        "server": {            "url": "http://localhost:8000/sse",            "transport": "sse",            "timeout": 30        }    }) as client:        tools = client.get_tools()        graph_builder = StateGraph(MessagesState)        chatbot_node = create_chatbot(docs_info)        graph_builder.add_node("chatbot", chatbot_node)                # 异步工具执行器实现        async def async_tool_executor(state):            # 工具调用处理逻辑            pass                # 添加工具节点和路由逻辑        graph_builder.add_node("tools", async_tool_executor)        # 路由器函数和边的添加        graph = graph_builder.compile()        return graph, client

Nodes.py 模块详解

这个模块包含聊天机器人的核心节点逻辑。get_system_prompt 函数动态生成系统提示,确保 AI 助手有清晰的工作指南和上下文感知能力。

函数首先格式化当前日期,然后定义助手的角色和能力。系统支持三个主要工具:generate_image (使用 DALL-E 生成图像)、data_visualization (用 matplotlib 创建图表) 和 python_repl (Python 代码执行环境)。

create_chatbot 函数处理用户输入并生成 AI 回应。它使用 ChatPromptTemplate 将系统指令与用户消息结合,创建无缝的处理链。函数确保消息格式一致性,维护结构化的对话历史。

def get_system_prompt(docs_info=None):    system_prompt = f"""    今天是 {datetime.now().strftime("%Y-%m-%d")}    你是一个有用的 AI 助手,可以使用这些工具:    - generate_image: 使用 DALL-E 根据提示生成图像    - data_visualization: 使用 Python 和 matplotlib 创建图表    - python_repl: 执行 Python 代码    """    return system_promptdef create_chatbot(docs_info=None):    prompt = ChatPromptTemplate.from_messages([        SystemMessagePromptTemplate.from_template(get_system_prompt(docs_info)),        HumanMessagePromptTemplate.from_template("{input}")    ])        chain = prompt | llm        def chatbot(state: MessagesState):        if isinstance(state["messages"], str):            messages = [HumanMessage(content=state["messages"])]        else:            messages = state["messages"]                    response = chain.invoke(messages)        return {"messages": messages + [response]}        return chatbot

Server.py 工具服务器实现

这个模块实现了多功能工具服务器。generate_image 工具使用 DALL-E 根据提示生成图像,确保提示有效后异步调用 OpenAI API。成功时返回图像 URL,失败时提供错误信息。

data_visualization 工具执行包含 matplotlib 的 Python 代码创建图表,将结果保存为 base64 编码的 PNG 图像。python_repl 工具提供 Python 代码的动态执行环境。

每个工具都设计了错误处理机制,向用户返回有意义的响应。get_tools 函数返回可用工具列表,确保只包含功能正常的工具。

@mcp.tool()async def generate_image(prompt: str) -> str:    """使用 DALL-E 根据提示生成图像"""    if not isinstance(prompt, str) or not prompt.strip():        raise ValueError("无效的提示")        try:        loop = asyncio.get_event_loop()        response = await loop.run_in_executor(            None,             lambda: client.images.generate(                model="dall-e-3",                prompt=prompt,                size="1024x1024",                quality="standard",                n=1            )        )                return f"成功生成了 {prompt} 的图像!URL:{response.data[0].url}"    except Exception as e:        return f"图像生成错误:{str(e)}"@mcp.tool()def data_visualization(code: str):    """执行 Python 代码,使用 matplotlib 进行可视化"""    try:        repl.run(code)        buf = io.BytesIO()        plt.savefig(buf, format='png')        buf.seek(0)        img_str = base64.b64encode(buf.getvalue()).decode()        return f"data:image/png;base64,{img_str}"    except Exception as e:        return f"图表创建错误:{str(e)}"def get_tools(retriever_tool=None):    base_tools = [generate_image, python_repl, data_visualization]    if retriever_tool:        base_tools.append(retriever_tool)    return base_toolsif __name__ == "__main__":    mcp.run(transport="sse")

Main.py 主程序入口

主程序实现异步智能体,处理用户输入并与工具动态交互。函数首先创建智能体和客户端,然后通过命令行获取用户输入,构造初始消息。

使用 agent.ainvoke() 异步调用智能体,处理请求和响应。根据消息类型打印不同内容,对图像生成结果进行特殊处理。所有异常都会被捕获并显示详细信息。

async def main():    agent, client = await create_agent()        user_input = input("您想问什么?")    initial_message = HumanMessage(content=user_input)        try:        print("正在处理您的请求...")        result = await agent.ainvoke({"messages": [initial_message]})                for message in result["messages"]:            if hasattr(message, "type") and message.type == "human":                print(f"用户:{message.content}")            elif hasattr(message, "type") and message.type == "tool":                print(f"工具结果:{message.content}")                if "image" in message.content.lower() and "url" in message.content.lower():                    print("图像生成成功!")            else:                print(f"AI:{message.content}")    except Exception as e:        print(f"错误:{str(e)}")if __name__ == "__main__":    asyncio.run(main())

系统架构和工作原理

核心组件说明

LangGraph 负责管理智能体的状态和工作流程,通过 StateGraph 定义节点和边来构建复杂的对话逻辑。每个节点代表一个处理步骤,边定义了节点间的转换条件。

MCP 作为开放协议,标准化了 AI 系统与外部工具的交互方式。它提供了发现、调用和管理工具的统一接口,让智能体能够动态使用各种功能。

异步处理机制确保系统能同时处理多个请求,提升响应速度和用户体验。工具执行器支持同步和异步工具,保证系统的兼容性和稳定性。

消息流处理

系统使用 MessagesState 管理对话状态,包含用户输入、AI 回复、工具调用和工具结果等各类消息。每条消息都有明确的类型和结构,便于系统识别和处理。

路由器根据最后一条消息的内容决定下一步操作。如果包含工具调用,就转到工具执行节点;否则结束对话或继续生成回复。这种设计让系统能灵活处理各种对话场景。

错误处理和容错机制

系统在多个层面实现了错误处理。工具执行时的异常会被捕获并转换为用户友好的错误信息。网络连接问题、API 调用失败等都有相应的处理逻辑。

超时机制防止系统无限等待外部服务响应。客户端连接管理确保资源的正确释放。这些措施保证了系统的稳定性和可靠性。

总结

通过本教程,我们深入探索了如何使用 LangGraph、MCP 和 Ollama 构建强大的多智能体聊天机器人。这套方案结合了最新的 AI 技术和开放标准,为构建智能应用提供了强大的基础。

MCP 作为新兴的开放协议,不仅仅是工具调用的升级版,更是 AI 系统架构的重大革新。它提供了标准化的接口,让 AI 系统能够灵活地连接各种数据源、工具和服务,大大简化了集成过程。

这种标准化的方法让现有的服务能够轻松地将自己的功能暴露给大语言模型使用,实现了 AI 与传统系统的无缝对接,无需对现有系统进行大幅修改。

随着 MCP 生态的不断发展,我们可以期待看到更多创新的应用和服务。对于开发者而言,掌握这些前沿技术将为在 AI 时代创造更大价值提供强有力的支撑。

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

MCP LangGraph Ollama 多智能体 聊天机器人
相关文章