一、LangGraph总览LangGraph 运行时底层基于自研的 Pregel 运行时其核心思想借鉴了 Google Pregel 计算模型用于组织和执行复杂的图计算流程。1.0.LangGraph和LangChain的版本迭代及定位LangChain 1.x的定位发生了明显变化旧式 Chain、Retriever、Memory 等组件被迁移至 langchain-classicLCEL 保留为 langchain-core 的底层组合机制但不再是主要开发入口。LangChain 1.x现在聚焦于 Agent 开发核心入口是 create_agent围绕 Agent 提供模型、工具、消息、结构化输出、Middleware 和记忆管理等高层抽象。LangGraph是更底层的编排框架与 Agent Runtime负责复杂工作流和有状态 Agent 的执行提供持久化、流式输出、Durable Execution、Human-in-the-loop 等运行时能力。create_agent 底层基于 LangGraph 实现。二者的定位对比如下对比维度LangChainLangGraph定位Agent 高层开发框架底层编排框架 Agent Runtime核心入口create_agentStateGraph/entrypoint适用场景结构直接的 Agent 应用复杂工作流、持久化状态、长时间运行、人工介入流程控制Agent 循环自动管理精细控制节点、边、条件分支学习成本较低较高LangChain提供易于使用的 Agent 高层抽象LangGraph提供可靠、可持久化且可精细控制的底层执行能力。对于大多数 Agent 项目从 LangChain 的 create_agent 开始即可需要复杂工作流编排、确定性步骤与 Agent 步骤混合、长时间运行或底层状态控制时再引入 LangGraph。1.1. 构成图的基本要素LangGraph 运行时主要由三个基本要素构成State状态、Node节点 和 Edge边State状态LangGraph 运行过程中的共享数据结构用于表示应用在某一时刻的状态快照。它承载了图运行所需的上下文信息、中间结果和后续节点需要读取的数据是节点之间传递信息的核心载体。它与我们在学习 LangChain Agent 时使用的 State 是同一概念。Node节点LangGraph 中的具体执行单元通常实现为一个函数。节点会读取当前 State执行相应的业务逻辑并返回对 State 的局部更新。节点本身并不直接修改全局状态状态的合并与提交由运行时统一完成。Edges边用于定义节点之间的流转关系决定一个节点执行完成后下一步应该进入哪个节点。Edge 可以是固定流转也可以根据当前 State 进行条件判断从而实现分支、循环等复杂控制流程。下图展示了一个非常简单的运行图只有两个计算节点其拓扑结构为START -- node_1 -- node_2 -- END如下图所示1.2. 图运行过程LangGraph 的图运行过程基于 Superstep超步 来组织和推进。Superstep 可以理解为图运行过程中的一次”单步循环”。一次图运行过程从开始到结束就是由一系列连续的 Superstep 串联而成。下文以node_1执行完毕后的Superstep为例说明。每个 Superstep 通常可以分为三个阶段计划/路由阶段Plan / Routing根据当前的 State状态 和 Edge边 的逻辑确定本轮超步中应该被执行的节点。执行阶段Execution运行本轮被选中的节点。如果本轮有多个节点同时被触发它们会并行执行。每个节点都会基于本轮开始时的状态快照进行计算并输出各自对状态的局部更新。在本阶段中一个节点产生的更新不会立即被其他节点读取到。状态更新/提交阶段Update / Commit当本轮所有节点都执行完成后LangGraph 会将它们的输出统一合并到 State 中生成新的状态快照。这个新状态会作为下一轮 Superstep 的输入。完整的运行流程查看 index.html 双击在浏览器打开即可。其中和Checkpoint相关的部分学习相关内容后再看。1.3. Graph API vs Functional APILangGraph 提供了两种不同的 API 来构建运行图Graph API图式 API 和Functional API函数式 API。这两种 API 共享相同的底层运行时可以在同一应用程序中协同使用但它们针对不同的使用场景和开发偏好而设计。1.3.1. Graph APIGraph API 采用声明式方式构建工作流。开发者需要显式定义 State、Node 和 Edge将业务流程组织成一个可视化的图结构。当流程中存在较复杂的分支、多个节点之间共享状态、并行执行、结果汇聚或者需要通过图结构帮助调试和团队协作时更适合使用 Graph API。官方文档也明确建议在需要复杂流程可视化、显式状态管理、多条件分支、并行路径以及团队协作时优先选择 Graph API。总之Graph API 更适合构建结构清晰、节点关系复杂、需要长期维护的工作流。典型场景包括场景说明多节点复杂流程流程中存在多个处理节点需要清晰表达节点之间的关系条件分支较多根据 State 中的不同字段决定后续执行路径并行执行与结果汇聚多个节点并行运行之后汇总结果多组件共享状态多个节点都需要读写同一个全局 State需要图结构展示便于调试、讲解、文档化和团队协作1.3.2. Functional APIFunctional API 采用命令式方式构建工作流更接近普通 Python 函数调用。开发者可以使用entrypoint定义工作流入口使用task定义可被检查点记录的任务然后在函数内部使用普通的if/else、循环和函数调用来组织流程。官方文档指出当已有过程式代码需要最小改造、流程主要是线性的、分支逻辑较简单、希望快速原型验证时更适合使用 Functional API。可以这样理解Functional API 更适合在普通 Python 函数流程中以较低成本接入 LangGraph 的持久化、中断恢复和任务记录能力。典型场景包括场景说明现有代码改造原本已有函数式或过程式代码不希望重构成完整图结构线性流程主要是 A → B → C 的顺序执行简单分支只有少量if/else判断快速原型验证希望减少样板代码快速验证业务逻辑局部任务持久化希望某些函数作为独立 task 被检查点记录1.3.3. 二者的核心区别对比项Graph APIFunctional API编程风格声明式图结构命令式函数流程核心抽象State、Node、Edgeentrypoint、task状态管理显式定义全局 State更多依赖函数参数和返回值流程表达通过节点和边表达通过普通 Python 控制流表达可视化能力强天然适合画图和调试弱更像普通代码流程适合场景复杂工作流、多分支、多节点协作简单流程、快速原型、已有代码改造学习成本相对更高相对更低1.3.4. 选型建议从零构建或流程结构复杂用Graph API现有代码改造、快速原型验证或流程逻辑简单用Functional API。学习LangGraph建议优先掌握Graph API。因为后者更能体现LangGraph的核心思想通过State、Node、Edge显式描述一个可执行的计算图。本文介绍Graph API对Functional API感兴趣的同学自行查阅https://docs.langchain.com/oss/python/langgraph/functional-api二、图的基础构建与运行本节将从一个基础案例入手掌握图的基本创建、调用和可视化方法。图的构建与运行分为三个阶段定义状态图、编译状态图、调用状态图2.1. 定义状态图状态图的定义可以分为以下几个步骤1. 定义全局状态定义整个运行图共享的全局状态实际上除了全局状态LangGraph还支持其它类型的状态下文详述2. 创建状态图创建 StateGraph实例将状态和状态图绑定3. 定义图结构定义节点和边并添加到状态图中2.1.1. 定义全局状态全局状态是 LangGraph 运行图每个节点都可以访问的公共对象。classOverAllState(TypedDict):logs:Annotated[list[str],add]cur_id:str2.1.2. 创建状态图builderStateGraph(state_schemaOverAllState)2.1.3. 定义图结构2.1.3.1. 定义图节点defnode_1(state:OverAllState)-OverAllState:pre_idstate[cur_id]return{logs:[node_1 运行完毕],cur_id:pre_id, node_1}defnode_2(state:OverAllState)-OverAllState:pre_idstate[cur_id]return{logs:[node_2 运行完毕],cur_id:pre_id, node_2}2.1.3.2. 添加节点builder.add_node(node_1,node_1)builder.add_node(node_2,node_2)2.1.3.3. 添加边builder.add_edge(START,node_1)builder.add_edge(node_1,node_2)builder.add_edge(node_2,END)2.2. 编译状态图将上一步得到的状态图编译为可执行的运行图graphbuilder.compile()2.3. 调用状态图可以通过invoke调用计算图print(graph.invoke({cur_id:start}))2.4. 完整代码fromlanggraph.graphimportStateGraph,START,ENDfromtypingimportTypedDict,AnnotatedfromoperatorimportaddclassOverAllState(TypedDict):logs:Annotated[list[str],add]cur_id:strdefnode_1(state:OverAllState)-OverAllState:pre_idstate[cur_id]return{logs:[node_1 运行完毕],cur_id:pre_id, node_1}defnode_2(state:OverAllState)-OverAllState:pre_idstate[cur_id]return{logs:[node_2 运行完毕],cur_id:pre_id, node_2}builderStateGraph(state_schemaOverAllState)builder.add_node(node_1,node_1)builder.add_node(node_2,node_2)builder.add_edge(START,node_1)builder.add_edge(node_1,node_2)builder.add_edge(node_2,END)graphbuilder.compile()print(graph.invoke({cur_id:start}))运行结果如下{logs: [node_1 运行完毕, node_2 运行完毕], cur_id: start, node_1, node_2}2.5. 图结构可视化2.5.1. 绘制mermaid并获取源码mermaid是一种生成图表和流程图的文本标记语言它可以把简单的文本描述直接渲染成可视化图形。通过以下代码可以用mermaid语法表达图结构并打印mermaid源码raw_mermaidgraph.get_graph().draw_mermaid()print(raw_mermaid)输出如下--- config: flowchart: curve: linear --- graph TD; __start__([p__start__/p]):::first node_1(node_1) node_2(node_2) __end__([p__end__/p]):::last __start__ -- node_1; node_1 -- node_2; node_2 -- __end__; classDef default fill:#f2f0ff,line-height:1.2 classDef first fill-opacity:0 classDef last fill:#bfb6fcmermaidmermain输出文本从graph TD;开始的部分为mermaid源码。__start__node_1node_2__end__2.5.2. 绘制mermaid并转换为pngLanggraph也支持将mermaid转换为图片字节流png_bytesgraph.get_graph().draw_mermaid_png()draw_mermaid_png()底层会先调用draw_mermaid()得到mermaid语法的图表代码然后调用在线服务渲染为mermaid图片。默认的mermaid在线渲染服务链接为https://mermaid.ink由于网络问题可能存在渲染失败的情况通常重试即可成功。可以通过draw_mermaid_png()的base_url参数替换可用的mermaid在线渲染服务2.5.2.1. jupyter环境下直接展示图片在jupyter环境下可以通过IPython提供的功能将图片字节流直接展示为图片。fromIPython.displayimportdisplay,Image png_bytesgraph.get_graph().draw_mermaid_png()pngImage(png_bytes)display(png)运行结果如下所示2.5.2.2. 保存为图片文件也可以将图片字节流转换为PNG文件落盘png_bytesgraph.get_graph().draw_mermaid_png()png_filenamefirst_demo_graph.pngwithopen(png_filename,wb)asf:f.write(png_bytes)运行结束后代码文件同级目录下将会出现生成好的图片文件如下图所示。如果看不到文件可以刷新上级目录图片内容如下2.5.2.3. 快捷用法在Jupyter环境下可以直接使用display(graph)快速展示编译后的图结构fromIPython.displayimportdisplay display(graph)效果如下
企业数字化 ERP 产品动态
相关推荐
squish6.3自动化代码用例编写 一、 用例函数之 init() 和 cleanup()
附加模式下 一定要注意用例结束后的恢复工作,否则会造成后续用例失败;
squish中默认提供了init和cleanup函数:
init()方法失败,main()方法不执行,cleanup()方法会执行;… · 2026/11/3 2:49:27
【元宝搜索开发者征文大赛】少点幻觉,多点搜索:我做了个政策过期检测器 目录
前言
1 起因:AI 拿着一份过期三年的补贴政策,差点让他报错材料
2 为什么治「政策幻觉」,非得用元宝搜索不可
3 先把钥匙拿到手:元宝搜索 API Key 开通全流程
3.1 开通服务,把版本选对
3.2 先用 curl 打通一… · 2026/11/3 2:49:27
大模型小白必看:收藏这份AI Agent底层逻辑解析,轻松上手构建智能应用 本文深入解析AI Agent的核心运作机制,揭示其本质为“调用工具的循环系统”。文章详细拆解了Agent的四大核心组件:Loop循环机制、Tools工具调用能力、Memory记忆模块以及Harness调度管控模块,并阐述了它们如何协同工作以实现智能任务执行。通过… · 2026/11/3 2:49:27
Excel日期格式不生效?文本型日期批量转换与排错指南 前两天有人抱着一份从业务系统导出的台账来找我,说 Excel 里明明把单元格格式设成了日期,数据却纹丝不动,只有挨个双击再回车才会变成日期样子,几千行总不能一行行点下去。这个场景我这些年遇到过太多次,Excel 设置单元… · 2026/11/3 3:25:33
WebSocket协议DDoS防御与智能流量清洗技术解析 1. 项目背景与核心挑战2026年的即时通讯应用正面临前所未有的DDoS攻击威胁。随着WebSocket长连接技术的普及和5G网络的全面覆盖,攻击者能够以更低的成本发动更大规模的流量攻击。去年某头部社交平台因遭受1.4Tbps的混合攻击导致服务中断37分钟,直接损失超… · 2026/11/3 3:25:33
电力系统网络安全:多传感器融合技术实践与优化 1. 电力系统网络安全现状与多传感器融合的必要性电力系统作为关键基础设施,其网络安全防护一直是行业重点。近年来随着智能电网和物联网设备的普及,电力系统的攻击面呈指数级增长。传统基于单一数据源的入侵检测系统(IDS)已难以应… · 2026/11/3 3:25:33
数字序列999999999的技术解析与应用实践 1. 项目概述"999999999"这个看似简单的数字序列,实际上蕴含着丰富的可能性。作为一名从业多年的数字文化观察者,我注意到这类重复数字组合在多个领域都有着特殊意义和应用场景。从编程中的占位符到金融交易中的特殊标识,从游戏设计… · 2026/11/3 3:25:33
电力系统多传感器融合安全监测技术解析 1. 电力系统网络安全现状与挑战现代电力系统正面临前所未有的网络安全威胁。去年某省级电网调度中心遭遇的APT攻击导致区域负荷控制系统异常,直接经济损失超过2000万元。这类事件暴露出传统单点安全监测的局限性——攻击者只需突破一个传感器节点的防御就能潜伏数月… · 2026/11/3 3:25:33
RFSoC ADC/DAC调试:6MHz频偏定位AXI时钟与抽取因子 简介:资源是一份面向具备一定硬件调试经验的FPGA与射频工程师的RFSoC实战调试文档,聚焦Alinx公司Zynq UltraScaleRFSoC开发板上ADC/DAC链路的频率配置与信号完整性排查。文中完整还原了从原厂demo工程(rfevm_rf_adaloop回环)入手&… · 2026/11/3 3:24:33
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 4:42:45
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 5:17:18