跳到主要内容

💾 持久化

在构建复杂的 AI 应用时,持久化是一个至关重要的功能。就像前端应用需要保存用户数据和应用状态一样,LangGraphJS 应用也需要能够保存和恢复执行状态。LangGraphJS 通过强大的检查点机制提供了完整的持久化解决方案。

🎯 持久化概述

从前端开发的角度来理解,LangGraphJS 的持久化机制类似于:

  • 检查点 类似于 Git 的提交记录 - 每个执行步骤都会保存状态快照
  • 线程 类似于浏览器的会话 - 每个对话或执行流程都有唯一标识
  • 状态恢复 类似于页面刷新后的状态恢复 - 应用可以从任意点继续执行
  • 时间旅行 类似于版本控制的回滚 - 可以回到任意历史状态

📝 检查点机制

检查点是 LangGraphJS 持久化的核心概念,它在每个步骤后自动保存图的状态快照。

核心概念

线程(Thread)

线程是每个检查点的唯一标识符,类似于数据库中的主键。每个线程代表一个独立的执行流程,可以是用户会话、任务实例或任何需要独立状态管理的场景。

// 线程管理:为每次对话/流程生成并复用 thread_id
import { randomUUID } from 'node:crypto';

const threadId = randomUUID();

// 调用图时将 thread_id 放入 configurable,确保同一线程可继续执行
const result = await graph.invoke(input, {
configurable: { thread_id: threadId },
});

// 后续请求继续复用同一个 thread_id,即可在同一状态链上推进
await graph.invoke(nextInput, { configurable: { thread_id: threadId } });

检查点(Checkpoint)

检查点包含完整的状态信息和元数据,包括:

  • 状态快照:当前图的完整状态
  • 执行位置:下一个要执行的节点
  • 元数据:时间戳、配置信息等
  • 历史记录:状态变更的完整链条
// 检查点管理:为图配置检查点器(持久化后端)
import { MemorySaver } from '@langchain/langgraph';
import { SqliteSaver } from '@langchain/langgraph-checkpoint-sqlite';
import { PostgresSaver } from '@langchain/langgraph-checkpoint-postgres';

// 开发期:内存后端(重启丢失,最快)
const devCheckpointer = new MemorySaver();

// 本地/小型项目:SQLite 文件持久化
const sqliteCheckpointer = new SqliteSaver({ filename: './state.db' });

// 生产:Postgres 持久化
const pgCheckpointer = new PostgresSaver(process.env.DATABASE_URL!);

// 选择一个后端编译工作流
const graph = workflow.compile({ checkpointer: pgCheckpointer });

状态查询和历史

持久化机制提供了强大的状态查询能力,允许你:

  • 获取当前状态快照
  • 查看完整的执行历史
  • 回溯到任意历史状态
  • 分析状态变更轨迹
// 状态查询与历史:查询当前状态与历史检查点
const threadId = 'your-thread-id';

// 获取当前状态(示例 API,具体以实际版本为准)
const currentState = await graph.getState({
configurable: { thread_id: threadId },
});
console.log('values:', currentState.values);
console.log('metadata:', currentState.metadata);

// 列出历史检查点(示例 API)
const checkpoints = await checkpointer.list({ thread_id: threadId });
console.log('history length:', checkpoints.length);

🗄️ 存储后端选择

LangGraphJS 提供多种存储后端,适用于不同的使用场景。选择合适的存储后端是构建可靠持久化系统的关键。

存储后端特性对比

不同存储后端适用于不同的应用场景:

存储类型适用场景优点缺点性能
MemorySaver开发测试简单快速,无需配置重启丢失,内存限制极高
SqliteSaver本地应用轻量级,文件存储单机限制,并发有限
PostgresSaver生产环境高性能,高可用配置复杂,资源消耗很高

🏭 生产环境配置

在生产环境中,需要考虑性能、可靠性和扩展性:

// 生产环境持久化配置(示例)
import { PostgresSaver } from '@langchain/langgraph-checkpoint-postgres';

const checkpointer = new PostgresSaver(process.env.DATABASE_URL!, {
pool: { min: 2, max: 10 },
statementTimeoutMs: 10_000,
});

const graph = workflow.compile({
checkpointer
});

📊 持久化工作流程

🎯 实践案例:支持持久化的图

import { ChatOpenAI } from '@langchain/openai'
import './lib/loadEnv'
import { Annotation, StateGraph } from '@langchain/langgraph'
import { BaseMessage, HumanMessage } from '@langchain/core/messages'
import { randomUUID } from 'node:crypto';
import { MemorySaver } from '@langchain/langgraph';
const devCheckpointer = new MemorySaver();

const llm = new ChatOpenAI({
model: 'qwen3-max',
})



const StateAnnotation = Annotation.Root({
messages: Annotation<BaseMessage[]>({
reducer: (oldState, newState) => {
return [...oldState, ...newState]
},
default: () => []
}),
})

const llmNode = async (state: typeof StateAnnotation.State) => {
const response = await llm.invoke(state.messages)
return {
messages: [response]
}
}



const graph = new StateGraph(StateAnnotation)
.addNode('llmNode', llmNode)
.addEdge('__start__', 'llmNode')
.addEdge('llmNode', '__end__')
.compile({ checkpointer: devCheckpointer })


const logMessages = (messages: BaseMessage[]) => {
messages.forEach((msg) => {
console.log(`%c Line:44 🥒 【${msg.getType()}`, "color:#2eafb0", msg.content);
});
}

async function runDemo() {
try {
const threadId = randomUUID();

console.log("%c Line:62 🍪==============第一轮对话============", "color:#7f2b82");

await graph.invoke({
messages: [
new HumanMessage('中国首都在哪里'),
]
}, {
configurable: {
thread_id: threadId
}
}).then(res => {
logMessages(res.messages)
})

console.log("%c Line:62 🍪==============第二轮对话============", "color:#7f2b82");

await graph.invoke({
messages: [
new HumanMessage('上一个问题问的是什么'),
]
}, {
configurable: {
thread_id: threadId
}
}).then(res => {
logMessages(res.messages)
})


} catch (error) {
console.error("错误:", error);
}
}

runDemo()

🔗 相关资源

持久化是构建可靠 AI 应用的基础设施。通过合理使用检查点机制,你可以创建出既稳定又灵活的应用,为用户提供无缝的体验。这为实现更复杂的功能如人机交互和流式处理奠定了坚实的基础。