跳至內容

會議與轉錄

Control Center 可以錄下通話,然後交回一份乾淨的成稿——摘要、待辦事項和決策 ——而語音識別與說話人分離全都跑在你自己的硬件上。可以把它想成 Granola,但由 你自行託管,並且接上你的代理所在的那同一個工作區。

會議是一段被錄下並轉寫的時段。它_並不_等同於日曆活動 :活動是從 Google 同步過來的一項既定安排,而會議是你實際錄下來的東西。兩者可以 互相關聯——因為你可以從某個活動開始錄製——但它們仍然是彼此獨立的記錄。

和 Control Center 裡其他一切一樣,每場會議都以工作區為範圍。在一個工作區錄下的 會議,絕不會出現在另一個工作區。

「裝置上」這個直覺沒錯,但用的名詞不對。用戶端負責擷取音訊,把 16 kHz PCM16 影格 串流到執行 cc_server 的那部機器。其餘一切由該主機完成:它會把各聲道的 WAV 寫到 <dataDir>/meetings/<meetingId>/ 之下、在工作程序隔離區中轉寫、過濾回音,並 在事後做說話人分離。在獨立桌面環境中,該主機就是同一部機器;但指向遠端伺服器時就 不是——所以「沒有東西離開我的電腦」只有在伺服器就是你這部電腦時才成立。

還有一個例外,而且是最重要的那一個。

摘要之前的一切——擷取、轉寫、回音消除、說話人分離、聲紋比對——都在伺服器上執行, 不會發出任何網絡呼叫。

嵌入、說話人分離與語音(ASR)模型會在首次啟動時強制安裝(示範模式下略過), 因此不必進入設定就能使用說話人分離和錄音功能。ASR 仍然可以選用——它有數百 MB, 而選擇器裡隨附四個版本。首次下載之後,語音功能仍需要重啟一次,因為轉寫器會在該次 抓取完成之前就解析好它的模型。

選擇器中的這四個項目,在大小、語言覆蓋範圍和準確度上各有不同:

  • Parakeet TDT 0.6B v3 —— 多語言,推薦的預設選項(約 600 MB)
  • Parakeet TDT 0.6B v2 —— 英語(約 480 MB)
  • Whisper large-v3-turbo —— 多語言(約 626 MB)
  • Whisper base.en —— 僅英語,體積較小的歷來預設項(約 198 MB)

模型是伺服器在執行階段唯一會抓取的產物;所有原生程式庫都隨套件一起附上。

一場會議會同時錄下兩個音訊聲道:

  • 你(「me」):你的麥克風。
  • 對方(「them」):會議的音訊輸出,透過免驅動程式的環回擷取——macOS 上是 Core Audio 的程序/裝置 tap,Windows 上是 WASAPI 環回,Linux 上是 PipeWire / PulseAudio 監聽來源。

由於兩個聲道是分別擷取的,轉寫從一開始就帶有說話人歸屬:你說的話標記為 me, 通話中其他人一律標記為 them。

你自己的聲音會從系統輸出滲回麥克風,否則就會被轉寫兩次。有兩道過濾器阻止這件事。 訊號層的 AEC3 會在每次遠端模式錄製中執行,而且是必要的——如果原生 AEC 程式庫 無法載入,錄製會拒絕啟動,而不是默默地串流一個受回音污染的麥克風。(面對面模式 沒有遠端參考可以抵消,因此那裡的 AEC 只是原樣透傳。)在此之上,主機端還有一道 文字層級的回音過濾器,在所有平台上都會執行。

作業系統層面的所有麥克風處理都刻意停用。在 macOS 上啟用作業系統本身的回音消除或 自動增益,會讓麥克風切換到 Voice Processing I/O,而在這個版本中,那會同時廢掉 麥克風_和_系統音訊 tap。

錄製期間,音訊會在 UI 執行緒之外以滾動視窗方式解碼——視窗在尾端出現一小段 靜音時切分,或達到視窗長度上限時切分。每個視窗都會成為一段帶說話人標記、附有 毫秒級偏移的轉寫片段。

從未超過某個 RMS 閾值的視窗會完全跳過、不做任何解碼,因為語音模型會把靜音 渲染成幻覺出來的非語音 token,而那次解碼只是白白浪費 CPU。實際後果是:一直很 小聲的說話人不會產生任何轉寫。如果有人回來時一片空白,先檢查他的輸入音量,再怪 模型。

停止之後,說話人分離會離線對整段錄音執行,把遠端聲道拆分成一個個可以重新 命名的說話人(Person 1、Person 2……)。說話人數目是從分群閾值推斷出來,而 不是你設定的數字——所以它只是閾值造成的產物,聲音小或與他人重疊的說話人可能會 被併入旁邊那一位。轉寫會渲染成一行行 [mm:ss] SPEAKER: text。

重新命名說話人不只是為某一段轉寫貼標籤。Control Center 可以把說話人的聲紋儲存成 一份聲紋檔案,讓它在之後的會議中自動認出這個人。當你為一位經說話人分離識別 出來的說話人命名時,系統會問你是否要儲存聲紋;如果儲存,聲紋會融入該名字對應的 一個持續更新的質心,並以餘弦相似度與新出現的說話人比對,因此同一個人下次出現時 就會直接帶著名字,不需要你重新標註。

聲紋檔案以工作區為範圍,絕不會跨出邊界。你可以在 設定 → 工作區 → 會議 管理 它們。重新命名一位先前已儲存的說話人,會註銷舊名字並詢問是否登記新名字;刪除 一份檔案會移除已儲存的聲紋,但已套用到過去會議的名字會原樣保留。

錄製停止時,伺服器會發佈一個 MeetingRecordingStopped 領域事件。內建的 meeting_summary 管線範本由該 事件觸發。錄製器不會等它;會議只是走過自己的狀態生命週期:

recording → processing → done

摘要代理會收到標題、你在現場隨手記的筆記,以及轉寫內容,並回傳結構化 JSON。 它會寫哪些章節,取決於該工作區的作用中會議筆記範本(設定 → 工作區 → 會議); 作用中的範本會套用於新建與重新執行的摘要。接著,管線的持久化步驟會把該 JSON 寫入 一列列獨立的記錄:

  • enhancedNotes 和 summary → 會議的筆記
  • 每個待辦事項 → 一列 MeetingActionItem(內容、負責人、可選的工單連結)
  • 每個決策 → 一列 MeetingDecision

待辦事項和決策絕不會從自由格式的 Markdown 中解析出來,只會取自代理的結構化 陣列。如果某次執行沒有產生結構化輸出,持久化步驟會被跳過,而原始轉寫會保留作 後備,因此你永遠不會失去這份記錄。管線中沒有任何環節會把會議標記為 done—— 那是由單一的對帳器依執行的終止事件來完成,因此即使某個同層步驟失敗,也不會留下 一場只寫了一半、看起來卻已經完成的會議。

介面 顯示內容
/meetings 會議清單,附帶待辦事項與決策數量
/meetings/record 即時錄製 HUD:一側是你的筆記,另一側是串流中的轉寫
/meetings/:meetingId 會議詳情:筆記、轉寫、待辦事項和決策分頁
設定 → 工作區 → 會議 此工作區的筆記範本與已儲存的聲紋檔案

在三個桌面平台上,擷取都不需要驅動程式(macOS 上是 Core Audio tap,Windows 上是 WASAPI,Linux 上是 PipeWire)。

網頁用戶端同樣可以錄製,而本頁其餘以桌面為主的敘述可能會蓋過這一點:瀏覽器 透過 getUserMedia 取得你的麥克風,並透過 getDisplayMedia(螢幕分享)取得會議 音訊,降採樣成 16 kHz PCM16 後串流到同一部主機。這裡有三點要注意:

  • 分享的介面必須帶有音軌。Safari、Firefox 和 macOS 的全螢幕分享都不會提供 音軌,錄製會直接拒絕啟動。
  • 沒有原生 AEC3。系統會向麥克風要求瀏覽器本身的回音消除;主機端的文字回音過濾器 仍會執行。HUD 會顯示一個由麥克風 PCM 驅動的輸入音量表。
  • 重新執行摘要與取消處理僅限桌面端。

日曆上的 開始錄製並關聯操作僅限桌面端,在網頁版上會直接說明這一點,儘管會議 畫面本身的錄製流程在網頁版上確實可以運作。