Điểm gây khó chịu nhất khi làm việc lâu dài với AI là cái nút “New chat”. Bạn vừa dựng xong context về codebase, về khách hàng, về đống quyết định kiến trúc trong ba tuần qua, rồi hết token, hết context window, và bạn phải bắt đầu lại từ đầu. UniiChat là một thử nghiệm nhắm thẳng vào vấn đề đó: một agent duy nhất, một cuộc hội thoại duy nhất, chạy mãi không kết thúc.
Repo: VictorTaelin/uniichat. Tác giả là Victor Taelin, người đứng sau Bend và HVM, nên không lạ khi thứ này mang tính thử nghiệm khá rõ. README mở đầu bằng một câu rất thẳng: “This repo is vibe-coded.” Toàn bộ code gần như do AI agent viết, AI agent review. Tác giả tự nói trước: đọc, chạy, fork thì hãy coi như sẽ có bug.
Nó giải quyết bài toán gì
Vấn đề cụ thể: chat AI bình thường có context window hữu hạn. Khi đầy, bạn buộc phải compaction, tức là tóm tắt rồi ném bớt quá khứ đi. Cái mất đi thường đúng là mấy chi tiết mà sau này bạn cần lại. UniiChat không làm vậy.
Cách nó hoạt động: mỗi tin nhắn được tóm tắt thành một dòng, các dòng cạnh nhau được gộp theo cặp liên tục, tạo thành một cây nhị phân ký ức. Mỗi lần gọi model nhận được một “view” của toàn bộ cuộc chat, tối đa 128 KB: tin gần đây thì một dòng mỗi tin, tin cũ hơn thì được đại diện bởi ít dòng hơn nhưng rộng hơn. Chi tiết mờ dần theo thời gian, nhưng không mất hẳn. Và vì là cây, agent có thể “zoom” một dòng ra thành hai dòng gốc, mở dần xuống tới tin nhắn gốc. Nghĩa là context không bị thối rữa, và không cần compaction kiểu vứt bỏ quá khứ.
Một chi tiết kỹ thuật đáng để ý: phần tóm tắt được viết bởi một model rẻ hơn (gọi là compactor) ngay khi tin nhắn đến, chạy nền. View chỉ đổi ở cuối, nên mỗi lần gọi đọc phần lớn input từ prompt cache của vendor. Đây là lý do thiết kế quan trọng, không có nó thì bài toán chi phí sẽ nổ ngay.
Mấy thứ khác trong README: agent chạy được shell, đọc và sửa file, điều khiển màn hình Mac trên bất kỳ máy nào đang mở unii (mỗi máy là một device có tên). Nó spawn được subagent, làm việc nền rồi báo lại bằng tin nhắn. Server sở hữu cuộc chat: một tab browser hay unii trong terminal đều xem live được, đều gửi tin, dừng việc, đổi model được. Có import lịch sử chat Claude và ChatGPT cũ (thư mục Claude Code, Codex, hoặc file export từ website), chúng nhập vào cây chung.
Vì sao đáng để ý
Repo mới tạo ngày 2026-10-19, cập nhật cùng ngày, đang ở 529 sao. Con số đó với một repo mới tinh, chưa có Topics, chưa có mô tả gốc, là dấu hiệu khá rõ: cộng đồng dev đang tò mò về hướng tiếp cận “memory tree” hơn là về sản phẩm hoàn chỉnh.
Điểm khác biệt nằm ở chỗ hầu hết giải pháp memory cho agent hiện nay đều đi theo hướng RAG: chunk, embed, retrieve top-k. Cách đó có vấn đề cố hữu là thứ gì không được retrieve thì coi như không tồn tại, và bạn không biết mình đã bỏ sót gì. Cây nhị phân của UniiChat là một cách khác: nén có cấu trúc, mất chi tiết nhưng giữ được khả năng mở ngược xuống bản gốc. Nghe thì giống một ý tưởng đơn giản, nhưng triển khai đúng thì không dễ, và đây là repo dám làm.
Cài và chạy thử
Cần Bun và một Anthropic API key (hoặc OpenAI, xem phần config bên dưới).
export ANTHROPIC_API_KEY=sk-ant-...
bun Server.ts # http://127.0.0.1:8788, data in ~/.unii
Mở http://127.0.0.1:8788, gõ email. Nếu chưa set mail key, server in link đăng nhập ra output, mở link đó là vào. Hoặc chat từ terminal:
bun Term.ts http://127.0.0.1:8788
Nó hỏi email, server in link, trang mở ra hỏi code mà terminal hiển thị. bun Term.ts help liệt kê phần còn lại.
Vài lệnh khác có trong README:
bun run test # the tests, each file on its own
bun run web # rebuilds web/app.js from web/src
bun build --compile Term.ts --outfile unii
# one `unii` executable; `unii serve`
# runs the server it carries
Dữ liệu chat nằm ở ~/.unii/users/, mỗi tin một dòng JSON (main/), mỗi summary một dòng (tree/). Đây chính là ký ức, nhớ backup.
Config ở ~/.unii/config.json, mỗi key cũng set được qua biến môi trường tiền tố UNII_. Mặc định chat chạy claude-api:sonnet-5.5:medium:slow, compactor là claude-api:haiku-5.5:high:slow. Nếu chỉ có key OpenAI thì phải set lại cả ba:
UNII_VENDORS=openai-api \
UNII_PICK=openai-api:gpt-6.1-sol:medium:slow \
UNII_COMPACTOR=openai-api:gpt-6-luna:high:slow
Key đọc từ env: ANTHROPIC_API_KEY, OPENAI_API_KEY, RESEND_API_KEY (để gửi mail link đăng nhập, không có thì in ra), APNS_KEY. Self-hosted server miễn phí, không tính tiền ai, không hiện giá, chỉ gọi vendor model. Billing.ts là chỗ duy nhất server hosted cắm billing vào, repo này không có phần đó.
Ai nên thử
Hợp nhất với người làm việc dài hạn trên một codebase hoặc một dự án cụ thể, kiểu bạn muốn con agent nhớ “tháng trước tụi mình quyết định bỏ Redis vì lý do X” mà không phải nhắc lại mỗi lần mở chat. Cũng hợp với ai muốn self-host toàn bộ, giữ dữ liệu trong ~/.unii trên máy mình, dùng key API riêng.
Không hợp với người cần một công cụ ổn định để đưa vào production ngay. README tự nhận là vibe-coded, tức là bạn nên đọc code trước khi tin. Và nếu bạn chỉ chat vài câu hỏi ngắn rồi bỏ, mô hình memory tree là overkill, tốn thêm một model phụ chạy liên tục.
Ưu và nhược
Ưu: ý tưởng memory tree có zoom là thứ đáng để đọc và có thể bê sang dự án khác. Thiết kế tận dụng prompt cache, chi phí được tính đến. Self-host được, dữ liệu local, license Apache-2.0 thoáng. Có import lịch sử chat cũ, giảm ma sát lúc bắt đầu. Tác giả ghi design ngay ở header comment từng file, bắt đầu từ Memory.ts, Server.ts, AskAI.ts là đọc được.
Nhược: repo mới, một ngày tuổi tại thời điểm viết, chưa có Topics, chưa có mô tả, chưa có cộng đồng xung quanh. README cảnh báo bug là chuyện thật, không phải câu khiêm tốn. Phụ thuộc Bun, phụ thuộc key Anthropic hoặc OpenAI, và mặc định gắn với mấy cái tên model khá lạ (sonnet-5.5, haiku-5.5, gpt-6.1-sol) nên bạn sẽ phải sửa config theo model hiện có. Telemetry: mỗi ngày unii gọi /check của bend-lang.com để hỏi version mới, gửi version, OS, CPU type, không tài khoản, không id, và nói máy này từng self-host chưa. Tắt bằng UNII_NO_TELEMETRY=1. Đây là call duy nhất một server self-hosted gửi về phía tác giả, nhưng nếu bạn khó chịu với telemetry thì biết trước mà set biến.
Tài liệu ở mức README cộng comment trong code. Không có docs site, không có hướng dẫn migration. Với một repo thử nghiệm thì bình thường, với người mới thì hơi mệt.
Tôi không so sánh trực tiếp với các sản phẩm memory khác vì chưa chắc chúng tương đương về kiến trúc, và bịa ra một phép so sánh ở đây thì vô nghĩa. Cái đáng so là triết lý: nén có thể mở ngược versus retrieve theo chunk. Hai cách có trade-off khác nhau, và UniiChat chọn cách thứ nhất.
Kết
529 sao cho một repo một ngày tuổi, không mô tả, không Topics, nói lên rằng người ta quan tâm đến ý tưởng memory tree hơn là đến việc cài nó lên máy. Nếu bạn đang vật lộn với chuyện agent quên sạch sau mỗi lần hết context, đọc Memory.ts trước đã, chạy thử sau. Còn nếu bạn cần một thứ chạy được ngay trong tuần này mà không phải sửa config, để nó thêm vài tháng nữa.
Repo ở đây: VictorTaelin/uniichat.
