7. Bộ nhớ ngắn hạn (Checkpointers)

Nam

Nam Hoang / Feb 07, 2026

7 min read

Trong các bài học trước, chúng ta đã xây dựng những Agent thông minh nhưng lại mắc phải một nhược điểm lớn: "Mất trí nhớ". LLM về bản chất là stateless (không trạng thái). Bài học này sẽ giúp bạn giải quyết vấn đề đó bằng cách sử dụng Checkpointers để duy trì ngữ cảnh trò chuyện, tích hợp vào hệ thống tiện ích chuyên nghiệp đã thiết lập từ Bài 1.

I. Tại sao AI lại "hay quên"?

Mỗi khi bạn gọi API của Gemini hay GPT, mô hình chỉ xử lý những gì bạn gửi trong yêu cầu hiện tại. Nếu bạn giới thiệu tên ở câu 1 và hỏi lại ở câu 2, AI sẽ không biết bạn là ai trừ khi bạn gửi lại toàn bộ lịch sử chat.

Việc gửi thủ công lịch sử chat rất tốn công và dễ sai sót. LangChain cung cấp Checkpointer để tự động hóa việc lưu trữ và khôi phục trạng thái dựa trên một định danh gọi là Thread ID.

II. Các thành phần cốt lõi của Bộ nhớ

Để triển khai bộ nhớ trong LangChain Agent, bạn cần nắm vững 3 khái niệm:

  1. Checkpointer: Nơi lưu trữ dữ liệu thực tế. Trong quá trình phát triển, chúng ta dùng MemorySaver (lưu vào RAM).
  2. Thread ID: Giống như một "mã phòng chat". Agent sẽ dựa vào ID này để biết cần truy xuất bộ nhớ của cuộc hội thoại nào.
  3. Configurable: Đối tượng chứa cấu hình được truyền vào hàm invoke, đây là nơi bạn chỉ định thread_id.

III. Mã nguồn: 07-short-term-memory-checkpointer.ts

Chúng ta sẽ tạo một Agent và thực hiện hai cuộc hội thoại song song để thấy cách Agent phân biệt bộ nhớ giữa các người dùng khác nhau.

// apps/langchain/scripts/07-short-term-memory-checkpointer.ts
// pnpm --filter=ai-notes-langchain run tsx scripts/07-short-term-memory-checkpointer.ts

import './env'; // Professional environment loader
import { createGeminiModel, generateImage } from '@workspace/util-langchain';
import { createAgent } from 'langchain';
import { MemorySaver } from '@langchain/langgraph';

async function main() {
  const model = createGeminiModel();

  // 1. Initialize the in-memory checkpointer
  const checkpointer = new MemorySaver();

  // 2. Create the Agent and attach the checkpointer
  const agent = createAgent({
    model: model,
    tools: [], // No tools needed to test memory
    checkpointer: checkpointer,
  });

  // 3. Generate visual diagram of the stateful agent
  await generateImage(agent.graph, 'graph-ignore/scripts-07-memory.jpg');

  // --- SCENARIO 1: Thread "user-nam" ---
  const configNam = { configurable: { thread_id: 'user-nam' } };

  console.log('--- [Thread: user-nam] Step 1: Introduction ---');
  await agent.invoke(
    {
      messages: [
        { role: 'user', content: 'Hi, my name is Nam and I live in Hanoi.' },
      ],
    },
    configNam,
  );

  console.log('--- [Thread: user-nam] Step 2: Testing Memory ---');
  const resNam = await agent.invoke(
    {
      messages: [
        { role: 'user', content: 'What is my name and where do I live?' },
      ],
    },
    configNam,
  );
  console.log('AI Response for Nam:', resNam.messages.at(-1).content);

  // --- SCENARIO 2: Thread "user-stranger" (Isolation Test) ---
  const configStranger = { configurable: { thread_id: 'user-stranger' } };

  console.log('\n--- [Thread: user-stranger] Step 1: Asking Identity ---');
  const resStranger = await agent.invoke(
    { messages: [{ role: 'user', content: 'Hello, do you know my name?' }] },
    configStranger,
  );
  console.log('AI Response for Stranger:', resStranger.messages.at(-1).content);
}

main().catch(console.error);

IV. Phân tích kỹ thuật

  • MemorySaver: Đây là giải pháp hoàn hảo cho môi trường thử nghiệm (Development). Nó lưu mọi thứ vào RAM nên sẽ bị xóa sạch nếu bạn khởi động lại script. Trong thực tế, bạn sẽ thay thế nó bằng PostgresSaver hoặc SqliteSaver để lưu trữ vĩnh viễn.
  • Tính biệt lập (Isolation): Như bạn thấy trong kết quả chạy, ở Thread user-nam, Agent nhớ rõ thông tin khách hàng. Nhưng ở Thread user-stranger, Agent hoàn toàn không có thông tin. Điều này đảm bảo tính riêng tư dữ liệu khi phục vụ nhiều người dùng cùng lúc.
  • Quản lý State tự động: Bạn không cần tạo mảng historypush tin nhắn mới vào. Mọi thứ từ câu hỏi của người dùng đến phản hồi của AI đều được LangChain tự động "chụp ảnh" và lưu vào Checkpointer sau mỗi Super-step.

Sơ đồ hoạt động:

Sơ đồ Stateful Agent

V. Tổng kết

  • Persistence là yếu tố biến một Chatbot đơn thuần thành một Trợ lý ảo thực thụ.
  • Luôn truyền thread_id vào tham số cấu hình để Agent có thể tìm lại ký ức.
  • Sử dụng hệ thống env.ts giúp bạn dễ dàng chuyển đổi từ bộ nhớ RAM sang Database thật mà không làm rối mã nguồn.

Khi cuộc hội thoại kéo dài hàng tuần với hàng ngàn tin nhắn, việc gửi toàn bộ lịch sử sẽ làm tốn rất nhiều chi phí Token. Trong bài học tiếp theo, chúng ta sẽ học cách tối ưu bộ nhớ bằng kỹ thuật Summarization Middleware!

👉 Bài tiếp theo: 8. Tóm tắt bộ nhớ (Summarization Middleware)