☰
LangChain 与 LangGraph 实战入门:从链式调用到图状态编排
2026/10/7 6:56:52 网站建设 项目流程

LangChain 与 LangGraph 实战入门:从链式调用到图状态编排

新手第一次打开 LangChain 文档,通常会有两种反应:要么觉得"这不就是帮我调 API 的封装吗",要么被一堆概念——Chain、Agent、Memory、Retriever、Tool——砸晕。两种反应都正常,但也都片面。LangChain 的真正价值不是省掉那几行 requests 代码,而是把大模型应用的通用组件——模型接入、提示词管理、检索、记忆、工具调用——沉淀成标准模块,让你像搭积木一样拼出业务链路。而 LangGraph 则更进一步,把复杂工作流从"链"升级为"图",解决了循环、分支、状态恢复这些生产级难题。这篇文章用一个完整项目,带你打通这两个框架的入门到实战。

一、先搞清楚框架的定位:Chain 与 Graph 的分工

很多人分不清 LangChain 和 LangGraph 的关系。简单说:LangGraph 是建立在 LangChain 之上的工作流编排框架,二者面向不同复杂度的问题。

LangChain 解决的是"线性组装"。它的核心抽象是 Chain(链):把"提示模板 → 模型调用 → 输出解析"串成一条流水线,再支持加记忆、接检索。它适合交互模式固定的应用:问答机器人、摘要工具、翻译系统。你可以把 LangChain 想象成一条流水线,原料从一头进去,成品从另一头出来。

LangGraph 解决的是"非线性编排"。它的核心抽象是 Graph(图):节点(Node)是执行单元,边(Edge)定义流转条件,支持循环(Agent 反复"思考→行动")、分支(按条件走不同路径)、并行(多路同时执行)、检查点(中断后从断点恢复)。它把工作流画成一张有向图,每个步骤的结果存进共享状态(State),后续节点都能访问。

用一句话记住二者分工:流程是线性的用 Chain,流程有循环分支用 Graph。Agent 类的自主决策系统天然带循环,所以工程实践中 Agent 的主流实现是 LangGraph,而不是裸的 LangChain。

二、LangChain 最小实战:搭一条带记忆的问答链

先从最实用的场景入手:搭一个能记住上下文的客服问答链。第一步,统一模型接入。LangChain 把所有模型封装成统一的 ChatModel 接口,切换厂商只改一行配置:

fromlangchain_openaiimportChatOpenAI llm=ChatOpenAI(model="qwen-plus",api_key="your-key",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",temperature=0.3,)``` 第二步,设计提示词模板。不要直接拼字符串,用 `PromptTemplate` 把变量和模板分离: ```pythonfromlangchain.promptsimportPromptTemplate template="""你是一位耐心的电商客服。 用户问题:{question} 请用不超过 100 字回答。"""prompt=PromptTemplate.from_template(template)

第三步,加上记忆。LangChain 记忆机制的本质是"保存历史 → 下一轮重新注入提示词",用MessagesPlaceholder在模板里占位:

fromlangchain.memoryimportConversationBufferMemoryfromlangchain_core.promptsimportMessagesPlaceholder memory=ConversationBufferMemory(return_messages=True)prompt=ChatPromptTemplate.from_messages([("system","你是电商客服,回答简洁专业"),MessagesPlaceholder(variable_name="history"),("human","{input}"),])chain=prompt|llm# LangChain 0.3+ 的管道语法

第四步,跑起来并管理历史:

result=chain.invoke({"input":"我的订单 3 天没到货,怎么回事?","history":memory.chat_memory.messages})memory.chat_memory.add_user_message("我的订单 3 天没到货")memory.chat_memory.add_ai_message(result.content)

注意生产环境要用ConversationBufferWindowMemory(只保留最近 N 轮)或ConversationSummaryMemory(把旧对话摘要压缩),否则历史无限膨胀,token 成本爆炸。

三、LangGraph 核心概念:State、Node、Edge

LangGraph 的思维模型和传统编程差异很大,建议先建立三个概念:

State(状态):工作流执行中需要保存和传递的数据,是一个 TypedDict。每个节点的返回值都会合并进 State,后续节点可以读取。这是 LangGraph 与普通函数调用的本质区别——状态是显式的、跨节点共享的。

Node(节点):一个执行单元,接收 State,返回 State 的一部分。节点里可以是模型调用、工具调用、任意 Python 函数。

Edge(边):定义节点之间的流转关系。普通边是"执行完 A 去 B";条件边是"根据 State 里的字段决定去哪个分支";还有 START 和 END 两个特殊节点,标记工作流的起点和终点。

fromtypingimportTypedDict,Annotatedfromlanggraph.graphimportStateGraph,ENDclassState(TypedDict):question:strplan:stranswer:strdefplan_node(state:State)->dict:# 调用模型生成执行计划return{"plan":"1. 检索资料 2. 组织回答"}defanswer_node(state:State)->dict:return{"answer":f"根据计划[{state['plan']}],这是最终答案"}graph=StateGraph(State)graph.add_node("plan",plan_node)graph.add_node("answer",answer_node)graph.add_edge("plan","answer")graph.add_edge("answer",END)graph.set_entry_point("plan")app=graph.compile()result=app.invoke({"question":"帮我分析一下竞品"})

这个例子很简单,但它揭示了 LangGraph 的核心价值:流程可见、可控、可恢复。真实项目中,节点之间的流转会变成这样:“先判断用户意图 → 意图是查资料就走 RAG 分支 → 是算数据就走代码执行分支 → 失败就进入降级节点”。这种多分支流程用 if-else 硬写会变成意大利面条,用图来表达则一目了然。

四、LangGraph 实战:做一个带工具调用的研究助手

接下来做一个真正有价值的案例:一个"研究助手" Agent——用户抛出一个问题,Agent 自己决定是直接回答,还是先调用搜索工具找资料,再综合成答案。这正是"Agent 与普通链"的分水岭:模型不再是"一次输出",而是进入"思考→行动→观察→再思考"的循环。

先定义两个工具:搜索和计算。工具的description极其重要,因为模型就是靠它判断"什么时候该用哪个工具":

fromlangchain_core.toolsimporttool@tooldefweb_search(query:str)->str:"""在互联网上搜索最新信息。当问题涉及实时数据、新闻或外部资料时使用。"""returnsearch_engine(query)@tooldefcalculator(expression:str)->str:"""执行数学计算。当用户要求计算、比较数字时使用。"""returnstr(eval(expression))``` 然后让模型具备"工具决策"能力:把工具以 JSON Schema 形式注入请求,模型返回的响应中会携带 `tool_calls` 字段,指示"我想调用哪个工具、传什么参数"。你的代码执行工具后,把结果以 tool 角色消息回传给模型,模型继续生成。 ```pythonfromlanggraph.prebuiltimportcreate_react_agent agent=create_react_agent(llm,tools=[web_search,calculator],prompt="你是一个严谨的研究助手,先思考需要什么信息,再决定是否调用工具。",)``` `create_react_agent` 是 LangGraph 提供的现成 Agent 实现,它内置了完整的"思考-行动-观察"循环:模型每轮先判断要不要调工具,调用后拿到结果再判断下一步,直到它认为可以输出最终答案或触发停止条件。这个预构建 Agent 非常适合快速验证,但生产系统通常要自己定制循环——增加最大步数限制、超时熔断、目标达成判定,防止模型死循环或跑偏。## 五、LangSmith 与可观测性:调试 Agent 的必备工具手写 Agent 循环最痛苦的是"黑盒":模型到底在想什么?为什么它调了那个工具?哪个节点的状态出了问题?LangSmith 解决的就是这个问题——它把每一次运行的完整轨迹记录下来:每个节点的输入输出、模型调用详情、token 消耗、耗时。 接入非常简单,设置两个环境变量即可: ```bash export LANGSMITH_TRACING=true export LANGSMITH_API_KEY="your-key"

之后每次invoke会自动上报轨迹,你可以在 LangSmith 控制台看到一张可交互的调用图:从用户提问开始,哪个节点做了规划、哪个节点调了工具、工具返回了什么、最终答案怎么生成,全部可视。调试时还能直接回放某次失败运行,对比不同 prompt 的效果差异。

我的建议是:从项目第一天就接上追踪,不要等出了问题再补。Agent 类应用的调试成本远高于普通后端,一份完整的调用轨迹能帮你省掉大量的猜测时间。

六、工程实践:从 Demo 到生产的四个关键改造

框架能帮你把 Demo 跑起来,但生产环境有一堆框架不管的事,需要你自己补上:

第一,状态持久化。LangGraph 的 State 默认在内存里,进程重启就丢。生产环境配置checkpointer(如 SqliteSaver 或 PostgresSaver),让任务状态持久化到数据库,这样长任务中断后可以从断点恢复,也支持并发任务的隔离。多用户系统里,State 还要带上 user_id,防止会话串号。

第二,循环控制与预算。Agent 循环必须有硬性边界:最大执行步数(比如 10 步)、单步超时(比如 30 秒)、总 token 预算。否则一个失控的 Agent 可能在失败的工具上反复重试,把账单烧穿。LangGraph 支持RecursionLimit,超出后强制终止并走降级路径。

第三,工具安全。Agent 能调用的工具就是它的能力边界,也是安全边界。所有工具要做参数校验(防止注入恶意参数)、权限校验(区分管理员工具与普通用户工具)、敏感操作二次确认(删除、转账类操作必须人工确认)。还要在 prompt 里约束模型:工具只做它该做的事。

第四,错误降级。Agent 不是每次都成功的。设计上要预设失败路径:模型输出格式错误 → 重试一次;工具调用失败 → 换工具或告知用户;整体失败 → 返回兜底答案并记录日志。生产系统的可靠性不是靠"模型足够聪明",而是靠"失败时有退路"。

七、框架之外:什么时候别用框架

最后说点反共识的:不是所有场景都需要 LangChain 或 LangGraph。如果你的应用只是"调 API + 拼 prompt",手写一个几百行的调用封装,可能比引入框架更清爽——少一层抽象,少一堆版本兼容问题。框架的价值在于帮你处理"通用但繁琐"的能力(记忆、检索、工具注册、状态管理),当这些能力你确实需要且系统复杂度足够高时,它们才真正划算。

判断标准很简单:如果业务逻辑里的分支和循环超过三四个,或者你需要跨重启恢复任务状态,就值得上 LangGraph;如果只是几条固定流程,Chain 甚至裸代码都够用。技术选型没有银弹,匹配需求才是最好的方案。

结语

LangChain 和 LangGraph 代表的不是"某个库",而是一种工程思维:把大模型应用的通用能力沉淀为模块,把复杂流程建模为可见可控的图。入门它们的正确路径不是背文档,而是带着真实业务问题去实践——先搭一条链,再升级成图,最后补齐状态、追踪、降级这些生产细节。当你亲手把一个会循环决策的 Agent 跑起来,并能在控制台里看清它每一步的思考过程时,你才真正跨过了"会用框架"到"会造系统"的门槛。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询