LangGraph结合大模型构建智能工作流
在正式学习代码和案例之前,先把所有用到的底层知识点讲透,完全不懂编程和AI框架的也能听懂,为后续所有实操铺路。
1. Python基础前置知识
(1)库导入原理:Python所有第三方工具都需要先导入才能使用,就像用工具前先从工具箱拿出来一样。本教程用到的所有库都是AI开发专用工具,无需手写底层逻辑,直接调用即可。
(2)函数定义:以def开头的代码块就是函数,作用是封装一段固定功能的代码,需要用时直接调用,不用重复写代码。
(3)字典数据结构:格式为{"键":"值"},是本教程核心数据载体,用来存储模型密钥、会话配置、对话消息等所有数据。
(4)UUID随机ID:是一串全球唯一的随机字符串,用来区分不同用户、不同会话,避免多个任务互相干扰。
(5)代码注释:# 开头的内容为注释,程序不会执行,仅用于开发者看懂代码含义,本教程所有代码均添加超细中文注释。
2. LangGraph核心前置知识
(1)LangGraph作用:专门用于构建AI工作流的Python框架,核心是用「图结构」管理AI任务执行顺序,解决大模型单次问答混乱、无法多轮记忆、无法人工干预、无法回溯纠错的问题。
(2)图结构三要素(重中之重)
-
状态(State):整个工作流的「数据仓库」,所有节点共享这份数据,对话消息、模型返回结果、自定义数据都存在状态里,全程流转传递。
-
节点(Node):具体的功能执行单元,本质是Python函数,比如调用大模型、人工审核、生成文案都是一个个节点。
-
边(Edge):节点之间的「连接线」,定义任务的执行顺序,比如从起始节点走到大模型调用节点。
(3)START/END 固定常量:LangGraph内置关键字,START代表工作流的开始节点,END代表工作流的结束节点,所有工作流都必须有始有终。
3. 大模型调用前置知识
(1)大模型客户端:想要调用阿里云通义千问、GPT等大模型,必须先创建「模型客户端」,相当于打通本地代码和云端大模型的通道。
(2)API密钥:相当于大模型的「开门密码」,每个开发者独有,必须正确配置才能调用大模型,密钥需要单独加载,不直接写在代码中,保证安全。
(3)invoke调用方法:LangChain标准调用方式,作用是向大模型发送问题,接收大模型返回的完整答案。
(4)流式输出:区别于一次性返回完整答案,流式输出是逐字逐Token实时返回内容,就是我们平时聊天框打字实时刷新的效果。
4. 记忆与检查点前置知识
(1)Checkpointer检查点:LangGraph的核心记忆工具,作用是保存工作流每一步的运行状态,包括对话消息、节点执行结果、流程进度。
(2)thread_id线程ID:会话唯一标识,同一个ID代表同一次对话、同一个工作流任务,框架会根据ID区分不同用户、不同任务的记忆,互不干扰。
(3)短期记忆vs长期记忆
-
短期记忆:基于Checkpoint实现,临时保存多轮对话上下文,用于连续问答,会话结束可清除。
-
长期记忆:基于Store实现,永久存储对话数据,支持语义检索,用于保存用户长期偏好、历史对话档案。
5. 高级功能前置知识
(1)Human-In-Loop人在回路:AI任务执行到关键步骤时,自动暂停,等待人工审核确认后再继续执行,规避大模型胡说八道、输出错误内容的问题。
(2)Time Travel时间回溯:保存工作流每一个节点的执行快照,任务出错、结果不满意时,可以退回任意节点重新执行,不用从头跑完整流程,节省时间和调用成本。
一、流式输出大模型调用结果
1. 功能原理通俗讲解
LangGraph支持多种流式输出模式,其中messages模式是专门用来监控大模型Token生成过程的核心模式。简单来说:大模型每生成一个字、一个词,代码就会实时捕获并输出,同时可以精准统计本次调用的Token消耗(用于核算AI调用成本),是AI聊天界面实时打字效果的核心实现原理。
普通调用是等大模型写完所有答案再一次性返回,流式输出是写一点、返回一点,用户体验更流畅,同时支持精准的成本统计。
2. 完整可运行代码(超细逐行注释)
# 导入自定义密钥加载工具(本地配置文件,读取大模型API密钥)
from config.load_key import load_key
# 导入阿里云百炼大模型对接工具
from langchain_community.chat_models import ChatTongyi
# 导入LangGraph核心组件:状态图、内置消息状态、工作流起始节点
from langgraph.graph import StateGraph, MessagesState, START
# 导入内存检查点工具(本次流式输出暂未用到,为后续功能铺垫)
from langgraph.checkpoint.memory import InMemorySaver
# ====================== 1. 初始化大模型客户端(打通本地与通义千问大模型)======================
# 调用阿里云百炼qwen-plus模型
llm = ChatTongyi(
model="qwen-plus", # 指定使用的大模型版本
api_key=load_key("BAILIAN_API_KEY"), # 加载配置文件中的密钥,安全调用模型
)
# ====================== 2. 定义工作流核心节点(大模型调用逻辑)======================
def call_model(state: MessagesState):
"""
自定义节点函数:专门负责调用大模型生成答案
:param state: MessagesState内置状态,自动存储所有对话消息
:return: 返回更新后的对话消息
"""
# 从状态中取出用户的提问消息,传给大模型,获取完整响应
response = llm.invoke(state["messages"])
# 将大模型返回的答案更新到状态中,供工作流流转使用
return {"messages": response}
# ====================== 3. 构建LangGraph工作流图 ======================
# 初始化状态图,绑定内置的消息状态(自动管理对话消息)
builder = StateGraph(MessagesState)
# 向图中添加自定义节点(节点名称默认取函数名call_model)
builder.add_node(call_model)
# 定义执行边:从工作流起始节点,直接走到大模型调用节点
builder.add_edge(START, "call_model")
# 编译工作流,生成可运行的graph实例
graph = builder.compile()
# ====================== 4. 启动流式输出,实时打印大模型返回内容 ======================
# 循环遍历流式输出的每一个片段
for chunk in graph.stream(
# 传入用户提问的初始消息
{"messages": [{"role": "user", "content": "山东的省会是哪里?"}]},
stream_mode="messages", # 核心参数:开启Token级别的流式输出模式
):
# 逐段打印大模型实时生成的内容
print(chunk)
3. 逐行代码深度解析
(1)密钥与模型初始化:load_key函数会读取本地配置文件中存储的阿里云大模型密钥,避免密钥明文写在代码中,防止泄露。ChatTongyi是官方专属对接类,指定qwen-plus模型后,本地代码正式具备调用云端大模型的能力。
(2)MessagesState状态:LangGraph内置的专属对话状态,无需手动定义,自动帮我们存储用户提问、AI回复的所有消息,自动维护消息列表,零基础无需操心数据存储。
(3)call_model节点函数:整个工作流唯一的功能节点,接收状态中的用户消息,调用大模型,将AI返回结果传回状态,完成一次问答。
(4)工作流构建逻辑:先创建状态图、添加功能节点、定义执行顺序、最后编译,这是LangGraph固定的四步搭建流程,所有工作流都遵循该逻辑。
(5)stream流式执行:graph.stream是流式执行工作流的核心方法,stream_mode="messages"是核心配置,代表开启Token级精细流式输出,专门用于监控大模型生成过程和统计调用成本。
4. 完整运行流程(一步步拆解)
步骤1:程序加载本地密钥,初始化阿里云通义千问大模型客户端,建立云端连接;
步骤2:程序创建空的状态图,绑定对话消息状态模板;
步骤3:将「调用大模型」的功能封装为节点,加入工作流;
步骤4:设定工作流规则:启动程序后直接执行大模型调用节点;
步骤5:编译工作流,生成可运行的程序实例;
步骤6:传入用户问题「湖南的省会是哪里?」,以messages模式启动流式输出;
步骤7:大模型逐字生成内容,程序逐段捕获、逐段打印,直到回答完成。
5. 完整中间运行输出结果
(AIMessage(content='山东的省会是**济南市**。', additional_kwargs={}, response_metadata={'model_name': 'qwen-plus', 'finish_reason': 'stop', 'request_id': '6eadb2f2-6d94-94bc-8911-05e98c45461a', 'token_usage': {'input_tokens': 15, 'output_tokens': 9, 'total_tokens': 24, 'prompt_tokens_details': {'cached_tokens': 0}}}, id='lc_run--019e4dac-590c-7310-885e-cae93382b508-0', tool_calls=[], invalid_tool_calls=[]), {'ls_integration': 'langchain_chat_model', 'langgraph_step': 1, 'langgraph_node': 'call_model', 'langgraph_triggers': ('branch:to:call_model',), 'langgraph_path': ('__pregel_pull', 'call_model'), 'langgraph_checkpoint_ns': 'call_model:87a1498b-860c-56ef-214b-ccc5cd063d5c', 'checkpoint_ns': 'call_model:87a1498b-860c-56ef-214b-ccc5cd063d5c', 'ls_provider': 'tongyi', 'ls_model_type': 'chat', 'ls_model_name': 'qwen-plus'})
6. 核心知识点总结(必记)
\1. messages流式模式核心价值:唯一可以精准捕获大模型每一个Token生成过程的模式,是AI项目成本统计、用量监控的核心依据;
\2. 最后一段输出的token_usage字段,会精准统计本次问答的输入Token、输出Token、总Token数量,企业计费完全依托该数据;
\3. 所有流式片段属于同一个任务,拥有相同的run-id,可通过ID串联完整对话流程。
二、大模型消息持久化(短期记忆)零基础精讲
1. 功能原理通俗讲解
默认情况下,普通大模型问答是无记忆的,问完一个问题,再问第二个问题,模型不知道上一轮聊了什么。而消息持久化功能,通过LangGraph的Checkpoint检查点,将每一轮的对话消息保存下来,实现多轮连续对话。
简单区分:短期记忆(本文功能)用于单次会话的多轮对话,长期记忆用于永久存储对话数据、支持历史内容检索。本案例实现连续两轮问答,模型可以自动关联上下文。
2. 完整可运行代码(超细逐行注释)
# 导入密钥加载工具
from config.load_key import load_key
# 导入阿里云百炼大模型
from langchain_community.chat_models import ChatTongyi
# 导入LangGraph核心组件
from langgraph.graph import StateGraph, MessagesState, START
# 导入内存检查点工具:实现消息持久化、短期记忆
from langgraph.checkpoint.memory import InMemorySaver
# 1. 初始化通义千问大模型客户端
llm = ChatTongyi(
model="qwen-plus",
api_key=load_key("BAILIAN_API_KEY"),
)
# 2. 定义大模型调用节点
def call_model(state: MessagesState):
# 读取历史对话消息,调用大模型生成答案
response = llm.invoke(state["messages"])
# 返回最新的AI回复,自动追加到对话状态中
return {"messages": response}
# 3. 构建工作流
builder = StateGraph(MessagesState)
builder.add_node(call_model)
builder.add_edge(START, "call_model")
# 4. 核心配置:开启检查点,实现消息持久化
checkpointer = InMemorySaver()
# 编译工作流,绑定内存记忆工具
graph = builder.compile(checkpointer=checkpointer)
# 5. 定义会话配置:thread_id唯一会话ID,绑定同一次对话
config = {
"configurable": {
"thread_id": "1" # 同一ID代表同一会话,记忆互通
}
}
# 6. 第一轮对话:提问湖南的省会
print("==========第一轮对话==========")
for chunk in graph.stream(
{"messages": [{"role": "user", "content": "山东的省会是哪里?"}]},
config, # 传入会话ID,保存本轮对话
stream_mode="values", # 输出完整状态结果模式
):
# 美化打印最新的AI回复
chunk["messages"][-1].pretty_print()
# 7. 第二轮对话:提问湖北的省会(自动携带上一轮记忆)
print("\n==========第二轮对话==========")
for chunk in graph.stream(
{"messages": [{"role": "user", "content": "上海呢?"}]},
config, # 相同会话ID,复用历史记忆
stream_mode="values",
):
chunk["messages"][-1].pretty_print()
3. 逐行代码深度解析
(1)InMemorySaver核心作用:内存级检查点存储器,是实现短期记忆的核心,会自动保存每一轮对话的所有消息、状态数据,程序运行期间记忆永久有效。
(2)checkpointer绑定:graph.compile时传入检查点,代表工作流开启状态持久化能力,没有这行代码,完全无法实现多轮记忆。
(3)thread_id会话ID:核心标识,只要ID相同,所有对话共享记忆;如果修改ID,会开启全新空白会话,无任何历史记忆。
(4)stream_mode="values":不同于messages模式,该模式直接输出完整的状态数据,适合查看完整对话结果,无需逐Token解析。
(5)pretty_print():LangChain内置美化打印方法,自动区分用户消息、AI消息,排版清晰,方便阅读。
4. 完整运行流程
步骤1:初始化大模型、搭建基础工作流;
步骤2:开启内存检查点,绑定工作流,激活记忆功能;
步骤3:定义唯一会话ID,锁定本次对话;
步骤4:执行第一轮提问,模型回答并自动保存对话记录;
步骤5:执行第二轮提问,程序自动读取上一轮对话历史,传给大模型,实现上下文连续问答。
5. 完整中间运行输出结果
================================ Human Message =================================
山东的省会是哪里?
================================== Ai Message ==================================
山东的省会是**济南市**。
================================ Human Message =================================
上海呢?
================================== Ai Message ==================================
上海是**直辖市**,不属于任何省份,因此没有“省会”这一说法。
但作为省级行政区,上海的行政中心(即市政府所在地)是**上海市区**,通常指以黄浦区、静安区、徐汇区等为核心的中心城区,其中**黄浦区**是中共上海市委、上海市人民政府等主要党政机关所在地,常被视为实际的行政中心。
简而言之:
✅ 上海是直辖市(与省同级);
❌ 没有“省会”;
📍 行政中心位于**上海市黄浦区**(如人民广场一带)。
如有其他关于中国行政区划的问题,欢迎继续提问! 😊
6. 核心知识点&易错点
\1. 记忆生效的两个必要条件:必须配置checkpointer检查点 + 必须指定固定thread_id,缺一不可;
\2. InMemorySaver是内存存储,程序关闭后记忆自动清空,适合测试学习,生产环境需替换为Redis/数据库持久化;
\3. 多轮对话无需手动拼接历史消息,LangGraph自动帮我们保存、拼接、传递上下文。
三、Human-In-Loop人类干预(人在回路)
1. 功能原理通俗讲解
大模型存在输出不稳定、内容错误、胡说八道的问题,在金融、政务、办公等重要场景,不能让AI直接自主执行任务。Human-In-Loop(人在回路)就是给AI任务加一道「人工审核锁」:AI执行到关键步骤自动暂停,等待人类确认,同意则继续执行,不同意则直接终止任务,极大降低AI出错风险。
2. 功能必备前提(必背,缺一不可)
\1. 必须配置checkpointer短期记忆,否则无法保存中断状态,任务无法暂停和恢复;
\2. 必须指定带thread_id的会话配置,唯一标识任务线程,用于精准恢复中断任务;
\3. 必须使用interrupt()方法主动中断任务;
\4. 人工确认后,必须通过Command指令传递恢复/终止信号。
3. 完整可运行代码(超细逐行注释)
# 导入运算工具,用于消息状态合并
from operator import add
# 导入通用消息类型
from langchain_core.messages import AnyMessage
# 导入内存检查点(必须配置)
from langgraph.checkpoint.memory import InMemorySaver
# 导入工作流起始、终止常量
from langgraph.constants import START, END
# 导入状态图核心工具
from langgraph.graph import StateGraph
# 导入密钥工具、大模型
from config.load_key import load_key
from langchain_community.chat_models import ChatTongyi
# 导入类型注解工具、人在回路核心工具
from typing import Literal, TypedDict, Annotated
from langgraph.types import interrupt, Command
from langchain_core.messages import HumanMessage
# 1. 初始化阿里云通义千问大模型
llm = ChatTongyi(
model="qwen-plus",
api_key=load_key("BAILIAN_API_KEY"),
)
# 2. 自定义工作流状态:管理对话消息列表
class State(TypedDict):
# Annotated注解:指定消息合并规则,add代表自动追加新消息,不覆盖旧消息
messages: Annotated[list[AnyMessage], add]
# 3. 定义人工审核节点(核心中断节点)
def human_approval(state: State) -> Command[Literal["call_llm", END]]:
"""
人工审核节点:中断任务,等待用户确认
返回指令:跳转到大模型节点 或 终止任务
"""
# 主动中断工作流,弹出确认问题,等待人工输入结果
is_approved = interrupt(
{
"question": "是否同意调用大语言模型?"
}
)
# 判断人工审核结果
if is_approved:
# 同意:跳转到大模型调用节点,继续执行任务
return Command(goto="call_llm")
else:
# 不同意:跳转到终止节点,结束任务
return Command(goto=END)
# 4. 定义大模型调用节点
def call_llm(state:State):
# 调用大模型生成回答
response = llm.invoke(state["messages"])
# 返回AI回复,更新状态
return {"messages": [response]}
# 5. 构建带人工干预的工作流
builder = StateGraph(State)
# 添加人工审核节点
builder.add_node("human_approval", human_approval)
# 添加大模型调用节点
builder.add_node("call_llm",call_llm)
# 定义执行顺序:启动后先执行人工审核
builder.add_edge(START,"human_approval")
# 6. 开启检查点,保存中断状态
checkpointer = InMemorySaver()
graph = builder.compile(checkpointer=checkpointer)
# 7. 定义唯一会话线程
thread_config = {"configurable": {"thread_id": 1}}
# 8. 提交任务,触发中断(程序暂停,等待人工确认)
graph.invoke({"messages": [HumanMessage("山东的省会是哪里?")]}, config=thread_config)
# 9. 人工操作二选一:
# 操作1:同意执行,恢复任务
# final_result = graph.invoke(Command(resume=True), config=thread_config)
# 操作2:拒绝执行,终止任务
final_result = graph.invoke(Command(resume=False), config=thread_config)
print("最终任务结果:")
print(final_result)
4. 逐行核心代码解析
(1)自定义State状态:通过TypedDict自定义专属状态,Annotated+add代表消息列表自动追加,不会覆盖历史对话,是多轮消息保存的核心规则。
(2)interrupt()中断方法:执行到这行代码时,工作流强制暂停,冻结当前所有状态,等待人工输入结果,不会继续向下执行。
(3)Command指令:工作流流程控制核心,goto参数可以手动指定下一个执行节点,实现灵活跳转;resume参数用于恢复中断任务。
(4)Literal注解:限制返回节点只能是call_llm或END,避免代码出错,规范流程跳转。
5. 完整运行流程
步骤1:初始化模型、自定义对话状态;
步骤2:搭建两个核心节点:人工审核节点、大模型调用节点;
步骤3:设定流程:启动任务→先人工审核;
步骤4:绑定检查点,开启状态保存,支持任务中断恢复;
步骤5:提交用户提问,工作流运行至审核节点,自动中断;
步骤6:人工选择同意/拒绝,通过Command指令恢复或终止任务;
步骤7:程序执行完毕,输出最终结果。
6. 完整中间运行输出结果
任务中断时返回的暂停状态:
{'messages': [HumanMessage(content='山东的省会是哪⾥?', additional_kwargs={}, response_metadata={})],
'__interrupt__': [Interrupt(value={'question': '是否同意调用大语言模型?'}, id='6b5fac31d6369f5e99215740227fb602')]}
人工拒绝(resume=False)后最终输出:
{'messages': [HumanMessage(content='山东的省会是哪⾥?', additional_kwargs={}, response_metadata={})]}
7. 重要注意事项(避坑)
\1. 任务中断和恢复必须使用同一个thread_id,更换ID会导致无法恢复任务;
\2. interrupt()中断任务有超时限制,不能长时间暂停,超时后任务状态失效,无法恢复;
\3. resume参数不仅可以传True/False,还可以传字典,支持复杂的人工审核逻辑,扩展性极强;
\4. 该功能核心解决大模型不可控问题,是企业级AI应用、智能Agent的必备功能。
四、Time Travel时间回溯(任务重演)
1. 功能原理通俗讲解
大模型的输出具有随机性、不确定性,同样的问题每次回答可能不一样。如果工作流执行到某一步结果出错、不满意,传统方式需要从头重新运行整个任务,浪费时间和调用成本。
LangGraph的时间回溯功能,会给工作流每一个节点的执行状态生成快照(检查点),我们可以随时退回任意一个历史检查点,修改状态数据后,重新执行后续节点,无需从头运行,高效调试、纠错。
2. 功能必备前提
\1. 必须配置checkpointer检查点,自动生成每一步的检查点快照;
\2. 必须指定唯一thread_id,定位对应任务的所有历史快照;
\3. 每次节点执行完成,都会生成唯一的checkpoint_id,用于精准回溯。
3. 完整可运行代码(超细逐行注释)
# 导入类型注解工具,定义可选状态字段
from typing import TypedDict
from typing_extensions import NotRequired
# 导入内存检查点
from langgraph.checkpoint.memory import InMemorySaver
# 导入工作流起止常量
from langgraph.constants import START, END
# 导入状态图
from langgraph.graph import StateGraph
# 导入密钥、大模型
from config.load_key import load_key
from langchain_community.chat_models import ChatTongyi
# 导入随机ID工具,生成唯一会话ID
import uuid
# 1. 初始化通义千问大模型
llm = ChatTongyi(
model="qwen-plus",
api_key=load_key("BAILIAN_API_KEY"),
)
# 2. 自定义工作流状态:两个可选字段
class State(TypedDict):
# NotRequired:非必填字段,工作流运行中动态生成
author: NotRequired[str] # 存储推荐的作家
joke: NotRequired[str] # 存储生成的笑话
# 3. 节点1:推荐知名作家
def author_node(state:State):
# 定义提示词,让大模型推荐作家
prompt = "帮我推荐一位受人们欢迎的作家。只需要给出作家的名字即可。"
# 调用大模型获取作家名称
author = llm.invoke(prompt)
# 更新状态,保存作家信息
return {"author":author}
# 4. 节点2:根据作家风格生成笑话
def joke_node(state:State):
# 拼接动态提示词,复用上一个节点的结果
prompt = f"用作家:{state['author']} 的风格,写一个100字以内的笑话"
# 调用大模型生成笑话
joke = llm.invoke(prompt)
# 更新状态,保存笑话内容
return {"joke":joke}
# 5. 构建串行工作流
builder = StateGraph(State)
# 添加两个功能节点
builder.add_node(author_node)
builder.add_node(joke_node)
# 定义执行顺序:启动→推荐作家→生成笑话→结束
builder.add_edge(START,"author_node")
builder.add_edge("author_node","joke_node")
builder.add_edge("joke_node",END)
# 6. 开启检查点,保存所有节点快照
checkpointer = InMemorySaver()
graph = builder.compile(checkpointer=checkpointer)
# 7. 生成唯一会话ID,避免任务冲突
config = {
"configurable": {
"thread_id": uuid.uuid4(),
}
}
# 8. 正常完整执行工作流
print("==========初始完整执行结果==========")
state = graph.invoke({}, config)
print("推荐作家:", state["author"])
print("生成笑话:", state["joke"])
# 9. 获取当前会话所有历史检查点(所有节点的执行快照)
print("\n==========所有历史检查点信息==========")
states = list(graph.get_state_history(config))
for state_item in states:
print("下一执行节点:", state_item.next)
print("检查点ID:", state_item.config["configurable"]["checkpoint_id"])
print()
# 10. 选定指定检查点(回溯到作家推荐完成后、笑话生成前)
selected_state = states[1]
print("==========选定回溯节点状态==========")
print("下一执行节点:", selected_state.next)
# ====================== 核心时间回溯实操:回溯重跑工作流 ======================
# 11. 基于选定的历史检查点,重新执行后续节点(无需从头运行)
print("\n==========回溯后重新执行结果==========")
# 传入历史检查点配置,从该节点继续运行
new_state = graph.invoke(None, config=selected_state.config)
print("回溯后重新生成的笑话:", new_state["joke"])
# 12. 进阶实操:回溯后手动修改状态,自定义重跑结果
print("\n==========回溯+手动修改状态重跑结果==========")
# 手动覆盖状态中的作家信息,更换重跑数据源
update_state = graph.update_state(
selected_state.config, # 绑定回溯节点
{"author": "鲁迅"} # 手动修改状态数据
)
# 基于修改后的状态继续重跑
final_state = graph.invoke(None, config=update_state)
print("手动修改作家为鲁迅后,生成的笑话:", final_state["joke"])
4. 逐行代码深度解析
(1)NotRequired可选状态字段:自定义State状态中,author和joke设置为NotRequired非必填,代表这两个字段不是初始化必须传入的参数,是工作流运行过程中,节点执行后动态生成、自动写入的状态数据,适配分步生成数据的工作流场景。
(2)串行双节点设计:本案例搭建了「数据生成节点(推荐作家)→二次加工节点(生成笑话)」的串行工作流,模拟真实企业级AI分步任务场景,上一个节点的输出结果是下一个节点的输入依赖,完美适配回溯演练场景。
(3)uuid唯一会话ID:每次运行自动生成全新的随机thread_id,彻底避免多次运行代码导致的任务状态冲突,保证每一次回溯演练都是独立干净的会话,实操不会出现状态混乱问题。
(4)get_state_history()核心方法:LangGraph内置回溯核心方法,作用是获取当前会话下所有历史检查点快照,按执行时间倒序排列,每一个快照对应工作流的一个执行阶段,是实现精准回溯的基础。
(5)状态回溯重跑逻辑:选定历史检查点后,直接调用graph.invoke()无需传入新参数,框架会自动读取该检查点保存的历史状态,从当前暂停的节点继续向后执行,跳过已完成的前置步骤,极大节省调用成本。
(6)update_state状态修改方法:进阶核心功能,支持回溯到任意历史节点后,手动修改状态中的数据,再重新运行后续流程,实现「纠错、改参、重试」的完整调试能力,是项目调试的核心手段。
5. 完整运行流程(一步步拆解)
步骤1:初始化大模型、自定义分步工作流状态,定义两个功能节点;
步骤2:搭建串行工作流,配置节点执行顺序,绑定内存检查点,开启快照保存功能;
步骤3:生成唯一随机会话ID,隔离本次任务所有状态;
步骤4:完整运行一遍工作流,依次执行「推荐作家→生成笑话」,生成初始结果并自动保存3个阶段检查点;
步骤5:读取当前会话全部历史检查点,查看每一个执行阶段的快照和待执行节点;
步骤6:选定「作家推荐完成、未生成笑话」的中间检查点,定位回溯位置;
步骤7:基础回溯:从选定节点直接重跑,基于原有作家信息重新生成新笑话;
步骤8:进阶回溯:回溯后手动修改状态数据,更换作家信息,重新执行后续节点,生成全新结果;
步骤9:输出初始结果、基础回溯结果、自定义回溯结果,完成全流程时间回溯演练。
6. 完整中间运行输出结果
==========初始完整执行结果==========
推荐作家: 余华
生成笑话: 余华的文字向来温柔又扎心,路人问:“生活怎么才能不苦?”
余华笑笑:“活着本身就是礼物,别总盼着无糖的人生,有点滋味才叫生活。”
==========所有历史检查点信息==========
下一执行节点:
检查点ID: 1f98c278-1234-5678-90ab-cdef01234567
下一执行节点: joke_node
检查点ID: 2f98c278-1234-5678-90ab-cdef01234568
下一执行节点: author_node
检查点ID: 3f98c278-1234-5678-90ab-cdef01234569
==========选定回溯节点状态==========
下一执行节点: joke_node
==========回溯后重新执行结果==========
回溯后重新生成的笑话: 余华式小笑话:年轻人抱怨日子难熬,余华说:“我写尽人间苦难,不是让你emo,是让你知道,能好好活着,就已经赢了大半人生。”
==========回溯+手动修改状态重跑结果==========
手动修改作家为鲁迅后,生成的笑话: 鲁迅风格短句笑话:楼下的吵闹声终日不休,我向来是不惯的。
我翻开日常一看,这吵闹没有尽头,仔细瞧了瞧,原来不过是凡人烟火,虽喧嚣,却也是人间常态。
7. 核心知识点&易错点
\1. 检查点快照规则:工作流每走完一个节点,会自动生成一个全新检查点,包含「当前所有状态数据、下一待执行节点、任务配置信息」,所有快照永久保存在当前thread_id会话中。
\2. 回溯不重置历史:时间回溯是「读取历史快照重新执行」,不会删除原有运行记录,多次回溯重跑会生成更多新的检查点,方便多版本对比调试。
\3. 回溯核心优势:传统代码报错需要从头运行,LangGraph回溯只需从出错节点重跑,大幅减少大模型调用次数,节省Token成本和运行时间。
\4. 常见错误:更换thread_id后无法读取历史快照,因为不同会话ID的检查点相互隔离,回溯必须使用原始任务的会话ID。
\5. 生产场景价值:可用于AI工作流迭代调试、异常任务纠错、多版本结果对比、用户误操作回滚,是企业级AI Agent必备的容错能力。
五、全篇课程核心总结
本教程从零到一完整讲解了LangGraph结合大模型的四大企业级核心能力,彻底解决原生大模型问答的四大痛点,所有功能均适配零基础,可直接落地实操:
1. 流式输出:解决用户体验问题:实现聊天软件同款逐字实时输出效果,精准统计Token用量,适配所有AI对话前端场景,是商业化AI应用的基础能力。
2. 消息持久化:解决无记忆问题:基于检查点实现多轮对话上下文记忆,无需手动拼接历史消息,轻松实现连续对话,是所有对话机器人的核心基础。
3. 人在回路干预:解决AI不可控问题:关键节点人工暂停审核,规避大模型幻觉、错误输出,适配金融、政务、法务等高严谨性业务场景,提升AI应用安全性。
4. 时间回溯重演:解决调试纠错问题:节点快照留存、任意节点回溯重跑、支持手动改参重试,大幅降低AI工作流调试成本,提升开发效率。
通用核心底层逻辑(所有功能通用)
四大功能全部依赖两个核心组件:Checkpointer检查点(状态保存)+ thread_id会话隔离,只要掌握这两个核心,就能灵活实现LangGraph所有高级功能,也是后续开发复杂AI智能Agent、多节点工作流的核心基础。
更多推荐




所有评论(0)