跳至主要內容
03 · 專案記錄開發中原型 · 160/160 PASS

VoiceFlow: 本機優先 macOS 語音工具

在 macOS 本機把口頭指令轉成自動化操作,結合本機 Whisper、動作確認機制與本機加密紀錄。

負責範疇產品構想、安全機制設計、穩定度測試
運行環境macOS Sonoma+ · Swift 6
語音辨識引擎faster-whisper CPU int8
安全與儲存AES-GCM SQLite · 零雲端依賴

目前進度與實測現況

專案狀態: 開發中原型 / ONGOING PROTOTYPE
✓ 已完成並正常運作
  • Carbon 全域快速鍵 Push-to-talk 收音,音訊僅存於本機記憶體
  • 本機 faster-whisper CPU int8 模型語音轉文字(中位數 2,003 ms,無網路傳輸)
  • 繁體中文專有名詞替換辭典,修正轉錄文字
  • 以規則為主的意圖分類器,區分唯讀查詢與具副作用操作
  • 確認視窗機制攔截寫入與對外操作(160 次穩定度測試中 0 次誤觸發)
  • 本機 SQLite 稽核紀錄採用 Apple CryptoKit AES-GCM 加密
  • 獨立 Watchdog 行程在工作程序崩潰時於 0.43 秒內自動重啟
⚠ 目前限制與未解決問題
  • 微調 Whisper 候選模型因時間戳記漂移(+310ms)且效益不明顯而淘汰捨棄
  • 瀏覽器自動化仍屬 DOM 層級的初步原型,尚未串接完整的系統輔助使用 API(AXUIElement)
  • 僅支援特定指令轉接器,尚未具備通用的全系統桌面操作能力

01 · 想要解決的問題

用麥克風控制電腦主要有兩個顧慮:一是把環境聲音持續傳到雲端伺服器,容易錄到私人對話或公司機密;二是語音辨識偶爾會聽錯,萬一模型擅自執行了刪除檔案、外發郵件或跑終端機指令,後果很難挽回。

VoiceFlow 的出發點是做一套完全在 Mac 本機跑的語音工具。錄音與轉文字全部在自己的電腦上完成;更重要的是,任何會改變檔案或對外發送的操作,都必須先跳出視窗讓使用者確認,絕不自行偷偷執行。

02 · 實作前提與限制

只在本機推論

錄音、語音轉文字到指令判斷都在 Mac 本機運算,不依賴雲端 API。

關鍵操作不自動執行

只要遇到刪除檔案、送出網頁表單或跑 shell 腳本,一定先彈出確認視窗。

操作紀錄加密儲存

本機儲存的語音指令與執行歷史,透過 macOS Keychain 管理的金鑰以 AES-GCM 加密寫入 SQLite。

03 · 流程劃分與確認機制

透過熱鍵收音,經 faster-whisper 辨識與繁體中文修詞後判斷動作類型。單純查資料直接跑,會動到系統的操作則停下來等候確認。

架構與資料流

本機語音到 macOS 指令執行流程

0.43 秒重啟恢復
01 聲音擷取

01. 聲音擷取:按下熱鍵才開始收音,16kHz 音訊直接放記憶體,不上傳雲端。

02 本機轉文字

02. 本機轉文字:用 faster-whisper int8 在 CPU 上跑辨識,中位數約 2 秒完成,不連外網。

03 文字清理

03. 文字清理:比對專用詞庫修正常見錯字,把口語轉換成比較規律的指令格式。

04 動作分類

04. 動作分類:判斷這條指令只是單純查資料,還是會變更系統狀態。

05 跳出確認手動確認

05. 跳出確認:只要涉及刪檔、送出或寫入操作,必須在螢幕上按確認才會繼續(測試中 0 起自動送出)。

06 執行與記錄

06. 執行與記錄:執行已確認的指令,並將操作記錄加密存入本機 SQLite,背景守護程序負責監控行程。

當前步驟:01. 聲音擷取:按下熱鍵才開始收音,16kHz 音訊直接放記憶體,不上傳雲端。
防護設計: 分派模組會將指令標上風險等級。只要有變更狀態的疑慮,就會進入 waiting_confirmation 狀態並跳出提示框。沒有收到使用者的按鍵或點擊前,後續動作完全不會觸發。

04 · 三項主要技術取捨

1. 重要操作一律手動確認,不追求全自動

安全性

評估考量:在辦公室或有人講話時,語音工具很容易把背景雜音誤當成指令。
採用的做法:規定修改檔案、送出請求或系統指令等操作,一定要跳出確認視窗。例如示範社群發文時,流程只會幫忙填好內容,停在送出按鈕前等待點擊。
結果與取捨:在連續 8 小時跑完 160 次任務的穩定度測試中,高風險操作自動送出的次數為 0。

2. 獨立的守護程序,崩潰時快速重啟

穩定度

評估考量:跑在背景的音訊轉錄行程或自動化模組,長時間運作偶爾可能卡死或出錯。
採用的做法:將選單列介面與背景 Worker 分成不同行程,中間用 UNIX domain socket 通訊,並寫了一個小守護程序負責監控心跳與自動重開。
結果與取捨:測試時手動砍掉背景 Worker,守護程序能在 0.43 秒內重新拉起行程,選單列介面不閃退、任務也不會遺失。

3. 記錄前過濾敏感資訊並加密

隱私保護

評估考量:除錯時需要看指令記錄,但把使用者講的話直接明文存檔,很容易存到密碼或個資。
採用的做法:寫入磁碟前先用正則比對過濾常見金鑰與密碼,並用 CryptoKit 的 AES-GCM 把整張 SQLite 資料表加密。
結果與取捨:在 160 次浸泡測試的日誌檢查中,沒有發現未過濾的明文密碼留存。

05 · 遇過最棘手的問題

全域熱鍵監聽失敗時介面卡住的問題

問題原因:在某些 macOS 權限設定下,Carbon 熱鍵監聽在背景初始化偶爾會失敗,導致狀態機一直停在等候確認的狀態,無法接收鍵盤反應。

解決方式:把熱鍵註冊和按鍵處理拆開,並加入 500ms 逾時機制:如果熱鍵模組一直沒有回應,系統就自動切換成一般的系統對話框。

測試結果:在測試環境模擬 100 次熱鍵模組崩潰,100 次都順利跳回一般視窗對話框,沒有發生畫面卡死。

06 · 失敗的實驗:微調 Whisper 模型

測試結果不如預期時,及時放棄比勉強採用更明智。

門檻紀錄 · VF-STT-03
未達標 · 已捨棄
測試對象
微調版 Whisper int8 模型(CTranslate2)
預期目標
相對 WER 改善 > 10% 且指令準確率 ≥ 0.90
實測結果
WER +0.019188 · Action +0.0727
淘汰原因: 雖然自己微調的 Whisper int8 順利轉檔並跑了起來,但實測指令辨識率只微幅上升 0.0727,字詞邊界反而變得不穩定。既然花時間微調的效果有限,我就直接放棄這版模型,改回官方基礎模型加上正則修詞。

07 · 長時間測試數據

160/160 次任務測試通過

連續 8 小時跑自動化工作流程,主程式未發生崩潰。

記憶體每小時增加 0.12 MB

8 小時運作下記憶體基本維持平穩,音訊緩衝區有正常釋放。

0.43 秒守護程序重啟時間

用 SIGKILL 強制終止背景行程時,守護程序在半秒內重啟。

語音辨識中位數 2,003 ms

在一般 Mac 的 CPU 上跑 20 個語音樣本,平均辨識時間約 2 秒。

08 · 專案回顧

專案心得:做語音控制工具,模型在固定音檔上的辨識分數不能代表日常使用的穩定度。微調模型帶來的效果其實很有限 (+0.0727),反而是把字詞清理寫好、在關鍵操作前加上確認視窗,更能避免不小心操作失誤。

如果重做會做的調整:如果重新設計,我會更早把瀏覽器操作換成 macOS 內建的輔助功能 API(AXUIElement),而不是直接在網頁 DOM 上點擊,這樣才不會因為目標網頁改版而讓流程壞掉。