如果你正在学习大语言模型应用开发可能会遇到这样的困惑看了很多教程每个概念都懂但一到实际项目就无从下手。特别是面对 LangChain、LangGraph、Agent、RAG 这些热门技术时感觉它们各自为战不知道如何将它们组合成一个真正能跑起来的、有实际价值的智能体系统。更具体地说你可能跟着教程跑通了 LangChain 的 Hello World但不知道如何用它处理复杂的、多步骤的业务逻辑。听说过 Agent 能“思考”和“使用工具”但自己写的 Agent 总是逻辑混乱无法完成预定任务。搭建了 RAG 系统但回答质量不稳定不知道如何引入更强大的推理和控制能力。看到 LangGraph 这个词感觉它很强大但官方文档概念抽象缺少一个从零到一的完整项目串联。这篇文章要解决的正是这个“从孤立知识点到完整项目”的断层问题。我的核心判断是LangGraph 不是 LangChain 的替代品而是其“大脑”和“调度中心”。它将 LangChain 提供的各种工具Tools、记忆Memory和模型LLMs组织成可控的、有状态的工作流是构建复杂、可靠 AI 智能体的关键框架。本文将围绕一个核心目标展开带你从零开始用 LangChain LangGraph 构建一个具备长期记忆、能调用工具、并可进行复杂推理的智能体Agent。我们会融入 RAG 作为知识库并初步探讨 MCP 协议如何扩展工具能力。这不是简单的 API 调用演示而是一个贴近真实开发场景的实战项目你会看到清晰的架构设计、每一步的代码实现、常见的“坑”以及生产环境的注意事项。读完本文你将能清晰理解 LangChain、LangGraph、Agent、RAG 在技术栈中的定位与协作关系。掌握使用 LangGraph 构建有状态、可循环、带条件判断的智能体工作流。实现一个具备对话记忆、能查询知识库RAG、能执行代码工具调用的实用智能体。了解 MCP 协议的概念及其在工具生态中的价值。获得一套可运行、可扩展的完整项目代码并知道如何将其适配到自己的业务中。1. 为什么你需要关注 LangChain LangGraph 这套组合在 AI 应用开发领域我们正从一个“单次问答”的简单模式走向“多轮交互、自主规划、使用工具”的智能体时代。LangChain 早期解决了“连接”问题把大模型、向量数据库、各种工具链接在一起。但当业务流程变得复杂时单纯链式调用就显得力不从心了。想象一下你要开发一个智能数据分析助手用户可能说“帮我分析上个月的销售数据找出增长最快的三个产品然后为每个产品生成一段市场推广文案。”这个任务包含了多个步骤理解意图、查询数据库、执行分析、排序筛选、调用文案生成模型。步骤之间有依赖关系必须先拿到数据才能分析有状态传递分析结果要传给文案生成还可能循环为每个产品生成文案。LangChain 本身不擅长描述这种复杂、有状态的工作流。这就是 LangGraph 登场的原因。它本质上是一个基于图Graph的工作流编排框架专门为构建有状态的、多智能体协作的应用而设计。它的核心价值在于显式的工作流定义用节点Node和边Edge清晰地描绘出应用的执行路径代码即架构图可读性和可维护性极大提升。内置的状态管理自动在节点间传递和更新一个共享的“状态”对象省去手动管理中间变量的麻烦。灵活的循环与路由轻松实现“思考-行动-观察”的 ReAct 循环或根据条件跳转到不同分支。对多智能体的原生支持可以方便地定义多个具有不同角色的智能体并编排它们之间的协作。所以LangChain LangGraph 的组合构成了当前开发复杂 AI 智能体最主流、最工程化的技术栈之一。LangChain 提供丰富的组件模型 I/O、检索器、工具LangGraph 提供强大的编排能力。学习它意味着你掌握了构建下一代 AI 应用的核心方法论。2. 核心概念拆解LangChain, LangGraph, Agent, RAG, MCP 分别是什么在深入代码之前我们必须统一语言。这些术语经常被混用但它们在架构中扮演着截然不同的角色。概念通俗理解在项目中的角色常见误区LangChain“连接器”与“工具箱”提供与大模型对话的接口LLM、从文档中提取和检索知识的能力RAG、以及封装好的各种工具函数Tools如计算器、搜索引擎API。以为 LangChain 本身就是一个完整的应用框架。实际上它更偏向于提供标准化、可复用的底层模块。LangGraph“大脑”与“调度中心”定义智能体的“思考”流程。它决定先做什么、后做什么、遇到条件如何判断、如何循环。它调用 LangChain 提供的工具和模型。以为 LangGraph 是 LangChain 的替代品。实际上它依赖于 LangChain 的组件并赋予它们“智能”的协作能力。Agent“执行者”一个能理解目标、规划步骤、调用工具来自 LangChain来完成任务的大模型驱动程序。在 LangGraph 中一个或多个节点可以承担 Agent 的职能。以为 Agent 是一个神秘的、不可控的黑盒。实际上它的行为完全由 LangGraph 定义的工作流和提供的工具所约束。RAG“外部知识库”一种为大模型提供非参数化知识的技术。通过将文档切片、向量化存储在问答时快速检索相关片段注入上下文让模型能回答训练数据之外的问题。以为 RAG 能100%解决幻觉问题。实际上检索质量、上下文长度、模型指令遵循能力共同决定最终效果。MCP“工具插拔协议”Model Context Protocol一个新兴的开放协议。它旨在标准化 AI 应用如智能体与外部工具、数据源之间的连接方式让工具可以像插件一样即插即用。以为 MCP 是某个特定工具。实际上它是一个协议标准未来可能改变 Agent 工具生态的集成方式。它们之间的关系你可以把LangGraph看作导演LangChain看作道具组和演员资源库Agent是执行具体动作的演员RAG是演员可以随时查阅的剧本库而MCP则是一种新的、更标准的道具接入规范。导演LangGraph根据剧情用户输入指挥演员Agent利用道具LangChain Tools和剧本RAG完成一场演出任务。3. 环境准备构建你的智能体开发环境我们的目标是构建一个本地可运行的开发环境。为了兼顾效果和本地部署的便利性我们选择以下方案大模型使用Ollama本地运行DeepSeek-V3模型。Ollama 极大简化了本地大模型的部署和管理。向量数据库使用ChromaDB因为它轻量、易用且与 LangChain 集成良好。开发框架LangChain和LangGraph。Python环境建议使用 Python 3.10 或以上版本。3.1 基础环境安装首先确保你的系统已安装 Python 和 pip。然后创建一个新的虚拟环境并安装核心依赖。# 创建并激活虚拟环境 (Windows 用户请使用 python -m venv venv 和 venv\Scripts\activate) python3 -m venv langgraph-agent-env source langgraph-agent-env/bin/activate # Linux/Mac # venv\Scripts\activate # Windows # 升级pip pip install --upgrade pip # 安装 LangChain 全家桶和 ChromaDB pip install langchain langchain-community langgraph langchain-chroma # 安装 Ollama 的 LangChain 集成包 pip install langchain-ollama # 安装其他可能用到的工具包 pip install pypdf # 用于读取PDF文档 pip install tiktoken # 用于token计数非必须但推荐3.2 安装并配置 OllamaOllama 的安装请参考其 官方文档 。安装完成后在终端拉取我们需要的模型。# 拉取 DeepSeek-V3 模型 (请根据你的硬件选择合适版本如 deepseek-r1:7b) ollama pull deepseek-r1:7b # 启动 Ollama 服务通常安装后会自动运行 # 检查服务是否运行 ollama list如果看到deepseek-r1:7b在列表中说明模型已就绪。3.3 验证基础环境创建一个简单的 Python 脚本test_env.py来验证 LangChain 和 Ollama 是否能正常工作。# test_env.py from langchain_ollama import OllamaLLM from langchain_core.prompts import ChatPromptTemplate # 1. 初始化本地LLM llm OllamaLLM(modeldeepseek-r1:7b) # 2. 创建一个简单的提示词模板 prompt ChatPromptTemplate.from_messages([ (system, 你是一个乐于助人的助手。), (user, {input}) ]) # 3. 创建链并调用 chain prompt | llm response chain.invoke({input: 你好请用一句话介绍你自己。}) print(模型回复, response)运行这个脚本python test_env.py如果看到模型返回了一段自我介绍恭喜你基础环境搭建成功如果遇到连接错误请检查 Ollama 服务是否正在运行ollama serve。4. 项目架构设计我们要构建一个什么样的智能体在写代码前先进行设计。我们将构建一个“多功能研究助手”智能体它具备以下能力对话记忆能记住同一会话中的历史对话。知识库问答RAG当用户问题涉及我们提供的专用知识如公司文档、技术手册时能优先从知识库中查找答案。工具调用能执行一些实用功能例如search_web: 搜索网络信息此处我们用模拟函数代替真实API。execute_python: 执行简单的 Python 代码并返回结果在安全沙箱中。自主规划与执行根据用户问题自主决定是否需要使用知识库、是否需要调用工具、以及调用哪个工具。技术架构图文字描述用户输入 | v [LangGraph 工作流入口] | v [路由节点] --是知识库问题-- [RAG 检索节点] --检索结果-- [回答生成节点] | | |--需要工具-- [工具调用节点] --工具结果--| | v [最终回答节点] -- 输出给用户这个工作流的核心是一个“路由”逻辑由一个大模型LLM根据用户问题和历史来判断下一步该走哪条分支。LangGraph 完美支持这种模式。5. 分步实现从知识库搭建到智能体工作流5.1 第一步构建本地知识库RAG假设我们有一份关于“LangGraph 最佳实践”的 PDF 文档。我们将其加载、切分、向量化并存入 ChromaDB。# rag_setup.py import os from langchain_community.document_loaders import PyPDFLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_chroma import Chroma from langchain_ollama import OllamaEmbeddings # 1. 加载文档 loader PyPDFLoader(./docs/langgraph_best_practices.pdf) # 请准备你的PDF文件 documents loader.load() # 2. 分割文档 text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 每个片段500字符 chunk_overlap50, # 重叠50字符以保证上下文 separators[\n\n, \n, 。, , , , 、, , ] ) splits text_splitter.split_documents(documents) print(f文档被分割成 {len(splits)} 个片段。) # 3. 初始化嵌入模型和向量数据库 # 使用 Ollama 的嵌入模型例如 nomic-embed-text embeddings OllamaEmbeddings(modelnomic-embed-text) # 指定持久化目录 persist_directory ./chroma_db # 4. 创建向量库 vectorstore Chroma.from_documents( documentssplits, embeddingembeddings, persist_directorypersist_directory ) vectorstore.persist() # 持久化到磁盘 print(知识库构建完成已保存至:, persist_directory)运行此脚本后./chroma_db目录下会保存向量数据库。后续我们可以直接加载它。5.2 第二步定义智能体可用的工具工具是智能体与外界交互的“手”。我们定义两个示例工具。# tools.py import subprocess import sys from langchain.tools import tool from typing import Optional tool def search_web(query: str) - str: 在互联网上搜索信息。对于需要最新、非本地知识的问题非常有用。 # 注意这是一个模拟函数。真实场景应接入 SerperAPI、Google Search API 等。 # 此处返回模拟结果。 print(f[工具调用] 正在搜索: {query}) # 模拟网络延迟 import time time.sleep(0.5) return f关于 {query} 的模拟搜索结果LangGraph 是一个用于构建有状态、多智能体应用的工作流库。 tool def execute_python(code: str) - str: 执行一段 Python 代码并返回结果。用于计算、数据处理或测试代码片段。 print(f[工具调用] 正在执行 Python 代码:\npython\n{code}\n) try: # 使用 subprocess 在隔离环境中运行代码更安全 result subprocess.run( [sys.executable, -c, code], capture_outputTrue, textTrue, timeout10 ) if result.returncode 0: output result.stdout.strip() return f代码执行成功。输出\n{output} if output else 代码执行成功无输出。 else: return f代码执行出错返回码 {result.returncode}:\n{result.stderr} except subprocess.TimeoutExpired: return 错误代码执行超时10秒。 except Exception as e: return f执行过程中发生未知错误{str(e)} # 将工具放入列表供后续使用 AGENT_TOOLS [search_web, execute_python]安全提醒execute_python工具在生产环境中存在极大安全风险。此处仅为演示真实场景必须使用严格的沙箱环境如 Docker 容器或禁用此类危险工具。5.3 第三步定义 LangGraph 工作流的状态State状态是 LangGraph 工作流中流动的“血液”它包含了所有节点需要共享的信息。# state.py from typing import TypedDict, List, Annotated import operator class AgentState(TypedDict): 智能体工作流的状态定义。 # 用户当前输入的问题 input: str # 对话历史 chat_history: List[str] # 从知识库检索到的上下文 context: str # 大模型生成的中间“思考”过程 reasoning: str # 需要调用的工具名称 tool_to_call: str # 调用工具时的参数 tool_input: str # 工具返回的结果 tool_output: str # 最终给用户的回答 final_output: str # 定义一个特殊的“归约”类型用于让 chat_history 能自动追加消息。 # 这是 LangGraph 处理列表状态更新的推荐方式。 class GraphState(TypedDict): input: str chat_history: Annotated[List[str], operator.add] # 关键自动追加 context: str reasoning: str tool_to_call: str tool_input: str tool_output: str final_output: strAnnotated[List[str], operator.add]是 LangGraph 的一个魔法它告诉框架当多个节点修改chat_history时应该用操作符即追加来合并它们的修改而不是覆盖。5.4 第四步构建核心工作流图这是最核心的部分。我们将创建多个节点函数并用StateGraph将它们连接起来。# graph.py from langgraph.graph import StateGraph, END from .state import GraphState from .tools import AGENT_TOOLS from langchain_ollama import OllamaLLM from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain.agents import create_react_agent from langchain.agents.format_scratchpad import format_log_to_str from langchain.agents.output_parsers import ReActSingleInputOutputParser from langchain.schema import AIMessage, HumanMessage # 初始化 LLM llm OllamaLLM(modeldeepseek-r1:7b, temperature0.1) # 加载之前创建的向量数据库 from langchain_chroma import Chroma from langchain_ollama import OllamaEmbeddings embeddings OllamaEmbeddings(modelnomic-embed-text) vectorstore Chroma(persist_directory./chroma_db, embedding_functionembeddings) retriever vectorstore.as_retriever(search_kwargs{k: 3}) # 检索最相关的3个片段 def retrieve_context(state: GraphState): 节点函数从知识库中检索相关内容。 print(f[节点检索] 正在检索与问题相关的知识...) docs retriever.invoke(state[input]) context \n\n.join([doc.page_content for doc in docs]) return {context: context} def route_question(state: GraphState): 节点函数路由决策。判断问题类型决定下一步。 print(f[节点路由] 分析问题类型...) # 这是一个简化的路由逻辑。实际应用中可以用一个LLM来做更复杂的判断。 question state[input].lower() # 规则1如果问题明显是关于我们知识库主题的例如包含“langgraph” if langgraph in question: return retrieve # 规则2如果问题要求计算、搜索或执行代码 elif any(keyword in question for keyword in [计算, 搜索, python, 代码, 执行]): return call_tool # 规则3其他情况直接回答 else: return generate_answer def call_tool(state: GraphState): 节点函数调用工具。 tool_name state.get(tool_to_call) tool_input state.get(tool_input) if not tool_name or not tool_input: # 如果没有指定工具则让LLM决定 return {final_output: 错误未指定要调用的工具或输入参数。} print(f[节点调用工具] 调用工具 {tool_name}输入{tool_input}) # 查找工具 tool_map {tool.name: tool for tool in AGENT_TOOLS} if tool_name not in tool_map: return {final_output: f错误未知工具 {tool_name}。} # 执行工具 try: tool_result tool_map[tool_name].invoke(tool_input) return {tool_output: tool_result} except Exception as e: return {tool_output: f工具执行失败{str(e)}} def generate_answer(state: GraphState): 节点函数生成最终回答。 print(f[节点生成回答] 综合信息生成回答...) # 构建提示词 prompt_template ChatPromptTemplate.from_messages([ (system, 你是一个AI研究助手。请根据以下信息结合你的知识给用户一个准确、有帮助的回答。 相关上下文来自知识库 {context} 工具执行结果如果有 {tool_output} 请用中文回答。如果信息不足可以说明。), MessagesPlaceholder(variable_namechat_history), (user, {input}) ]) # 准备输入 messages prompt_template.format_messages( contextstate.get(context, 无), tool_outputstate.get(tool_output, 无), chat_historystate[chat_history], inputstate[input] ) # 调用LLM response llm.invoke(messages) # 更新对话历史 new_history state[chat_history] [ HumanMessage(contentstate[input]), AIMessage(contentresponse.content) ] return {final_output: response.content, chat_history: new_history} def update_history(state: GraphState): 节点函数将本轮对话更新到历史中在最终输出后调用。 # 此节点主要演示状态更新。generate_answer 中已经更新了历史。 # 这里可以做一些清理或格式化工作。 print(f[节点更新历史] 本轮对话结束。) return {} # 构建图 workflow StateGraph(GraphState) # 添加节点 workflow.add_node(retrieve, retrieve_context) # 检索知识库 workflow.add_node(call_tool, call_tool) # 调用工具 workflow.add_node(generate_answer, generate_answer) # 生成回答 workflow.add_node(update_history, update_history) # 更新历史 # 设置入口点首先进行路由决策 workflow.set_conditional_entry_point( route_question, { retrieve: retrieve, # 去检索 call_tool: call_tool, # 去调用工具 generate_answer: generate_answer # 直接回答 } ) # 定义边连接节点 workflow.add_edge(retrieve, generate_answer) # 检索完后生成回答 workflow.add_edge(call_tool, generate_answer) # 调用工具后生成回答 workflow.add_edge(generate_answer, update_history) # 生成回答后更新历史 workflow.add_edge(update_history, END) # 最后结束 # 编译图 app workflow.compile()这个图定义了完整的工作流入口根据问题类型路由分别走向检索、调用工具或直接生成回答最后汇聚到生成回答节点更新历史后结束。5.5 第五步创建并运行智能体现在我们将所有部分组合起来并创建一个简单的交互循环。# main.py import sys sys.path.append(.) # 确保可以导入自定义模块 from graph import app from state import GraphState def run_agent(): print( 多功能研究助手智能体已启动 ) print(输入 quit 或 exit 退出程序。) print(- * 40) # 初始化状态 initial_state GraphState( input, chat_history[], context, reasoning, tool_to_call, tool_input, tool_output, final_output ) while True: try: user_input input(\n你: ).strip() if user_input.lower() in [quit, exit, q]: print(再见) break if not user_input: continue # 更新状态中的输入 initial_state[input] user_input # 执行工作流 print(\n[智能体正在思考...]) final_state app.invoke(initial_state) # 输出结果 print(f\n助手: {final_state[final_output]}) print(- * 40) # 为下一轮对话更新初始状态保留历史清空其他中间状态 initial_state GraphState( input, chat_historyfinal_state[chat_history], # 保留历史 context, reasoning, tool_to_call, tool_input, tool_output, final_output ) except KeyboardInterrupt: print(\n\n程序被中断。) break except Exception as e: print(f\n发生错误{e}) # 可以选择重置状态或继续 initial_state GraphState( input, chat_history[], context, reasoning, tool_to_call, tool_input, tool_output, final_output ) if __name__ __main__: run_agent()6. 运行与效果验证现在让我们运行这个智能体并进行多轮对话测试。启动智能体python main.py测试对话记忆你: 你好我叫小明。 [智能体正在思考...] 助手: 你好小明很高兴认识你。我是你的AI研究助手可以帮你查询知识、搜索信息或执行简单的计算。有什么我可以帮你的吗 --- 你: 我刚才说我叫什么名字 [智能体正在思考...] 助手: 你刚才说你叫小明。验证点智能体正确回忆了历史对话。测试知识库问答RAG你: LangGraph 有什么优势 [节点路由] 分析问题类型... [节点检索] 正在检索与问题相关的知识... [节点生成回答] 综合信息生成回答... 助手: 根据知识库内容LangGraph 的主要优势在于它提供了清晰的工作流编排能力支持有状态的多步骤任务处理便于构建复杂的多智能体应用...此处应结合你的PDF内容返回验证点智能体识别出这是知识库问题触发了检索节点并基于检索到的上下文生成回答。测试工具调用你: 请计算一下 2 的 10 次方是多少。 [节点路由] 分析问题类型... [节点调用工具] 调用工具 execute_python输入2**10 [工具调用] 正在执行 Python 代码: python 2**10[节点生成回答] 综合信息生成回答... 助手: 代码执行成功。输出1024。所以2 的 10 次方是 1024。* **验证点**智能体识别出计算需求正确调用了 execute_python 工具并整合结果生成回答。测试综合场景你: 我想了解一下 LangGraph然后帮我用 Python 写一个简单的 hello world。 [节点路由] 分析问题类型...这里我们的简单路由可能只会触发一个分支实际更复杂的Agent会用LLM规划多个步骤验证点这个复杂请求暴露了我们当前简单路由的局限性。一个更强大的智能体应该能将其分解为“检索 LangGraph 信息”和“调用代码生成工具”两个子任务。这需要通过更复杂的“规划”节点或使用 LangChain 的create_react_agent来实现。7. 常见问题与排查思路在构建和运行此类智能体时你一定会遇到各种问题。下表列出了最常见的问题及其解决方法。问题现象可能原因排查方式解决方案Ollama 连接错误Ollama 服务未启动模型未下载端口被占用。1. 运行ollama list检查模型。2. 运行ollama serve查看服务日志。3. 检查OllamaLLM初始化时指定的模型名是否正确。1. 确保 Ollama 服务运行 (ollama serve)。2. 拉取正确模型 (ollama pull deepseek-r1:7b)。3. 确认代码中model参数与拉取的模型名一致。ChromaDB 报错No such file or directory向量数据库持久化目录不存在或路径错误。检查persist_directory路径。运行rag_setup.py的目录是否与主程序一致使用绝对路径或确保工作目录正确。先运行rag_setup.py生成数据库。工具调用失败或无效工具函数定义错误工具未正确传递给 Agent工具执行环境问题。1. 在tools.py中单独测试工具函数。2. 检查AGENT_TOOLS列表是否正确定义并导入。3. 查看工具函数的tool装饰器和参数。1. 确保工具函数有明确的文档字符串docstringLangChain 依赖它。2. 检查工具导入路径。3. 对于execute_python确保系统有 Python 环境且 subprocess 可用。智能体不调用工具总是直接回答路由逻辑 (route_question) 太简单或错误LLM 在 ReAct 模式下的提示词不佳。1. 打印route_question函数的返回值。2. 检查触发工具调用的关键词是否匹配用户输入。3. 如果使用 ReAct Agent检查其提示词。1. 强化路由逻辑或引入一个 LLM 作为“规划器”来动态决定下一步。2. 使用 LangChain 的create_react_agent它能更好地让 LLM 自主决定何时调用工具。对话历史丢失或混乱GraphState中chat_history的定义或更新方式错误。1. 检查state.py中Annotated[List[str], operator.add]的定义。2. 在generate_answer节点中检查是如何更新chat_history的。1. 确保状态定义正确。2. 在更新历史的节点返回{chat_history: new_history}LangGraph 会自动执行追加操作。程序运行缓慢本地模型推理慢检索器返回片段过多网络工具调用慢。1. 观察是哪个环节慢模型响应、检索、工具。2. 检查检索的k值是否过大。3. 检查模拟工具中的time.sleep。1. 考虑使用更小的模型或量化版本。2. 调整检索参数k如从 5 降到 3。3. 优化工具实现或对耗时工具进行异步调用。RuntimeError: ...图编译错误节点名拼写错误边连接了不存在的节点条件路由返回值不在映射中。仔细检查workflow.add_node和workflow.add_edge使用的字符串名称是否完全一致。使用常量或枚举来定义节点名避免拼写错误。仔细核对set_conditional_entry_point的映射字典。8. 进阶优化与最佳实践上面的示例是一个教学原型。要用于实际项目你需要考虑以下优化点8.1 使用更强大的“规划器”替代简单路由当前的route_question函数基于关键词非常脆弱。应该用一个 LLM 作为规划器分析用户意图并生成一个任务执行计划Plan。LangChain 的Plan-and-Execute模式或 LangGraph 的StateGraph本身都支持更复杂的规划逻辑。8.2 实现真正的 ReAct 循环我们的工具调用是“一次性”的。真正的 ReActReasoning Acting模式要求智能体能够根据工具返回的结果进行再次思考决定是继续调用工具还是给出最终答案。这需要在图中添加一个从generate_answer或call_tool回到“路由/规划”节点的循环边并设置合适的停止条件。8.3 集成更真实的工具网络搜索注册 SerperDev、Google Search API 等服务替换search_web模拟函数。知识库更新增加一个工具或后台进程定期或手动更新向量数据库。安全沙箱对于execute_python务必使用 Docker 容器等隔离环境并限制资源CPU、内存、运行时间、网络访问。8.4 引入 MCP 协议前瞻性MCP 旨在让工具集成标准化。你可以探索将一些工具改造成 MCP Server然后通过 LangChain 的 MCP 集成来调用。这虽然增加了初期复杂度但长期来看有利于工具的管理和复用。关注langchain-mcp等社区包的发展。8.5 生产环境部署注意事项配置管理将模型名称、API密钥、数据库路径等抽离到环境变量或配置文件中。错误处理与重试在图中的关键节点如 LLM 调用、工具调用添加完善的try...except并考虑实现指数退避重试。日志与监控使用logging模块替代print记录详细的运行日志便于排查问题。监控智能体的耗时、工具调用成功率等指标。状态持久化当前的chat_history在内存中服务重启会丢失。需要将其持久化到数据库如 Redis、SQLite中并以session_id区分不同对话。异步优化如果智能体需要调用多个外部 API考虑使用asyncio进行异步调用以提升吞吐量。9. 总结从项目实战中获得的真正洞察通过这个从零搭建的 LangChain LangGraph 智能体项目我们得到的远不止一段可运行的代码。最关键的是理解了复杂 AI 应用的构建范式LangChain 是基石它提供了与大模型、数据、工具交互的标准化接口。学 LangChain重点是学它的抽象LLM、PromptTemplate、Retriever、Tool而不是死记硬背 API。LangGraph 是灵魂当你需要处理多步骤、有状态、带循环或条件判断的任务时就应该想到 LangGraph。它用“图”这个直观的概念让你能把复杂的业务逻辑清晰地画出来、写出来。Agent 是模式不是具体实现“智能体”是一种设计模式它由感知输入、规划大脑/LangGraph、执行工具/LangChain、记忆状态组成。我们这个项目就是这种模式的一个具体实现。RAG 和工具是能力的延伸它们让智能体突破了模型本身的知识和功能限制。RAG 注入领域知识工具赋予行动能力。它们的质量直接决定了智能体的上限。从简单开始迭代复杂不要一开始就设计一个巨无霸智能体。像本文一样从一个清晰的核心工作流路由-检索/工具-回答开始验证可行性然后逐步加入规划、多轮工具调用、多智能体协作等高级特性。下一步你可以做什么深化 LangGraph研究StateGraph的add_conditional_edges来实现更动态的路由尝试MessageGraph来处理纯消息流。探索多智能体用 LangGraph 定义两个具有不同角色如“研究员”和“写作者”的智能体让它们协作完成一篇报告。接入真实数据与工具用公司的 Confluence、Notion 或代码仓库构建真正的 RAG 系统接入 Jira、GitHub API 等真实工具。关注 MCP 生态随着 MCP 协议支持度的提高尝试将一两个工具改造成 MCP Server体验标准化工具集成的便利。构建 AI 智能体的过程就像教一个实习生你先要告诉他工作流程LangGraph给他提供资料和工具LangChain RAG Tools然后通过不断的对话和反馈记忆与迭代让他变得更熟练。希望这个项目能成为你那位“实习生”的第一份清晰的工作手册。