当前位置: 首页 > news >正文

LangGraph核心揭秘:让AI「想一步、停一步、判断一步」的大模型学习之旅(收藏版)

本文深入解析LangGraph的底层执行引擎,通过状态机设计实现AI的智能控制流。文章详细介绍了状态机三要素(状态、节点、边)在LangGraph中的应用,以及Reducer的核心机制如何实现状态更新。此外,还探讨了条件边、并行执行和编译产物的相关知识,帮助读者全面理解LangGraph的工作原理,为构建复杂的AI应用打下坚实基础。

上一篇我们把 LangChain Memory 模块拆了个底朝天,搞清楚了截断、总结、检索三种记忆方案各自的适用场景。这一篇我们进入 LangGraph 的核心地带——它的底层执行引擎。

你有没有想过:为什么同样是调用 LLM,用了 LangGraph 之后,AI 就能「想一步、停一步、判断一步」?就能在工具调用和 LLM 推理之间来回切换,还不会乱套?

答案就藏在它的状态机设计里。

01 先说说 LangChain 的老问题

LangChain 的早期架构是线性的——Chain。

用户输入 → PromptTemplate → LLM → OutputParser → 输出

这个模型干净利落,但有个致命弱点:控制流是固定的。

一旦你想实现「如果 LLM 觉得需要查数据库就查,不需要就跳过」,或者「出错了重试三次」,你会发现原来的 Chain 根本放不下这些逻辑。要么把判断逻辑硬编码在节点里,要么用 Python 的 if/else 在外层手动管流程——乱成一锅粥。

现实中的 Agent 场景根本不是线性的:

  • 调工具 → 看结果 → 决定调下一个还是直接回答
  • 生成草稿 → 自我审查 → 不行就重写
  • 多轮对话 → 根据意图走不同分支

这些都需要带状态的循环控制流。这正是 LangGraph 解决的核心问题。


02 状态机是什么:用最简单的例子解释

状态机(State Machine)不是什么新概念。你手机的蓝牙就是个状态机:

[关闭] --打开--> [扫描中] --发现设备--> [配对中] --成功--> [已连接] | --失败--> [扫描中]

三个核心要素:

┌─────────────────────────────────────────────┐ │ 状态机三要素 │ ├──────────┬──────────────────────────────────┤ │ State │ 当前的数据快照(系统处于什么情况)│ │ Node │ 执行动作,并更新 State │ │ Edge │ 决定下一步去哪个 Node │ └──────────┴──────────────────────────────────┘

LangGraph 就是把这套机制套在了 LLM 上:

  • State = 对话历史 + 工具结果 + 中间变量
  • Node = LLM 调用 / 工具执行 / 业务逻辑
  • Edge = 普通跳转 / 条件分支(Conditional Edge)

03 StateGraph 执行引擎:它的心脏长什么样

打开 LangGraph 的源码(Python 版langgraph/graph/state.py,JS 版同理),你会看到StateGraph类维护了几个核心数据结构:

┌──────────────────────────────────────────────────┐ │ StateGraph 内部 │ ├─────────────────┬────────────────────────────────┤ │ nodes │ Map<名称, 函数> │ │ edges │ Map<from, to[]> │ │ conditional_ │ Map<from, (state)=>节点名> │ │ edges │ │ │ channels/ │ 每个状态字段的 Reducer │ │ schema │ │ └─────────────────┴────────────────────────────────┘

当你调用graph.compile()时,它做了什么?

compile() 阶段 │ ├─ 验证图结构(有没有孤立节点?有没有到 END 的路径?) ├─ 构建邻接表(预计算每个节点的后继) ├─ 初始化 Channels(每个状态字段注册 Reducer) └─ 返回 CompiledGraph(可以 invoke/stream)

compile()本质上是把你「描述的图」变成「可执行的调度器」。


04 一次完整执行:从 invoke 到节点运行的全流程

来看最简单的例子,一个单节点 LLM Agent:

import { StateGraph, START, END } from "@langchain/langgraph"; import { Annotation } from "@langchain/langgraph"; import { ChatOpenAI } from "@langchain/openai"; import { HumanMessage } from "@langchain/core/messages"; // 1. 定义状态结构 const AgentState = Annotation.Root({ messages: Annotation<HumanMessage[]>({ reducer: (prev, next) => [...prev, ...next], default: () => [], }), }); // 2. 初始化 LLM const llm = new ChatOpenAI({ model: "gpt-4o-mini" }); // 3. 定义节点函数 async function callLLM(state: typeof AgentState.State) { const response = await llm.invoke(state.messages); return { messages: [response] }; } // 4. 构建图 const graph = new StateGraph(AgentState) .addNode("llm", callLLM) .addEdge(START, "llm") .addEdge("llm", END) .compile(); // 5. 运行 const result = await graph.invoke({ messages: [new HumanMessage("你好,介绍一下自己")], });

执行流程逐步拆解:

graph.invoke({ messages: [...] }) │ ▼ 1. 初始化 State messages = [HumanMessage("你好...")] │ ▼ 2. 调度器从 START 出发 → 找到边:START → "llm" │ ▼ 3. 执行节点 "llm" callLLM(state) 被调用 → llm.invoke(messages) → 返回 { messages: [AIMessage("我是...")] } │ ▼ 4. 合并状态(Reducer) 新 messages = [...旧, AIMessage("我是...")] │ ▼ 5. 调度器检查下一步 → "llm" 的边指向 END → 执行结束 │ ▼ 6. 返回最终 State


05 Reducer:状态更新的核心机制

这是很多人没搞清楚的地方。

节点函数返回的不是「新 State」,而是「State 的更新片段」。LangGraph 用 Reducer 把旧状态和更新片段合并。

// 三种常见 Reducer 写法 // 方式1:用内置 messagesStateReducer(追加消息) const State1 = Annotation.Root({ messages: Annotation<BaseMessage[]>({ reducer: (prev, next) => [...prev, ...next], }), }); // 方式2:覆盖(最新值覆盖旧值) const State2 = Annotation.Root({ step: Annotation<number>({ reducer: (_, next) => next, // 直接替换 }), }); // 方式3:累加计数 const State3 = Annotation.Root({ callCount: Annotation<number>({ reducer: (prev, next) => prev + next, default: () => 0, }), });

Reducer 的执行时机:

节点返回 { key: value } │ ▼ 对每个 key,找到对应 Reducer newState[key] = reducer(oldState[key], value) │ ▼ 生成新 State 快照 (旧 State 不变,不可变数据结构)

关键点:State 是不可变的。 每次节点执行都产生一个新的 State 快照,旧快照被保留(这是 Checkpoint 能实现的基础,后面讲)。


06 图的调度器:它怎么决定下一步去哪

这是 LangGraph 最有意思的部分——调度器(Scheduler)。

调度器本质上是一个事件循环:

while 当前节点 != END: 1. 执行当前节点 node(state) → partial_update 2. 用 Reducer 合并状态 → new_state 3. 查询当前节点的出边 - 普通边:直接去下一个节点 - 条件边:调用路由函数 router(new_state) → 返回节点名 4. 把下一个节点加入执行队列 5. 取队列头 → 重复

条件边(Conditional Edge)长这样:

import { StateGraph, START, END } from "@langchain/langgraph"; // 路由函数:根据 state 返回下一个节点名 function routeAfterLLM(state: typeof AgentState.State): string { const lastMessage = state.messages[state.messages.length - 1]; // 如果 LLM 想调工具 if ("tool_calls" in lastMessage && lastMessage.tool_calls?.length) { return "tools"; // → 去工具节点 } return END; // → 直接结束 } const graph = new StateGraph(AgentState) .addNode("llm", callLLM) .addNode("tools", callTools) .addEdge(START, "llm") .addConditionalEdges("llm", routeAfterLLM, { tools: "tools", // 映射:路由函数返回值 → 节点名 [END]: END, }) .addEdge("tools", "llm") // 工具执行完回到 LLM .compile();

执行路径示意:

START → llm → [判断] → 需要工具? Yes → tools → llm → [判断] → 不需要了? Yes → END No → END

这就是 ReAct Agent 的本质:一个带条件边的循环图。


07 并行执行:Fan-out / Fan-in 模式

LangGraph 支持一个节点连到多个后继节点,实现并行执行。

// Fan-out:一个节点触发多个并行节点 const parallelGraph = new StateGraph(AgentState) .addNode("start", startNode) .addNode("search_web", searchWeb) // 并行 .addNode("search_db", searchDB) // 并行 .addNode("merge", mergeResults) // 合并 .addEdge(START, "start") .addEdge("start", "search_web") // 同时出发 .addEdge("start", "search_db") .addEdge("search_web", "merge") // 都完成后汇聚 .addEdge("search_db", "merge") .addEdge("merge", END) .compile();

调度器处理并行的方式:

start 节点执行完毕 │ ├──→ search_web(加入执行队列) └──→ search_db(加入执行队列) 执行队列:[search_web, search_db] 同时调度(异步并发执行) 两者都完成后: merge 节点的所有前驱都就绪 → merge 入队 │ ▼ merge 执行 → END

这个 Fan-out/Fan-in 模式,是并行搜索、多 Agent 协作的基础。


08 编译产物:CompiledGraph 里藏了什么

compile()返回的CompiledGraph暴露了四个主要接口:

interface CompiledGraph { // 同步执行,返回最终 State invoke(input: State, config?: RunnableConfig): Promise<State>; // 流式执行,每个节点完成后 yield 一次 stream( input: State, config?: RunnableConfig ): AsyncGenerator<Record<string, State>>; // 可视化图结构(调试用) getGraph(): DrawableGraph; // 获取当前状态(需要 Checkpointer) getState(config: RunnableConfig): Promise<StateSnapshot>; }

stream()的输出格式:

for await (const chunk of graph.stream(input)) { // chunk 是一个对象:{ 节点名: 该节点产生的状态更新 } // 例如: // { llm: { messages: [AIMessage(...)] } } // { tools: { messages: [ToolMessage(...)] } } console.log(chunk); }

这就是为什么前端能实现「打字机效果」——每个节点完成,前端就能收到一次更新。


总结

这篇我们从底层拆解了 LangGraph 把 LLM 变成状态机的核心机制:

  • StateGraph 三要素:State 存数据、Node 执行动作、Edge 决定走向,缺一不可

  • Reducer 是关键:节点返回的是「更新片段」而非「完整新状态」,Reducer 负责合并,State 始终不可变

  • 调度器是心脏:本质是一个事件循环,条件边让它能根据运行时状态动态决策

  • compile() 的意义:把声明式的图描述变成可执行的调度引擎,做结构验证和邻接表预计算

  • 并行靠 Fan-out:多条出边同时触发,Fan-in 等待所有前驱完成,调度器自动处理同步

  • stream() 是流式基础:每个节点完成即 yield,这是打字机效果和实时反馈的技术支撑

    最后

如果说程序员已经是高薪职业,那么干AI的程序员,就是高薪中的高薪。

现在的市场,已经用数据给程序员指明了方向:学AI大模型,就是冲刺高薪的最优解!

看着身边越来越多的同行转型大模型、拿到高薪offer,很多人心里都动了心,但真正的难题来了:零基础小白不知道从哪入门?有基础的程序员找不到系统学习路径?实战项目练手无门?面试不知道考什么?

别慌!今天就给大家整理了一份【2026年最新版】AI大模型免费学习资源包,覆盖从入门到实战、从理论到面试、从基础到进阶的全流程,所有资料均已整理归档,无冗余、无套路,免费分享给每一位想抓住AI风口的程序员和小白!

👇👇扫码免费领取全部内容👇👇

1、大模型系统化学习路线

2、大模型学习书籍&文档

3、AI大模型最新行业报告

4、大模型项目实战&配套源码

5、大模型大厂面试真题

四阶段精细化学习规划(附时间节点,可直接照做)

结合上述资源,给大家整理了一份可直接落地的四阶段学习规划,总时长约2个月,小白可循序渐进,程序员可根据自身基础调整节奏,高效掌握大模型核心能力,快速实现从“入门”到“能落地、能面试”的跨越。

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范
第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署
第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建
第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

👇👇扫码免费领取全部内容👇👇

6、这些资料真的有用吗?

这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。

资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

http://www.jsqmd.com/news/1103313/

相关文章:

  • 堆料全能本标杆:机械革命无界 15X Pro(R7 H255 版)深度解析
  • AI期刊论文写作工具哪家好?2026主流平台实测对比与选型建议
  • 计算机毕业设计之房屋中介服务平台
  • 8 款 AI 毕业论文写作工具横向实测,本硕博撰稿避坑全指南
  • 5步轻松实现PC游戏分屏:Nucleus Co-Op让单机游戏变多人派对
  • EM3080-W与PIC18F67K40的条形码识别系统设计
  • Unity Profiler连接抖音开发者工具
  • 《HarmonyOS技术精讲-Core File Kit》第4篇:目录操作与文件遍历
  • 深度解析exif-js:高效读取图片元数据的实战技巧
  • 影刀RPA新手教程:文本清洗与正则提取完全指南——手机号、邮箱、金额、日期提取实战
  • NcmpGui专业工具:高效解锁网易云音乐NCM格式的终极解决方案
  • 新手向 OpenClaw 部署实战,十分钟搭建个人桌面数字员工(含安装包)
  • 【深度指南】5大核心模块:全面掌握AMD Ryzen硬件调试工具SMUDebugTool
  • 深入解析XSS攻击:从反射型到DOM型的攻防实战
  • 如何在5分钟内完成Mac Boot Camp驱动部署?Brigadier终极自动化方案
  • STM32CUBEMX没有配置sys导致的问题
  • Sunshine游戏串流服务器终极指南:免费打造个人专属云游戏平台
  • 别天天手动复制聊天记录了!定时增量同步个人微信,自动喂饱 AI 知识库
  • TMSpeech:Windows本地实时语音转文字的专业解决方案
  • Outfit字体完全指南:9种字重免费开源几何无衬线字体的专业使用教程
  • 品牌实体建设实操:复杂B2B企业如何搭建稳定表达系统
  • 王二明配方茶商城小程序开发指南
  • 东晟密封科技博客:打造密封件技术交流新平台
  • 75.可直接运行!CODESYS/TwinCAT 通用 ST 物料分拣源码|标准四状态机架构
  • 70天倒计时!2026年9月PMP末班车:报名窗口即将开启,现在不冲就真没了
  • 2026本+专科报考资料合集
  • 5个Nucleus Co-op分屏技巧:让单机游戏变多人派对
  • 掌握Microsoft Orleans状态管理:从持久化配置到事务处理
  • 国产大模型本地部署与API调用实战指南
  • 词达人Python智能助手:如何每周节省2.5小时英语学习时间?