# Letta: dựng agent có bộ nhớ bền vững, và khi nào không nên đưa nó cho khách

> Bộ nhớ của agent không có gì kỳ bí: đó là chuyện chọn token nào được vào context window, và mỗi token được ghim vào đó đều có giá phải trả ở mọi lần gọi.

Bản gốc: https://fdetimes.net/vi/cong-cu/letta-bo-nho-agent-co-trang-thai-cho-fde/

Với Letta, mọi thứ một agent từng thấy và từng làm đều được ghi vào database, gồm memory, tin nhắn của người dùng, reasoning và tool call. Nghe thì giống lời giải cho chuyện agent hay quên. Nhưng thứ agent thật sự "nhớ" khi trả lời lại là chuyện khác hẳn.

Letta viết trên blog của mình rằng suy cho cùng, bộ nhớ là việc chọn token nào được đặt vào context window ở mỗi thời điểm. Câu đó nên là điểm xuất phát của mọi FDE trước khi hứa với khách một agent "nhớ được người dùng".

Nếu bạn đang dựng agent chăm sóc khách hàng, trợ lý nội bộ hay copilot cho một đội vận hành, sớm muộn khách cũng hỏi vì sao hôm qua bot biết họ mà hôm nay lại không. Letta là một câu trả lời nghiêm túc cho câu hỏi đó. Có điều nó có giá, và có những trường hợp bạn không nên dùng nó.

## Letta từ đâu ra, và nó làm gì?

Letta bắt nguồn từ bài báo MemGPT của nhóm UC Berkeley (Packer, Wooders, Lin, Fang, Patil, Stoica, Gonzalez), nộp ngày 12/10/2023. Ý tưởng là quản lý một "context ảo" theo kiểu phân cấp bộ nhớ của hệ điều hành, vì LLM bị giới hạn bởi context window.

Repo mã nguồn mở theo giấy phép Apache-2.0 tự mô tả là nền tảng cho stateful agent, ghi rõ trước đây tên là MemGPT, và cho tự host bằng `letta server`.

Tài liệu của Letta định nghĩa stateful agent là agent giữ được memory và ngữ cảnh qua nhiều cuộc hội thoại. Để làm việc đó, Letta chia trạng thái thành hai tầng mà bạn phải tách bạch.

Tầng thứ nhất là memory block. Block gắn vào agent luôn nằm trong context, ghim vào system prompt. Block sửa được qua API, nên bạn hoặc chính agent có thể xem và chỉnh những gì agent đang "nhớ". Tầng thứ hai là phần còn lại: lịch sử, reasoning, tool call. Chúng nằm trong database và chỉ vào context khi được chọn.

## Mỗi token được ghim đều tốn tiền ở mọi lần gọi

Thử hình dung một trợ lý hỗ trợ kỹ thuật cho khách B2B. Bạn tạo một block "hồ sơ khách" ghi gói dịch vụ, hệ thống họ đang chạy và các sự cố cũ. Nhờ block này, agent không phải hỏi lại những điều người dùng đã nói.

Giờ làm phép tính. Giả sử block đó dài 2.000 token và agent nhận 1.000 lượt gọi mỗi ngày: riêng phần hồ sơ đã là 2 triệu token input mỗi ngày, kể cả khi câu hỏi chỉ là "đổi mật khẩu ở đâu".

Vì block luôn bị ghim, nó chiếm chỗ trong context ở mọi lần gọi. Câu cần hỏi khi thiết kế là thông tin này có cần ở *mọi* lượt không, hay chỉ cần tra khi có liên quan.

Lịch sử hội thoại cũng có giá riêng. Letta thừa nhận eviction và tóm tắt đều làm mất thông tin: tin nhắn cũ mất dần ảnh hưởng. Lời khuyên của họ là chỉ evict một phần, ví dụ 70%, để giữ mạch hội thoại.

Cụ thể, với 100 tin nhắn sắp tràn context, bạn đẩy 70 tin cũ nhất vào bản tóm tắt và giữ nguyên 30 tin gần nhất. Bất kỳ chi tiết nào chỉ có trong 70 tin kia đều có thể bị mờ đi.

**Điểm mấu chốt:** Bộ nhớ của agent là quyết định token nào được vào context, không phải chuyện lưu được bao nhiêu.

## Khi nào nên nói "không" với khách?

Trường hợp thứ nhất là tác vụ không có trạng thái thật: phân loại ticket, trích xuất trường từ hóa đơn, tóm tắt một tài liệu. Gọi model trực tiếp với một prompt cố định sẽ dễ debug, dễ viết eval và rẻ hơn. Thêm một database trạng thái vào đây chỉ thêm chỗ để hỏng.

Trường hợp thứ hai là dữ liệu nhạy cảm. Letta lưu vào database cả tin nhắn người dùng lẫn reasoning, nên trước khi bật, bạn cần trả lời cùng đội bảo mật của khách: database nằm ở đâu, ai đọc được, và khi một người dùng yêu cầu xóa thì xóa thế nào.

Bản tự host bằng `letta server` giúp dữ liệu ở lại hạ tầng của khách, nhưng không thay được cuộc nói chuyện đó.

Trường hợp thứ ba là khách cần hệ thống ổn định nhiều năm. Letta đã bỏ vòng lặp kiểu MemGPT để chuyển sang "Letta V1" cho các reasoning model đời mới: heartbeats và tool `send_message` bị deprecate, kiến trúc cũ vẫn được hỗ trợ. Chính Letta cũng ghi lại cả cái được lẫn cái mất, chẳng hạn reasoning thường chỉ còn dạng tóm tắt và không sửa được.

Tầng SDK cũng đang thay đổi. Letta V1 SDK đang bị deprecate để nhường chỗ cho Letta Agent SDK, với hệ thống memory mới nhất là MemFS, trong khi V1 chỉ hỗ trợ memory block. Nếu giao cho khách, hãy pin phiên bản và ghi rõ lộ trình nâng cấp vào tài liệu bàn giao.

## Đừng mua bộ nhớ chỉ vì một con số benchmark

Letta công bố agent chỉ dùng filesystem của họ đạt 74,0% trên LoCoMo, so với con số 68,5% mà Mem0 báo cáo. Đây là kết quả do chính Letta chạy, nên cần đọc thận trọng.

Thú vị là cũng trong bài đó, Letta cho rằng các benchmark như LoCoMo có thể là tín hiệu yếu, và chất lượng bộ nhớ phụ thuộc vào cách agent quản lý context hơn là cơ chế truy xuất cụ thể.

Với FDE, bài học là tự dựng eval trên hội thoại thật của khách. Lấy 20 phiên người dùng quay lại sau vài ngày, ghi ra những gì agent *phải* nhớ, rồi chấm xem nó có nhớ không. Bạn sẽ học được nhiều hơn mọi bảng xếp hạng.

## Học gì trước, và ghi gì vào CV?

Hãy học khái niệm trước công cụ: context window, cái gì được ghim, cái gì được tra, cái gì bị evict. Sau đó chạy Letta tự host và sửa một memory block qua API để thấy câu trả lời của agent đổi theo. Chi tiết API sẽ đổi theo SDK, còn tư duy chọn token thì vẫn dùng được.

Trong CV, đừng chỉ ghi "đã dùng Letta". Hãy viết rằng bạn thiết kế bộ nhớ cho một agent, quyết định thông tin nào được ghim, đo được chi phí token và đã từ chối dùng bộ nhớ bền vững ở chỗ nào. Khi đọc JD có cụm "agent memory" hay "stateful agents", câu hỏi phỏng vấn đáng chuẩn bị nhất là: lúc nào bạn chọn *không* lưu trạng thái?

Một agent nhớ mọi thứ chưa chắc đã là agent tốt. FDE giỏi là người biết agent cần quên gì.

**Thử ngay tuần này:**

- Chạy `letta server` trên máy, tạo một agent có một memory block, rồi sửa block đó qua API và xem câu trả lời của agent thay đổi thế nào
- Lấy một use case agent của khách, ghi ra cái gì thật sự cần nhớ qua các phiên và ước lượng số token nó chiếm ở mỗi lần gọi
- Viết một trang ghi chú cho khách: dùng SDK nào, phiên bản nào, và kế hoạch nâng cấp khi V1 SDK hết hỗ trợ

## Nguồn

- [Introduction to Stateful Agents | Letta Docs](https://docs.letta.com/guides/agents/overview)

- [Agent Memory: How to Build Agents That Learn and Remember](https://www.letta.com/blog/agent-memory)

- [MemGPT: Towards LLMs as Operating Systems](https://arxiv.org/abs/2310.08560)

- [letta-ai/letta (GitHub)](https://github.com/letta-ai/letta)

- [Benchmarking AI Agent Memory: Is a Filesystem All You Need?](https://www.letta.com/blog/benchmarking-ai-agent-memory)

- [Rearchitecting Letta's Agent Loop: Lessons from ReAct, MemGPT, & Claude Code](https://www.letta.com/blog/letta-v1-agent)

- [Letta V1 SDK | Letta Docs](https://docs.letta.com/concepts/memgpt)
