Stevens: Trợ lý AI có thể hack được, tạo ra chỉ với một bảng SQLite duy nhất và vài cron job
(geoffreylitt.com)- Stevens là trợ lý AI cá nhân tổng hợp lịch trình, thời tiết, thư từ và lời nhắc của gia đình rồi gửi qua Telegram mỗi sáng, mang lại ích lợi thực tế ngay cả khi không dùng agent phức tạp hay RAG
- Cốt lõi của hệ thống là một bảng bộ nhớ SQLite duy nhất đặt trên Val.town cùng nhiều cron job, dùng để chuyển các bộ nhớ liên quan vào ngữ cảnh của LLM nhằm tạo bản tóm tắt
- Hệ thống lưu riêng các bộ nhớ có ngày tháng và thông tin nền không có ngày; trong bản tóm tắt buổi sáng, nó đưa vào các mục của một tuần tới cùng với bộ nhớ nền luôn cần thiết
- Google Calendar, API thời tiết, OCR từ USPS Informed Delivery, dữ liệu nhập từ Telegram·email và fun facts hằng tuần đều được nối vào dưới dạng các job nhập dữ liệu để điền vào cùng một bảng log
- Công cụ AI cá nhân trở nên hữu ích hơn khi gom ngữ cảnh đời sống đang phân tán giữa nhiều ứng dụng vào một bộ nhớ dùng chung; nếu quy mô thông tin nhỏ và ranh giới thời gian rõ ràng thì có thể bắt đầu chỉ với cấu trúc đơn giản
Stevens làm gì
- Stevens là trợ lý AI cho gia đình, lấy tên từ người quản gia trong tiểu thuyết Remains of the Day của Ishiguro
- Mỗi sáng, Stevens gửi bản tóm tắt qua Telegram để chuyển toàn bộ thông tin cần cho ngày hôm đó trong một lần
- Lịch trong ngày
- Xem trước dự báo thời tiết
- Thư từ hoặc kiện hàng dự kiến nhận
- Các lời nhắc mà người dùng giao theo dõi
- Bản tóm tắt được viết bằng giọng điệu quản gia trang trọng
- Ngoài bản tin hằng ngày, người dùng cũng có thể tương tác trực tiếp với Stevens
- Chuyển tiếp email chứa thông tin quan trọng
- Để lại lời nhắc qua chat Telegram
- Đặt câu hỏi trên Telegram
- Dù cấu trúc đơn giản, nó đã được đánh giá là hữu ích hơn Siri với vai trò trợ lý cá nhân cho gia đình
Kiến trúc đơn giản đặt trên Val.town
- Toàn bộ hệ thống được host trên Val.town
- Val.town cung cấp tại một nơi các chức năng cơ bản mà dự án này cần
- Lưu trữ SQLite
- Xử lý yêu cầu HTTP
- Cron job theo lịch
- Email gửi và nhận
- Stevens đọc nội dung để đưa vào bản tóm tắt buổi sáng từ một log tương đương với “cuốn sổ tay của người quản gia”
- Cuốn sổ này là bản ghi chứa mọi thứ Stevens biết, và có thể xem nội dung trong màn hình quản trị
Tạo bản tóm tắt bằng một bảng bộ nhớ duy nhất
- Phần triển khai thực tế của cuốn sổ là một bảng SQLite duy nhất với vài cột
- Mỗi mục log chứa văn bản và, nếu cần, gắn thêm ngày tháng được cho là có liên quan
- Các mục không có ngày được coi là thông tin nền chung và luôn được đưa vào ngữ cảnh
- Khi thiết lập ban đầu, có thể tạo bộ nhớ nền thông qua intake interview trên Telegram
- Luồng tạo bản tóm tắt buổi sáng khá đơn giản
- Cron job chạy
- Gọi Claude API để viết câu cập nhật
- Gửi văn bản kết quả vào thread Telegram
- Ngữ cảnh truyền cho mô hình gồm hai loại
- Các mục log có ngày trong một tuần tới
- Các mục nền không có ngày
Các job nhập dữ liệu cùng điền vào một log
- Nhiều job nhập dữ liệu khác nhau cùng điền vào một bảng SQLite
- Nguồn của các mục log hiện tại gồm
- Lấy dữ liệu mỗi giờ từ Google Calendar API
- Kiểm tra dự báo thời tiết địa phương mỗi giờ qua API thời tiết
- Khi chuyển tiếp email USPS Informed Delivery, Stevens dùng Claude để OCR ảnh quét thư từ
- Tin nhắn Telegram và email nhận vào có thể tạo mục log
- Mỗi tuần, các “fun facts” được thêm vào log để làm cho các bản cập nhật hằng ngày sinh động hơn
- Đây là cấu trúc dễ gắn thêm job nhập dữ liệu mới
- Job nhập dữ liệu có thể là bất kỳ quy trình nào thêm hoặc sửa bộ nhớ trong log
- Nội dung bộ nhớ chỉ cần là văn bản tùy ý sẽ được đưa lại cho LLM về sau
Vì sao có thể bắt đầu với bộ nhớ đơn giản
- Công cụ AI cá nhân hữu ích hơn khi tiếp cận được ngữ cảnh rộng hơn lấy từ các nguồn thông tin khác nhau
- Chỉ cần biết lịch và dự báo thời tiết, một chatbot đơn giản cũng có thể thành trợ lý thực tế hơn
- ChatGPT gần đây đã thêm bộ nhớ về các cuộc trò chuyện gần đây, nhưng vẫn còn nhiều thông tin không được lưu trong silo đó
- Hình thái dài hạn của phần mềm cá nhân dùng AI có lẽ không phải là thêm nhiều silo ứng dụng, mà gần với những công cụ nhỏ hoạt động trên một kho ngữ cảnh dùng chung về cuộc sống
- Trường hợp sử dụng của Stevens khá giới hạn và thông tin về bản chất có ranh giới thời gian, nên dễ tìm ngữ cảnh liên quan để đưa cho LLM
- Cửa sổ ngữ cảnh dài của các mô hình mới cũng giúp cách tiếp cận đơn giản này khả thi
- Khi quy mô thông tin tăng lên, có thể cần RAG hoặc cơ chế truy cập bộ nhớ phức tạp hơn, nhưng không cần phải bắt đầu phức tạp ngay từ đầu
Dự án cá nhân dễ đổi giọng điệu và UI
- Ban đầu Stevens có giọng điệu khô khan giống sản phẩm của Apple hay Google
- Việc chuyển sang giọng điệu quản gia trang trọng chỉ cần sửa vài dòng prompt
- Dashboard quản trị cũng được làm để mang cảm giác như một trò chơi điện tử
- Tài nguyên hình ảnh được tạo bằng ChatGPT, còn UI được vibe coding bằng Cursor và Claude 3.7 Sonnet
- Chỉ với một chút công sức bổ sung, dự án đã trở nên thú vị hơn nhiều
Cách tự xem thử
- Stevens không phải sản phẩm có thể chạy ngay, mà là một dự án cá nhân
- Có thể xem mã nguồn và fork tại stevensDemo
- Mẫu thiết kế gồm một bảng bộ nhớ duy nhất và một nhóm cron job có thể mở rộng cũng có thể áp dụng cho các công cụ cá nhân hữu ích khác
- Khi chỉnh sửa mã, cách được khuyến nghị là dùng trình soạn thảo AI bạn muốn cùng Val Town CLI để đồng bộ với hệ thống file cục bộ
1 bình luận
Ý kiến trên Hacker News
Không rõ là vì tính hữu ích thuần túy hay vì kiểu nói khoa trương “Proper English Butler”, nhưng tôi thực sự rất thích nó
Điều càng khiến tôi chú ý hơn là tại sao tôi lại đang đọc thứ như thế này trên blog của một kỹ sư thông minh thay vì trong buổi công bố sản phẩm của Apple hay Google. Ngay cả khi đặt điều kiện phải dùng hệ sinh thái khép kín của riêng họ cho email, lịch và điện thoại, việc hai công ty này vẫn không thể tung ra nổi một gói chức năng nhỏ đến mức này thật đáng xấu hổ. Chỉ là điều đó đang bị che khuất vì hai công ty thiếu tham vọng trong việc áp dụng công nghệ AI vào những lĩnh vực gần như đã là bài toán được giải quyết, như tóm tắt và hỏi đáp
Nếu có cơ hội nào để làm rung chuyển thế song mã trì trệ và phản cạnh tranh này, thì chắc chắn sẽ là từ phía liên quan đến AI
Thỉnh thoảng người ta đọc trên báo những câu chuyện về hai lập trình viên trong garage cải tạo tạo ra một chương trình quan trọng vượt qua nỗ lực tốt nhất của các đội ngũ lớn, và mọi lập trình viên đều sẵn sàng tin những câu chuyện như vậy. Vì họ biết rằng bất kỳ chương trình nào cũng có thể được tạo ra nhanh hơn rất nhiều so với mức năng suất 1000 câu lệnh mỗi năm của các nhóm công nghiệp
Vậy thì tại sao mọi đội lập trình công nghiệp lại chưa bị thay thế bằng những bộ đôi garage tận tụy? Cần phải nhìn vào thứ đang được sản xuất
Việc dữ liệu cá nhân đi vào một cơ sở dữ liệu do phần mềm mang tính thử nghiệm rất cao xử lý có thể không phải vấn đề lớn với nhà phát triển này, nhưng với các công ty như Google hay Apple thì đó có thể là rủi ro nghiêm trọng
Đội HA thực sự phát hành các bản cập nhật hữu ích hằng tháng, ví dụ như khả năng để trợ lý chủ động hỏi lại trước
Tôi cho rằng Google và Apple có vấn đề lớn trong việc phối hợp giữa các nhóm sản phẩm, còn chuyện hợp tác với công ty bên ngoài thì gần như bất khả thi
Điều các tập đoàn khổng lồ muốn làm chỉ là vắt trứng nhanh hơn từ con ngỗng của chính mình
Nó khiến tôi nghĩ về việc nếu một chương trình trợ lý tiện ích nhỏ kiểu Stevens có quyền truy cập hộp thư thì sẽ thế nào
Có một tiện ích nhỏ mà tôi có thể bảo nó lấy thời tiết hoặc chạy những lệnh hay dùng được tối ưu cho hệ thống của tôi. Nó tiện, và nếu muốn thì còn có thể chạy định kỳ bằng cron
Nếu nó có một hộp thư riêng, tôi có thể gửi thông tin qua email, AI có thể phân tích thông tin đó rồi trả lời hoặc gửi tin nhắn mới. Như vậy sẽ khá hữu ích. Chỉ cần không phá hỏng hộp thư cá nhân của tôi, đọc thư, đưa vào kho lưu trữ nội bộ rồi xóa tin nhắn đi là được
Tác nhân của tôi đã hoàn thành thành công 18 thử thách. Bài viết được viết sau vòng chung kết nằm ở đây
https://msrc.microsoft.com/blog/2025/03/announcing-the-winne...
Từ đó có thể làm đủ kiểu tự động hóa. Có thể đưa vào mô hình ngôn ngữ lớn để gắn thẻ hoặc lưu trữ ngay lập tức. Tôi gắn một nhãn riêng cho các email quan trọng, và nếu người đó trả lời thì tức là thật sự quan trọng nên tôi muốn biết ngay, vì vậy tôi nối với Twilio để điện thoại gọi đến. Chi phí khoảng 20 xu mỗi tháng
Tôi dùng nó để viết nhật ký. Tôi tạo một hệ thống nhỏ gửi email cho tôi mỗi ngày, và khi tôi trả lời thì phản hồi được gửi tới một trang nào đó và lưu vào cơ sở dữ liệu
https://www.val.town/x/geoffreylitt/stevensDemo/code/importe...
Có vẻ sẽ khá dễ để mở rộng hỗ trợ các loại email đến khác nữa. Tôi làm ở Val Town nên nếu có câu hỏi thì tôi có thể trả lời
Tôi muốn thấy nhiều kiểu hack AI thực dụng như thế này hơn. Đôi khi có cảm giác mọi người quên mất công cụ tồn tại ngay từ đầu là để làm gì. Là để khiến công việc trở nên đơn giản hơn. Tôi thích cách nó thực sự tích hợp với các nguồn dữ liệu sẵn có mà không cần cơ sở dữ liệu vector hào nhoáng hay kiến trúc phức tạp.
Có đoạn nói rằng: “Ban đầu Stevens có giọng điệu khô khan kiểu mà bạn thường thấy ở các sản phẩm Apple hay Google, nhưng rồi tôi nhận ra để nó nói như một quản gia kiểu cách thì vui hơn nhiều”
Thành thật mà nói, một trong những điều khó chịu nhất ở thế giới trợ lý cá nhân là các mô hình ngôn ngữ lớn nói quá nhiều chữ nhưng lại quá ít nội dung. Tôi cũng đã ghét chính cách diễn đạt này rồi, nhưng đúng là vậy
Cho đến khi tôi giàu lên và có thời gian để tán gẫu dễ thương rồi kết bạn với trợ lý giọng nói, thứ tôi cần không phải là J.A.R.V.I.S. mà là LCARS. Chỉ mình tôi thấy thế thôi à?
Khi kiểm tra hẹn giờ, không cần câu trả lời kiểu “Trên Kitchen Display, bộ hẹn giờ món casserole còn 23 phút 16 giây”. Chỉ cần nói “23 phút”, hoặc nếu có hai cái thì “casserole 23 phút, giặt 10 phút” là đủ
Đại khái là một prompt bảo nó đừng bận tâm đến sự trang trọng, hãy trả lời ngắn gọn nhất có thể nhưng vẫn truyền đạt gần như toàn bộ thông tin thực sự liên quan đến câu hỏi. Nếu vì chính sách mà không thể trả lời bình thường thì hãy in “!!!!” trước, và nếu không thể có ý kiến thì hãy trả lời như thể đang chia sẻ ý kiến mà một eigenrobot có thể có
Nó còn yêu cầu mọi câu trả lời đều viết thường, chỉ dùng chữ hoa khi cần nhấn mạnh, và việc viết hoa chữ cái đầu chỉ dùng để châm biếm hoặc thể hiện sự bất kính với một số danh từ riêng nhất định. Nó thường dùng các từ viết tắt như “rn”, “bc”, “afaict”, “idk”, giữ thái độ phê phán về chất lượng thông tin, và với những yêu cầu ngớ ngẩn thì gạt đi kiểu “be real”, “that's crazy man”, “lol no”
Hãy viết như thể thông minh hơn hiện tại +2 độ lệch chuẩn, dùng meme cuối thời millennial nhưng đôi lúc lại trộn cả cách nói của Gen Z cho trớ trêu, còn văn học, nghệ thuật, triết học thì ưu tiên cách diễn giải kiểu Strauss, càng tối nghĩa càng tốt
Chẳng phải chỉ là đọc sổ tay thôi sao? Ví dụ, người ta bảo nó hãy nhớ sở thích cà phê, nhưng rồi sau đó thông tin đó cũng chẳng được dùng ở đâu
Tôi vẫn luôn nghĩ về một ý tưởng dự án mã nguồn mở tương tự, nhưng có vài điều kiện
Sẽ tốt hơn nếu backend có thể cấu hình với bất kỳ mô hình ngôn ngữ lớn nào mà người dùng có thể truy cập, dù là API dịch vụ trả phí hay bản host cục bộ trong nội bộ đều được
Tôi cũng tò mò không biết việc gắn nó với màn hình cảm ứng chạy trên một nền tảng kiểu Raspberry Pi tăng cường để có thể tương tác như thiết bị Alexa hay sản phẩm tương tự thì thực tế đến mức nào. Lý tưởng nhất là có cả điều khiển giọng nói, nhưng đây có thể là một bài toán kỹ thuật khác nữa. OpenAI API nhận tệp âm thanh, nhưng phần lớn dịch vụ khác thì phải chuyển giọng nói thành văn bản trước khi gửi prompt qua API
Tôi muốn các tính năng tích hợp có thể mở rộng. Không chỉ lịch, thời tiết mà còn cả Homebridge, Spotify, v.v. Tôi đang cân nhắc liệu MCP server có phải là hướng đi đúng cho việc đó không
Hiện giờ tôi không có dư nhiều thời gian để đầu tư vào kiểu dự án này, nhưng nếu ai đó đang đi theo hướng này thì tôi muốn tham gia
Nó chạy cục bộ nhưng dùng API key cho nhiều mô hình ngôn ngữ lớn. Hiện giờ tôi thích QwQ-32B được Groq host hơn hẳn. Nó rất nhanh và khá thông minh. Tôi dùng các mô hình khác nhau cho từng công cụ
Hiện tại nó có thể tạo 3 loại tài liệu tôi cần cho công việc hằng ngày: báo cáo công việc, hóa đơn và bảng chấm công phục vụ quy định. Nó cũng có tích hợp thời tiết, có thể parse hóa đơn để tạo mã QR giúp thanh toán ngân hàng di động dễ hơn, và cũng hoạt động với lịch của tôi
Tiếp theo tôi định làm tích hợp email. Nhưng tôi muốn làm cho ra hồn. Nghĩa là cần email IMAP có thể đồng bộ cục bộ và lập chỉ mục. Biết đâu nó còn phát triển thành một ứng dụng email desktop thực sự dùng được. Đám hiện có đều tệ khủng khiếp, nên cứ chờ xem
Nếu có một bộ tính năng chung như lưu trữ/tìm kiếm bộ nhớ, tích hợp giao diện chat/email, đồng bộ lịch/Notion, thông báo..., rồi biến nó thành framework mã nguồn mở thì sẽ rất mạnh
Tôi cũng không có thời gian để tự vận hành thứ như vậy, nhưng sẵn sàng giúp và bỏ tiền. Hiện giờ tôi đang làm việc khác như cơ sở dữ liệu phân tán lưu trữ đối tượng local-first, có vẻ có thể dùng như một kho kiểu OrbitDB, nhưng vẫn chưa ở trạng thái có thể dùng được
Từ trước đến nay tôi vẫn bực vì lựa chọn chỉ có hoặc là dùng giao diện chat quá nhiều ràng buộc, hoặc là tự xây nguyên một framework agent hoàn chỉnh như trong bài gốc
Dạo này tôi đang thử nghiệm cách lách qua vùng ngọt của token ngữ cảnh, dưới 20 nghìn token, và với 2.5 thì dưới 50 nghìn token
Về bản chất, đây là cách làm “nén ngữ cảnh” thủ công. Mô hình ngôn ngữ lớn sẽ lưu bền dữ liệu vào cơ sở dữ liệu theo một schema nghiêm ngặt, rồi khi ngữ cảnh hiện tại bắt đầu vượt ra khỏi vùng ngọt thì nó sẽ tóm tắt lại và chuyển sang một instance mới với ngữ cảnh mới. Tôi vẫn còn lẫn lộn trong việc nên làm phần tóm tắt này như nhật ký liên tục hay làm theo kiểu hồi cố như một bản tổng kết cuối kỳ
Với các mô hình suy luận, cách này khá hiệu quả. Suy luận ngốn ngữ cảnh khủng khiếp, nhưng đồng thời cũng tạo ra các “tài liệu tóm tắt” rất tốt. Vì thế có thể nhận được phần nào lợi ích của suy luận mà không phải hy sinh phần ngữ cảnh ngon lành dưới 50 nghìn
Cơ sở dữ liệu hoạt động như một dạng fallback trong trường hợp bản tóm tắt bỏ sót chi tiết quan trọng, hoặc giống như retrieval-augmented generation. Chỉ là mô hình phải nhận ra điều đó và lấy ngữ cảnh từ cơ sở dữ liệu
Hiện tôi đang thử dùng nó để xây một tác tử quản lý tồn kho và tối ưu hóa BOM cho cơ sở dữ liệu khoảng 10 nghìn linh kiện/vật tư riêng lẻ
Những hạng mục lớn xuất hiện trong đầu là caching dài hạn giá rẻ, đột phá về nén, và xử lý vi sai kiểu delta. Tôi tự hỏi liệu có cách nào chỉ dùng những phần cần thiết trong ngữ cảnh đầu vào đã được cache hay không
Theo cùng hướng đó, tôi vừa làm một thứ tên là Jeeves. Ít hào nhoáng hơn một chút nhưng lắp rất nhanh. Stack là Claude Desktop, Projects, MCP cho Notion và Todoist, và bản nâng cấp tiếp theo tôi đang nhắm tới là duyệt email và WhatsApp
Tôi làm nó để hỗ trợ quy trình năng suất cho công việc tư vấn và startup. Các cơ sở dữ liệu Notion gồm khách hàng, dự án, cuộc họp, và thêm vài cơ sở dữ liệu của Jeeves. Các cơ sở dữ liệu của Jeeves chỉ nhận một ít chỉ dẫn rồi để Jeeves tự ghi chép. Ví dụ, nó dùng cơ sở dữ liệu riêng để theo dõi việc di chuyển toàn bộ biên bản họp cũ sang cấu trúc mới
Trong cơ sở dữ liệu của tôi có các thực tiễn sử dụng mẫu. Biên bản họp trông như thế này, tài liệu một trang cho khách hàng trông như thế kia, đây là thông tin kết nối tất cả những thứ đó, và đây là cách quản lý việc cần làm. Sau đó tôi dùng prompt mở rộng văn bản của Alfred để đưa bản chép lời vào một cuộc chat mới theo các kiểu họp phổ biến, rồi nó tự xử lý tiếp
Nó chuyển bản chép lời thành biên bản họp, tạo việc cần làm, xác nhận lại với tôi, tinh chỉnh thêm một lần nữa, rồi sắp xếp và đưa vào cả Notion lẫn Todoist qua MCP
Quy trình này cũng tự được tài liệu hóa. Vì Todoist MCP có lỗi, tôi đã chỉ thị cho Jeeves chạy càng nhiều trường hợp sử dụng càng tốt, nắm rõ giới hạn và điểm mạnh, tài liệu hóa chúng rồi lưu vào cơ sở dữ liệu của Jeeves. Sau đó có thể gọi lại làm ngữ cảnh
Hơi tiếc là không có chức năng cron, nhưng thành thật mà nói, mỗi ngày một lần đưa prompt đã chuẩn bị sẵn vào Claude cũng chẳng khó lắm
Điều mà bài này làm tôi cảm nhận rõ nhất là Apple đang hoàn toàn ngủ quên trên chiến thắng
Hôm nay khi đang lái xe, tôi muốn trả lời ai đó nên đã bảo Siri: “Gọi cho người cuối cùng tôi nhắn tin”
Nếu hỏi việc nó không làm được có đáng ngạc nhiên không thì giờ cũng chẳng còn ngạc nhiên nữa. Nhưng dù vậy, việc khoảng cách giữa Siri và cả những mô hình ngôn ngữ lớn kém nhất vẫn lớn đến thế thật đáng thất vọng
Đây là một gợi ý khá ngớ ngẩn. Nếu cần thì tôi tự làm được
Lúc đầu tôi tưởng họ dùng cơ sở dữ liệu sqlite cho việc dự đoán token tiếp theo
Nói để người khác khỏi hiểu nhầm, thực tế họ dùng Claude
Hay đấy. Tôi cũng đã làm một thứ tương tự bằng mcp.run và task
https://docs.mcp.run/tasks/tutorials/telegram-bot
Để làm bộ nhớ thì tôi đã tạo pantry, dù nó chưa xuất hiện trong tutorial này [0], và cũng làm một servlet cho nó [1]. Rồi tôi chỉnh prompt để trước tiên kiểm tra xem có cuộc hội thoại nào tương ứng với chat ID được cung cấp hay không và lưu kết quả vào đó
Điểm hay là bạn có thể thêm bất kỳ servlet nào vào registry để làm con bot mạnh đến mức nào tùy muốn
[0] https://getpantry.cloud/
[1] https://www.mcp.run/evacchi/pantry
Tiện nói luôn là tôi làm ở Dylibso :o)