國台語詞語對照

這篇講的東西

台語辭典上線當天,朋友就抓到兩個洞。

一個朋友查「想像」,查不到。另一個朋友查「長頸鹿」,也查不到。

一個號稱給長輩和想學台語的人用的辭典,連這種日常詞都查不到,這不行。但 iTaigi 查得到,而且它的資料來源也寫教育部。同一份官方資料,別人有我沒有,問題一定出在我這邊。

這篇講這兩個洞怎麼來的(root cause 還不一樣)、怎麼在同一天內修好,以及修的過程順便長出了什麼。

先講這東西是為誰做的

阿瑋在 AI 願望池許了一個願望:希望視力不佳的長輩,也能用「聽」的方式接近台語內容。願望還沒結案,但先長出了兩個作品,一個是把網頁新聞唸成台語的 Chrome 擴充套件(還在商店審核,之後另外寫),另一個就是這本辭典:用華語、台語漢字或臺羅查詞,對照教育部收錄的漢字、臺羅、腔口,還能直接聽官方發音。

做著做著發現它其實還有另一群使用者:聽得懂阿公阿嬤講的台語、輪到自己開口就卡住的年輕人。查詞、聽音檔、玩「聽台語猜華語」、答錯進錯題本,通勤路上就能練。

免登入、免 API key,載入一次之後離線也能查。沒有後端、沒有帳號、沒有追蹤碼。

兩個洞,兩個根因

先講共同點。教育部《臺灣台語常用詞辭典》的公開資料裡有一張「詞彙比較」表,是官方人工整理的華台對照,982 個華語詞目。第一版辭典只用了這張表,兩個洞都是這樣來的。

「想像」的洞:華語和台語寫法一模一樣的詞(想像 sióng-siōng 這種),官方把它們歸在「臺華共同詞」,根本不會出現在對照表裡。這批有 5,548 筆,每筆都有官方錄音,下午先補上。

「長頸鹿」的洞比較深。同一份 ODS 檔裡還有 15,558 個「主詞目」,每一個都有官方錄音,長頸鹿就在裡面:台語叫「長頷鹿 tn̂g-ām-lo̍k」,或「麒麟鹿 kî-lîn-lo̍k」。但它們的華語意思寫在「義項」表的釋義欄開頭,沒有現成的對照關係。iTaigi 查得到,就是因為它把這塊也建了索引。

修法:釋義第一句如果是乾淨的華語短詞(1 到 6 個漢字、沒有標點),就把它當成這個主詞目的華語對應詞,音檔直接用主詞目的官方錄音。再加一個黑名單,擋掉「動詞後綴」這種語法功能描述。

結果:可查詞目從 982 變 13,419,台語官方音檔從 1,093 個變 13,161 個。兩個朋友的兩句「怎麼沒有」,同一天內全部查到根因、修完、上線。

兩件事我覺得必須做對:

推導的詞要標清楚。 官方人工對照跟程式推導是兩種可信度,介面上推導的詞條會掛「依教育部釋義對照」的標籤,跟官方對照表分開。「聽台語猜華語」的題庫也故意不混入推導詞,出題品質不能賭。

推導有極限,照實呈現。 有些釋義開頭是「蔬菜名」「指數量多的」這種描述,不是乾淨的詞,它們也會變成可查的條目。那是教育部原文,我選擇照實收,不擅自加工。反過來,真的沒收錄的詞就老實說找不到,不用 AI 猜一個答案給你。

華語發音也有一條類似的誠實線:教育部《國語辭典簡編本》的公開資料只有單一個字的錄音,沒有多字詞。所以「醫」有官方發音、「醫院」沒有。詞庫擴大後重配了一次,官方單字音從 98 個變 274 個,多字詞還是用裝置內建的語音,這件事在網站上寫明,不假裝。

隔天,客語版長出來了

台語版收工的當晚,我把同一套需求丟給另一個 AI 工具(這次是 Codex),資料來源換成教育部《臺灣客語辭典》。隔天早上,華客語詞語對照上線。

客語的資料比台語複雜,因為有腔:四縣、海陸、大埔、饒平、詔安、南四縣,六份官方 ODS。建出來是 105,852 筆腔別資料、23,004 個詞目、67,304 個官方音檔連結,另外每腔精選 360 個 MP3 隨站提供,下載後可以離線玩挑戰。這些數字是建置程式從官方檔案直接算出來、由測試核對的,不是人工填的估計值。

47 MB 的 JSON 教我的事

資料一大,第一個撞到的問題很實際:客語版的詞庫 JSON 有 47.3 MB,首次載入要把它整包吞完才能查詞,手機上等到懷疑人生。

解法是把資料拆成兩包。核心包 5.43 MB(詞目、拼音、釋義、挑戰需要的欄位),載完就能查;完整包 13.01 MB(例句、同反義詞、發音播放資料)在背景補。走 CDN 的話 Brotli 壓完首包只剩約 1.55 MB。台語版也跟著改成同一套。

CDN 這段有一個我覺得值得寫下來的決定:資料 URL 只 pin 完整 40 字元的 commit SHA,禁用 @main、@latest 和任何會移動的 tag。 因為 core 和 details 兩份檔案如果在不同時間命中 CDN 上的不同版本,驗證就對不起來。殼、詞庫、語音三個各自獨立版號,改個 UI 不會讓使用者重抓 186 MB 的語音包。CI 會直接去比對 pinned commit 裡的 JSON 跟目前檔案是不是逐 byte 相同,文件、快取名、SHA-256 任何一個不一致就擋下來。

這些規則全部寫進兩個 repo 的 AGENTS.md 和 DATA-RELEASE.md。這個案子是兩個 AI 工具接力做的(Claude 開資料管線和推導邏輯,Codex 接手 CDN、拆包和客語版),交接文件寫得夠明確,換手才不會把契約踩爛。老實說一開始只有程式和零散測試,是被提醒了才補齊的。

分工線

照慣例講清楚。起點是阿瑋在願望池的願望;「想像」和「長頸鹿」兩個洞是朋友當使用者踩到回報的;範圍、每一個「要不要做」的決策、驗收標準是我定的,包括「推導詞不進題庫」「沒收錄就說找不到」「多字詞不假裝有官方音」這幾條線;落成能跑的程式碼和測試全部是 AI 寫的。我的貢獻是把每一句「怎麼沒有」追到根因,然後丟對地方。

刻意不做的也講一下:這兩本辭典不做任意句子的 AI 翻譯(那是新聞朗讀那個作品的事),不做帳號、不做後端、不收任何資料。成績、錯題本、學習卡全部只存在使用者自己的裝置。

去查一個詞

台語:https://yazelin.github.io/mandarin-taigi/,查查看「長頸鹿」,聽聽「麒麟鹿」怎麼唸。

客語:https://yazelin.github.io/mandarin-hakka/,六個腔的「食飯」都不一樣。

願望池那個還沒結案的願望在這裡:https://yazelin.github.io/wish-pool/#wish-26,有共鳴可以去留一筆。