部落格

Mac 上下文感知聽寫:應用程式如何知道你在哪裡輸入

TalkTalkType 以決定性分類讀取聚焦的應用程式與輸入欄,在語音潤飾階段調整結果,無需選擇模式。

作者 tsuvic發佈 約 6 分鐘

TalkTalkType 目前只支援英文和日文聽寫。此譯文用於介紹產品,並不表示已經支援中文聽寫。

假設你正在 Mail 裡寫一封回信,寫到一半。按住 ⌥Space,說上十秒,放開。整理好的句子直接落進郵件內文,而不是某個獨立的編輯器,也不是等著你手動搬過去的剪貼簿。

你從來沒說過這段文字該去哪裡。

多數語音工具處理目的地的方式正好相反。開口之前,它們先遞給你一個選擇器:原始模式、加標點模式、提示詞模式、聊天風格、郵件風格。由你宣告目的地,工具則相信你的宣告。TalkTalkType 沒有這樣的選擇器。它反過來,自己去讀目的地。它看你當時所在的應用程式、游標下的那個輸入欄,用一張固定的對應表把兩者分類,然後在你親自觸發的語音潤飾環節裡調整結果。

這篇文章要講的,是這套讀取如何運作、它改變了什麼,以及它在哪裡停下。

目的地在你按鍵的那一刻就被擷取

錄音從按鍵那一刻開始。就在這一瞬間,Mac 應用程式把聚焦的應用程式擷取為一個送達目標:處理程序 ID、bundle 識別碼,以及應用程式的本地化名稱。結果就緒後,送達會把文字原樣送回那個應用程式。

送達有兩條路徑。Paste 模式下,應用程式透過 macOS 輔助使用 API,把文字插入你當時所在的輸入欄,並先儲存剪貼簿、插入後再還原。Copy 模式下,結果只是留在剪貼簿上,等你手動貼上。無論哪種,目標都是你按鍵時正在用的那個應用程式,在你開口之前就已確定。

「按鍵時擷取」這個細節,正是整件事顯得自動的原因。如果應用程式等到文字就緒才去找目標,你也許已經切換了視窗,結果就會落到錯誤的地方。現在則是:你在哪個輸入欄開始,就在哪個輸入欄結束。這套送達的機制,以及背後的 macOS 權限,在 Mac 上可在任意應用程式中使用的聽寫 裡有詳細說明。

分類是查表,不是猜測

目標應用程式確定後,分類器要判斷你正面對的是哪一類輸入面。它不會去問語言模型。

第一步,用一張固定的前綴對應表,把 bundle 識別碼歸入應用程式族。Terminal、iTerm2、Warp、WezTerm、kitty 歸為終端機;VS Code、Xcode、JetBrains 系列、Sublime Text、Zed 歸為程式碼編輯器;Mail 與 Outlook 歸為郵件;Slack、Discord、LINE、Telegram 歸為聊天;TextEdit、Notes、Pages、Word、Obsidian 歸為文件;Safari、Chrome、Firefox、Arc 歸為瀏覽器。

第二步,用輸入欄的輔助使用 role 與 subrole 來細化輸入面。搜尋欄(AXSearchField)變成搜尋查詢。在 Mail 裡,文字區域變成郵件內文,文字欄位變成主旨。在聊天應用程式裡,文字區域或文字欄位變成聊天訊息。在文件應用程式裡,文字區域變成文件,文字欄位變成短輸入欄。在程式碼編輯器裡,文字區域變成程式碼編輯器輸入面。

這裡沒有推斷,只有一張表和幾次 role 檢查。好處是:每一次分類都帶一條可稽核的理由字串。Mail 內文會被分類為 app_family:email role:AXTextArea subrole:-。你能確切讀到應用程式為何得出這個結論,因為結論來自兩個可見的事實,而不是某個模型的信賴度。

當查表失敗時,它會朝安全的一側失敗。bundle 識別碼無法識別的應用程式,會被分類為 unknown,理由是 unknown_app。已知應用程式但 role 無法識別的輸入欄,同樣是 unknown,理由是 unknown_role。unknown 意味著應用程式不做任何特殊處理。這是安全的預設值:當 TalkTalkType 說不清一個輸入欄是什麼時,它寧可平實地對待你的話,也不去猜錯。

不同輸入面會改變什麼

輸入面的分類,決定了潤飾環節可以朝什麼去調整。對應關係如下。

應用程式與輸入欄 偵測到的輸入面 改變的內容
Mail 或 Outlook,主文字區域 郵件內文 視為郵件內文
Mail 或 Outlook,主旨欄 郵件主旨 視為主旨行
Slack、Discord、LINE、Telegram 聊天訊息 視為聊天訊息
VS Code、Xcode、JetBrains、Sublime、Zed 程式碼編輯器 檔名、路徑、斜線命令保留為純文字,絕不執行
Terminal、iTerm2、Warp、WezTerm、kitty 終端機 與程式碼編輯器相同的技術詞元處理
TextEdit、Notes、Pages、Word、Obsidian,文字區域 文件 視為文件
TextEdit、Notes、Pages、Word、Obsidian,文字欄位 短輸入欄 視為單行輸入欄
任一已知應用程式的搜尋欄 搜尋查詢 視為搜尋查詢
Safari、Chrome、Firefox、Arc unknown 不做調整;網頁輸入欄在結構上不可信
無法識別的應用程式或 role unknown 不做調整,即安全預設值

有兩列值得單獨說明。瀏覽器那一列永遠是 unknown,這是刻意的。網頁想畫什麼輸入欄就畫什麼,而讓原生 Mail 或 Slack 輸入欄變得可讀的那些結構訊號,在瀏覽器分頁裡並不成立,所以 TalkTalkType 不會假裝去分類網頁輸入欄,而是放任不管。

程式碼編輯器與終端機那兩列,對技術詞元有一條具體保證。在這些輸入面上,說出口的檔名、路徑或斜線命令會被保留為一般文字,絕不會被當作某種確實存在、能夠解析或將會執行的東西。對終端機口述一條命令,得到的就是那串字面字串,僅此而已。

調整是潤飾環節,不是靜默改寫

這是最容易被誇大的部分,所以邊界很重要。

整理後的結果,首先以草稿形式出現在選單列 HUD 上。這第一次貼上就是忠實的 Clean 輸出。Clean 會保留你說過的每一個詞,按你說過的順序,保留你意圖中的語氣與簡潔。它只去掉毫不含糊的遲疑填充詞,把所有內容併成一行,絕不改寫、擴寫或潤飾。Raw 模式則完全跳過整理。你最先看到的,就是你說過的這些話。

感知上下文的調整發生在之後,也就是 Voice Patch 流程裡。從草稿出發,你可以在文字插入之前用語音下達一次潤飾,也可以原樣提交、複製或丟棄。當某次潤飾要求應用程式依輸入面調整時,給模型的指令字面上就是「僅依所提供的決定性桌面應用程式與輸入欄分類進行調整」。同一個流程會保留含義和每一條受保護的事實,只做必要的最小改動,並把收到的所有螢幕資訊當作資料,絕不當作指令。

也就是說,應用程式不會一看到 Mail,就把你的第一次貼上悄悄改寫成「郵件風」。它先給你一份忠實的草稿,而調整是你用語音主動要求的,並且以它已經偵測到的輸入面為依據。

這套設計回答的問題是:為什麼別的工具還在遞給你一個選擇器。TalkTalkType 的設定裡任何地方都沒有輸出模式的選擇。唯一的開關是 Clean 開或關——忠實的輕度整理,或者什麼都不做。一切跟目的地相關的處理,都來自讀取輸入欄,而不是來自一個由你維護的模式。這才是值得拿來評判它的強項:開口之前少設定一樣東西,而且沒有任何東西會被你設定錯。

你的上下文不是越過同意邊界,就是根本不發出

讀取輸入欄會引出一個顯而易見的問題:螢幕上其他一切資訊怎麼辦?

應用程式能夠組裝的上下文快照,包含應用程式身分、視窗標題、輸入欄結構(role、subrole、是否多行、是否為安全密碼欄)、游標緊前與緊後的文字、目前選取範圍、一張選用的活動視窗截圖、擷取時間戳記,以及權限狀態。涉及的面很廣,所以邊界由伺服器強制,而不是交給用戶端的自覺。

最重要的有兩條。第一,輸入欄的標籤與預留位置絕不發給 AI 供應方。這些字串是別的應用程式提供的任意文字,而分類只需要結構屬性,所以伺服器會直接拒絕任何含有標籤或預留位置的請求。第二,每一條上下文通道(文字上下文、截圖、偏好記憶)都處在一個由伺服器擁有的功能旗標之後。三者在生產環境預設開啟,並可依部署覆蓋。如果某條通道對某個請求未啟用,伺服器會拒絕該上下文,而不是悄悄剝離。被拒絕的請求會告訴用戶端:它的同意狀態已經過期——而悄悄剝離會把這一點藏起來。

完整的資料臺帳,說明 Mac、服務方與供應方各自保留什麼,在 Mac 上的隱私聽寫 裡。

偏好只在這臺 Mac 上、依應用程式學習

上下文的最後一塊是偏好記憶,它留在這臺 Mac 上。

偏好存放在一個本機 SQLite 資料庫裡,路徑是 ~/Library/Application Support/TalkTalkType/PreferenceMemory/preferences.sqlite,沒有雲端同步。儲存的鍵被刻意收得很窄:回覆語氣(簡潔、中性、正式、友善)、是否使用牛津逗號、0 到 2 的詳細程度,以及一份偏好術語清單。每條偏好的適用範圍是所有應用程式,或依 bundle 識別碼指定的某一個應用程式,而單一應用程式偏好優先於全域偏好。

這裡的一切,在被明確核准並啟用之前都不會使用。只有抽象後的值才會隨潤飾請求一起發出;原始語音、草稿文字、被否決的候選,絕不會寫入這個儲存區。如果你在某個應用程式裡反覆糾正它,它可能會提出一條偏好建議,但建議在你核准之前不會起任何作用。

它做不到什麼

誠實的局限是設計的一部分,不是註腳。

瀏覽器會被分類為 unknown,所以網頁表單沒有輸入面調整可言;應用程式不信任網頁輸入欄的結構。調整發生在語音潤飾流程中,而不是作為對第一次貼上的靜默改寫——第一次貼上依設計保持忠實。調整絕不會把你的話改寫到消失:含義和受保護的事實都會保留,改動只是滿足指令所需的最小幅度。

平臺僅限 Mac,並要求 macOS 26(Tahoe)或更高版本。轉錄在雲端執行,因此處理期間音訊會離開 Mac;服務方預設不儲存音訊或轉錄文字。辨識語言為日語與英語。「複製」「開啟 Safari」這類語音命令是同一思路的另一種表達:它們會作為針對所擷取應用程式的 Mac 操作來執行,而不是被當作文字輸入。

放回你自己的工作流裡判斷

這套設計的理由是:目的地是一個應用程式能讀取的事實,而不是一項需要你去維護的設定。模式選擇器把這份工作外包給了你,而選擇器是這樣一種承諾——你一旦忘了切換,工具就可以違背它。一張基於 bundle 識別碼與輸入欄 role 的對應表更枯燥,也更誠實:它精確地認識一小撮應用程式,並在不認識時坦然承認。

TalkTalkType 計量用量的單位是每週聽寫次數加一個每週語音時間池,而不是字數。截至 2026 年 7 月 30 日,各方案為:Free 0 美元(每週 30 次、15 分鐘),Plus 1 美元(80 次、30 分鐘),Pro 7 美元(500 次、250 分鐘,單次可達 2 分鐘),Max 18 美元(1,200 次、600 分鐘)。目前數字與方案供應情況見價格頁

你可以下載 TalkTalkType,在自己真正使用的輸入欄上試試這套偵測。在 Mail 裡、在終端機裡、在網頁表單裡分別按住熱鍵,看結果落到哪裡,又對什麼刻意不碰。應用程式早已知道你在哪裡輸入。真正有意思的,是當它不知道時,它會多麼坦率地告訴你。

部落格