
你好我是专注于AI应用开发的技术博主。在构建智能体Agent应用时你是否遇到过这样的困境工具调用不稳定、状态管理混乱、多步骤任务难以编排或者Agent经常“胡言乱语”产生幻觉网上资料虽多但往往零散不成体系从入门到项目落地总感觉隔着一道鸿沟。本文将为你彻底解决这些问题。我将手把手带你构建一个基于LangChain MCP LangGraph的现代化AI Agent实战项目。这不是一个简单的“Hello World”示例而是一个覆盖工具扩展、工作流编排、状态管理、记忆增强的完整生产级解决方案。无论你是想入门AI应用开发的新手还是希望优化现有Agent系统的开发者都能从本文获得可直接复用的代码和清晰的架构思路。我们将从核心概念讲起一步步搭建环境、编写代码并深入探讨如何避免那些让你浪费大量时间的“坑”。1. 背景与核心概念为什么需要这套技术栈在深入代码之前我们必须理解每个组件扮演的角色以及它们如何协同工作解决传统AI应用开发的痛点。1.1 AI Agent 的进化与挑战一个基础的AI应用如简单的聊天机器人通常只涉及用户输入和模型输出。而AI Agent则更进一步它被赋予“自主性”能够感知环境、进行思考、制定计划并调用工具来执行任务最终达成目标。例如一个数据分析Agent可以理解你的问题自动编写SQL查询数据库对结果进行可视化并生成分析报告。然而构建一个健壮的Agent面临诸多挑战工具管理混乱如何让Agent方便、安全地调用各种外部API、数据库或本地函数状态难以追踪在多轮对话或复杂任务中Agent的思考过程、中间结果如何保存和传递流程编排复杂对于需要多个步骤、有条件分支或循环的任务如何清晰地定义和控制执行流程幻觉与稳定性如何减少模型的胡说八道并确保工具调用的稳定性和错误处理1.2 技术栈分工LangChain, MCP, LangGraph 各司其职我们的技术栈正是为解决上述挑战而设计的黄金组合。LangChainAI应用的“脚手架”与“粘合剂”LangChain 是一个用于开发由大语言模型驱动的应用程序的框架。它提供了模块化的组件如模型封装、提示模板、记忆模块、索引等和链Chains来串联这些组件。在Agent开发中LangChain 的核心价值在于其标准的Agent执行器AgentExecutor它封装了“思考-行动-观察”的循环逻辑是驱动Agent运行的基础引擎。MCPModel Context Protocol工具的“统一接入层”这是解决工具管理问题的关键。MCP 是一个新兴的开放协议旨在为AI模型提供一个标准化、安全的方式来访问外部工具、数据和计算资源。你可以把它想象成电脑的“驱动程序”体系。传统方式每个Agent项目都需要硬编码或单独配置工具函数难以复用和管理。MCP方式工具以独立的MCP Server形式提供如一个提供天气查询的Server一个提供数据库操作的Server。你的Agent应用作为MCP Client只需连接这些Server就能自动发现并使用其所有工具。这实现了工具与应用的解耦工具可以独立开发、部署和升级极大提升了可维护性和安全性。LangGraphAgent的“大脑皮层”与“流程控制器”如果说LangChain的AgentExecutor提供了基础的反射弧那么LangGraph则提供了更高级的认知和协调能力。它基于图Graph的概念来构建复杂、有状态的AI工作流。核心是“图”将Agent的每个步骤如“思考”、“调用工具”、“判断结果”定义为节点Node通过边Edge来定义步骤间的流转逻辑。管理状态提供一个全局的、类型化的状态State对象在所有节点间共享和传递信息完美解决了多步骤任务的状态管理难题。支持复杂逻辑可以轻松实现循环让Agent反复尝试、条件分支根据结果走不同路径、并行执行等复杂控制流。总结一下协作关系LangGraph作为顶层编排器定义Agent的决策流程和状态LangChain提供与LLM交互、提示工程等基础能力MCP则为Agent提供标准化、可扩展的工具库。三者结合便能构建出强大、稳定且易于维护的智能体系统。2. 环境准备与项目初始化我们将在Python环境中进行开发。请确保你的环境满足以下要求。2.1 基础环境与版本说明操作系统Windows 10/11, macOS, 或 Linux (Ubuntu 20.04)。本文命令以macOS/Linux的bash为例Windows用户可在PowerShell或WSL中运行。Python版本 3.10 或 3.11。这是当前多数AI库兼容性最好的版本。使用python --version检查。包管理工具推荐使用pip和venv创建虚拟环境。大语言模型LLM我们将使用OpenAI GPT-4o或GPT-3.5-Turbo作为推理核心。你需要准备一个有效的 OpenAI API Key 。你也可以替换为其他LangChain支持的模型如 Anthropic Claude 或本地部署的 Ollama 模型但本文示例以OpenAI为准。代码编辑器VS Code, PyCharm 等任选。重要提示AI生态迭代迅速以下依赖版本为撰写本文时的稳定选择。实际开发时请关注官方文档和更新日志版本号可根据需要调整。2.2 创建项目并安装依赖首先创建一个干净的项目目录并初始化虚拟环境。# 1. 创建项目目录并进入 mkdir ai-agent-tutorial cd ai-agent-tutorial # 2. 创建并激活Python虚拟环境 (Linux/macOS) python3 -m venv venv source venv/bin/activate # Windows 用户请使用: venv\Scripts\activate # 3. 升级pip pip install --upgrade pip接下来安装核心依赖库。我们将使用uv作为更快的包安装器可选也可用pip。# 安装 uv (可选但推荐) pip install uv # 使用 uv 批量安装核心依赖 (如果不用uv可将依赖写入requirements.txt后用pip安装) uv pip install langchain langchain-openai langgraph langchain-mcp-clients mcp[cli] # 安装 pydantic 用于状态类型定义安装 requests 用于示例工具 uv pip install pydantic requests依赖包说明langchain,langchain-openai: LangChain 核心框架及OpenAI集成。langgraph: 用于构建工作流图。langchain-mcp-clients: LangChain 官方对 MCP Client 的支持库方便我们集成MCP工具。mcp[cli]: MCP 协议的核心库及命令行工具用于运行和测试MCP Server。pydantic: 用于定义强类型的数据结构在LangGraph中定义状态时非常有用。2.3 项目结构预览在开始编码前我们先规划一下项目结构这有助于理解代码组织。ai-agent-tutorial/ ├── venv/ # Python虚拟环境目录 ├── tools/ # 自定义工具目录备用 │ └── __init__.py ├── mcp_servers/ # 本地MCP Server示例 │ ├── calculator_server.py │ └── web_search_server.py ├── config.py # 配置文件如API密钥 ├── simple_agent.py # 示例1基础LangChain Agent ├── agent_with_mcp.py # 示例2集成MCP工具的Agent ├── langgraph_agent.py # 示例3使用LangGraph编排的增强Agent └── README.md3. 核心组件详解与基础示例让我们先抛开复杂的组合分别看看每个核心组件的基本用法为后续整合打下坚实基础。3.1 LangChain Agent 快速入门一个最基础的LangChain Agent由几个部分构成LLM、工具Tools、Agent类型。下面是一个极简示例。创建文件simple_agent.py# simple_agent.py import os from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.tools import Tool # 1. 设置OpenAI API Key (建议通过环境变量设置这里仅为演示) os.environ[OPENAI_API_KEY] 你的-OpenAI-API-Key # 请务必替换 # 2. 定义一个简单的自定义工具 def get_current_time(*args, **kwargs): 获取当前时间。当用户询问时间时使用此工具。 from datetime import datetime return f当前时间是: {datetime.now().strftime(%Y-%m-%d %H:%M:%S)} # 将函数包装成LangChain Tool对象 time_tool Tool( nameget_current_time, funcget_current_time, description当需要知道当前日期或时间时使用此工具。 ) # 3. 初始化LLM llm ChatOpenAI(modelgpt-3.5-turbo, temperature0) # 4. 定义Agent的提示词模板 prompt ChatPromptTemplate.from_messages([ (system, 你是一个乐于助人的助手。请使用提供的工具来回答问题。), (user, {input}), MessagesPlaceholder(variable_nameagent_scratchpad), # 用于存放Agent的思考过程 ]) # 5. 创建Agent tools [time_tool] agent create_openai_tools_agent(llm, tools, prompt) # 6. 创建Agent执行器 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue) # 7. 运行Agent if __name__ __main__: try: response agent_executor.invoke({input: 现在几点了}) print(\n Agent 回答 ) print(response[output]) except Exception as e: print(f运行出错: {e})运行这个脚本python simple_agent.py你会看到类似以下的输出其中verboseTrue会打印出Agent内部的思考Reasoning和行动Action过程 Entering new AgentExecutor chain... 我需要找到当前的时间。我可以使用 get_current_time 工具来获取。 Action: get_current_time Action Input: {} Observation: 当前时间是: 2024-05-27 10:30:15 Thought:我已经获得了当前时间可以回答用户的问题了。 Action: Final Answer 当前时间是: 2024-05-27 10:30:15。 Finished chain. Agent 回答 当前时间是: 2024-05-27 10:30:15。这个示例展示了LangChain Agent的核心执行循环思考 - 选择工具并执行 - 观察结果 - 继续思考或给出最终答案。3.2 MCP 初体验创建你的第一个工具服务器MCP 的核心思想是工具与主程序分离。让我们创建一个最简单的 MCP Server 来提供计算器功能。创建文件mcp_servers/calculator_server.py# mcp_servers/calculator_server.py import mcp.types as types from mcp.server import Server, NotificationOptions from mcp.server.models import InitializationOptions import mcp.server.stdio import asyncio # 创建MCP Server实例 server Server(calculator-server) # 1. 定义工具加法 server.list_tools() async def handle_list_tools() - list[types.Tool]: 向客户端声明本Server提供的所有工具 return [ types.Tool( nameadd_numbers, description计算两个数字的和。, inputSchema{ type: object, properties: { a: {type: number, description: 第一个加数}, b: {type: number, description: 第二个加数}, }, required: [a, b], }, ), types.Tool( namemultiply_numbers, description计算两个数字的乘积。, inputSchema{ type: object, properties: { x: {type: number, description: 被乘数}, y: {type: number, description: 乘数}, }, required: [x, y], }, ), ] # 2. 实现工具加法 server.call_tool() async def handle_call_tool( name: str, arguments: dict | None ) - list[types.TextContent | types.ImageContent | types.EmbeddedResource]: 处理客户端的工具调用请求 if name add_numbers: a arguments.get(a, 0) if arguments else 0 b arguments.get(b, 0) if arguments else 0 result a b return [types.TextContent(typetext, textstr(result))] elif name multiply_numbers: x arguments.get(x, 0) if arguments else 0 y arguments.get(y, 1) if arguments else 1 result x * y return [types.TextContent(typetext, textstr(result))] else: raise ValueError(f未知工具: {name}) async def main(): 运行Server的主函数 async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, InitializationOptions( server_namecalculator-server, server_version0.1.0, capabilitiesserver.get_capabilities( notification_optionsNotificationOptions(), experimental_capabilities{}, ), ), ) if __name__ __main__: asyncio.run(main())这个Server提供了两个工具add_numbers和multiply_numbers。它通过标准输入输出stdio与客户端通信这是MCP的常见通信方式。在另一个终端运行这个Servercd ai-agent-tutorial python mcp_servers/calculator_server.pyServer会启动并等待客户端连接。我们暂时让它运行着。3.3 LangGraph 核心概念状态与图LangGraph 通过“状态”和“图”来管理工作流。状态是一个包含所有运行数据的字典通常用Pydantic模型定义图则由节点和边组成。一个最简单的LangGraph工作流可能只包含一个调用LLM的节点。但它的强大之处在于可以轻松添加循环和条件逻辑。我们将在下一节的实战中深入应用。4. 完整实战构建集成MCP与LangGraph的智能体现在我们将把前面所学组合起来构建一个功能更强大的智能体。这个智能体能连接我们刚创建的MCP计算器Server。利用LangGraph管理复杂的多轮对话状态。处理需要多次计算或信息整合的任务。4.1 项目配置与工具连接首先创建一个配置文件来管理敏感信息如API Key。创建文件config.py# config.py import os from dotenv import load_dotenv # 可选用于从.env文件加载 # 加载环境变量文件如果存在 load_dotenv() # 从环境变量读取配置如果不存在则使用空字符串运行时会报错 OPENAI_API_KEY os.getenv(OPENAI_API_KEY, ) # 可以在这里定义MCP Server的路径或连接信息 # CALCULATOR_SERVER_PATH python /path/to/calculator_server.py # 配置检查 if not OPENAI_API_KEY: print(警告: OPENAI_API_KEY 未设置。请在.env文件中设置或直接赋值。)更安全的方式是创建.env文件确保在.gitignore中忽略它OPENAI_API_KEYsk-你的真实key4.2 创建集成MCP工具的LangChain Agent我们将创建一个Agent它不仅能使用内置工具还能动态连接并调用我们运行的MCP Server中的工具。创建文件agent_with_mcp.py# agent_with_mcp.py import asyncio import os import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from config import OPENAI_API_KEY from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_openai_tools_agent from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_mcp_adapters.tools import MCPToolkit async def main(): # 1. 设置API Key os.environ[OPENAI_API_KEY] OPENAI_API_KEY if not OPENAI_API_KEY: print(错误: 请先在config.py或.env文件中设置OPENAI_API_KEY) return # 2. 初始化LLM llm ChatOpenAI(modelgpt-4o, temperature0) # 使用GPT-4o以获得更好的工具调用能力 # 3. 连接到MCP Server并获取工具 # 注意这里假设你的calculator_server.py正在另一个终端运行。 # MCPToolkit.connect_to_server 支持多种连接方式这里使用stdio连接一个子进程。 import subprocess server_process subprocess.Popen( [python, mcp_servers/calculator_server.py], stdinsubprocess.PIPE, stdoutsubprocess.PIPE, stderrsubprocess.PIPE, textTrue, bufsize1 ) # 注意实际生产中MCPToolkit的连接可能需要异步上下文管理。 # 以下代码为概念演示具体连接方式请参考 langchain-mcp-adapters 最新文档。 print(正在连接MCP Server...此示例需要根据库的实际情况调整连接代码) # 由于langchain-mcp-adapters的API可能变化这里提供核心思路 # toolkit await MCPToolkit.connect_to_server(server_process) # mcp_tools toolkit.get_tools() # 为了演示的连贯性我们暂时回退到使用一个模拟的MCP工具列表。 # 在实际开发中你应该使用上述方式真实连接。 print(演示模式使用模拟工具列表) # 4. 定义提示词和Agent (使用模拟工具) from langchain.tools import Tool def mock_add(a: float, b: float) - str: return f计算结果: {a b} def mock_multiply(x: float, y: float) - str: return f计算结果: {x * y} mock_tools [ Tool(nameadd_numbers, funclambda args: mock_add(args[a], args[b]), description计算两个数字的和。输入参数: {a: number, b: number}), Tool(namemultiply_numbers, funclambda args: mock_multiply(args[x], args[y]), description计算两个数字的乘积。输入参数: {x: number, y: number}), ] prompt ChatPromptTemplate.from_messages([ (system, 你是一个强大的计算助手。你可以使用计算器工具来帮助用户解决数学问题。请清晰地向用户展示计算步骤和结果。), (user, {input}), MessagesPlaceholder(variable_nameagent_scratchpad), ]) agent create_openai_tools_agent(llm, mock_tools, prompt) agent_executor AgentExecutor(agentagent, toolsmock_tools, verboseTrue, handle_parsing_errorsTrue) # 5. 运行测试 print(\n 测试1: 简单加法 ) result1 await agent_executor.ainvoke({input: 请计算 125 加上 378 等于多少}) print(f回答: {result1[output]}) print(\n 测试2: 复合运算 ) result2 await agent_executor.ainvoke({input: 先计算 15 乘以 4 然后再加上 20。}) print(f回答: {result2[output]}) # 6. 清理 server_process.terminate() server_process.wait() if __name__ __main__: asyncio.run(main())这个示例展示了集成MCP工具的核心思路。在实际项目中你需要根据langchain-mcp-adapters或langchain-mcp-clients库的具体API来建立连接。关键点在于工具列表是动态从MCP Server获取的而不是硬编码在主应用中的。4.3 使用LangGraph构建有状态的增强Agent现在我们来构建本教程的核心一个使用LangGraph编排的、具备长期记忆和复杂流程控制能力的Agent。我们将创建一个“研究助手”Agent它可以进行多轮信息搜集和整合。创建文件langgraph_agent.py# langgraph_agent.py import operator from typing import Annotated, TypedDict from langgraph.graph import StateGraph, END from langgraph.graph.message import add_messages from langgraph.prebuilt import ToolNode from langchain_openai import ChatOpenAI from langchain.tools import Tool from langchain_core.messages import HumanMessage, SystemMessage import functools import os from config import OPENAI_API_KEY # 0. 配置 os.environ[OPENAI_API_KEY] OPENAI_API_KEY llm ChatOpenAI(modelgpt-4o, temperature0) # 1. 定义状态State # 使用TypedDict清晰地定义状态的结构 class AgentState(TypedDict): Agent工作流的状态定义 # 消息历史LangGraph内置的add_messages操作符可以智能地合并消息 messages: Annotated[list, add_messages] # 用户当前查询 query: str # 收集到的信息用于多轮工具调用 gathered_info: list[str] # 最终答案 final_answer: str # 2. 定义工具 # 模拟一个网络搜索工具 def web_search(query: str) - str: 模拟网络搜索。在实际应用中这里应调用SerpAPI、Google Search API等。 print(f[工具调用] 正在搜索: {query}) # 模拟返回结果 mock_results { LangGraph是什么: LangGraph是一个用于构建有状态、多参与者AI工作流的库基于图结构。, MCP协议: MCP (Model Context Protocol) 是一个用于标准化AI模型与工具/数据源连接的开放协议。, 今天的天气: 北京晴15-25℃上海多云18-28℃。, Python最新版本: 截至2024年5月Python的最新稳定版本是3.12。 } return mock_results.get(query, f未找到关于 {query} 的明确信息。) # 模拟一个计算工具 def calculate(expression: str) - str: 安全地计算数学表达式。警告在生产环境中应对输入进行严格校验。 print(f[工具调用] 正在计算: {expression}) try: # 使用eval有安全风险仅用于演示。生产环境应用ast.literal_eval或专用库。 # 这里极度简化实际应解析表达式并安全计算。 if in expression: parts expression.split() result sum(float(p.strip()) for p in parts) return str(result) else: return 此计算器仅演示加法。 except Exception as e: return f计算错误: {e} # 创建LangChain Tool对象 search_tool Tool(nameweb_search, funcweb_search, description用于搜索网络信息。输入一个搜索关键词。) calc_tool Tool(namecalculate, funccalculate, description用于计算数学表达式目前仅支持加法。输入如 5 3。) tools [search_tool, calc_tool] # 将LLM与工具绑定使其具备调用能力 llm_with_tools llm.bind_tools(tools) # 3. 定义图节点Nodes def agent_node(state: AgentState): Agent节点分析状态决定下一步行动调用工具或结束。 print(f\n--- Agent 思考中 ---) messages state[messages] # 将系统提示加入消息历史 system_message SystemMessage(content你是一个研究助手。根据用户问题和已有信息决定是否需要使用工具搜索或计算来获取更多信息。如果你认为信息已足够请直接给出最终答案。) full_messages [system_message] messages # 调用LLM它会返回一个包含可能工具调用的AIMessage response llm_with_tools.invoke(full_messages) # 将LLM的响应添加到消息历史中 return {messages: [response]} def tool_node(state: AgentState): 工具节点执行Agent选择的工具。 print(f\n--- 执行工具 ---) # 获取最近一条消息应该是LLM的响应 last_message state[messages][-1] # 初始化结果列表 tool_messages [] # 检查LLM是否调用了工具 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] print(f调用工具: {tool_name}, 参数: {tool_args}) # 找到对应的工具并执行 tool_to_use next((t for t in tools if t.name tool_name), None) if tool_to_use: try: # 执行工具 if tool_name web_search: result tool_to_use.invoke(tool_args[query]) elif tool_name calculate: result tool_to_use.invoke(tool_args[expression]) else: result tool_to_use.invoke(tool_args) # 将工具执行结果格式化为ToolMessage from langchain_core.messages import ToolMessage tool_messages.append(ToolMessage(contentresult, tool_call_idtool_call[id])) # 将获取的信息存入gathered_info状态 current_info state.get(gathered_info, []) current_info.append(f{tool_name}: {result}) except Exception as e: error_msg f工具 {tool_name} 执行出错: {e} tool_messages.append(ToolMessage(contenterror_msg, tool_call_idtool_call[id])) else: error_msg f未知工具: {tool_name} tool_messages.append(ToolMessage(contenterror_msg, tool_call_idtool_call[id])) # 返回更新后的消息历史和收集的信息 return {messages: tool_messages, gathered_info: state.get(gathered_info, []) [msg.content for msg in tool_messages if isinstance(msg.content, str)]} def final_answer_node(state: AgentState): 最终答案节点当Agent决定结束时生成最终回答。 print(f\n--- 生成最终答案 ---) messages state[messages] gathered state.get(gathered_info, []) # 构建一个提示让LLM基于所有信息总结答案 summary_prompt f 用户的问题是: {state[query]} 在过程中我们收集了以下信息: {chr(10).join(f- {info} for info in gathered)} 请基于以上信息给用户一个清晰、完整、准确的最终答案。 final_response llm.invoke([SystemMessage(content你是一个研究助手负责总结信息并回答用户。), HumanMessage(contentsummary_prompt)]) return {final_answer: final_response.content, messages: [final_response]} # 4. 定义条件边Edges def should_continue(state: AgentState) - str: 路由函数根据最后一条消息决定下一步是调用工具还是结束。 last_message state[messages][-1] # 如果LLM没有调用工具说明它想直接回答则结束 if not hasattr(last_message, tool_calls) or not last_message.tool_calls: return end # 否则继续调用工具 return continue # 5. 构建图Graph workflow StateGraph(AgentState) # 添加节点 workflow.add_node(agent, agent_node) # 思考节点 workflow.add_node(tools, tool_node) # 执行工具节点 workflow.add_node(final_answer, final_answer_node) # 最终回答节点 # 设置入口点 workflow.set_entry_point(agent) # 添加边定义节点间的流转逻辑 workflow.add_conditional_edges( agent, should_continue, # 根据这个函数的返回值决定路由 { continue: tools, # 继续 - 去执行工具 end: final_answer # 结束 - 去生成最终答案 } ) workflow.add_edge(tools, agent) # 工具执行完后回到Agent继续思考 workflow.add_edge(final_answer, END) # 最终答案节点后图结束 # 编译图 app workflow.compile() # 6. 运行工作流 def run_agent(query: str): 运行Agent工作流的入口函数 print(f\n 开始处理查询: {query} ) # 初始化状态 initial_state: AgentState { messages: [HumanMessage(contentquery)], query: query, gathered_info: [], final_answer: } # 执行图 final_state app.invoke(initial_state) print(f\n 最终答案 ) print(final_state[final_answer]) print(*40) return final_state if __name__ __main__: # 测试用例 test_queries [ LangGraph和MCP分别是什么它们有什么关系, 计算一下 12 25 8 等于多少, # 今天北京的天气怎么样, # 可以测试但我们的模拟搜索有对应mock数据 ] for q in test_queries: result run_agent(q) print(\n\n)这个示例构建了一个完整的、有状态的LangGraph工作流状态定义使用AgentState清晰定义了工作流中需要维护的所有数据。节点分工agent_node: 负责思考决定行动。tool_node: 负责执行具体的工具调用。final_answer_node: 负责汇总信息并生成最终答案。条件路由should_continue函数实现了智能判断让Agent可以自主决定何时停止调用工具。图编译与执行将节点和边组装成app通过invoke方法运行。运行这个脚本你将看到Agent的完整思考和执行过程python langgraph_agent.py5. 常见问题与排查思路在开发过程中你一定会遇到各种问题。以下是高频问题及其解决方案。问题现象可能原因排查思路与解决方案Agent 不调用工具直接回答1. 工具描述不清晰。2. LLM温度temperature过高导致随机性太强。3. 提示词Prompt未明确要求使用工具。4. 使用的模型如gpt-3.5-turbo工具调用能力较弱。1. 检查工具的描述description是否准确、具体说明输入输出格式。2. 将temperature设为 0 或接近 0 的值降低随机性。3. 在系统提示词中强调“你必须使用提供的工具来回答问题”。4. 升级到gpt-4或gpt-4o它们在工具调用上更可靠。工具调用参数解析错误1. 工具函数参数定义与LLM生成的不匹配。2. 参数格式如JSON错误。1. 使用Tool类或tool装饰器时确保函数有清晰的类型提示和文档字符串。2. 在Agent执行器AgentExecutor中设置handle_parsing_errorsTrue以优雅处理错误并打印出中间步骤verboseTrue进行调试。MCP Server 连接失败1. Server脚本路径错误或未启动。2. 通信协议stdio/stdio不匹配。3. 依赖库版本不兼容。1. 确保Server进程已正确启动并且主程序使用的连接命令如子进程命令与Server的启动方式匹配。2. 查阅langchain-mcp-clients或所用MCP客户端库的最新文档确认连接方式。3. 检查mcp和相关库的版本尝试使用稳定的版本组合。LangGraph 状态更新异常1. 状态State的键Key在节点中未正确返回。2. 使用了错误的状态合并操作符Reducer。1. 确保每个节点函数返回的字典包含要更新的状态键。不需要更新的键可以不返回。2. 对于列表类型的状态如消息历史使用Annotated[list, add_messages]等LangGraph提供的操作符来确保正确合并。仔细阅读官方文档关于状态管理的部分。“上下文过大”或Token超限1. 对话历史或收集的信息过多。2. 工具返回的内容过于冗长。1. 在LangGraph中实现记忆管理策略如只保留最近N轮对话或对长历史进行总结Summarization。2. 让工具返回精简的结果或在调用LLM前对长文本进行摘要。Agent陷入循环不停调用工具1. 路由逻辑should_continue有缺陷。2. LLM无法从工具结果中得出最终结论。1. 在路由函数中添加更严格的终止条件例如限制最大工具调用次数并在状态中记录调用次数。2. 优化提示词指导LLM在信息足够时停止。可以在状态中提供已收集信息的摘要帮助LLM判断。6. 最佳实践与工程建议将原型转化为稳定、可维护的生产级应用需要遵循以下工程实践。6.1 工具设计与开发单一职责每个工具应只做一件事并做好。避免创建“万能”工具。清晰描述工具的name和description至关重要它们是LLM选择工具的主要依据。描述应包含用途、输入格式、输出示例。错误处理工具内部必须有健壮的错误处理try-except并返回对Agent友好的错误信息而不是抛出未处理的异常。安全性对于执行代码、访问数据库或调用外部API的工具必须进行严格的输入验证和权限控制。永远不要相信来自LLM的未经清洗的输入。6.2 提示词工程系统提示词System Prompt是灵魂明确Agent的角色、职责、约束和行为规范。例如“你是一个数据分析助手必须通过查询数据库工具来获取数据不得虚构数据。”分阶段提示对于复杂任务可以在LangGraph的不同节点使用不同的提示词。例如在“规划”节点使用一个提示词在“总结”节点使用另一个。提供示例Few-Shot在提示词中提供一两个工具调用的成功示例能显著提升LLM使用工具的准确性。6.3 状态与记忆管理最小化状态只在状态中保存必要的信息。过大的状态会增加Token消耗并降低性能。短期记忆 vs 长期记忆使用add_messages管理对话历史是短期记忆。对于需要长期记住的用户偏好或事实可以设计单独的状态字段或引入外部向量数据库。状态序列化如果需要暂停或恢复工作流确保你的状态对象TypedDict或Pydantic模型是可序列化为JSON的。6.4 可观测性与调试开启详细日志在开发阶段将verboseTrue传递给AgentExecutor并打印关键节点的状态。可视化工作流LangGraph 提供了app.get_graph().draw_mermaid()功能可以生成Mermaid图来可视化你的工作流这对于理解复杂流程非常有帮助。记录与追踪考虑集成像 LangSmith 这样的追踪平台它可以详细记录每个LLM调用、工具调用和状态转换是调试复杂Agent的利器。6.5 生产环境部署配置管理API密钥、模型名称、Server地址等配置项必须通过环境变量或配置中心管理切勿硬编码。超时与重试为LLM API调用和工具调用设置合理的超时和重试机制提高系统的鲁棒性。限流与降级对LLM API的调用进行限流防止意外费用激增。设计降级策略例如当主要模型不可用时切换到备用模型或返回缓存结果。测试为你的Agent工作流编写单元测试和集成测试模拟各种用户输入和工具响应确保其行为符合预期。通过本教程你不仅学会了如何组合使用 LangChain、MCP 和 LangGraph 这些强大的工具更重要的是掌握了构建下一代AI智能体的系统化方法。从基础的工具调用到通过MCP实现工具的动态接入与解耦再到利用LangGraph编排复杂、有状态的工作流你已经走过了从概念到实战的完整路径。记住构建优秀的Agent是一个迭代过程从定义清晰的工具和提示词开始构建一个最小可行产品MVP然后通过持续的测试、观察和优化逐步完善其可靠性和智能水平。现在你可以尝试将示例中的模拟工具替换为真实的API如SerpAPI搜索、数据库查询或者设计更复杂的多Agent协作工作流将你的想法变为现实。