001 · ai · agent · buzz · 08.2026 ·8 phút đọc

Buzz: dựng team người + AI agent trên relay của riêng mình

Tôi vừa dựng xong Buzz — dự án open source của Block — trên một máy Ubuntu ở nhà. Ý tưởng của Buzz nghe đơn giản nhưng khá mới: một workspace self-host nơi người và AI agent ngồi chung phòng chat, agent không phải là “bot” gắn vào chat mà là thành viên thật — có danh tính riêng, được mời vào channel như người, và mọi thứ nó làm đều nằm trong log có thể tra lại.

Bài này ghi lại cách Buzz vận hành, setup thực tế của tôi, những chỗ vướng khi dựng relay, và tôi hình dung áp dụng nó cho ba loại team như thế nào: vibecoding, bán hàng Shopify, và marketing chạy ads.

Buzz vận hành thế nào

Kiến trúc của Buzz gói gọn trong một câu: mọi thứ đi qua một relay duy nhất.

  • Relay là trái tim: một server (Rust/Axum) nói giao thức kiểu Nostr — mọi tin nhắn, reaction, bước workflow, lần duyệt code, sự kiện git… đều là một signed event ghi vào chung một log. Phía sau relay là Postgres (lưu event + full-text search), Redis (pub/sub, presence) và S3/MinIO (media).
  • Client — app desktop (Tauri), mobile (Flutter), CLI — đều kết nối vào relay qua WebSocket. URL của relay chính là “địa chỉ” workspace: một relay = một community.
  • Agent kết nối y hệt client: nó có cặp khoá riêng (BUZZ_PRIVATE_KEY), tự ký event của mình. Hai mảnh ghép quan trọng:
    • buzz-cli: giao diện “JSON in / JSON out” để LLM gọi như tool.
    • buzz-acp: harness chạy các agent bên ngoài — Goose, Codex, Claude Code — qua giao thức ACP. Nó là process cha, nhận tín hiệu điều khiển từ relay (ví dụ owner gõ !shutdown là agent thoát) và spawn CLI agent bên dưới.

Điểm tôi thích nhất: không có kênh quản trị ngầm nào cả. Muốn biết agent sống hay chết → nhìn presence event trên relay. Muốn dừng nó → nhắn lệnh vào phòng. Mọi quan sát và điều khiển đều là message trong log, nghĩa là audit được toàn bộ.

Setup của tôi: Ubuntu relay + CLI agent + Tailscale

Máy Ubuntu của tôi chạy relay (bundle production trong deploy/compose/ — Postgres, Redis, MinIO). Trên cùng máy đó tôi chạy các agent bằng buzz-acp bọc quanh các CLI: Claude Code, Codex, Goose.

Lý do chạy agent bằng CLI thay vì gọi API trực tiếp: các CLI này đăng nhập bằng OAuth của gói subscription — Claude Code dùng gói Claude, Codex dùng gói ChatGPT. Nghĩa là chi phí chạy agent nằm gọn trong subscription hằng tháng đã trả sẵn, không phát sinh bill API theo token. Với nhu cầu cá nhân / team nhỏ, đây là khác biệt lớn: agent chạy cả ngày mà không phải nhìn đồng hồ đo tiền.

Phần kết nối từ xa tôi giao hết cho Tailscale: app desktop và mobile trỏ BUZZ_RELAY_URL về địa chỉ tailnet của máy Ubuntu. Không mở port ra internet, không cần domain, không cần reverse proxy public — đi đâu cũng mở app lên là thấy team agent của mình đang làm việc.

Những chỗ vướng khi setup relay

Ghi lại để ai dựng sau đỡ mất thời gian:

  1. Toolchain riêng của dự án. Buzz dùng Hermit để quản lý tool (Rust, Node, pnpm, just). Nếu không quen mô hình . ./bin/activate-hermit thì dễ loay hoay vì cài Rust/Node hệ thống xong build vẫn không khớp version.
  2. docker-compose.yml ở gốc repo chỉ dành cho dev. Muốn chạy thật phải dùng bundle trong deploy/compose/ — tôi mất một lúc mới nhận ra mình đang chạy cấu hình dev cho môi trường “production tại gia”.
  3. Chuyện ws:// vs wss://. Trong tailnet, chạy ws:// trần là được vì Tailscale đã mã hoá tầng dưới. Nhưng một số client khó tính với kết nối không TLS — nếu vướng thì cấp cert bằng tailscale cert cho MagicDNS name rồi để Caddy (có sẵn trong bundle) terminate TLS.
  4. Agent không có key là không chạy. Buzz từ chối khởi động agent nếu thiếu BUZZ_PRIVATE_KEY — đúng đắn về thiết kế, nhưng lúc đầu tôi chưa hiểu mô hình “mỗi agent một danh tính” nên cứ thắc mắc sao không mượn key của mình cho nhanh.
  5. Sửa config agent không ăn ngay. Agent đang chạy sẽ giữ cấu hình cũ đến khi nó thoát và chạy lại — docs ghi rõ “no live reconfiguration”. Biết trước thì đỡ tưởng mình cấu hình sai.
  6. Dự án còn trẻ. Mobile client chính thức đang “being wired up”, push notification chưa xong, cổng duyệt workflow thì “infra exists, glue still drying” — nguyên văn trong README. Core (relay, channel, thread, search, desktop) chạy ổn, nhưng đừng kỳ vọng mọi thứ trong README đều đã thành hình.

Relay: ưu và nhược

Ưu điểm

  • Một log duy nhất, audit được tất cả. Ai (người hay agent) làm gì, lúc nào, đều là signed event. Cần truy vết một quyết định — search là ra, kèm bằng chứng.
  • Dữ liệu là của mình. Self-host toàn bộ: chat, media, lịch sử làm việc của agent không nằm trên SaaS của ai.
  • Agent là thành viên có danh tính. Mỗi agent một keypair — thu hồi, phân quyền, tra log theo từng con một.
  • Điều khiển qua chính phòng chat. Không SSH, không dashboard riêng — dừng agent bằng một tin nhắn. Mô hình này cũng có nghĩa là bạn quản lý agent từ mobile được, miễn nhắn tin được vào phòng.
  • Ghép với Tailscale rất gọn: không lộ cổng nào ra internet mà vẫn truy cập từ mọi thiết bị.

Nhược điểm

  • Single point of failure. Relay sập là cả workspace đứng hình — người không chat được, agent mất kết nối. Máy Ubuntu của tôi giờ là “văn phòng”, nó tắt là cả công ty nghỉ.
  • Gánh cả một stack. Postgres + Redis + MinIO + relay là bốn thứ phải nuôi: backup, update, disk. “Self-host” luôn có giá của nó.
  • Trạng thái agent có độ trễ. Presence có TTL 180 giây — agent chết bất thường thì mất tới 3 phút mới biết, vì không có kênh quản trị trực tiếp nào để phát hiện ngay. Đây là đánh đổi có chủ đích của thiết kế.
  • Mọi thứ phụ thuộc độ chín của dự án. Giao thức mở (Nostr-style) là điểm cộng dài hạn, nhưng hôm nay bạn vẫn đang đặt cược vào một repo còn đang đổ móng.

Dựng team kiểu gì với Buzz

Cái hay của mô hình “agent là thành viên” là bạn tổ chức team agent y như tổ chức team người: mỗi channel một mảng việc, mời đúng agent vào đúng phòng.

Team vibecoding. Đây là use case Buzz sinh ra để phục vụ. Mô hình branch-as-room: mỗi feature branch mở một phòng, trong đó có patch, kết quả CI, review và quyết định merge nằm cùng một chỗ. Tôi thả Claude Code (qua buzz-acp) vào phòng làm chân code chính, Codex làm reviewer chéo — hai agent hai danh tính, cãi nhau trong thread cũng thành log tra được. Con người chỉ cần vào duyệt: cơ chế approve bằng emoji reaction đang được hoàn thiện, còn hiện tại thì gõ một tin nhắn là đủ. Điểm ăn tiền là incident memory — agent search được toàn bộ lịch sử, nên gặp bug từng xử một lần là nó tự lôi thread cũ ra làm bằng chứng.

Team bán Shopify. Một phòng #van-hanh: agent nối với Shopify qua MCP tool, mỗi sáng đăng tổng kết đơn hàng và cảnh báo tồn kho vào phòng; một agent khác chuyên soạn mô tả sản phẩm — mình thả link ảnh + vài gạch đầu dòng vào phòng, nó trả bản mô tả trong thread. Người quyết những việc có tiền (đổi giá, hoàn đơn), agent làm phần đọc — tổng hợp — soạn thảo. Toàn bộ trao đổi người-agent nằm trong log, sau này thuê người thật vào làm chỉ cần đọc lại phòng là hiểu quy trình.

Team marketing chạy ads. Phòng #ads: agent kéo số liệu chiến dịch (qua MCP/API của nền tảng ads) và đăng báo cáo chi tiêu — CPA hằng ngày, agent khác viết biến thể content cho A/B test. Nguyên tắc tôi tự đặt: agent không bao giờ được tự đụng vào ngân sách — nó chỉ đề xuất trong thread, người react/nhắn xác nhận rồi tự tay bấm. Khi cơ chế workflow approval của Buzz hoàn thiện thì vòng duyệt này sẽ chặt chẽ hơn nữa.

Kết

Buzz chưa phải sản phẩm hoàn thiện, nhưng nó trả lời đúng câu hỏi tôi đang gặp: khi bạn có nhiều agent chạy bằng CLI + subscription, làm sao quản chúng như quản một team — có phòng ban, có danh tính, có log, điều khiển được từ điện thoại? Một relay trên Ubuntu + Tailscale hoá ra là đủ cho câu trả lời. Nếu bạn đang vibecoding với 2-3 CLI agent rải rác trong tmux, thử gom chúng về một relay xem — cảm giác khác hẳn.