如果你正准备学 LangChain 和 LangGraph,但打开官方文档就被“一大堆概念”劝退,那么这篇文章就是为你准备的。
零基础学 LLM 应用开发,最痛苦的往往不是代码本身,而是不知道“先学什么、后学什么、哪些是核心、哪些可以跳过”。很多初学者今天看到一个人说“直接学 LangGraph 就行,LangChain 要过时了”,明天又看到另一个人说“先从 RAG 入手”,后天又冒出 MCP 协议、Agentic RAG、多智能体框架,整个人是懵的。
先给一个明确判断:2026 年做 Agent 开发,主线不是某一个框架,而是一条完整链路——LangChain 负责组件生态,LangGraph 负责状态编排,RAG 负责知识注入,MCP 负责工具协议标准化,Agent 是最终产品形态。这五者不是替代关系,而是分层关系。你不需要把每个都学到精通,但要先看懂这条主线上每一环解决什么问题。
这篇文章会从零开始,把 LangChain、LangGraph、RAG、MCP、多智能体这五件事的关系讲清楚,然后用三个可运行的实战项目把它们串起来。读完你会得到一个清晰的入门路线、一套最小可运行的代码,以及一份避开常见大坑的排查清单。
1. 2026 年了,为什么还要从 LangChain 学起?
先说一个很多新手最容易踩的认知误区:看到 LangGraph 越来越火,就觉得“LangChain 是不是已经过时了,干脆跳过”。这个判断是错的。
LangChain 和 LangGraph 不是同一个层面的东西。LangChain 解决的是“怎么方便地调用大模型、怎么写 Prompt、怎么接向量库、怎么封装工具”这些基础问题;LangGraph 解决的是“当流程变复杂、有循环、有分支、需要多步骤决策时,怎么编排整个状态流程”的高级问题。
打个比方:LangChain 像是给你一堆搭积木的标准积木块,LangGraph 像是教你怎么按照图纸把积木搭成一座能住人的房子。你没有积木块,直接学图纸是没有意义的。
从零基础的学习路径来看,更应该先学 LangChain。原因有两条:
第一,LangChain 的抽象接口把所有东西统一了。今天你用 OpenAI,明天换个国产模型,只需要改很少的代码;今天用 Chroma 做向量库,明天换 Milvus、PGVector,接口也基本一致。这种“统一抽象”对初学者非常友好,它让你不用在早期纠结太多细节。
第二,LangGraph 官方文档里的很多示例,底层仍然依赖 LangChain 的 ChatModel、Tool、Retriever 这些对象。换句话说,你跳过 LangChain 去学 LangGraph,会在工具函数、模型绑定、消息格式这些地方反复卡壳,最后还得回来补课。
所以对于零基础读者,我的建议非常直接:先花几天时间把 LangChain 的基本概念过一遍,理解 ChatModel、PromptTemplate、DocumentLoader、VectorStore、Retriever、Tool 这几个核心对象,再进入 LangGraph 的世界。这篇文章后面的实战也是按这个顺序设计的。
2. LangChain、LangGraph、RAG、MCP 到底是什么关系?
如果只看热搜词,你会觉得“LangChain、LangGraph、Agent、RAG、MCP”是五个并列的技术名词。但实际在开发链路里,它们的定位差异非常明显。
2.1 LangChain:LLM 应用的组件库
LangChain 是围绕大模型应用开发的框架,它提供的主要能力包括:
- 模型封装:统一调用 OpenAI、Anthropic、国产大模型等不同厂商的模型。
- Prompt 管理:通过 ChatPromptTemplate 等类组织提示词,支持变量注入和模板复用。
- 文档加载与切片:从 PDF、TXT、网页、数据库加载数据,并按规则切分成 Chunk。
- 向量存储与检索:对接 Chroma、FAISS、Milvus 等向量数据库,完成语义检索。
- 工具封装:把普通 Python 函数标记成可以被模型调用的 Tool。
- 链式组合:通过 LCEL(LangChain Expression Language)把不同组件串联成一条处理管线。
初学者理解 LangChain 时,最需要记住的就是:它是一个“组件库 + 胶水层”。它不解决“这个 Agent 该先做什么后做什么”的流程问题,只解决“这一步怎么实现”的组件问题。
2.2 LangGraph:状态化的 Agent 编排框架
LangGraph 是 LangChain 团队推出的另一个框架,它的核心模型是“图”。你要定义一个 Agent,不再是写一条从头到尾的链,而是定义:
- State(状态):整个流程中需要共享的数据,比如消息列表、中间结果、用户目标。
- Node(节点):每个处理步骤,比如“调用模型”“调用检索工具”“调用代码执行工具”。
- Edge(边):节点之间的连接关系,包括普通边和条件边。
- 循环与分支:模型可以反复决定“要不要调用工具”,直到它认为可以给出最终答案。
LangGraph 真正解决的是传统 Chain 做不到的事情:循环控制、复杂分支、人工确认、状态持久化、多 Agent 协作。
2.3 RAG:给大模型注入私有知识
RAG(Retrieval-Augmented Generation,检索增强生成)解决的是大模型“不知道”的问题。大模型的知识来自训练数据,有截止日期,也无法覆盖你公司的私有文档。RAG 的流程是:先把文档切片、向量化、存入向量库;用户提问时,先从向量库中召回相关内容,再把“问题 + 检索到的资料”一起交给大模型生成回答。
值得多提一句的是 RAG 已经从最初的“向量检索 + 拼接 Prompt”进化到了更复杂的形态。热搜词里出现的Agentic RAG(智能体 RAG),就是把 RAG 中的检索动作也交给 Agent 决定:什么时候检索、检索哪一路、检索结果不行怎么办,都由 Agent 临场判断。还有RAG 多路召回,指的是同时使用向量检索、关键词检索、知识图谱检索等多种方式,再经过重排合并,得到更高质量的候选片段。
2.4 MCP:模型上下文协议
MCP(Model Context Protocol)是最近讨论度很高的开放协议,它解决的是“Agent 怎么接各种外部工具”的标准化问题。没有 MCP 之前,Agent 接数据库要写一套数据库工具,接飞书要写一套飞书工具,接内部系统又要单独对接一遍。有了 MCP 之后,工具提供方按照统一协议暴露能力,Agent 框架按统一协议调用能力,类似给工具接入了一个“USB-C 接口”。
你可以把 MCP 理解成三个角色的协作:MCP Server(提供工具的一方)、MCP Client(发起调用的一方)、MCP 协议(两者之间的通信规范)。
2.5 四者关系的一句话总结
- 用LangChain获取组件和工具,连接各种模型、向量库、文档处理器;
- 用LangGraph设计流程,把普通链升级成能够自主决策的 Agent;
- 用RAG解决知识来源问题,让 Agent 能够基于自己的私有知识回答;
- 用MCP标准接入外部工具,让 Agent 从“会说话”变成“会做事”。
不少新手容易把 Agent 和 RAG 放在对立位置,但更合理的理解是:RAG 是 Agent 的一项能力,Agentic RAG 就是把这项能力组合进 Agent 的决策循环中。这也是 2026 年实际项目里最常见的落地形态。
3. 零基础入门路线与环境准备
3.1 合理的学习顺序
零基础直接扎进 LangGraph 源码,很容易被状态图、Reducer、持久化这些概念击穿心理防线。推荐的学习顺序是:
- 先理解大模型 API 的基本调用方式,知道什么是 System Prompt、User Message。
- 学习 LangChain 的五个核心对象:ChatModel、PromptTemplate、DocumentLoader、VectorStore、Tool。
- 完成一个最小 RAG 项目,理解“切片 - 向量化 - 检索 - 生成”全流程。
- 学习 LangGraph 的基础概念,把 RAG 脚本改造成带工具调用的 Agent。
- 学习 MCP,把第三方数据源和工具通过协议接入 Agent。
- 尝试多智能体协作,理解 Supervisor 和子 Agent 的分工模式。
3.2 环境准备
本文代码基于 Python,建议使用虚拟环境管理依赖。具体版本号建议以你实际安装时官方文档为准,下面演示的是通用思路。
# 创建虚拟环境 python -m venv .venv source .venv/bin/activate # Windows 环境执行 .venv\Scripts\activate # 安装核心依赖 pip install langchain langchain-openai langchain-community pip install langgraph pip install chromadb langchain-chroma pip install mcp安装完成后,建议先确认核心包能正常导入:
python -c "import langchain, langgraph; print(langchain.__version__); print(langgraph.__version__)"执行这段如果没有任何报错,说明 LangChain 和 LangGraph 都装好了。这里需要提醒一句:LangChain 的版本变化较快,不同大版本的 API 可能存在差异。如果你看的是 1 年以前的教程,代码跑不通不一定是你写错了,很可能是 API 变了。所以实际项目里一定要锁定版本,在多人在线协作时,团队应该约定一个固定的 requirements.txt。
3.3 密钥与配置准备
调用大模型需要准备 API Key。建议把密钥放在环境变量中,而不是直接写在代码里。以 OpenAI 兼容接口为例:
export OPENAI_API_KEY="sk-你的密钥"如果使用的是国产模型或本地模型,只要它提供 OpenAI 兼容接口,都可以通过调整 base_url 来接入。比如把 base_url 指向本地服务:
from langchain_openai import ChatOpenAI llm = ChatOpenAI( model="your-model-name", api_key="your-key", base_url="http://localhost:8000/v1", # 按实际服务地址填写 )这样做的好处是:你的业务代码不变,只改配置就能切换模型服务商,这也是 LangChain 统一抽象带来的实际收益。
4. 实战一:用 LangChain 搭建 RAG 知识库问答
第一个实战,我们做一个本地知识库问答系统。场景是:你有一份内部文档,希望大模型只基于这份文档回答问题,避免它胡说。
为了让代码保持简洁,这里使用本地 TXT 文件作为数据源,使用 Chroma 作为向量数据库。你需要先准备一个knowledge目录,并在里面放一个base.txt作为测试文档。
# 文件路径:rag_qa.py from langchain_community.document_loaders import TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain_chroma import Chroma from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_core.output_parsers import StrOutputParser # 1. 加载文档 loader = TextLoader("./knowledge/base.txt", encoding="utf-8") docs = loader.load() # 2. 文档切片 splitter = RecursiveCharacterTextSplitter( chunk_size=500, chunk_overlap=50, ) chunks = splitter.split_documents(docs) print(f"文档被切分为 {len(chunks)} 个片段") # 3. 向量化并写入 Chroma embeddings = OpenAIEmbeddings(model="text-embedding-3-small") vectorstore = Chroma.from_documents( documents=chunks, embedding=embeddings, persist_directory="./chroma_db", ) # 4. 创建检索器 retriever = vectorstore.as_retriever(search_kwargs={"k": 4}) # 5. 编写提示词模板 prompt = ChatPromptTemplate.from_template( """你是文档助手。请只根据以下资料回答用户问题。 如果资料中没有答案,请直接说“资料里没有相关内容”,不要自行编造。 资料: {context} 问题: {question} """ ) # 6. 组装 LCEL 链 llm = ChatOpenAI(model="gpt-4o-mini", temperature=0) chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser() ) # 7. 提问验证 answer = chain.invoke("LangGraph 和 LangChain 有什么区别?") print(answer)这段代码完整展示了一个最小 RAG 链路,几个关键点值得展开:
- 切片参数:
chunk_size=500表示每段约 500 个字符,chunk_overlap=50表示相邻片段有 50 个字符重叠,目的是避免完整语义被切断。实际项目中切片大小要根据文档类型和模型上下文窗口调整,没有一个万能值。 - 检索参数:
k=4表示召回 4 个最相关的片段。召回太少可能漏掉答案,召回太多会引入噪声,甚至超过模型上下文限制。 - Prompt 约束:在提示词中强制模型“只根据资料回答”,这是 RAG 防止幻觉的最基础手段。但要注意,提示词约束不是万能的,真正要保证回答质量,还得在检索质量上下功夫。
- LCEL 管道:
{"context": retriever, "question": RunnablePassthrough()}表示把用户问题同时传给检索器和占位符,最终拼装成 Prompt。这里的|符号表示把上一个组件的输出传给下一个组件。
运行这段代码之前,确保你的OPENAI_API_KEY已配置。首次运行会自动建立 Chroma 向量库,后续运行不需要重新入库。如果你想清理环境,删除./chroma_db目录即可。
运行成功后,你会看到模型基于文档内容生成的回答。如果回答内容不在你的文档里,说明检索没有命中或者 Prompt 约束没生效,这是排查 RAG 问题的两个核心方向。
5. 实战二:用 LangGraph 把 RAG 升级成 Agent
第一阶段的 RAG 是“一问一答”的直线流程:收到问题、检索、生成、结束。这种模式在简单场景下够用,但存在一个明显问题:模型没有决策能力。它不能判断“当前检索结果是否足够”,也不能决定“是不是需要换个关键词再查一次”,更不能回答“我需要查一下数据库”这种工具调用需求。
LangGraph 的出现就是为了解决这类问题。我们用 LangGraph 把刚才的 RAG 逻辑封装成一个 Tool,让模型自己决定是否调用它,甚至可以在回答之前进行多轮工具调用。
# 文件路径:agent_graph.py from typing import Annotated, TypedDict from langchain_openai import ChatOpenAI from langchain_core.tools import tool from langchain_core.messages import HumanMessage from langgraph.graph import StateGraph, START, END from langgraph.graph.message import add_messages # 1. 定义 Agent 状态 class AgentState(TypedDict): messages: Annotated[list, add_messages] # 2. 定义一个知识库查询工具 @tool def query_knowledge(question: str) -> str: """查询本地知识库,返回与问题相关的资料片段。""" # 实际项目中可以复用上一节 RAG 的检索逻辑 # 这里用静态字符串演示工具调用流程 return "LangGraph 是一个负责状态编排的框架,LangChain 是组件库,两者是配合关系。" tools = [query_knowledge] llm = ChatOpenAI(model="gpt-4o-mini", temperature=0).bind_tools(tools) # 3. Agent 节点:模型决定是否调用工具 def agent_node(state: AgentState): response = llm.invoke(state["messages"]) return {"messages": [response]} # 4. 工具节点:执行模型发起的工具调用 def tool_node(state: AgentState): last_message = state["messages"][-1] tool_calls = last_message.tool_calls results = [] for call in tool_calls: if call["name"] == "query_knowledge": result = query_knowledge.invoke(call["args"]) results.append(result) return {"messages": results} # 5. 条件路由:有工具调用就进工具节点,否则结束 def route_after_agent(state: AgentState): last_message = state["messages"][-1] if last_message.tool_calls: return "tools" return "end" # 6. 构建状态图 graph_builder = StateGraph(AgentState) graph_builder.add_node("agent", agent_node) graph_builder.add_node("tools", tool_node) graph_builder.add_edge(START, "agent") graph_builder.add_conditional_edges( "agent", route_after_agent, {"tools": "tools", "end": END}, ) graph_builder.add_edge("tools", "agent") graph = graph_builder.compile() # 7. 运行 Agent result = graph.invoke({ "messages": [HumanMessage(content="LangGraph 和 LangChain 有什么区别?")] }) print(result["messages"][-1].content)这个示例是 LangGraph Agent 的最小骨架,结构值得反复看:
- State 是核心:
AgentState里只定义了一个messages字段,用Annotated[list, add_messages]声明这个字段在每次节点返回后是追加而不是覆盖。这就是 LangGraph 状态管理的核心机制。 - Agent 节点:把模型绑定工具后,模型输出有两种可能。一是直接给出最终回答,此时
tool_calls为空;二是希望调用工具,此时tool_calls里有工具名和参数。模型自己决定走哪条路。 - Tool 节点:Agent 发起工具调用后,由 Tool 节点真正执行函数,并把执行结果作为一条消息放回状态。
- 条件边:
route_after_agent是决策路由,返回"tools"就进入工具节点,返回"end"就结束。这种“模型 - 工具 - 再模型”的循环,就是 Agent 与普通 Chain 最本质的差别。
运行这段代码,如果一切正常,你会看到模型先调用工具、再基于工具返回内容组织答案的过程。这和上一节 RAG 的直接问答体验不一样:模型不再是固定流程中的一个执行器,而是流程的控制者。
实际开发中,很多人把 Agent 代码写好后,发现模型没有发起工具调用。最常见的排查点是:忘记调用bind_tools(tools),或者模型本身不支持工具调用。另外,工具的描述写得是否清晰也直接影响调用准确率。工具描述应该是“什么时候用、做什么事”,而不是简单一句话。
6. 实战三:用 MCP 给 Agent 接上外部工具
RAG 解决了“查资料”的问题,LangGraph 解决了“决策循环”的问题,但实际业务里还有一大类需求没覆盖:Agent 怎么连数据库、连 HTTP 接口、连内部系统。每个系统都手写一套工具接入代码,既重复又难维护,于是 MCP 协议的价值就体现出来了。
MCP 的核心是把工具调用标准化。对 Agent 开发者来说,你不需要关心对方内部是怎么实现的,只需要按协议与 MCP Server 建立连接、获取工具列表、发起工具调用。这个过程很像插件机制,但它是跨应用的标准协议。
6.1 MCP 客户端配置示例
以 Claude Code 风格的 MCP 客户端配置为例,下面这段 JSON 用于声明一个名为database的 MCP Server:
{ "mcpServers": { "database": { "command": "python", "args": ["mcp_db_server.py"], "env": { "DATABASE_URL": "postgresql://user:pass@localhost:5432/app" } } } }配置项含义:command是启动命令,args是启动参数,env是传给该服务进程的环境变量。配置完成后,客户端会启动你的 MCP Server,自动发现它暴露的工具。
6.2 自定义 MCP Server 示例
下面用 Python 的 MCP SDK 写一个极简的数据库查询 MCP Server。注意这里只演示结构,实际连接数据库时建议使用只读账号、最小权限,并在生产环境配合网关和审计策略。
# 文件路径:mcp_db_server.py from mcp.server.fastmcp import FastMCP mcp = FastMCP("db-helper") @mcp.tool() def query_readonly(sql: str) -> str: """对授权数据库执行只读 SQL 查询,返回文本结果。 只允许 SELECT 查询,严禁执行写操作。 """ # 实际项目中在这里连接数据库并执行 SQL # 建议使用只读账号、超时控制、LIMIT 限制返回行数 return "查询结果示例:当前共有 128 条记录" if __name__ == "__main__": mcp.run()这段代码声明了一个名为query_readonly的工具。任何支持 MCP 协议的 Agent 框架,都可以通过标准流程发现这个工具,并在需要查询数据库时调用它。
把 MCP 接入 Agent 的实际收益是:你的 Agent 工具层不再和某个特定系统绑定。想要新增一个数据源,只要开发对应的 MCP Server,让协议去完成对接,上层 Agent 逻辑基本不用改。
实践中有几个重要提醒:
- 权限与安全边界:MCP Server 暴露的是对真实系统的访问能力,必须做授权和鉴权。上面例子里的工具名刻意写成
query_readonly,因为生产环境的默认原则就是只读优先,能不给写权限就不要给。 - 错误处理:MCP 工具调用可能因为网络、权限、数据格式原因失败,Agent 不能因为一次工具报错就整个崩溃,应该把错误信息传回模型,让它决定下一步怎么做。
- 配置管理:不要把数据库密码直接写在 MCP Server 的 JSON 配置里,更推荐使用环境变量或者密钥管理服务。
热搜词里出现过的“claude code 安装 mcp 读取数据库”其实就是这类场景的一个具体应用:安装好 MCP Server 后,通过自然语言让 Agent 查询数据库。理解上面的最小示例后,再看这类教程就不会觉得神秘了。
7. 多智能体协作:编排与分工
当单 Agent 面临的任务变复杂,比如既要检索知识库、又要算数据、还要写报告、最后还要人审,把所有逻辑塞进一个 Agent 会导致提示词越来越长、上下文越来越乱、模型决策越来越不稳定。多智能体协作就是用“拆分”的思路解决这个问题。
多智能体不是“多开几个 Agent 同时跑”,而是有明确的协作模式。最常见的有三种:
- Supervisor 模式:一个管理者 Agent 负责任务分配,多个 Worker Agent 分别执行子任务,最终由管理者汇总输出。
- Pipeline 流水线模式:任务按固定阶段传递,比如先检索、再分析、再生成,每个阶段由不同 Agent 完成。
- 分层模式:高层 Agent 拆任务,中层 Agent 再细化,底层 Agent 执行。适合大型企业级系统。
LangGraph 对多智能体的支持非常自然,因为每个 Agent 本身就是一个子图,可以被当作一个节点加入到更大的图中。下面是一段结构示意代码,重点是理解“子图即节点”的组装思路:
# 文件路径:multi_agent_supervisor.py(结构示意,伪代码级别) from langgraph.graph import StateGraph, START, END # 实际项目中,这些函数会返回编译好的 LangGraph 图对象 def build_researcher(): """负责检索和资料整理的研究 Agent。""" pass def build_writer(): """负责成稿写作的 Agent。""" pass def build_reviewer(): """负责质量审核的 Agent。""" pass def supervisor_node(state): """管理者节点:根据任务类型决定接下来交给谁。""" # 这里会根据 state 中的任务描述做路由判断 return {"next_agent": "researcher"} def route_after_supervisor(state): return state["next_agent"] # 构建顶层图 builder = StateGraph(OverallState) builder.add_node("supervisor", supervisor_node) builder.add_node("researcher", build_researcher()) builder.add_node("writer", build_writer()) builder.add_node("reviewer", build_reviewer()) builder.add_edge(START, "supervisor") builder.add_conditional_edges( "supervisor", route_after_supervisor, {"researcher": "researcher", "writer": "writer", "reviewer": "reviewer"}, ) # 还需要根据实际流程补充普通边和条件边多智能体的价值是让每个 Agent 只关心一个职责,提示词更短、状态更干净、问题更容易定位。但代价也很明显:系统复杂度上升、token 消耗增加、调试难度变大。
所以一个务实的建议是:先单 Agent,后多智能体。你不要因为听到“多智能体”是热点就强行拆成多个 Agent。如果单 Agent 加工具调用能解决需求,那就是最优方案。只有在提示词臃肿到没法维护、上下文频繁超限、或者确实需要不同领域模型分工时,再考虑引入 Supervisor 模式。
8. 常见问题与排查方法
零基础跑 LangChain 和 LangGraph 代码,遇到报错是常态。这里整理几个最高频的问题:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 安装失败或导入报错 | 包版本冲突,或多环境混乱 | 检查 pip list,确认是否在虚拟环境内 | 统一使用虚拟环境;锁定 requirements.txt;必要时重建环境 |
| API Key 报错或鉴权失败 | 环境变量未生效,或密钥权限不足 | 打印环境变量是否读取成功;测试一次原始 API 调用 | 正确配置环境变量;检查 Key 是否有模型访问权限 |
| RAG 回答与文档无关 | 文档没被成功加载,或检索切片过大/过小 | 打印检索召回的片段内容,检查向量库文件 | 调整 chunk_size;检查文档编码;清除向量库重新入库 |
| 模型没有发起工具调用 | 忘记 bind_tools;工具描述不清晰;模型不支持工具调用 | 打印模型原始输出,确认 tool_calls 是否存在 | 在代码里显式 bind_tools;优化工具 name 和 description |
| Agent 进入死循环 | 条件路由写错,或工具始终返回可继续操作的结果 | 给图添加最大步数限制;打印每一步的状态变化 | 检查条件边返回值;在 compile 时配置 recursion_limit |
| MCP 工具找不到 | Server 没启动,或协议版本不兼容 | 查看 MCP Server 日志;确认端口/进程状态 | 校验配置中的 command/args/env;检查 SDK 版本 |
印象里很多初学者卡得最久的是 RAG 的“知识没生效”问题。这里强调一个排查技巧:不要只看最终答案,而要先打印检索器返回的片段内容。如果片段里根本没有正确答案,问题在检索环节,跟模型、Prompt 都无关;如果片段里有答案但模型回答错了,问题才在生成环节。这样定位问题会快很多。
还有一个 LangGraph 特有的大坑:执行 Agent 时直接报 “agent execution terminated due to error”,这是网络热搜词里也出现过的报错。它通常不是 LangGraph 本身的问题,而是节点内部抛出的异常,比如工具函数报错、模型调用超时、API 限流。排查时先在节点内部加 try/except,把异常信息打印出来,不要只看图执行的外层报错。
9. 工程化最佳实践与学习建议
实战代码能跑通只是第一步,真正要把它用到项目里,有几条工程化建议值得认真对待。
9.1 配置与密钥管理
把 API Key、模型名、base_url、向量库连接信息全部抽到配置文件中,使用.env或环境变量管理。代码仓库里不要提交任何真实密钥。团队协作时,统一使用配置中心或密钥管理服务,而不是靠口头传递配置文件。
9.2 版本锁定与复现
LangChain、LangGraph 迭代速度快,api 变动频繁。项目里必须使用requirements.txt或pyproject.toml锁定版本,并在 README 里写清楚测试过的版本组合。遇到网上教程代码跑不通,第一时间看目标版本的官方文档或迁移说明,不要盲改。
9.3 日志与可观测性
Agent 应用和普通后端接口不同,它的中间过程非常多:模型调用、工具选择、工具执行结果、路由决策。没有日志,出了问题根本无从查起。建议至少记录几类信息:
- 用户原始输入;
- 每次模型返回的完整消息,包括 tool_calls;
- 每次工具调用的入参和返回结果;
- 最终回答和用到的关键参考资料。
很多 LangGraph 应用会搭配 LangSmith 这类可观测性工具做链路追踪,小项目至少也要在关键节点打印结构化日志。
9.4 安全与权限
Agent 能调用工具,意味着它在某些场景下掌握了“执行能力”。生产环境必须遵循最小权限原则:数据库用只读账号,外部接口使用独立凭据,高危操作增加人工确认节点。LangGraph 本身支持在图中插入断点,可以在执行敏感操作前停下来等人工审批。这个能力在业务落地时价值很大。
9.5 评估优先于调参
不管是 RAG 还是 Agent,都不要靠“感觉回答变好了”来判断效果。更稳妥的做法是准备一批标准问题集,每次改动后记录回答的准确率、检索命中率、调用成功率等指标。RAG 还可以拆开评估:检索环节单独评估召回率,生成环节单独评估回答质量。没有评估体系的 Agent 项目,后面会越改越混乱。
9.6 给零基础学习者的最后建议
学 LangChain 和 LangGraph 最忌讳的是“收藏一百篇教程然后只看不练”。正确姿势是找一个二十行左右的示例代码,先跑通,再改其中的模型、工具、数据源,最后尝试加一个自己的工具函数。只要完整跑通一遍 RAG、一遍 Agent、一遍 MCP 工具接入,你就能超过大部分停留在概念层的初学者。
时间安排上,建议按两周来规划:前三天学 LangChain 核心对象,四到六天做 RAG 实战,七到十天做 LangGraph 工具调用和 MCP 接入,最后留几天尝试拆一个多智能体小项目。每个阶段都要以“跑通代码”为终点,而不是以“看完文档”为终点。
这篇文章真正想帮你解决的问题不是某一个 API 怎么用,而是帮你建立一张完整的 Agent 开发地图:LangChain 提供零件,LangGraph 提供控制流,RAG 提供知识,MCP 提供工具,多智能体是最后的组合形态。接下来你要做的,就是打开终端,把第一段 RAG 代码跑起来。跑通了第一条链路,后面所有概念都会开始变得具体。