9. Persistence - Cơ chế lưu trữ Checkpoint

Nam

Nam Hoang / Sep 09, 2025

6 min read

Trong các bài học trước, khi Graph kết thúc hoặc ứng dụng bị tắt, mọi dữ liệu trong State sẽ tan biến. Để xây dựng các AI Agent chuyên nghiệp có khả năng ghi nhớ hội thoại hoặc phục hồi sau sự cố, chúng ta cần đến Persistence (Tính bền bỉ). LangGraph giải quyết vấn đề này thông qua các Checkpointers.

I. Khái niệm về Threads và Checkpoints

Hãy tưởng tượng LangGraph giống như một trò chơi video có tính năng lưu trữ:

  1. Thread (Luồng): Là một "lượt chơi" duy nhất của một người dùng cụ thể, được định danh bằng một thread_id.
  2. Checkpoint (Điểm lưu): Là hành động "Save game". Cứ sau mỗi bước chạy của một Node (Super-step), LangGraph tự động chụp một bản snapshot của toàn bộ State và lưu vào Thread đó.

Cơ chế này giúp Agent có thể nhớ những gì đã nói ở các bước trước, hỗ trợ khả năng chịu lỗi (fault-tolerance) và cho phép con người can thiệp vào quy trình (Human-in-the-loop).

II. Cách hoạt động của Checkpointer

Khi bạn biên dịch (compile) một graph với một checkpointer, LangGraph sẽ thực hiện quy trình sau:

  1. Nhận diện: Nhận dữ liệu đầu vào kèm theo thread_id.
  2. Tải dữ liệu: Tra cứu trong bộ nhớ xem thread_id này đã có checkpoint nào chưa. Nếu có, nó sẽ tự động tải lại trạng thái cũ.
  3. Thực thi & Lưu: Sau khi mỗi Node chạy xong, nó thực hiện "Put" một checkpoint mới vào cơ sở dữ liệu.

III. Mã nguồn: 09-persistence-fundamentals.ts

Dưới đây là ví dụ sử dụng MemorySaver để lưu trữ trạng thái vào RAM. Chúng ta sẽ chạy Graph hai lần với cùng một thread_id để thấy dữ liệu được cộng dồn như thế nào.

// path: 09-persistence-fundamentals.ts
import { END, MemorySaver, START, StateGraph } from '@langchain/langgraph';
import { generateImage } from '@workspace/util-langchain';
import z from 'zod';

// 1. Define State
const State = z.object({
  foo: z.string(),
  count: z.number().default(0),
});

// 2. Simple node logic
function nodeA(state: typeof State.Shape) {
  console.log('--- Running Node A ---');
  // Increments the count by 1
  return { foo: 'a', count: state.count + 1 };
}

// 3. Initialize Checkpointer (In-memory storage)
const checkpointer = new MemorySaver();

// 4. Compile Graph with checkpointer
const workflow = new StateGraph(State)
  .addNode('nodeA', nodeA)
  .addEdge(START, 'nodeA')
  .addEdge('nodeA', END);

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

// 5. Execution with thread_id
async function run() {
  await generateImage(
    graph,
    'graph-ignore/scripts-09-persistence-fundamentals.jpg',
  );

  const config = { configurable: { thread_id: 'user_123' } };

  console.log('--- Run 1 ---');
  // Initialize state with foo: 'initial'
  await graph.invoke({ foo: 'initial' }, config);

  // Retrieve current snapshot from memory
  const snapshot = await graph.getState(config);
  console.log('State after Run 1:', snapshot.values);

  console.log('\n--- Run 2 (Same thread_id) ---');
  // Passing existing values back into invoke.
  // LangGraph loads the checkpoint and starts from START node again.
  await graph.invoke(snapshot.values, config);

  const finalSnapshot = await graph.getState(config);
  console.log('State after Run 2:', finalSnapshot.values);
  // Expected count: 2
}

run();

IV. Các API quản lý trạng thái

Khi đã kích hoạt Persistence, bạn có quyền sử dụng các "siêu năng lực" sau để quản lý Thread:

  • graph.getState(config): Lấy bản snapshot mới nhất của một Thread, bao gồm dữ liệu (values) và node tiếp theo sẽ chạy (next).
  • graph.getStateHistory(config): Trả về toàn bộ lịch sử các bước chạy (checkpoints). Bạn có thể thấy dữ liệu đã thay đổi như thế nào qua từng node.
  • graph.updateState(config, values): Cho phép bạn can thiệp thủ công vào bộ nhớ của Agent (ví dụ: sửa lỗi dữ liệu trước khi cho Agent chạy bước tiếp theo).

Sơ đồ hoạt động:

Sơ đồ Persistence Fundamentals

V. Tổng kết

  • Persistence biến LangGraph từ một tập hợp các hàm rời rạc thành một hệ thống có trí nhớ bền bỉ.
  • Thread ID là chìa khóa duy nhất để phân biệt và quản lý bộ nhớ của từng phiên làm việc.
  • Checkpointer tự động làm việc sau mỗi bước chạy, giúp bạn không cần viết code lưu trữ thủ công.

Ở bài học tiếp theo, chúng ta sẽ học về Sustainable Execution - cách tận dụng cơ chế Persistence này để xây dựng các hệ thống có khả năng tự phục hồi cực mạnh trước các lỗi mạng!

👉 Bài tiếp theo: 10. Sustainable Execution - Thực thi bền bỉ và Phục hồi lỗi