Tất cả bài viết Ảnh bìa: Bộ nhớ của agent: nhớ đúng còn khó hơn nhớ nhiều
15 tháng 7, 2026 · 13 phút đọc

Bộ nhớ của agent: nhớ đúng còn khó hơn nhớ nhiều

Bộ nhớ của agent không chỉ là nhét lịch sử chat vào vector database. Bài này đi từ các loại bộ nhớ tới luồng ghi, truy xuất, hợp nhất, quên và cách đo một hệ thống bộ nhớ dùng được trong thực tế.

LLM AgentsMemoryArchitecture

Thứ Hai, bạn bảo agent: “Đừng deploy vào chiều thứ Sáu.” Nó trả lời đã hiểu. Bốn ngày sau, đúng 16 giờ 45, agent hoàn tất một thay đổi và hí hửng chạy lệnh deploy. Lịch sử chat vẫn còn đó, vector database vẫn chứa nguyên câu dặn, model cũng chẳng hề mất một trọng số nào. Vậy mà hệ thống vẫn quên.

Đây là chỗ khái niệm bộ nhớ (memory) dễ đánh lừa người xây agent. Lưu được một đoạn text không có nghĩa là agent sẽ tìm đúng đoạn đó, hiểu nó còn hiệu lực, đưa nó vào context đúng lúc và hành động theo nó. Một hệ thống bộ nhớ chỉ làm được việc khi cả chuỗi ghi → tổ chức → truy xuất → sử dụng → cập nhật hoặc quên cùng chạy đúng.

Tôi nghĩ nên nhìn bộ nhớ của agent như một hệ thống dữ liệu có policy, không phải một cái túi vô hạn để đổ transcript vào.

Context không phải là bộ nhớ dài hạn

Mỗi lần gọi, LLM chỉ thấy những token được đưa vào context hiện tại. Phần mềm bên ngoài có thể nạp system prompt, vài tin nhắn gần nhất, kết quả tool và một ít dữ liệu truy xuất từ trước; model không tự mở lại cuộc trò chuyện hôm qua nếu ứng dụng không đưa nó vào.

Context vì thế gần với bộ nhớ làm việc: nhanh, nằm ngay trước mắt model, nhưng hữu hạn và biến mất khỏi tầm nhìn khi lượt gọi kết thúc. Bộ nhớ dài hạn nằm ngoài model, có thể là bảng SQL, document store, vector index, file hoặc graph. Muốn biến dữ liệu ở đó thành thứ agent “nhớ”, hệ thống phải có hai quyết định riêng:

  • Ghi: thông tin nào đáng giữ, giữ dưới dạng gì, thuộc về ai và có hiệu lực tới bao giờ?
  • Đọc: trước một nhiệm vụ cụ thể, ký ức nào đáng chiếm chỗ trong context window?

MemGPT mô tả bài toán này bằng phép so sánh với phân cấp bộ nhớ của hệ điều hành: context window là tầng nhỏ và nhanh, còn dữ liệu ngoài context là tầng lớn hơn nhưng phải được chuyển vào đúng lúc.3 Phép so sánh hữu ích ở một điểm rất thực dụng: tăng dung lượng lưu trữ không tự giải quyết được việc chọn dữ liệu để nạp.

Bộ nhớ thực ra là vài loại dữ liệu khác nhau

Khung CoALA của Sumers và cộng sự chia bộ nhớ trong language agent thành nhiều thành phần, thay vì gom mọi thứ vào một kho chung.1 Khi áp dụng cách phân loại đó vào thiết kế hệ thống, tôi thường dùng bảng sau:

Loại bộ nhớNó giữ gì?Ví dụCách lưu phù hợp
WorkingThứ đang cần cho lượt suy luận nàymục tiêu hiện tại, output của tool vừa chạycontext, state tạm
EpisodicMột sự kiện đã xảy radeploy lần trước fail vì thiếu biến môi trườngevent log có thời gian và nguồn
SemanticMột sự thật hoặc quan hệ tương đối ổn địnhservice thanh toán dùng PostgreSQL; người dùng thích câu trả lời ngắnbản ghi có cấu trúc, document hoặc graph
ProceduralBiết cách làm một việcquy trình release, skill debug một queue bị nghẽncode, workflow, skill có phiên bản

Ranh giới không phải lúc nào cũng tuyệt đối. Ký ức về một lần sửa production thuộc loại episodic; sau vài lần tương tự, agent có thể rút ra một quy tắc semantic; nếu quy tắc ấy được đóng gói thành checklist hoặc script, nó trở thành procedural memory (bộ nhớ thủ tục). Điểm đáng giữ không phải tên gọi, mà là mỗi loại cần cách ghi, truy xuất và kiểm chứng khác nhau.

Nhét tất cả vào cùng một vector index làm mất sự khác biệt đó. Câu “Nam thích dark mode” không nên cạnh tranh bằng cosine similarity với 400 KB log build. Một quy trình rollback cũng không nên được cập nhật như một sở thích có thể đổi theo thời gian.

Một pipeline bộ nhớ đủ dùng trông như thế nào?

Nếu bỏ tên framework và database cụ thể, luồng đầy đủ có hình dạng như sau:

flowchart TD
    O[Quan sát mới] --> W{Có đáng ghi?}
    W -- không --> X[Bỏ qua]
    W -- có --> N[Chuẩn hoá<br/>nguồn · thời gian · phạm vi]
    N --> S[(Kho bộ nhớ)]
    Q[Nhiệm vụ mới] --> P[Lập truy vấn]
    P --> R[Hybrid retrieval<br/>lọc · tìm · rerank]
    S --> R
    R --> B[Đóng gói theo<br/>context budget]
    B --> A[Agent suy luận & hành động]
    A --> U[Đánh giá kết quả]
    U --> C[Giữ · sửa · hợp nhất · quên]
    C --> S

Hai khâu dễ bị làm qua loa nhất là ghi và cập nhật sau khi sử dụng. Nhiều demo lưu mọi message, chạy similarity search rồi gọi đó là bộ nhớ. Cách này chạy đẹp với năm lượt chat; tới tháng thứ ba, kho biến thành một đống câu lặp, dữ kiện hết hạn và suy luận cũ chưa từng được xác nhận.

Ghi có chọn lọc, nhưng đừng xoá mất bằng chứng

Không phải câu nào model nhìn thấy cũng đáng thành ký ức dài hạn. Output tạm của một lệnh ls, lời chào xã giao và một giả thuyết debug bị bác bỏ thường không nên được lưu ở cùng mức ưu tiên với một quyết định kiến trúc đã được duyệt.

Một write gate nên xem xét ít nhất các tín hiệu sau:

  • Giá trị tương lai: thông tin này có khả năng thay đổi quyết định ở một lượt khác không?
  • Trùng lặp: kho đã có dữ kiện này chưa?
  • Độ tin cậy: đây là lời người dùng xác nhận, kết quả tool, hay suy đoán do model tự sinh?
  • Phạm vi: ký ức thuộc user, project, task hay một session cụ thể?
  • Thời hạn: nó là sự thật lâu dài, trạng thái tạm thời hay preference có thể đổi?

Tôi thích lưu hai tầng. Tầng đầu là event log bất biến, giữ quan sát gốc cùng timestamp và provenance. Tầng thứ hai là fact đã chuẩn hoá, phục vụ truy xuất nhanh và có thể được cập nhật. Khi người dùng nói “từ giờ dùng pnpm, không dùng npm”, fact hiện hành đổi sang pnpm, nhưng event cũ vẫn còn để giải thích vì sao hệ thống từng làm khác.

Một bản ghi tối thiểu có thể trông như thế này:

{
  "subject": "project:namnn-com",
  "predicate": "package_manager",
  "value": "pnpm",
  "valid_from": "2026-07-15T09:20:00+07:00",
  "valid_to": null,
  "scope": "project",
  "source": {
    "type": "user_message",
    "id": "msg_01J..."
  },
  "confidence": 1.0
}

valid_fromvalid_to quan trọng hơn ta tưởng. Nếu chỉ overwrite npm bằng pnpm, agent biết trạng thái mới nhưng mất lịch sử. Nếu giữ cả hai mà không có thời gian hiệu lực, retrieval có thể kéo về hai câu trái nhau rồi bắt model tự đoán. Bộ nhớ tốt không né mâu thuẫn; nó biểu diễn được dữ kiện đã thay đổi.

Vector search trả lời khá tốt câu hỏi “đoạn nào giống về ngữ nghĩa?”, nhưng agent thường cần nhiều hơn thế. Quy tắc deploy chiều thứ Sáu có thể không giống về từ vựng với nhiệm vụ “phát hành bản 2.4.1”; một lỗi có mã E11000 lại cần exact match; còn preference mới nhất phải thắng preference cũ dù embedding của cả hai gần như nhau.

Trong Generative Agents, Park và cộng sự chấm ký ức theo ba tín hiệu: độ liên quan, tính gần đây và mức độ quan trọng; hệ thống còn tạo các reflection ở mức khái quát hơn từ chuỗi quan sát.2 Đây không phải công thức duy nhất cho mọi agent, nhưng nó chỉ ra đúng vấn đề: similarity thuần tuý chưa đủ để quyết định cái gì đáng nhớ lúc này.

Một retrieval pipeline thực tế thường cần phối hợp:

  • filter cứng theo tenant, user, project, quyền truy cập và thời gian hiệu lực;
  • tìm kiếm lexical cho mã lỗi, tên symbol và chuỗi chính xác;
  • semantic search cho ý định được diễn đạt khác chữ;
  • ưu tiên theo recency, importance và độ tin cậy của nguồn;
  • rerank theo nhiệm vụ hiện tại, rồi loại các bản ghi trùng hoặc mâu thuẫn đã hết hiệu lực.

Sau cùng, hệ thống phải đóng gói kết quả vào một context budget. Top 20 đoạn “có liên quan” vẫn có thể làm model tệ đi nếu chúng dài, lặp và che mất chỉ dẫn chính. Retrieval không dừng lại khi query trả row; nó chỉ hoàn tất khi agent nhận được một gói context ngắn, có nguồn và đủ để ra quyết định.

Hợp nhất và quên là tính năng, không phải dọn rác

Kho bộ nhớ chỉ tăng mà không có quá trình consolidation sẽ sớm ngập dữ liệu. Generative Agents dùng reflection để tổng hợp các quan sát thành kết luận ở mức cao hơn.2 Trong hệ thống kỹ thuật, việc tương tự có thể là gom 30 event deploy thành một fact: “ba lần fail gần nhất đều do secret chưa đồng bộ”.

Nhưng summary là phép nén có mất mát. Nó nên trỏ ngược về event nguồn, và không được thay thế bằng chứng gốc khi độ chính xác còn quan trọng. Nếu summary nói “user luôn muốn câu trả lời ngắn” trong khi dữ liệu gốc chỉ có một lần người dùng yêu cầu viết gọn, hệ thống vừa biến một tình huống thành tính cách lâu dài.

Quên cũng cần policy rõ ràng:

  • xóa theo yêu cầu của người dùng và xóa lan sang index, cache, summary dẫn xuất;
  • giảm ưu tiên cho dữ kiện cũ, nhưng không âm thầm xóa audit trail vẫn thuộc diện phải lưu;
  • đánh dấu bản ghi cũ đã hết hiệu lực khi có thông tin mới thay thế, thay vì để hai “sự thật hiện hành” cùng tồn tại;
  • đặt TTL cho trạng thái tạm như branch đang làm việc hoặc incident đã kết thúc.

Có thêm một lý do để dè sẻn: bộ nhớ là input không đáng tin cậy. Một trang web có thể chứa prompt injection; output của tool có thể sai; model có thể ghi nhầm suy đoán của chính nó thành fact. Vì vậy provenance và trust level phải đi cùng bản ghi tới tận lúc nạp vào context. Đừng biến một câu đọc được trên web thành chỉ dẫn cấp hệ thống chỉ vì nó nằm trong “bộ nhớ”.

Đo bộ nhớ bằng hành vi, không bằng số row

Một dashboard khoe “đã lưu 50.000 ký ức” gần như không nói gì về chất lượng. Câu hỏi đúng là agent có hành động tốt hơn nhờ chúng hay không.

LoCoMo được Maharana và cộng sự xây để kiểm tra hội thoại rất dài qua nhiều session. Dataset của họ có các cuộc trò chuyện trung bình khoảng 600 lượt và 16.000 token, kéo dài tới 32 session; bài toán bao gồm hỏi đáp, tóm tắt sự kiện và sinh hội thoại đa phương thức.4 Kết quả của nhóm cho thấy long context và RAG đều giúp, nhưng các mô hình được thử vẫn gặp khó với quan hệ thời gian và nhân quả dài hạn, đồng thời hiệu năng vẫn kém đáng kể so với con người trong thiết lập đó.4

Với một agent sản phẩm, tôi sẽ đo riêng từng khâu:

KhâuCâu hỏi cần đo
WriteFact đáng giữ có được ghi không? Rác và suy đoán sai có lọt vào không?
RetrieveBằng chứng cần thiết có nằm trong top-k? Dữ kiện hết hạn có bị loại?
UseKhi bằng chứng đã vào context, agent có áp dụng đúng không?
UpdateCorrection mới có thay thế trạng thái cũ mà vẫn giữ provenance?
ForgetYêu cầu xóa có loại bỏ cả bản gốc lẫn dữ liệu dẫn xuất?
CostMỗi lượt tốn bao nhiêu latency, token và lần gọi model?

Tách như vậy mới debug được. Nếu bằng chứng đúng đã nằm trong context mà agent vẫn deploy chiều thứ Sáu, lỗi ở reasoning hoặc policy enforcement, không phải retrieval. Nếu query chẳng kéo được câu dặn, thay model lớn hơn thường chỉ là cách đắt tiền để chữa sai tầng.

Bắt đầu nhỏ, nhưng tách rõ trách nhiệm

Bạn chưa cần một graph bộ nhớ cầu kỳ cho phiên bản đầu tiên. Một kiến trúc gọn vẫn có thể đứng vững nếu tuân theo sáu nguyên tắc sau:

  1. Lưu event gốc theo kiểu append-only, có thời gian, phạm vi và nguồn.
  2. Trích fact có cấu trúc ở một tầng riêng; không coi mọi câu model sinh ra là fact.
  3. Retrieval kết hợp filter, lexical search và semantic search; đừng giao hết cho cosine similarity.
  4. Context pack tuân theo ngân sách token, loại bỏ bản ghi trùng và đính kèm provenance.
  5. Ngay từ đầu, cần có API cho phép sửa và xóa bộ nhớ, kể cả dữ liệu dẫn xuất.
  6. Đánh giá bằng các kịch bản nhiều session có correction, mâu thuẫn và dữ kiện hết hạn.

Khi đã có nền này, bạn mới biết lúc nào cần graph để nối quan hệ, reflection để hợp nhất trải nghiệm, hay bộ nhớ thủ tục để tái sử dụng cách làm. Công nghệ lưu trữ có thể đổi. Policy quyết định thứ gì được gọi là ký ức mới là phần khó thay.

Agent ở đầu bài không thất bại vì thiếu dữ liệu. Nó thất bại vì hệ thống không đưa một quy tắc còn hiệu lực tới đúng thời điểm ra quyết định. Nhớ nhiều chỉ làm cái kho lớn hơn; nhớ đúng đòi hỏi cả kiến trúc biết chọn, biết nghi ngờ và biết quên.

Tài liệu tham khảo

  1. Sumers, T. R., Yao, S., Narasimhan, K., Griffiths, T. L. (2023). Cognitive Architectures for Language Agents. arXiv:2309.02427
  2. Park, J. S., O'Brien, J. C., Cai, C. J., Morris, M. R., Liang, P., Bernstein, M. S. (2023). Generative Agents: Interactive Simulacra of Human Behavior. arXiv:2304.03442
  3. Packer, C., Wooders, S., Lin, K., Fang, V., Patil, S. G., Stoica, I., Gonzalez, J. E. (2023). MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560
  4. Maharana, A., Lee, D.-H., Tulyakov, S., Bansal, M., Barbieri, F., Fang, Y. (2024). Evaluating Very Long-Term Conversational Memory of LLM Agents. arXiv:2402.17753 · ACL 2024