VoiceFlow · Hậu trường
Case study nội bộ · Cách một app ra đời

Hậu trường VoiceFlow

Từ một bản mã nguồn mở → app chạy được trên Mac & Windows, có tự cập nhật — và cách vượt qua những con bọ dọc đường. Viết lại thành 4 quy trình để bạn cũng làm được, không phải mò từ đầu.

01/07/2026 · Coach Thắng Huyền Đức · dựa trên VoiceFlow v0.8.5
QUY TRÌNH 01

Dựng lõi — chọn một việc, đứng trên vai người khổng lồ

Mục tiêu: từ ý tưởng → app chạy được trên máy — bằng cách Việt hoá một nền mã nguồn mở tốt sẵn, thay vì viết lại từ số 0.
  1. Chốt một việc app làm thật tốtVoiceFlow = nói tiếng Việt → chữ, chạy offline, riêng tư. Một mũi tên, một đích.
  2. Đứng trên vai người khổng lồKhông làm lại từ đầu. Fork một dự án mã nguồn mở đã tốt (app chép lời "Handy"), rồi cải tiến trên đó — tiết kiệm hàng tháng trời.
  3. Việt hoá & đổi nhận diệnĐặt tên VoiceFlow, màu navy/cam 10X, mặc định tiếng Việt, chọn model chuẩn cho giọng Việt (hiểu cả tiếng Anh xen kẽ).
  4. Chạy lõi trên máy mình trướcĐảm bảo phần "ruột" nói-ra-chữ chạy đúng trên máy mình → rồi mới lo đóng gói cho người khác.
Chi tiết kỹ thuật (cho Claude)
Nền: Tauri (Rust + WebView) · whisper.cpp (Metal trên Mac, Vulkan trên Windows) · SQLite · xử lý âm thanh thuần Rust.
Nguồn gốc: fork github.com/cjpais/Handy → repo riêng github.com/thanghuyenduc10x/voiceflow · bản gốc trên máy: ~/App-VoiceFlow/Handy.
Model chuẩn: "VoiceFlow Standard" = large-v3-turbo-q5 (547MB) — nhanh, chính xác tiếng Việt. Mặc định ngôn ngữ vi.
Bộ nhớ: voiceflow-project, voiceflow-updater-key.
QUY TRÌNH 02

Để máy chủ đóng gói 3 nền tảng — đừng build tay

Mục tiêu: gắn một nhãn phiên bản → GitHub tự build bản Mac + Windows + Linux → tự đăng lên Releases. Không ngồi build tay từng bản.
  1. Viết "công thức" đóng gói tự độngGitHub Actions: một file quy trình build cho cả 3 hệ, tự ký để app cập nhật được.
  2. Tạo khoá ký riêng cho appKhoá kế thừa từ dự án gốc không dùng được (không có nửa khoá bí mật) → phải tự tạo khoá mới của mình.
  3. Gắn nhãn phiên bản rồi đẩy lênTăng số (v0.8.5) → push → máy chủ tự chạy, khoảng 20–25 phút ra đủ bản cài.
  4. Kiểm tra Releases đã có bản càiTải về máy "sạch" thử để chắc bạn bè mở là chạy.

Lần đầu luôn trục trặc — và cách trị

Lần đóng gói đầu, cả 3 bản đều lỗi, mỗi bản một lý do khác nhau: Mac cố nạp một "chứng chỉ rỗng"; Windows sai mật khẩu khoá; Linux thiếu công cụ đóng gói. Không có bản nào giống bản nào.

Bài học: đừng đoán. Đọc nhật ký lỗi của từng bản, tìm đúng nguyên nhân gốc, vá từng cái — rồi chạy lại. Lần hai: xanh hết cả 4 bản.

Chi tiết kỹ thuật (cho Claude)
Phát hành: GitHub Actions .github/workflows/release.yml — kích hoạt bằng tag v* → macOS (arm64 + Intel), Windows x64, Linux (deb + rpm) → tạo Release, gộp latest.json cho tự cập nhật.
Khoá updater: minisign, tạo cục bộ (miễn phí), lưu bí mật trên GitHub Secrets. Pubkey trong tauri.conf.json.
Ký số: lộ trình miễn phí (self-signed/ad-hoc) → app vẫn cần bước "Open Anyway" lần đầu trên Mac.
3 bẫy đã trị: macOS truyền biến chứng chỉ rỗng → chỉ truyền khi thật sự ký; Windows khoá không mật khẩu bị từ chối → tạo lại khoá có mật khẩu; Linux linuxdeploy lỗi → ship .deb/.rpm, bật APPIMAGE_EXTRACT_AND_RUN.
Bộ nhớ: voiceflow-updater-key.
QUY TRÌNH 03 · ⭐ CASE STUDY GỠ LỖI

Săn con bọ "đơ" — đọc dấu vết, sửa tận gốc

Mục tiêu: app treo cứng khi micro không dây rớt sóng giữa chừng → truy đến tận nguyên nhân gốc → vá cho tự phục hồi.

Triệu chứng

Đang ghi âm, micro Bluetooth rớt kết nối → thanh ghi âm đứng hình, app kẹt ở trạng thái "đang bận" mãi mãi, chỉ tắt mở lại mới hết.

  1. Đọc nhật ký tìm dấu vếtLog chỉ thẳng: "thiết bị không còn khả dụng" → ngay sau đó "bỏ qua lệnh: đang bận". Có manh mối là có hướng.
  2. Truy đến đúng chỗ kẹtLuồng xử lý âm thanh đang "chờ mãi" một mẩu dữ liệu không bao giờ tới (vì micro đã chết), nên không nghe lệnh Dừng.
  3. Sửa tận gốc, nhiều lớpLuồng luôn kiểm lệnh Dừng mỗi vòng; khi micro chết thì tự báo "hết luồng" để thoát; thêm van an toàn.
  4. Nhờ 3 "chuyên gia ảo" soi đối khángTrước khi tin bản vá, cho 3 góc nhìn độc lập cố tìm lỗi (kẹt lại · mất tiếng · hồi quy). Kết luận: an toàn.

Kết quả

Từ treo vĩnh viễn phải khởi động lại → giờ app tự nhận ra micro mất và phục hồi cho lần ghi sau. Bài học lớn: một lỗi "khó chịu" thường có một nguyên nhân gốc rất cụ thể — cứ đọc log và lần theo là ra.

Chi tiết kỹ thuật (cho Claude)
Gốc: recorder.rs — luồng consumer chặn trên recv(), chỉ rút lệnh SAU khi có mẫu; thiết bị chết → không mẫu → Cmd::Stop không bao giờ tới → stop() treo → pipeline kẹt "busy".
Vá: rút lệnh mỗi vòng + recv_timeout(200ms); error callback set stream_dead + gửi EndOfStream; đường dừng nhanh khi stream chết; stop() chống treo.
Kiểm định: workflow review 3 góc → safe-to-ship. Chế độ on-demand (mặc định) tự phục hồi bằng đóng+mở lại.
Bộ nhớ: voiceflow-freeze-bug.
QUY TRÌNH 04

Audit & nâng cấp — từ 6 lên 9 điểm, có kiểm chứng

Mục tiêu: đánh giá toàn diện, rồi nâng cấp những thứ người dùng cảm nhận được — không đập đi làm lại, không ôm hết một lần.
  1. Audit 3 góc song songCùng lúc soi: kiến trúc/cấu trúc · tốc độ trên chip Apple · giao diện & trải nghiệm. Ba báo cáo độc lập.
  2. Sửa cái cảm nhận được trướcHết đơ; nhẹ & nhanh hơn; chữ dễ đọc (đạt chuẩn tương phản); dùng được bằng bàn phím; hết chữ tiếng Anh sót.
  3. Xây → chạy thử → soi lỗi → mới phát hànhĐóng gói bản thật, chạy thử trên máy, soi đối kháng — rồi mới đẩy ra cho người dùng.
  4. Ghi rõ "để lại đợt sau"Trung thực liệt kê phần chưa làm (rủi ro cao hơn) để làm sau, thay vì hứa hết.
Chi tiết kỹ thuật (cho Claude)
Nâng cấp v0.8.5: hết đơ (QT03) · bỏ gửi mức âm thừa sang cửa sổ chính · target-cpu=apple-m1 cho aarch64 · token màu chữ phụ + trạng thái (đạt WCAG AA) · sửa nút/panel "lạc tông" trên nền navy · bàn phím + viền focus · Việt hoá tự nhiên.
Để lại (khuyến nghị): tách ngôn ngữ để mở app nhanh hơn · cache settings · hâm nóng model trước · gộp lệnh · làm lại onboarding tải model.
Bộ nhớ: voiceflow-v085-upgrade.
RÚT GỌN

6 bài học mang đi

01Một việc, làm thật tốt. Một app — một đích. Đừng ôm đồm.
02Đứng trên vai người khổng lồ. Fork mã nguồn mở tốt sẵn, cải tiến trên đó — nhanh gấp nhiều lần làm từ 0.
03Để máy chủ đóng gói. GitHub tự build Mac/Windows/Linux — đừng build tay từng bản.
04Lần đầu luôn trục trặc. Bình thường. Đọc log, sửa đúng gốc, chạy lại — đừng đoán, đừng nản.
05Chạy thử + soi đối kháng rồi mới phát hành. Đừng tin bản vá cho tới khi có bằng chứng nó chạy.
06Đánh số phiên bản mỗi lần. v0.8.3 → v0.8.5… Mỗi lần đẩy là tăng số, ghi rõ "sửa gì".