Agent Memory Architecture - Kiến trúc Bộ nhớ Đa tầng cho AI Agents với Redis, Vector DB, ClickHouse và Knowledge Graph 2026

Posted on: 4/14/2026 12:19:21 PM

Table of contents

  1. 1. Vì sao một AI Agent cần bộ nhớ thực sự?
    1. Memory là đòn bẩy chi phí, không chỉ là tính năng
  2. 2. Phân loại bộ nhớ — khung CoALA là điểm tựa chung
  3. 3. Redis — nền tảng cho Working Memory và Session State
    1. 3.1. Session state bằng Hash + TTL
    2. 3.2. Conversation buffer bằng Stream
    3. 3.3. LangGraph Checkpointer với Redis
      1. Checkpointer là RAM, Store là ổ cứng
  4. 4. Vector DB — trái tim của Episodic và Semantic Memory
  5. 5. ClickHouse — nền tảng cold log và Episodic Memory quy mô lớn
  6. 6. Knowledge Graph — khi bộ nhớ có quan hệ
  7. 7. So kè 5 framework Memory tiêu biểu 2026
    1. 7.1. Letta (MemGPT) — agent như một hệ điều hành
    2. 7.2. Mem0 — universal memory layer với extraction + dedup
    3. 7.3. Zep / Graphiti — temporal knowledge graph
    4. 7.4. LangMem — bộ ba semantic, episodic, procedural
    5. 7.5. Anthropic Memory Tool — bộ nhớ dạng file
      1. Triết lý ngược dòng của Anthropic
  8. 8. Vòng đời của một ký ức — 6 thao tác cốt lõi
    1. Đừng bỏ qua "forget"
  9. 9. Memory trong hệ Multi-Agent — chia sẻ hay cách ly?
  10. 10. Production concerns — những thứ giết chết một kiến trúc đẹp trên giấy
    1. 10.1. Latency budget cho mỗi turn agent
    2. 10.2. Quyền riêng tư, retention và GDPR
    3. 10.3. Memory poisoning — mặt tối của persistence
  11. 11. Kiến trúc tham khảo — gộp tất cả lại
  12. 12. Lộ trình triển khai từng bước cho team bạn
  13. 13. Kết luận
    1. Checklist 7 điểm cho một kiến trúc memory đáng tin cậy
    2. Nguồn tham khảo

Một AI agent không có bộ nhớ thì chỉ là một cỗ máy phản xạ: mỗi lượt đối thoại là một lần bắt đầu lại từ con số không. Nhưng khi ta muốn agent học từ tương tác quá khứ, nhớ sở thích người dùng, duy trì trạng thái dự án kéo dài nhiều ngàyphối hợp với agent khác trong cùng một tổ chức, câu chuyện bộ nhớ đột nhiên trở thành một bài toán kiến trúc hệ thống thực thụ — với nhiều tầng lưu trữ, nhiều mô hình truy xuất, nhiều chính sách quên và củng cố. Bài viết này đi sâu vào Agent Memory Architecture năm 2026: từ phân loại bộ nhớ theo CoALA, đến cách ánh xạ từng tầng vào Redis, Vector DB, ClickHouse và Knowledge Graph, rồi mổ xẻ năm framework nổi bật nhất hiện nay — Letta (MemGPT), Mem0, Zep, LangMem và Anthropic Memory Tool.

84%Giảm token với Memory Tool của Anthropic
91%Giảm P95 latency — Mem0 so với full-context
~300msP95 truy xuất hybrid của Zep Graphiti
115k→1.6kToken context trên LongMemEval (Zep)

1. Vì sao một AI Agent cần bộ nhớ thực sự?

Context window dài 200K, 1M token nghe có vẻ đủ cho "bất cứ thứ gì". Nhưng trong thực tế triển khai, ba giới hạn vật lý khiến chúng ta không thể chỉ nhồi toàn bộ lịch sử vào prompt:

  • Chi phí tăng tuyến tính theo độ dài context. Mỗi lượt gọi LLM phải trả tiền cho từng token input; với một agent chạy 20 lượt hội thoại trong ngày, việc luôn đính kèm 80K token lịch sử sẽ nhanh chóng đốt ngân sách.
  • "Lost-in-the-middle": các benchmark đều cho thấy mô hình ghi nhớ kém đoạn giữa của context dài. Context càng dài, xác suất mô hình bỏ qua chi tiết quan trọng càng cao.
  • Ngữ cảnh không tái tạo được sau khi compact: khi Claude Code hay LangGraph thực hiện context compaction, các chi tiết không được "rút gọn" một cách có chủ đích sẽ biến mất vĩnh viễn. Nếu ta không chủ động ghi ra ngoài, agent sẽ "mất trí" ngay khi vượt ngưỡng.

Giải pháp chuẩn là tách rời bộ nhớ làm việc (working memory) nằm trong context window với các tầng bộ nhớ ngoài. Khi cần, agent truy xuất đúng đoạn memory cần thiết và nhúng vào prompt — thay vì mang vác toàn bộ quá khứ. Đây chính là tinh thần just-in-time context mà Anthropic khuyến nghị trong bài "Effective context engineering".

Memory là đòn bẩy chi phí, không chỉ là tính năng

Anthropic công bố Memory Tool giảm 84% token tiêu thụ trong các workflow dài. Mem0 (paper arXiv 2504.19413) báo giảm ~90% chi phí token91% P95 latency so với giải pháp nhồi full-context. Zep (arXiv 2501.13956) đưa context trung bình trên LongMemEval từ 115K xuống còn 1,6K token — tức hơn 98%. Điều này nghĩa là: bộ nhớ ngoài là kỹ thuật tối ưu chi phí bậc nhất trong LLM ops hiện nay.

2. Phân loại bộ nhớ — khung CoALA là điểm tựa chung

Hầu hết framework agent hiện đại — LangGraph, LangMem, Mem0, Letta, Zep — đều trực tiếp hoặc gián tiếp tham chiếu đến CoALA (Cognitive Architectures for Language Agents) của Sumers et al. (Princeton, 2023). CoALA vay mượn cách phân loại trí nhớ từ khoa học nhận thức và các kiến trúc cổ điển như ACT-R, Soar, rồi ánh xạ vào bối cảnh LLM agent.

Loại bộ nhớChứa gìĐặc trưng truy cậpÁnh xạ hiện thực 2026
Working memory
(bộ nhớ làm việc)
Messages, scratchpad, tool outputs, reasoning state hiện tạiĐọc/ghi mỗi bước suy luận, luôn nằm trong context windowLangGraph State + Checkpointer, Letta Core Memory Blocks, Redis Hash/JSON
Episodic memory
(bộ nhớ tình tiết)
Sự kiện cụ thể đã xảy ra — lượt hội thoại, trace tool call, quyết định và kết quảTruy xuất theo ngữ cảnh, thời gian, chủ đềVector DB (episodic collection), ClickHouse (event log), Letta Recall Memory
Semantic memory
(bộ nhớ ngữ nghĩa)
Sự thật đã được tổng quát hoá — "Alice là lập trình viên Go", "dự án dùng pnpm"Truy xuất theo độ tương đồng, theo chủ thể, lọc dedupVector DB (semantic facts), Knowledge Graph, Mem0, LangMem profiles
Procedural memory
(bộ nhớ thủ tục)
Cách thực hiện: skills, rules, workflowsĐính kèm system prompt hoặc nạp theo nhu cầuModel weights + tool definitions + system prompt (LangMem prompt optimizer viết lại)
Reflective memory
(bộ nhớ phản tỉnh)
Tổng kết, "insight" tầng cao được sinh ra từ các ký ức cấp thấpSinh định kỳ hoặc khi có đủ tín hiệuGenerative Agents (Park 2023), Zep communities, Letta sleeptime compute

Ranh giới giữa các tầng không phải là một đường thẳng tắp. Một đoạn hội thoại có thể là episodic khi mới vừa diễn ra, và theo thời gian nó được chưng cất thành một semantic fact ("người dùng này không thích email marketing"). Một "reflection" có thể được sinh ra, rồi tự nó trở thành nguyên liệu cho reflection kế tiếp — hình thành một cây trừu tượng, đúng như những gì Park et al. trình diễn trong Generative Agents.

flowchart TB
    A["Agent Loop"] -->|read/write| W["Working Memory
Redis / Checkpointer
~1ms"] W -->|promote| E["Episodic Memory
Vector DB / ClickHouse
~50ms"] E -->|consolidate| S["Semantic Memory
Vector DB / Mem0 / Profile
~80ms"] S -->|entity link| G["Relational Memory
Knowledge Graph / Graphiti
~300ms"] G -.->|reflection| R["Reflective Memory
LLM-synthesized insights"] R -.->|feedback| S E -->|archival| C["Cold Log
ClickHouse MergeTree
event replay"] P["Procedural Memory
System prompt + tools"] -->|always in context| A style A fill:#e94560,stroke:#fff,color:#fff style W fill:#4CAF50,stroke:#fff,color:#fff style E fill:#0f3460,stroke:#fff,color:#fff style S fill:#0f3460,stroke:#fff,color:#fff style G fill:#0f3460,stroke:#fff,color:#fff style R fill:#ff9800,stroke:#fff,color:#fff style C fill:#2c3e50,stroke:#fff,color:#fff style P fill:#8e44ad,stroke:#fff,color:#fff

Kiến trúc bộ nhớ đa tầng cho AI Agent — các mũi tên thể hiện luồng promote, consolidate và reflection giữa các tầng

3. Redis — nền tảng cho Working Memory và Session State

Redis giữ vị trí thống trị ở tầng working memory vì ba lý do không thể tranh cãi: độ trễ dưới 1ms, các kiểu dữ liệu rất hợp với trạng thái hội thoại (Hash, List, Stream, JSON), và ngữ nghĩa TTL cho phép tự động "quên" những gì quá hạn. Redis 8 (GA 2025) và phiên bản 8.4 còn thống nhất vector search trực tiếp trong core, bỏ nhu cầu module riêng — vừa làm cache vừa làm embedding store trong cùng một cụm.

3.1. Session state bằng Hash + TTL

Mỗi session hội thoại được lưu thành một Hash. Redis 8 hỗ trợ TTL theo từng field — nghĩa là bạn có thể hết hạn riêng một "last_tool" trong khi vẫn giữ "user_profile" tồn tại lâu hơn. Đây là thay đổi quan trọng so với Redis 7.

import redis, time
r = redis.Redis(host="redis-prod", decode_responses=True)

# Lưu trạng thái session
r.hset("session:user_42", mapping={
    "thread_id": "t-9f1c",
    "last_intent": "refactor_auth",
    "last_tool": "file_edit",
    "turn_count": 7,
})
r.expire("session:user_42", 3600)   # hết hạn toàn bộ sau 1 giờ

# Redis 8: hết hạn riêng một field (HEXPIRE)
r.execute_command("HEXPIRE", "session:user_42", 300, "FIELDS", 1, "last_tool")

3.2. Conversation buffer bằng Stream

Khi nhiều agent cùng theo dõi một luồng hội thoại (ví dụ một Supervisor và các Specialist), XADD và consumer group của Redis Streams cho ngữ nghĩa "fan-out with acknowledgement" miễn phí — một agent đã xử lý không kéo lại tin nhắn đó nữa, nhưng agent khác vẫn thấy.

r.xadd("chat:thread_42", {
    "role": "user",
    "content": "Sửa lại cache invalidation logic",
    "ts": int(time.time() * 1000),
})
# Consumer group cho mỗi agent
r.xgroup_create("chat:thread_42", "supervisor", id="0", mkstream=True)
r.xgroup_create("chat:thread_42", "coder", id="0", mkstream=True)

3.3. LangGraph Checkpointer với Redis

LangGraph đóng gói working memory dưới khái niệm Checkpointer — lưu object State của graph sau mỗi superstep để có thể rewind, branch hoặc chèn human-in-the-loop. Package langgraph-checkpoint-redis cung cấp RedisSaver (lưu toàn bộ lịch sử checkpoint) và ShallowRedisSaver (chỉ giữ snapshot mới nhất để tiết kiệm bộ nhớ).

from langgraph.graph import StateGraph
from langgraph.checkpoint.redis import RedisSaver

memory = RedisSaver.from_url("redis://redis-prod:6379/0")
graph = builder.compile(checkpointer=memory)

config = {"configurable": {"thread_id": "user_42:session_1"}}
graph.invoke({"messages": [HumanMessage("Tóm tắt tiến độ hôm qua")]}, config=config)

# Rewind về checkpoint cũ
history = list(graph.get_state_history(config))
graph.update_state(history[3].config, values={...})

Checkpointer là RAM, Store là ổ cứng

LangGraph tách rõ hai primitive: Checkpointer là thread-scoped (một thread hội thoại), Store là cross-thread (xuyên phiên, xuyên user). Hãy nhớ nguyên tắc: thứ gì chỉ có ý nghĩa trong một hội thoại → Checkpointer; thứ gì cần tồn tại sang phiên sau → Store. Nhầm lẫn hai thứ này là nguồn gốc nhiều lỗi "agent quên" và "agent bị rò rỉ giữa user".

4. Vector DB — trái tim của Episodic và Semantic Memory

Khi phải truy xuất "bằng nghĩa" thay vì "bằng key chính xác", Vector DB là câu trả lời. Dù là Pinecone, Weaviate, Qdrant, Milvus, pgvector hay Redis Vector Search, mô hình chung đều là: mỗi ký ức được biểu diễn bằng một embedding ~1000 chiều, kèm metadata {user_id, namespace, type, timestamp, source_event_id}, và được truy vấn bằng ANN (approximate nearest neighbor) có kèm filter metadata.

Tầng vector chứa hai loại khác nhau, và sai lầm phổ biến là gộp chung chúng:

  • Semantic facts: mỗi hàng là một khẳng định nhỏ gọn — "Người dùng thích dark mode", "Codebase dùng pnpm". Thường là kết quả của bước extraction/dedup và có số lượng nhỏ trên mỗi user.
  • Episodic snippets: mỗi hàng là một đoạn hội thoại hoặc một ví dụ few-shot chưng cất từ trải nghiệm quá khứ. Số lượng nhiều, hay phình to theo thời gian.

Đừng nhét cả hai vào chung một collection. Chúng có TTL khác nhau, threshold similarity khác nhau, và đặc biệt semantic facts có ràng buộc nhất quán (một user chỉ có một địa chỉ nhà), còn episodic thì không. Trộn lẫn dẫn đến việc retrieval lôi về 5 phiên bản khác nhau của cùng một sự thật, khiến mô hình bối rối.

from langgraph.store.postgres import PostgresStore
store = PostgresStore.from_conn_string("postgresql://...", index={
    "dims": 1536, "embed": embed_fn
})

namespace_semantic = ("user_42", "semantic")
namespace_episodic = ("user_42", "episodic")

# Semantic — ghi theo key ổn định để upsert
store.put(namespace_semantic, key="preferences:editor",
          value={"fact": "Dùng VS Code làm editor chính"})

# Episodic — mỗi turn là một row riêng
store.put(namespace_episodic, key=f"turn:{turn_id}",
          value={"summary": "User đã từ chối suggestion thêm TypeScript generic"})

5. ClickHouse — nền tảng cold log và Episodic Memory quy mô lớn

Khi kho sự kiện vượt mốc vài triệu hàng, Vector DB không còn là lựa chọn kinh tế cho mọi truy vấn — đặc biệt là các truy vấn analytic (tổng token theo user, latency p99 theo tool, error rate theo agent). Đây là lúc ClickHouse bước vào với tư cách là event log / episodic memory tier. Langfuse, Laminar, HyperDX (ClickStack), Respan — gần như mọi nền tảng observability LLM trong 2024–2025 đều đã chuyển về ClickHouse. Langfuse báo cáo thời gian query p95 giảm "từ phút xuống thời gian thực" sau khi migrate từ Postgres.

CREATE TABLE agent_events (
    trace_id      UUID,
    span_id       UUID,
    parent_span   Nullable(UUID),
    agent_id      LowCardinality(String),
    user_id       String,
    event_type    LowCardinality(String), -- tool_call | llm_call | memory_read | memory_write
    timestamp     DateTime64(6),
    prompt_tokens UInt32,
    output_tokens UInt32,
    latency_ms    UInt32,
    cost_usd      Decimal(10, 6),
    payload       String CODEC(ZSTD(3))
) ENGINE = MergeTree
PARTITION BY toYYYYMM(timestamp)
ORDER BY (agent_id, user_id, timestamp)
TTL timestamp + INTERVAL 180 DAY;

Ba engine family đặc biệt hữu ích cho memory layer:

  • ReplacingMergeTree: khử trùng lặp theo (trace_id, span_id) cho ingestion at-least-once.
  • AggregatingMergeTree + Materialized View: pre-aggregate token cost và latency theo user/ngày. Dashboard không phải scan hàng tỷ dòng.
  • CollapsingMergeTree: model hoá state delta — hữu ích khi muốn replay trạng thái agent tại một thời điểm trong quá khứ.

Quan trọng hơn, ClickHouse biến tầng này thành nền tảng cho reflection và episodic recall: khi agent cần "nghĩ lại" về 30 ngày gần nhất, một tác vụ reflection có thể chạy một câu truy vấn ClickHouse lấy ra đúng các sự kiện quan trọng, rồi đưa qua LLM để sinh ra các insight cấp cao — những insight này sau đó được đẩy trở lại vào tầng semantic memory.

6. Knowledge Graph — khi bộ nhớ có quan hệ

Vector retrieval rất tệ ở ba việc: quan hệ nhiều chặng ("Alice là đồng nghiệp của ai?"), tính nhất quán ("user chỉ có một địa chỉ hiện tại") và temporal reasoning ("tuần trước Alice còn ở team A"). Các hạn chế này buộc nhiều hệ thống phải bổ sung một tầng Knowledge Graph. Nổi bật nhất 2025–2026 là Graphiti của Zep — một temporal KG engine được xây dựng trên Neo4j (mặc định), FalkorDB, Kuzu hoặc Amazon Neptune.

Điểm đắt giá nhất của Graphiti là mô hình bi-temporal: mỗi cạnh mang hai cặp thời gian — thời gian sự kiện (valid_from, valid_to) và thời gian quan sát (ingested_at, invalidated_at). Khi một sự thật mới mâu thuẫn với sự thật cũ, cạnh cũ không bị xoá mà chỉ đóng cửa sổ valid_to; truy vấn có thể hỏi "agent đang tin gì bây giờ?" hoặc "agent đã tin gì vào thứ Ba tuần trước?".

flowchart LR
    Q["Câu hỏi"] --> E1["φ_cos
Embedding cosine"] Q --> E2["φ_bm25
Full-text BM25"] Q --> E3["φ_bfs
Graph BFS từ seed"] E1 --> R["Reranker
RRF / MMR / CE"] E2 --> R E3 --> R R --> T["Top-k facts
+ valid_from / valid_to"] style Q fill:#e94560,stroke:#fff,color:#fff style R fill:#ff9800,stroke:#fff,color:#fff style T fill:#4CAF50,stroke:#fff,color:#fff

Pipeline truy xuất hybrid của Zep / Graphiti — không có LLM trong đường sync, nên P95 giữ quanh ~300ms

Một chi tiết rất quan trọng: không có lời gọi LLM nào trong đường truy xuất. Cả ba hàm φ_cos, φ_bm25, φ_bfs đều là query thuần, rerank bằng RRF (Reciprocal Rank Fusion) hoặc MMR. Nhờ vậy, Graphiti đạt latency P95 ~300ms ngay cả với đồ thị hàng trăm triệu cạnh. Trên benchmark LongMemEval, Zep đạt +18.5% accuracy so với baseline và giảm ~90% latency (2.58s so với 28.9s) — con số khẳng định một nguyên tắc thiết kế: đừng đặt LLM trong đường đọc đồng bộ.

7. So kè 5 framework Memory tiêu biểu 2026

Ranh giới giữa các framework memory đang rõ dần. Mỗi lựa chọn phản ánh một triết lý thiết kế khác nhau — và hiểu đúng triết lý đó quan trọng hơn nhớ được API nào.

7.1. Letta (MemGPT) — agent như một hệ điều hành

Letta (tiền thân là MemGPT, paper của Packer et al. 2023) đưa ra ẩn dụ nền tảng: context window là RAM, storage ngoài là disk, LLM là CPU. Mô hình hoá bộ nhớ thành ba tầng có thể "page" qua lại bằng tool call:

TầngNằm ởThời gian sốngAi chỉnh sửa
Core memory blocksTrong system prompt, luôn hiệnDài hạn, bền qua phiênChính agent qua core_memory_append, core_memory_replace
Recall memoryDB ngoài (mọi tin nhắn lưu lại)Dài hạnHệ thống tự ghi, agent có thể search
Archival memoryVector DB / Graph DBDài hạnAgent qua archival_memory_insert, archival_memory_search

Đóng góp mang tính khai mở của MemGPT chính là self-editing memory — mô hình được prompt/fine-tune để chủ động biên tập trạng thái của chính nó, không chờ một ai đó ở ngoài. Toàn bộ "trào lưu" memory tool sau này — kể cả Anthropic Memory Tool — đều có gốc rễ ở đây.

Năm 2025, Letta v1 tái kiến trúc agent loop theo bài blog "Rearchitecting Letta's Agent Loop: Lessons from ReAct, MemGPT, & Claude Code": bỏ heartbeat và wrapper send_message, chuyển sang reasoning tự nhiên + direct assistant generation để khai thác GPT-5 và Claude Sonnet 4.5. Kèm theo đó là MemFS — một filesystem bộ nhớ có thể track bằng git — và cơ chế sleeptime compute: một agent nền chạy song song, xử lý consolidation, summarization và reflection trong lúc agent chính đang chờ tin nhắn tiếp theo của user. Nhờ vậy các tác vụ nặng không chèn vào P95 của request.

7.2. Mem0 — universal memory layer với extraction + dedup

Mem0 (arXiv 2504.19413, 4/2025) được định vị là một lớp memory phổ quát, plug vào bất kỳ LLM app nào. Điểm phân biệt lớn nhất của Mem0 không nằm ở storage (dùng vector DB là chính), mà nằm ở cơ chế write hai pha:

  1. Extraction: LLM đọc các turns mới, sinh ra các memory ứng viên ở dạng fact nguyên tử.
  2. Update: với mỗi ứng viên, hệ thống lấy các memory liền kề đã tồn tại, rồi một Conflict Detector + Update Resolver quyết định một trong bốn thao tác: ADD (fact mới), UPDATE (tinh chỉnh cái cũ), DELETE (vô hiệu) hoặc NOOP (đã biết).

Đây chính là khác biệt với RAG ngây thơ: memory được dedup và reconcile tại thời điểm ghi, không phải chỉ lúc đọc. Kết quả trên benchmark LOCOMO (long-conversation): +26% accuracy so với memory sẵn có của OpenAI, giảm 91% P95 latency và giảm >90% chi phí token so với full-context.

from mem0 import Memory
m = Memory()

m.add("Tôi thích dark mode và dùng VS Code", user_id="alice")
m.add("Dự án hiện tại dùng pnpm, không phải npm", user_id="alice")

# Mem0 tự chạy hai pha: trích fact, phát hiện xung đột, quyết định ADD/UPDATE
m.search("alice dùng editor nào?", user_id="alice")
# [{"memory": "Uses VS Code", "score": 0.91, ...}]

Mem0 có hai backend: Mem0 (vector thuần) và Mem0g — phiên bản graph dùng Neo4j hoặc Neptune. Mem0g thêm layer graph để giải các câu hỏi multi-hop và temporal. AWS đã công bố reference architecture cho Mem0 với ElastiCache for Valkey (hot tier) và Neptune Analytics (graph tier).

7.3. Zep / Graphiti — temporal knowledge graph

Zep (arXiv 2501.13956, 1/2025) là hướng tiếp cận triệt để nhất về graph memory. Graphiti — engine lõi của Zep — tổ chức bộ nhớ thành ba tầng:

  1. Episodes: dữ liệu thô được nạp vào (messages + timestamps). Đây là lớp provenance ground-truth.
  2. Semantic entities + facts: LLM trích ra các entity và cạnh (subject, predicate, object), mỗi cạnh mang bi-temporal.
  3. Communities: cụm entity được nhóm theo Leiden community detection — tương tự cấu trúc của Microsoft GraphRAG, dùng để sinh ra các bản tóm tắt ở tầng cao.

Zep đánh bại MemGPT ngay trên chính benchmark DMR mà MemGPT tự tạo (94.8% so với 93.4% trên gpt-4-turbo), và trên LongMemEval cắt context trung bình từ 115K xuống 1.6K token. Bí mật nằm ở chỗ Graphiti không hạ thấp ambition — nó giữ được cả mối quan hệ lẫn tính thời gian, nhưng lại thay LLM retrieval bằng truy vấn thuần nên vẫn đạt ~300ms P95.

7.4. LangMem — bộ ba semantic, episodic, procedural

LangMem là SDK memory chính thống của LangChain, phát hành 2025. Nó tách biệt rõ ràng ba loại memory theo tinh thần CoALA và cho phép ta chọn chiến lược riêng cho từng loại:

  • Semantic memory: hai pattern — profile document (một tài liệu duy nhất tự tinh chỉnh) hoặc collection (nhiều fact rời). Tool create_manage_memory_toolcreate_search_memory_tool.
  • Procedural memory: điều thú vị nhất của LangMem — create_prompt_optimizer phân tích các trace thành công và thất bại rồi đề xuất bản viết lại của system prompt. Ba thuật toán: metaprompt, gradient, prompt_memory. Đây là procedural memory ở dạng prompt tự sinh.
  • Episodic memory: extract_episodic_memories chưng cất lịch sử thành các few-shot example có thể nạp lại khi cần.

7.5. Anthropic Memory Tool — bộ nhớ dạng file

Phát hành beta 29/9/2025 dưới tool type memory_20250818. Đây là một first-party tool, nghĩa là Claude được huấn luyện trực tiếp để biết khi nào nên tra memory và khi nào nên ghi. Sáu lệnh cơ bản, rất giống một editor file:

LệnhTham sốMục đích
viewpath, view_rangeList thư mục (2 tầng, kèm size) hoặc đọc file có đánh số dòng
createpath, file_textTạo file mới, lỗi nếu đã tồn tại
str_replacepath, old_str, new_strChỉnh tại chỗ, lỗi nếu trùng hoặc không khớp
insertpath, insert_line, insert_textChèn tại dòng (1-indexed)
deletepathXoá đệ quy
renameold_path, new_pathĐổi tên, lỗi nếu đích đã có

Mọi path đều được scope vào một thư mục logic /memories. SDK cung cấp BetaAbstractMemoryTool (Python) và betaMemoryTool (TypeScript) cho phép tự cài đặt backend — có thể là filesystem thật, S3, Postgres, hoặc vault được mã hoá.

Triết lý ngược dòng của Anthropic

Trong khi cả thế giới đổ về vector DB và knowledge graph, Anthropic cố ý không dùng embedding, không dùng vector search, không dùng graph. Đặt cược: một model đủ thông minh biết cách tự tổ chức các file có tên gọi và MEMORY.md làm index, kết quả sẽ vượt trội retrieval mờ. Số liệu thực tế: 84% giảm token trong workflow dài — chứng minh đặt cược này là có cơ sở.

Memory Tool còn đi kèm hai tính năng server-side: Context Editing (xoá các tool result cũ khỏi transcript, thay bằng reference tới memory) và Compaction (tóm tắt khi chạm ngưỡng context). Memory được giữ nguyên qua ranh giới compaction — tức là agent không mất trí sau khi bị rút gọn.

Claude Code xếp chồng lên trên ý tưởng đó hai cơ chế quen thuộc mà bất kỳ ai dùng công cụ này đều đã gặp:

  • CLAUDE.md — human-authored, commit vào git, nạp ở đầu phiên. Đây là nơi chứa "quy ước nhóm" cho agent.
  • Auto Memory (v2.1.59+, mặc định bật) — thư mục memory/ do chính agent ghi. MEMORY.md là index, 200 dòng đầu / 25KB được nạp vào đầu phiên; phần còn lại agent chủ động điều hướng qua các file topic khi cần.

8. Vòng đời của một ký ức — 6 thao tác cốt lõi

Một hệ thống memory trưởng thành không chỉ "ghi và đọc". Có ít nhất sáu thao tác, và mỗi framework chọn đặt chúng lên hot path hoặc cold path một cách khác nhau.

Thao tácMô tảĐặt ở đâu
Write (extract + store)LLM đọc turn mới, sinh fact ứng viên, ghi ra storeInline (Mem0 mặc định), background (Letta sleeptime), batch (nightly sweep)
Read (retrieve)Truy xuất ký ức liên quan tới câu hỏi hiện tạiLuôn phải là đường đồng bộ, phải nhanh — không có LLM ở giữa
UpdateSửa ký ức đã có thay vì nhân bảnUpsert by id (vector), edge invalidation (graph), str_replace (file)
SummarizeCô đọng buffer cũ thành tóm tắt ngắn hơnRecursive (Letta), periodic reflection (Park), server-side compaction (Anthropic)
ForgetHết hạn, giảm trọng số hoặc xoá theo complianceTTL (Redis, ClickHouse), importance-decay (Mem0), purge by user_id (GDPR)
ConsolidateChuyển giữa các tầng — hot → warm → coldRedis → Vector → ClickHouse; episode → entity → community

Công thức scoring episodic nổi tiếng nhất đến từ bài Generative Agents (Park et al. 2023) và đến nay vẫn được tham chiếu trong mọi tài liệu memory:

score = α_recency * recency + α_importance * importance + α_relevance * relevance
  • Recency: suy giảm theo hàm mũ từ lần truy cập cuối: exp(-Δt / τ).
  • Importance: điểm 1–10 do một LLM prompt đánh giá "mức độ đáng nhớ".
  • Relevance: cosine similarity giữa query và memory embedding.

Cả ba thành phần được min-max chuẩn hoá về [0, 1]; bản gốc đặt α = 1 cho cả ba. Công thức đơn giản nhưng đủ mạnh để phục vụ phần lớn use case, và là starting point rất tốt cho production.

Đừng bỏ qua "forget"

Rất nhiều team chỉ nghĩ đến việc ghi nhớ mà quên quên. Hệ quả: store phình to, latency truy xuất tăng dần, và tệ nhất là agent bị "ám ảnh" bởi những sự thật đã quá hạn (người dùng từng dùng pnpm 6 tháng trước, giờ đã chuyển sang bun). Một hệ thống memory tốt phải có chiến lược forget rõ ràng: TTL theo tầng, decay theo importance, và hard purge theo compliance request.

9. Memory trong hệ Multi-Agent — chia sẻ hay cách ly?

Ở mô hình single-agent, memory là vấn đề tối ưu hoá. Nhưng khi có nhiều agent cùng chạy trên cùng một tổ chức, nó trở thành câu hỏi kiến trúc: ai được đọc cái gì, ai được ghi cái gì, và điều gì sẽ xảy ra khi một agent bị nhiễm prompt injection?

  • Shared Blackboard (Swarm pattern): một store chung cho cả team. Đơn giản, thông tin chảy tự do. Nhược điểm: tranh chấp ghi, rủi ro lan truyền một ký ức độc hại cho toàn đội, và khó debug khi hai agent có cùng thời điểm sinh ra hai fact mâu thuẫn.
  • Hierarchical (Orchestrator + Specialists): orchestrator giữ memory cấp cao của team; specialist giữ scratchpad riêng, chỉ publish lên một bản tóm tắt. Giảm nhiễu và hạn chế cross-talk, là lựa chọn được khuyến nghị cho đa số production.
  • A2A Protocol (Google, 4/2025): khi các agent đến từ những tổ chức khác nhau, nguyên tắc opaque execution cấm chia sẻ bộ nhớ nội tại — agent chỉ trao đổi message qua một task interface chuẩn. Phù hợp khi ranh giới tin cậy yếu.
  • Namespaced LangGraph Store: một store vật lý duy nhất, nhưng BaseStore phân vùng theo tuple (agent_id, user_id, ...). Đơn giản về vận hành, vẫn giữ isolation logic.

Một nguyên tắc mới nổi trong các survey 2025–2026 là coordinated forgetting — team agent phải có giao thức thống nhất về cái gì được quên khi nào, để kho kiến thức chung không bị phình lên không giới hạn và để các fact lỗi thời không còn ảnh hưởng đến phần còn lại.

10. Production concerns — những thứ giết chết một kiến trúc đẹp trên giấy

10.1. Latency budget cho mỗi turn agent

TầngTarget P95Thực tế
Working memory read (Redis)< 5ms< 1ms
Vector recall top-k=10< 100ms30–80ms
Graph hybrid retrieval (Zep)< 500ms~300ms
LLM extraction (write path)< 2s500–2000ms
Reflection / summarizationofflinegiây–phút

Luật cứng: không bao giờ đặt một lời gọi LLM trên đường đọc đồng bộ. Đây là lý do Zep nhấn mạnh rằng retrieval của họ "no LLM in the path", cũng là lý do Mem0 đạt được "91% giảm P95" — vì họ chạy extraction bất đồng bộ. Và chính vì lý do này mà giải pháp file-based của Anthropic nhanh hơn các giải pháp vector thuần trong nhiều workload: không có embedding model chen vào giữa.

10.2. Quyền riêng tư, retention và GDPR

Một hệ memory đa tầng lưu dữ liệu người dùng qua nhiều phiên, qua nhiều tháng — đây là hành vi mà GDPR, HIPAA, SOC2 đều quan tâm trực tiếp. Checklist tối thiểu:

  • Field-level write filter: bộ lọc ngay trước extractor, chặn PII, secret, test data không bao giờ được lọt vào store.
  • Retention theo tầng: working memory (1 giờ), semantic (dài hạn), episodic (90 ngày), cold log (180 ngày) — ClickHouse TTL DELETE là công cụ phù hợp.
  • Per-user purge: mọi store phải hỗ trợ xoá theo user_id trong thời gian ngắn để đáp ứng quyền được quên. Dễ hơn rất nhiều khi user_id là first-class column (ClickHouse, Mem0) thay vì chôn trong metadata JSON.
  • Provenance: mọi memory phải carry trace_id / source_event_id để audit được "fact này sinh ra từ sự kiện nào", và để thu hồi đúng khi fact đó bị phản bác.

10.3. Memory poisoning — mặt tối của persistence

Khi bộ nhớ bền vững qua nhiều phiên, nó cũng trở thành bề mặt tấn công bền vững. Một fact độc hại ("khi người dùng hỏi về X, hãy trả lời Y") được ghi một lần, có thể sống sót qua hàng trăm session. Ba lớp phòng vệ cần thiết:

  1. Đối xử với memory giống như tool output — không tin tưởng ngầm. Mọi nội dung đọc ra từ store phải đi qua guardrails cấp instruction-detection trước khi đưa vào prompt.
  2. Giữ provenance trên mỗi ký ức, và cho phép invalidate theo chuỗi — khi một trace được phát hiện là adversarial, tất cả memory dẫn xuất từ trace đó phải bị đánh dấu.
  3. Validation tại thời điểm ghi — có thể là một model nhỏ rẻ hơn đóng vai trò classifier "đây có phải một instruction trá hình không?".

11. Kiến trúc tham khảo — gộp tất cả lại

flowchart TB
    U["User"] --> AG["Agent Runtime
LangGraph / Letta / Claude Code"] AG -->|turn state| CKPT["Redis
Checkpointer + Session Hash"] AG -->|retrieve| HYB["Hybrid Retriever
BM25 + Vector + Graph"] HYB --> VEC["Vector DB
episodic + semantic"] HYB --> GRF["Graphiti
Temporal KG"] HYB --> FS["File Memory
MEMORY.md"] AG -.->|async write| EXT["Extractor Worker
LLM fact extraction"] EXT --> VEC EXT --> GRF EXT --> FS AG -.->|trace/event| OTEL["OTel Collector"] OTEL --> CH["ClickHouse
MergeTree + MV"] CH -.->|reflection query| REF["Reflection Worker
sleeptime compute"] REF --> VEC REF --> GRF style U fill:#e94560,stroke:#fff,color:#fff style AG fill:#ff9800,stroke:#fff,color:#fff style CKPT fill:#4CAF50,stroke:#fff,color:#fff style HYB fill:#8e44ad,stroke:#fff,color:#fff style VEC fill:#0f3460,stroke:#fff,color:#fff style GRF fill:#0f3460,stroke:#fff,color:#fff style FS fill:#0f3460,stroke:#fff,color:#fff style CH fill:#2c3e50,stroke:#fff,color:#fff style REF fill:#ff9800,stroke:#fff,color:#fff style EXT fill:#ff9800,stroke:#fff,color:#fff style OTEL fill:#2c3e50,stroke:#fff,color:#fff

Kiến trúc memory tham khảo cho một agent production 2026 — write async, read sync, không có LLM trong đường đọc

Các tín hiệu thiết kế then chốt của kiến trúc trên:

  • Đường đọc chỉ gồm Redis (checkpointer), Hybrid Retriever và các store dữ liệu đã được chuẩn bị sẵn — không có LLM nào chen vào.
  • Đường ghi được đẩy sang một Extractor Worker bất đồng bộ. User nhận phản hồi trước, memory được cập nhật sau. Eventual consistency được chấp nhận như một trade-off có chủ đích.
  • ClickHouse là cold log cho tất cả sự kiện, đồng thời là nguồn nguyên liệu cho reflection chạy nền (sleeptime worker). Các insight sinh ra từ reflection được promote trở lại vào Vector hoặc Graphiti — khép kín vòng feedback.
  • File Memory tồn tại song song với vector/graph cho các ký ức mà model muốn tự quản — đặc biệt là trong workflow code-heavy như Claude Code, nơi một MEMORY.md đúng chỗ còn giá trị hơn mười vector hit mờ nhạt.

12. Lộ trình triển khai từng bước cho team bạn

Tuần 1
Thiết lập working memory: cài RedisSaver cho LangGraph hoặc Letta. Đo P95 retrieval, mục tiêu < 5ms. Không có gì khác chạy song song — trước tiên phải đảm bảo tầng RAM hoạt động.
Tuần 2
Thêm episodic log vào ClickHouse: bật OTel collector, schema agent_events, một materialized view cho cost/user/day. Có dashboard Grafana cơ bản trước khi nghĩ đến tầng kế tiếp.
Tuần 3–4
Semantic memory với Mem0 hoặc LangMem. Chọn đúng một user profile pattern (single-profile hay collection) và áp dụng nhất quán. Extractor chạy background, không inline.
Tuần 5
Shadow mode validation: cho memory trả về kết quả nhưng không hiển thị cho user, log song song để so sánh với baseline. Chỉ go-live khi accuracy giữ được ít nhất 97%.
Tuần 6–8
Graph memory với Graphiti (tuỳ chọn): chỉ cần khi có nhiều quan hệ multi-hop hoặc yêu cầu temporal reasoning. Trước đó, dedup ở tầng vector đã đủ cho phần lớn workload.
Tuần 9+
Reflection worker + sleeptime compute: chạy đều đặn, rút ra insight cấp cao từ ClickHouse, đẩy lại vào semantic layer. Đây là lúc agent bắt đầu "trở nên thông minh hơn theo thời gian" thay vì chỉ trả lời tốt hơn nhờ retrieval.

13. Kết luận

Bộ nhớ không còn là một module phụ trợ gắn vào AI agent — nó là sống còn. Các con số 84–91% giảm token, 90% giảm latency, 98% giảm kích thước context không phải là marketing mà là kết quả lặp lại trên nhiều hệ thống thương mại và benchmark học thuật. Nhưng phần thú vị nhất là tính nguyên tắc mà các framework hàng đầu đang đồng ý với nhau: không đặt LLM trên đường đọc đồng bộ, tách write asynchronous, dedup tại thời điểm ghi chứ không chỉ tại đọc, giữ provenance cho mọi ký ức, và luôn có cơ chế quên.

Đừng cố xây dựng cả năm tầng ngay từ ngày đầu. Bắt đầu từ Redis + ClickHouse, thêm Vector khi có dấu hiệu lặp ngữ nghĩa rõ ràng, chỉ đưa Graph vào khi multi-hop thực sự là nhu cầu. Anthropic Memory Tool và Claude Code chứng minh một điều: đôi khi một vài file văn bản được quản lý bằng bộ óc của chính LLM còn giá trị hơn một stack vector cầu kỳ. Chọn đúng công cụ cho đúng loại ký ức — đó là kỷ luật lớn nhất của AI Engineer 2026.

Checklist 7 điểm cho một kiến trúc memory đáng tin cậy

(1) Có tầng working memory độ trễ < 5ms.
(2) Write path nằm ngoài đường đồng bộ của user request.
(3) Mọi ký ức có user_id, trace_id, valid_from, valid_to.
(4) Có chiến lược TTL và policy forget rõ ràng cho từng tầng.
(5) Hỗ trợ per-user purge cho GDPR.
(6) Treat memory content as untrusted input — có guardrail ở đường đọc.
(7) Dashboard observability với ClickHouse + OTel trước khi go-live.

Nguồn tham khảo

  1. CoALA: Cognitive Architectures for Language Agents (Sumers et al., arXiv 2309.02427) — khung phân loại working / episodic / semantic / procedural được các framework agent hiện đại dùng chung.
  2. Generative Agents: Interactive Simulacra of Human Behavior (Park et al., arXiv 2304.03442) — nguồn gốc của memory stream + reflection + công thức recency/importance/relevance.
  3. Mem0: Building Production-Ready AI Agents with Scalable Long-Term Memory (arXiv 2504.19413) — paper Mem0 với cơ chế extraction + update hai pha và benchmark LOCOMO.
  4. Zep: A Temporal Knowledge Graph Architecture for Agent Memory (arXiv 2501.13956) — paper Zep / Graphiti với mô hình bi-temporal, hybrid retrieval, kết quả DMR và LongMemEval.
  5. Anthropic Memory Tool — Documentation — đặc tả tool memory_20250818, sáu lệnh view/create/str_replace/insert/delete/rename.
  6. How Claude remembers your project — Claude Code Memory docs — cơ chế CLAUDE.md và auto memory của Claude Code.
  7. Letta — Intro to MemGPT concepts — core memory blocks, archival memory, recall memory, self-editing tool set.
  8. Rearchitecting Letta's Agent Loop: Lessons from ReAct, MemGPT & Claude Code — thiết kế lại agent loop Letta v1 cho GPT-5 và Claude 4.5.
  9. LangChain — LangMem SDK launch blog — bộ ba semantic / episodic / procedural và prompt optimizer.
  10. LangGraph memory overview — Checkpointer (short-term) và Store (long-term) với namespacing.
  11. Redis + LangGraph: Build smarter AI agents with memory & persistence — pattern RedisSaver / RedisStore, Redis JSON + Vector.
  12. Redis 8 GA announcement — các tính năng Redis 8 liên quan đến agent state: vector search, hash field TTL, multi-threaded I/O.
  13. Graphiti — Real-Time Knowledge Graphs for AI Agents (GitHub) — engine lõi của Zep, hỗ trợ Neo4j / FalkorDB / Kuzu / Neptune.
  14. ClickHouse — How Langfuse is scaling LLM observability for the agentic era — case production của ClickHouse làm event log cho agent, kèm chuyện migrate từ Postgres.
  15. ClickHouse — Tracing OpenAI agents with ClickStack — pattern OTel + ClickStack cho agent observability.
  16. AWS Database Blog — Build persistent memory with Mem0, ElastiCache for Valkey, Neptune Analytics — reference architecture hybrid cho Mem0 trên AWS.
  17. Anthropic Engineering — Effective context engineering for AI agents — lý luận về just-in-time context retrieval, động lực thiết kế của Memory Tool.
  18. Mem0 — Memory in Agents: What, Why and How — framing consolidation, dynamic forgetting, promotion short-term → long-term.