ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

LangChain架构演进:基于MCP与LangGraph构建现代化AI智能体

LangChain架构演进:基于MCP与LangGraph构建现代化AI智能体 如果你最近关注AI应用开发可能会发现一个现象很多教程还在教你用LangChain的旧版API写Agent但GitHub上活跃的项目和最新的官方文档已经悄悄转向了一套更模块化、更工程化的新范式。你跟着旧教程写的代码跑不通查错时发现一堆DeprecationWarning而社区讨论的热词变成了MCP、LangGraph、StateGraph——这感觉就像刚学会开车却发现地图已经更新了。问题就在这里LangChain生态正在经历一次重要的架构演进其核心是从一个“大而全”的链条转向“核心编排框架 标准化工具协议”的松散耦合模式。对于开发者而言这意味着学习路径和最佳实践都变了。继续用老方法不仅效率低还会错过新架构带来的核心优势更强的可控性、更清晰的边界和更好的团队协作能力。本文不会重复那些随处可见的“Hello World”示例。我们将直接切入当前2024年最值得投入学习的实战组合新版LangChain MCP (Model Context Protocol) LangGraph。我会手把手带你完成环境搭建、概念理解并最终实现一个具备长期记忆和复杂工作流能力的本地AI智能体Agent。无论你是想快速上手一个新项目还是希望将现有AI功能升级到更健壮的架构这篇文章都能提供一条清晰的路径。1. 为什么是“新版LangChainMCPLangGraph”在深入代码之前我们必须先理清一个关键问题为什么是这三个技术的组合它们分别解决了什么痛点LangChain新版它已经从一个“什么都管”的框架演变为AI应用编排的核心引擎。它的新定位是轻量、灵活专注于管理提示词Prompt、连接大模型LLM、调用工具Tools以及最重要的——状态管理。它不再试图内置所有功能而是通过标准接口去集成。MCP (Model Context Protocol)这是解决“工具爆炸”和“上下文污染”问题的关键。以前要给Agent加功能比如查数据库、调用API你需要写Python代码将其包装成LangChain Tool然后硬编码到Agent中。这导致Agent的上下文Context越来越臃肿且工具难以复用和共享。MCP定义了一个标准化的工具协议让工具如计算器、文件读写、网络搜索能以独立服务Server的形式存在。Agent通过MCP客户端按需发现和调用它们实现了工具与Agent逻辑的彻底解耦。LangGraph这是构建复杂、有状态Agent的“大脑”。传统的LangChain Agent执行链是线性的难以处理需要循环、分支、并行或长期记忆的任务。LangGraph引入了图Graph计算模型你可以将Agent的每一步如“思考”、“执行工具”、“判断”定义为一个节点Node用边Edge控制流程走向。它内置了状态管理使得构建像AutoGPT那样的多步规划Agent变得异常清晰。组合起来看新版LangChain负责最基础的LLM交互和提示管理MCP提供了丰富、可插拔的“技能包”LangGraph则用流程图的方式设计和执行复杂的“任务剧本”。这个组合正是开篇提到的从“链条”到“框架协议引擎”演进的具体体现。接下来我们从零开始搭建这个现代化的AI智能体开发环境。2. 环境准备与核心工具安装我们将创建一个干净的Python虚拟环境并安装所有必要的依赖。请确保你的系统已安装Python 3.10或更高版本。2.1 创建并激活虚拟环境使用虚拟环境是Python项目的最佳实践可以避免包依赖冲突。# 创建项目目录并进入 mkdir modern-ai-agent cd modern-ai-agent # 创建虚拟环境这里使用venv你也可以用conda python -m venv .venv # 激活虚拟环境 # 在Windows上 .venv\Scripts\activate # 在macOS/Linux上 source .venv/bin/activate激活后你的命令行提示符前应该会出现(.venv)字样。2.2 安装核心依赖我们将安装LangChain、LangGraph、MCP客户端以及一个本地大模型运行框架这里选用Ollama它轻量且支持多种开源模型。# 安装LangChain核心包和社区包包含MCP集成 pip install langchain langchain-community # 安装LangGraph用于构建有状态的智能体工作流 pip install langgraph # 安装MCP客户端库用于连接MCP工具服务器 # 注意官方MCP SDK正在快速迭代以下是最常见的安装方式 pip install mcp[cli] # 安装mcp及其命令行工具 # 安装Ollama的LangChain集成包用于调用本地模型 pip install langchain-ollama # 安装Ollama本体用于在本地运行大模型 # 访问 https://ollama.com/ 下载并安装对应操作系统的Ollama # 安装后在终端运行 ollama 命令应能显示帮助信息2.3 启动本地大模型服务OllamaOllama允许我们在本地无GPU或轻量GPU上运行如Llama 3、Mistral等开源模型。# 1. 首先确保Ollama服务已启动安装后通常会自动运行 # 可以通过以下命令检查或启动 ollama serve # 或者直接运行它会保持在前台运行 # 2. 拉取一个适合对话和推理的轻量模型例如Llama 3.1 8B ollama pull llama3.1:8b # 如果你内存有限可以尝试更小的模型如 phi3:mini # ollama pull phi3:mini拉取完成后模型就准备好了。我们可以通过简单的Python代码测试连接是否正常。2.4 验证环境与本地模型对话创建一个测试文件test_env.py# test_env.py from langchain_ollama import OllamaLLM from langchain_core.prompts import ChatPromptTemplate # 1. 初始化本地LLM指定我们刚拉取的模型 llm OllamaLLM(modelllama3.1:8b) # 2. 创建一个简单的提示词模板 prompt ChatPromptTemplate.from_messages([ (system, 你是一个乐于助人的AI助手。), (user, {input}) ]) # 3. 将提示词和模型组合成链 chain prompt | llm # 4. 调用链并打印结果 response chain.invoke({input: 请用一句话介绍你自己。}) print(模型回复, response)运行这个脚本python test_env.py如果看到模型返回了一句自我介绍如“我是由Meta开发的Llama 3.1 AI助手...”恭喜你基础环境已就绪。如果遇到连接错误请检查Ollama服务是否正在运行ollama list命令可以列出已拉取的模型。3. 理解MCP将工具变为可插拔的“技能”MCP是本次实战中最关键的新概念。让我们用一个类比来理解它传统的Agent工具开发像是给电脑装内置软件而MCP则是让电脑通过USB接口连接外部设备。在没有MCP时一个能查天气、算数学的Agent其代码结构可能是这样的# 传统方式工具硬编码在Agent内部 from langchain.agents import Tool def get_weather(city): # 模拟天气查询 return f{city}的天气是晴天25°C。 def calculate(expression): # 模拟计算 return eval(expression) weather_tool Tool(nameWeather, funcget_weather, description查询城市天气) calc_tool Tool(nameCalculator, funccalculate, description计算数学表达式) # 然后把这些tools塞进Agent的初始化参数里这种方式的问题很明显工具逻辑和Agent核心逻辑强耦合增加新工具需要修改代码并重启服务工具难以跨项目复用。MCP的解决方案工具作为独立服务每个工具如计算器、文件浏览器、SQL查询器都是一个独立的MCP服务器Server。标准化的通信协议MCP定义了Server和Client如你的LangChain Agent之间如何发现工具、描述工具、调用工具、传递结果的JSON-RPC协议。动态发现与调用Agent启动时可以连接一个或多个MCP Server动态获取可用的工具列表。当需要时通过协议调用这些工具无需预先编码。3.1 启动你的第一个MCP工具服务器MCP社区已经有很多现成的工具服务器。我们从最简单的“标准输入/输出”stdio和“计算器”calculator服务器开始体验。首先安装一些常用的MCP服务器实现。MCP生态的包名通常以mcp-server-开头。# 安装一个提供基础工具如时钟、随机数、计算器的MCP服务器 pip install mcp-server-cli实际上更常见的做法是直接使用MCP官方或社区维护的独立服务器。为了快速体验我们可以使用一个简单的Python脚本模拟一个计算器MCP服务器。但请注意生产环境通常会使用更稳定的实现。下面我们将直接进入LangGraph学习如何在其工作流中集成MCP工具。因为从LangGraph的视角去理解MCP的调用会更加直观。4. 构建核心用LangGraph设计智能体工作流LangGraph的核心是状态State和图Graph。我们通过定义状态的结构、图的节点和边来构建一个可控的、有记忆的智能体。4.1 定义智能体的状态状态是一个字典或Pydantic模型它记录了智能体在整个对话或任务执行过程中的所有信息。典型的智能体状态可能包括messages: 对话历史消息列表。next: 指示下一步应该执行哪个节点。sender: 当前消息的发送者用于多角色协作。scratchpad: 智能体思考的中间步骤记录。我们来定义一个基础状态# agent_state.py from typing import TypedDict, Annotated, List from langchain_core.messages import BaseMessage import operator class AgentState(TypedDict): 定义智能体的状态结构 # 消息历史记录用户、AI、工具的所有消息 messages: Annotated[List[BaseMessage], operator.add] # 下一步动作用于控制流程走向 next: strAnnotated[List[BaseMessage], operator.add]是一个高级用法它告诉LangGraph当多个节点并行修改messages字段时使用operator.add即列表的操作来合并结果而不是覆盖。这确保了对话历史的完整性。4.2 创建图Graph并定义节点一个最简单的智能体工作流通常包含两个核心节点agent负责思考和tools负责执行工具。它们之间通过条件边conditional edge连接。# build_graph.py from langgraph.graph import StateGraph, END from langchain_ollama import OllamaLLM from langchain_core.prompts import ChatPromptTemplate from langchain_core.messages import HumanMessage, AIMessage, ToolMessage from langchain.tools import Tool from .agent_state import AgentState # 导入上面定义的状态 # 1. 初始化大模型 llm OllamaLLM(modelllama3.1:8b) # 2. 创建几个模拟的本地工具后续会替换为MCP工具 def search_web(query: str) - str: 模拟网络搜索。在实际中这里会调用Serper API或Google Search API。 return f根据网络搜索关于{query}的信息是这是一个模拟搜索结果。知识截止日期为2023年10月。 def calculate(expression: str) - str: 模拟计算器。注意实际应用中应使用安全评估避免eval。 try: # 警告生产环境切勿使用eval此处仅为演示。 result eval(expression) return f计算结果{expression} {result} except Exception as e: return f计算错误{e} # 将函数包装成LangChain Tool对象 tools [ Tool(nameWebSearch, funcsearch_web, description用于搜索互联网上的最新信息。输入应为搜索查询词。), Tool(nameCalculator, funccalculate, description用于计算数学表达式。输入应为如 2 3 * 4 的字符串。), ] # 3. 将工具绑定到大模型上让模型知道它可以调用哪些工具 llm_with_tools llm.bind_tools(tools) # 4. 定义提示词模板 system_prompt 你是一个专业的AI助手可以调用工具来帮助用户解决问题。 你可以使用的工具如下 {tools_descriptions} 请根据用户的问题决定是否需要调用工具以及调用哪个工具。 如果你决定调用工具请严格按照工具要求的格式提供输入。 工具返回结果后我会将结果提供给你请你综合所有信息给出最终回答。 prompt ChatPromptTemplate.from_messages([ (system, system_prompt), (placeholder, {messages}), # 这是一个占位符会被实际的消息历史替换 ]) # 5. 定义 agent 节点负责思考并决定下一步 def agent_node(state: AgentState): 接收当前状态调用大模型返回模型的决定可能是回复消息或工具调用请求。 # 格式化提示词将工具描述插入系统提示 formatted_prompt prompt.invoke({ tools_descriptions: \n.join([f- {tool.name}: {tool.description} for tool in tools]), messages: state[messages] }) # 调用绑定了工具的模型 response llm_with_tools.invoke(formatted_prompt) # 将模型的响应添加到消息历史中 return {messages: [response], next: tools} # 默认下一步去执行工具检查 # 6. 定义 tools 节点执行模型要求的工具调用 def tools_node(state: AgentState): 检查上一条消息是否是工具调用请求如果是则执行工具。 last_message state[messages][-1] tool_messages [] # 判断上一条消息是否包含工具调用AIMessage的tool_calls属性 if hasattr(last_message, tool_calls) and last_message.tool_calls: for tool_call in last_message.tool_calls: tool_name tool_call[name] tool_args tool_call[args] # 根据工具名找到对应的Tool对象 tool_to_use next((t for t in tools if t.name tool_name), None) if tool_to_use: # 执行工具 result tool_to_use.invoke(tool_args) # 创建工具执行结果消息 tool_message ToolMessage(contentstr(result), tool_call_idtool_call[id]) tool_messages.append(tool_message) else: # 如果工具不存在返回错误信息 error_msg ToolMessage(contentf错误工具 {tool_name} 未找到。, tool_call_idtool_call[id]) tool_messages.append(error_msg) # 如果没有工具调用则直接传递消息 if not tool_messages: tool_messages [last_message] # 决定下一步如果有工具调用结果应该让agent再次思考否则可以结束。 next_step agent if tool_messages and tool_messages[0].tool_call_id else END return {messages: tool_messages, next: next_step} # 7. 构建图 workflow StateGraph(AgentState) # 添加节点 workflow.add_node(agent, agent_node) workflow.add_node(tools, tools_node) # 设置入口点 workflow.set_entry_point(agent) # 添加边从agent到tools workflow.add_edge(agent, tools) # 添加条件边从tools出来根据状态中的next字段决定去向 workflow.add_conditional_edges( tools, # 这是一个路由函数根据当前状态返回下一个节点名 lambda state: state[next], { agent: agent, # 如果next是agent则跳回agent节点 END: END # 如果next是END则结束图执行 } ) # 编译图得到一个可执行的对象 app workflow.compile()这段代码构建了一个基础但完整的智能体循环Agent思考 - 调用工具 - 返回结果 - Agent再次思考 - ...直到模型认为不需要再调用工具最终给出答案。4.3 运行并测试智能体现在让我们运行这个智能体问它一个需要组合使用工具的问题。# run_agent.py from build_graph import app # 导入上面编译好的图应用 from langchain_core.messages import HumanMessage # 初始化对话历史从用户问题开始 initial_state { messages: [HumanMessage(content请先搜索Python的最新版本然后用计算器算一下它的版本号假设是3.11的平方是多少)], next: agent } # 运行图应用 final_state app.invoke(initial_state) # 打印所有消息 print( 完整的对话历史 ) for msg in final_state[messages]: print(f{type(msg).__name__}: {msg.content})运行python run_agent.py你会看到类似以下的输出具体内容因模型而异 完整的对话历史 HumanMessage: 请先搜索Python的最新版本然后用计算器算一下它的版本号假设是3.11的平方是多少 AIMessage: 我需要先搜索Python的最新版本然后进行计算。我将调用WebSearch工具。 ToolMessage: 根据网络搜索关于Python的最新版本的信息是这是一个模拟搜索结果。知识截止日期为2023年10月。 AIMessage: 搜索结果显示信息是模拟的。根据假设版本号是3.11。现在我将调用Calculator计算3.11的平方。 ToolMessage: 计算结果3.11 ** 2 9.6721 AIMessage: 根据假设Python版本号3.11的平方是9.6721。这个输出清晰地展示了智能体的思考过程它先决定搜索得到模拟结果后再决定计算最后综合信息给出答案。这就是LangGraph管理的有状态工作流。5. 关键升级将硬编码工具替换为MCP工具前面的例子中工具WebSearch,Calculator是硬编码在Python代码里的。现在我们将其升级为通过MCP协议调用。假设我们已经有一个运行在本地http://localhost:8080的MCP服务器它提供了计算器功能。步骤1连接MCP服务器并获取工具列表我们需要使用MCP客户端库来发现工具。这里我们使用一个模拟的MCP客户端函数来演示概念。# mcp_integration.py import json # 假设我们已经有了一个MCP客户端实例 mcp_client # 在实际中你可能使用 mcp.Client 来建立连接 def get_mcp_tools(mcp_server_urlhttp://localhost:8080): 模拟从MCP服务器获取工具列表。 # 真实代码示例概念性 # async with mcp.Client(mcp_server_url) as client: # tools await client.list_tools() # return tools # 为了演示我们返回一个模拟的工具列表结构与LangChain Tool兼容 mock_tools [ { name: mcp_calculator, description: 一个通过MCP协议提供的安全计算器支持基本算术运算。, input_schema: { type: object, properties: { expression: {type: string, description: 数学表达式如 2 3 * 4} }, required: [expression] } }, { name: mcp_clock, description: 获取当前日期和时间。, input_schema: { type: object, properties: {}, required: [] } } ] return mock_tools def create_langchain_tool_from_mcp(mcp_tool_def): 将一个MCP工具定义转换为LangChain Tool对象。 from langchain.tools import Tool import requests # 假设通过HTTP调用MCP服务器 def mcp_tool_func(**kwargs): # 模拟调用MCP服务器 # 真实调用可能是response requests.post(f{MCP_SERVER_URL}/call, json{tool: mcp_tool_def[name], args: kwargs}) # return response.json()[result] if mcp_tool_def[name] mcp_calculator: # 这里简单模拟实际应由MCP服务器执行安全计算 try: # 再次强调生产环境不要用eval result eval(kwargs.get(expression, 0)) return fMCP计算器结果{result} except Exception as e: return f计算错误{e} elif mcp_tool_def[name] mcp_clock: from datetime import datetime return fMCP时钟当前时间是 {datetime.now().isoformat()} else: return f工具 {mcp_tool_def[name]} 未实现模拟。 return Tool( namemcp_tool_def[name], funcmcp_tool_func, descriptionmcp_tool_def[description] ) # 在主构建流程中替换工具初始化部分 mcp_tool_defs get_mcp_tools() tools [create_langchain_tool_from_mcp(def_) for def_ in mcp_tool_defs] # 后续的 llm.bind_tools(tools) 和 graph 构建保持不变核心变化工具的来源从本地函数变成了从MCP服务器动态获取的定义。create_langchain_tool_from_mcp函数创建了一个适配器它将LangChain Tool的调用转发给MCP服务器。优势解耦工具的开发、部署、升级独立于智能体应用。标准化任何符合MCP协议的工具无论用何种语言编写都能被集成。可发现性智能体启动时可以连接多个MCP服务器动态扩展其能力范围。6. 完整实战构建具备长期记忆的AI智能体现在我们整合所有组件构建一个更实用的智能体它不仅能用MCP工具还能记住之前的对话长期记忆。我们将使用LangGraph的Checkpointer和MessageHistory来实现。6.1 使用SQLite存储对话历史我们将使用LangChain内置的SQLiteSaver作为检查点存储器它可以将图的状态包括所有消息保存到SQLite数据库。# persistent_agent.py import sqlite3 from langgraph.checkpoint.sqlite import SqliteSaver from build_graph import workflow, AgentState # 复用之前定义的图和状态 from langchain_ollama import OllamaLLM from langchain.tools import Tool from mcp_integration import get_mcp_tools, create_langchain_tool_from_mcp # 导入MCP工具逻辑 # 1. 初始化LLM和MCP工具复用之前的代码 llm OllamaLLM(modelllama3.1:8b) mcp_tool_defs get_mcp_tools() tools [create_langchain_tool_from_mcp(def_) for def_ in mcp_tool_defs] llm_with_tools llm.bind_tools(tools) # 2. 创建检查点存储使用SQLite conn sqlite3.connect(:memory:) # 内存数据库重启后丢失。可改为文件路径如 ./checkpoints.db 以持久化。 checkpointer SqliteSaver(conn) # 3. 重新编译图并注入检查点存储器 # 注意我们需要重新定义节点函数因为它们依赖于新的llm_with_tools和tools from langgraph.graph import StateGraph, END from langchain_core.prompts import ChatPromptTemplate system_prompt 你是一个有记忆的AI助手。你可以调用工具。 之前的对话历史如下 {history} 当前用户的问题是{input} 请根据历史决定是否需要调用工具。 prompt ChatPromptTemplate.from_template(system_prompt) def agent_node_with_memory(state: AgentState): 带记忆的agent节点 # 从状态中提取历史消息和最新输入 history_msgs state[messages][:-1] if len(state[messages]) 1 else [] latest_input state[messages][-1].content if state[messages] else formatted_prompt prompt.invoke({ history: \n.join([f{m.type}: {m.content} for m in history_msgs]), input: latest_input }) response llm_with_tools.invoke(formatted_prompt) return {messages: [response], next: tools} def tools_node_with_memory(state: AgentState): 工具执行节点同前略作调整 last_message state[messages][-1] tool_messages [] if hasattr(last_message, tool_calls) and last_message.tool_calls: for tool_call in last_message.tool_calls: tool_name tool_call[name] tool_args tool_call[args] tool_to_use next((t for t in tools if t.name tool_name), None) if tool_to_use: result tool_to_use.invoke(tool_args) tool_message ToolMessage(contentstr(result), tool_call_idtool_call[id]) tool_messages.append(tool_message) else: error_msg ToolMessage(contentf错误工具 {tool_name} 未找到。, tool_call_idtool_call[id]) tool_messages.append(error_msg) if not tool_messages: tool_messages [last_message] next_step agent if tool_messages and tool_messages[0].tool_call_id else END return {messages: tool_messages, next: next_step} # 重建图 memory_workflow StateGraph(AgentState) memory_workflow.add_node(agent, agent_node_with_memory) memory_workflow.add_node(tools, tools_node_with_memory) memory_workflow.set_entry_point(agent) memory_workflow.add_edge(agent, tools) memory_workflow.add_conditional_edges( tools, lambda state: state[next], {agent: agent, END: END} ) # 关键步骤编译时传入checkpointer app_with_memory memory_workflow.compile(checkpointercheckpointer)6.2 运行带记忆的智能体现在我们可以运行这个智能体并且通过config参数传递一个线程ID来区分不同的对话会话。# run_persistent_agent.py from persistent_agent import app_with_memory from langchain_core.messages import HumanMessage # 为本次对话定义一个唯一的线程ID thread_id user_123_session_1 config {configurable: {thread_id: thread_id}} print( 第一次对话 ) # 第一次调用传入初始状态和配置 result1 app_with_memory.invoke( {messages: [HumanMessage(content我的名字是张三。)], next: agent}, config ) print(fAI回复: {result1[messages][-1].content}) print(\n 第二次对话在同一个thread_id下 ) # 第二次调用只传入新消息。图会从检查点恢复之前的状态。 result2 app_with_memory.invoke( {messages: [HumanMessage(content我刚才说我叫什么名字)], next: agent}, config ) print(fAI回复: {result2[messages][-1].content}) # 让我们再问一个需要工具的问题 print(\n 第三次对话询问时间 ) result3 app_with_memory.invoke( {messages: [HumanMessage(content现在几点了)], next: agent}, config ) print(fAI回复: {result3[messages][-1].content})运行此脚本你会看到智能体在第二次对话时能回忆起“张三”这个名字并在第三次对话时成功调用了我们模拟的MCP时钟工具如果工具列表里有的话。这就是长期记忆的效果状态被SqliteSaver持久化每次以相同thread_id调用时都会从上次结束的地方继续。7. 部署与生产环境最佳实践将上述原型部署到生产环境还需要考虑以下关键点7.1 安全与权限MCP服务器认证生产环境的MCP服务器必须实施认证如API Key、OAuth。不要在客户端代码中硬编码密钥。工具输入验证MCP服务器必须严格验证和清理输入如计算器工具绝对不能用eval应使用安全的数学表达式解析库如ast.literal_eval或numexpr。网络隔离确保MCP服务器运行在受信任的网络环境中特别是那些能访问内部数据库或系统的工具。7.2 性能与可观测性连接池为MCP客户端配置连接池避免频繁建立HTTP连接的开销。超时与重试为MCP工具调用设置合理的超时和重试机制。日志记录在LangGraph的每个节点函数中增加详细日志记录输入、输出、耗时和错误。这对于调试复杂工作流至关重要。监控指标收集智能体调用次数、工具调用成功率、各节点耗时等指标。7.3 配置管理MCP服务器列表不要硬编码在代码中。使用环境变量或配置中心如Consul、Apollo来管理可用的MCP服务器地址。模型配置将LLM的模型名称、温度temperature、最大令牌数等参数外部化。7.4 错误处理与韧性工具降级当某个MCP服务器不可用时智能体应能优雅降级例如使用本地备用工具或直接告知用户该功能暂时不可用。状态恢复检查点存储如SQLite应定期备份。对于关键业务可以考虑使用更健壮的存储后端如PostgreSQL。循环中断在LangGraph中设置最大循环次数防止智能体陷入无限思考-调用工具的循环。8. 常见问题与排查思路在开发过程中你可能会遇到以下典型问题问题现象可能原因排查方式解决方案ollama命令未找到Ollama未安装或未加入系统PATH。在终端执行ollama --version。从Ollama官网重新下载安装并确保安装向导提示的路径已加入系统环境变量。连接Ollama模型超时Ollama服务未启动防火墙阻止模型未拉取。1. 执行ollama serve查看服务状态。2. 执行ollama list查看模型是否存在。3. 检查localhost:11434端口是否可访问。1. 启动服务ollama serve 。2. 拉取模型ollama pull model_name。3. 检查Ollama服务配置。LangGraph报错State字段不匹配自定义的AgentState类型与节点函数返回的字典键不匹配。仔细核对AgentState的TypedDict定义和每个节点return的字典键。确保节点函数返回的字典包含AgentState定义的所有键或使用...操作符合并状态。智能体不调用工具直接回复1. 工具描述不清晰模型不理解。2. 模型能力不足。3. 提示词未明确要求调用工具。1. 打印出模型接收到的完整提示词检查工具描述是否被正确插入。2. 尝试更强大的模型。3. 在系统提示词中加强引导如“你必须使用工具来回答问题”。1. 优化工具描述使其更精确。2. 升级模型如使用llama3.1:70b。3. 使用Few-shot示例在提示词中演示工具调用。MCP工具调用返回错误1. MCP服务器未运行。2. 网络连接问题。3. 工具输入参数格式错误。1. 检查MCP服务器进程和日志。2. 使用curl或Postman测试MCP服务器端点。3. 对比MCP工具定义的input_schema和实际发送的参数。1. 启动MCP服务器。2. 检查防火墙和网络配置。3. 严格按照schema构造参数。检查点记忆未生效1. 未在compile时传入checkpointer。2. 每次调用使用了不同的thread_id。1. 确认app.compile(checkpointercheckpointer)被调用。2. 检查每次invoke时传入的config中的thread_id是否一致。1. 确保图编译正确。2. 为同一会话使用固定的thread_id。9. 总结与进阶方向通过本文的实战我们完成了一次从传统AI应用开发到现代智能体架构的升级。核心收获在于理解并实践了LangChain编排、MCP工具协议、LangGraph工作流引擎这三者如何各司其职共同构建出可维护、可扩展、具备复杂推理能力的AI智能体。下一步你可以探索的方向真实的MCP服务器尝试部署或编写一个真实的MCP服务器。可以参考 Model Context Protocol官方仓库 那里有文件系统、时钟、数据库查询等众多官方和社区服务器的实现。更复杂的工作流利用LangGraph实现多智能体协作、人工审核节点Human-in-the-loop、子图嵌套等高级模式。前端集成为你的智能体构建一个Web界面如使用Gradio、Streamlit让用户可以通过聊天框与之交互。生产化部署将整个应用容器化Docker并使用像 FastAPI 这样的框架提供HTTP API使其能够被其他系统集成。这个技术栈代表了当前AI工程化的前沿思路。它可能不是解决所有问题的最简方案但对于需要长期维护、团队协作、能力不断扩展的严肃AI项目来说这种关注点分离和协议标准化的设计无疑是更优的选择。建议你将本文的示例代码作为起点根据实际项目需求进行修改和深化逐步构建起你自己的智能体生态系统。
返回列表