- macOS の mozc に ut-jawiki (124 万件) を入れると
kMaxEntrySize=1,000,000で詰む。Top N 抽出も コスト値が POS デフォルトで上書きされる仕様で無効。 - 正解は slim デファクト UT =
ut-skk-jisyo(16.5 万件) +ut-edict2(17.5 万件)。jawiki の 1/10 サイズで五十音偏りなし。 - mozc DictionaryTool GUI は 100 万件級でフリーズ。protobuf 直書きで回避し、TSV を SSOT に git で育てる。
- macOS で UT 取り込み事例は 2026-05 時点で公開ゼロ件。空席のフロンティアにコミュニティ事例 第 1 号を置いた。
intro出発点 ― Google IME に絶望して、azooKey を試して、Mozc に行き着いた
Google 日本語入力に限界が来ていた。助詞の 「に」が「二」(漢数字)に化ける連文節バグで、書くたびに引っかかる。リリース自体は今も出ているが、変換エンジン本体は 2018 年あたりで止まったまま。新語にも文脈にも追従しない。バージョンだけ上がって中身は据え置き。
救いを求めたのが azooKey-Desktop だった。Neural モデル(Zenzai)で助詞精度が上がる、ローカル LLM 74MB を内蔵した意欲作。試すと確かに賢い。が、本番採用は見送った。
🔍 azooKey を本番採用しなかった 2 つの理由
① もたつき: 入力中の遅延が無視できない。原因は Zenzai の inferenceLimit(推論回数の上限)。公式 Docs は「通常 1 で十分、高精度狙いなら 5」としているが、v0.1.3 でデフォルトが 5 に引き上げられた。しかも GUI から変更できない(ConfigWindow.swift に該当 UI なし)。α〜β 品質ゆえ。
② Windows 追従性: Win/Mac で同じ IME を使いたい。だが公式 azooKey は macOS のみ。Windows 版はサードパーティ fkunn1326/azooKey-Windows(Rust 製の別実装)で、alpha リリース 1 個・⭐152・辞書同期なし。人柱コストが高い。
azooKey の方向性自体は良いと思う。個人開発で macOS Neural IME + ローカル LLM 統合という未踏に挑んでいる。v1.0 stable で速度が安定したら戻りたい枠。今はまだ早いというだけ。
azooKey を落とし、ATOK や かわせみ も並べて検討して却下した(本筋から外れるので割愛)。最後に残った標準 IME に切り替えた瞬間、今度は 「きょう」が 2026-05-09 にならない問題に直面する。
Mac 標準 IME で きょう と打つと 2026/05/09(スラッシュ区切り)は候補に出る。だが ISO 8601 ハイフン区切りの 2026-05-09 は出ない。Git のコミットメッセージやファイル名でハイフン形式を多用する開発者には、これが地味に効く。
そこで IME を mozc に変えただけで、Google IME と同じエンジンが動き、ハイフン形式日付も候補に出るようになった。原点目的は 5 分で達成。本記事の本筋はその先 ―― mozc を Google IME 本家超え品質に育てる副次目的の方にある。
02ハマりの三重罠
「ut-jawiki を入れれば固有名詞バッチリだろう」と 124 万件のユーザ辞書を投入したら、3 つの罠が連鎖して詰んだ。mozc 公式ソースを読むまで気付けない仕様ばかりだ。
1 辞書あたり 100 万件まで。jawiki / sudachidict / neologd は全て超過、構造的に詰む。
📜 一次資料
kMaxEntrySize = 1,000,000 は mozc の user_dictionary_storage.cc にハードコード。docs には明示されていない仕様。
TSV のコスト値は mozc が読まない。頻度反映による Top N 抽出は原理的に不可能。
📜 一次資料
ユーザ辞書のコスト値は mozc 内部で品詞 (POS) のデフォルト値で上書きされる仕様。user_dictionary_storage.cc の保存処理を読むと確認できる。TSV にどんなコストを入れても無視される。
jawiki TSV はコスト値が均一なので Top N で切ると五十音順上位だけ残る。「ま〜ん」全滅。
📊 実測した分布
jawiki TSV のコスト値はほぼ全件 8000 で均一。Top N で切ると安定ソートで五十音順上位になる。100 万件版で実測すると:
--- ut-jawiki Top 100万件 の五十音別エントリ数 ---
あ: 75,009 ████████████████
い: 47,607 █████████
う: 24,994 ████
え: 28,323 █████
お: 50,858 ██████████
(中略)
ふ: 40,544 ████████
へ: 6,194 █
ほ: 15,585 ███
ま: 0 ← ここから完全ゼロ
み: 0
む: 0
(以下、ん まで全部 0)「松本市」「八幡神社」「南千住駅」「山田太郎」全部欠落する。これでは固有名詞拡張の意味がない。
3 つの中で最も致命的なのは罠 ②。「コスト値で頻度を反映させて Top N を取る」というアプローチは、mozc がそもそもそのコスト値を読まない。最初から成立しないわけだ。気付くまでに DB を 3 回作り直した。五十音偏りの実測でようやく構造を理解した。
03slim デファクト UT の発見 ― 17 万件級の二択
「kMaxEntrySize = 1,000,000 なら、100 万件以下の UT 辞書なら問題なく入る」という気付きから、utuhiro78 の各 repo の実件数を全件実測した。明確に 2 グループに分かれる:
| UT 辞書 | 件数 | 上限 | サイズ感 | 採否 |
|---|---|---|---|---|
| ut-neologd | 1,538,454 | ❌ 超え | 大型 | 却下(dictionary 更新停止) |
| ut-sudachidict | 1,271,800 | ❌ 超え | 大型 | 却下 |
| ut-jawiki | 1,238,147 | ❌ 超え | 大型 | 却下(五十音偏り) |
| ut-alt-cannadic | 178,776 | ✅ 余裕 | slim | 候補(古典寄り) |
| ⭐ ut-edict2 | 175,725 | ✅ 余裕 | slim | 採用(英和混在) |
| ⭐ ut-skk-jisyo | 165,063 | ✅ 余裕 | slim | 採用(一般語彙) |
17 万件級が「slim デファクト UT」の正体。Linux 中心の UT エコシステムでは jawiki / sudachidict / neologd の大型辞書ばかりがフィーチャーされ、この slim 系は陰に隠れている。macOS の kMaxEntrySize 制約環境ではむしろこちらが本命。
04最終構成 ― D-1 王道(4 辞書)
抑制 28 + 動詞サ変 30 + 名詞 18
akirakubo メンテ
SUGGESTION_ONLY 品詞
SUGGESTION_ONLY 品詞
合計 346,129 件、DB 12.1 MB、各辞書 100 万件上限以下 ✓
なぜ SUGGESTION_ONLY 品詞か
UT 辞書由来の固有名詞・専門語を変換候補ウィンドウには出さず、予測変換(サジェスト)のみで参照させたい。Space で変換する通常文章入力では「鬼滅の刃」「ヴルスト」のような固有名詞ノイズは邪魔。「きめ」と打った瞬間にサジェストに「鬼滅の刃」が出れば 1 タップで確定できる。mozc の学習機能との相性も良い。使うほど個人最適化されていく。
ディレクトリ構造
config/i_IME/
├── README.md ← 設計方針 + 第一原理 FAQ
├── personal.tsv ← 個人 SSOT (76 件、git で履歴管理)
├── upstream/ ← 外部 snapshot (自分では編集しない)
│ ├── mazegaki.txt
│ ├── mozcdic-ut-skk-jisyo.txt.bz2
│ └── mozcdic-ut-edict2.txt.bz2
└── scripts/
├── apply.py ← TSV/bz2 → mozc DB 投入
├── status.py ← DB 中身確認
├── refresh-upstream ← 上流から再 DL
└── *.proto / pb2.py ← mozc 公式 schema05protobuf 直書き ― GUI フリーズを突破する
macOS の Mozc.pkg には CLI 辞書ツールが付属していない。Linux 版にある mozc_tool が macOS 配布版には含まれず、DictionaryTool.app は GUI のみ。しかも 100 万件級の TSV をインポートすると UI が完全フリーズ。
解決策はユーザ辞書 DB を Python で直接生成すること。~/Library/Application Support/Mozc/user_dictionary.db は非暗号化の protobuf binaryで、mozc 公式 schema UserDictionaryStorage をそのまま serialize しただけ。
TSV を読んで protobuf に詰めて書き出すだけ。mozc は次回起動時に新 DB を読み込むので、GUI フリーズは原理的に発生しない。
🐍 apply.py の核心部分 (再現用)
import bz2
from pathlib import Path
import user_dictionary_storage_pb2 as udp
PosType = udp.UserDictionary.PosType
DB_PATH = Path.home() / "Library/Application Support/Mozc/user_dictionary.db"
def load_ut_bz2(path, pos_id):
seen = set()
entries = []
with bz2.open(path, "rt", encoding="utf-8") as f:
for line in f:
parts = line.rstrip("\n").split("\t")
if len(parts) < 5: continue
yomi, _, _, _, value = parts
key = (yomi, value)
if key in seen or len(yomi) > 256: continue
seen.add(key)
entries.append((yomi, value, pos_id))
return entries
storage = udp.UserDictionaryStorage()
# personal + mazegaki + ut-skk-jisyo + ut-edict2 を別辞書として追加
# ...
DB_PATH.write_bytes(storage.SerializeToString())
# mozc は次回起動時に新 DB を読み込む事前に user_dictionary_storage.proto から user_dictionary_storage_pb2.py を生成しておく必要がある (protoc --python_out=. user_dictionary_storage.proto)。
06選択肢の比較 ― なぜ D-1 か
| 案 | 内容 | 初回工数 | 月次 | 長期コスト | 判定 |
|---|---|---|---|---|---|
| A | 2 辞書のみ (UT 無し、学習任せ) | 5 分 | 0 | 無料 | 無難・leverage 低 |
| B | mozc fork ビルドで UT システム辞書化 | 3〜4 h | 15〜30 m | 無料(Gatekeeper 警告 / 年 $99 課金可) | 正攻法だが過剰 |
| C | ATOK Passport サブスク | 30 分 | 0 | ¥660/月 × 24m = ¥15,840 (解約で全消失) | 却下 (BYOK 違反) |
| ⭐ D-1 | slim UT (edict2 + skk-jisyo) + protobuf 直書き | 30 分 | 5 分 | 無料・TSV 資産永続化 | 採用 |
07Q&A ― よくある疑問
主要な疑問 2 つだけ先に答える:
- 辞書ツール GUI じゃなくても動くの? 動く。mozc 本体は起動時に
user_dictionary.dbを読むだけで、GUI は編集ツールに過ぎない。 - 「に → 二」連文節バグは消える? 消えない(mozc も Google IME 同エンジンで同症状)。個人辞書の抑制単語で軽減のみ。構造問題で根治不能。
❓ その他の Q&A を展開 (4 問)
| 疑問 | 答え |
|---|---|
| サジェストが固有名詞だらけにならない? | SUGGESTION_ONLY 品詞で投入してあるので、Space 変換ウィンドウには出ない。サジェストポップアップも mozc 設定の「サジェスト最大候補数 = 3」が地味に効いて、ノイズが抑えられる。 |
| fork ビルドで UT 取り込む方が筋では? | 確かに正攻法(dictionary00.txt に append → Actions で .pkg ビルド)。だが Gatekeeper 警告 / 月次手動再インストール / コードサイニング年 $99 の運用コストが見合わない。slim UT で実用十分。 |
| Mac/Win 同期は? | TSV ファイルを SSOT として git 管理。両 OS で同じ apply.py を実行すれば同一 DB を再生成可能。DB ファイル直コピーは Mac/Win フォーマット差異リスクで NG。 |
| UT 更新の追従は? | refresh-upstream.sh で akirakubo/mazegaki / utuhiro78/mozcdic-ut-skk-jisyo / utuhiro78/mozcdic-ut-edict2 を最新版に再 DL。差分があったら apply.py で DB 再生成。月 1 回 5 分の作業。 |
08今回得た一次知見
本セッションで得た「ネットに明示的に書かれていないが、公式ソース / 実機検証で確定した事実」を 8 つ:
- 🔍 macOS で UT 辞書を取り込んだ和文記事は 2026-05 時点で公開ゼロ件(Qiita / Zenn / note / Hatena / 個人ブログ全探索)。Linux ディストロには豊富な事例があるが、macOS は空席のフロンティア。
- 📜 mozc はユーザ辞書のコスト値を POS デフォルトで上書きする。これは 公式ソースで確認できる仕様だが、公式 doc には明示されていない。Top N 抽出による頻度反映は原理的に不可能。
- 📜
kMaxEntrySize = 1,000,000がハード上限(1 辞書あたり)。kMaxDictionarySize = 100が辞書数上限。ファイルサイズは 512 MB が上限。 - 📊 slim デファクト UT = ut-edict2 + ut-skk-jisyo(各 17 万件級)。コミュニティで明示的に語られていない正解。jawiki / sudachidict / neologd は 100 万件超で詰む。
- ⚡ protobuf 直書きで DictionaryTool GUI フリーズを完全回避できる。mozc の user_dictionary.db は非暗号化の protobuf binary。schema は
user_dictionary_storage.protoで公開。 - 🎯 SUGGESTION_ONLY 品詞で UT 固有名詞を投入すれば、変換候補ウィンドウのノイズはゼロ。サジェストポップアップでのみ参照され、mozc 学習で個人最適化される。
- 🧩 mazegaki と personal.tsv は機能直交(grep で重複ゼロ実証)。前者は交ぜ書き抑制、後者は助詞単独抑制 + 文節境界ヒント。両立する。
- 🚫 抑制単語は連文節境界判定には効きにくい。「
に → 二」を抑制すると次のスコア候補「似」が浮上するモグラ叩きが発生。単独入力時にだけ効く。
09References ― 一次資料と参考リンク
mozc 本体・公式
- google/mozc ― 本体
- user_dictionary_storage.cc ―
kMaxEntrySize等の制約値の出典 - user_dictionary_storage.proto ― protobuf schema
- build_mozc_in_osx.md ― macOS ビルド公式手順
- google/mozc macOS Actions ― Mac/Win バイナリ artifact 取得
UT 辞書 / コミュニティリポ
- ⭐ mozcdic-ut-skk-jisyo
- ⭐ mozcdic-ut-edict2
- mozcdic-ut-alt-cannadic
- merge-ut-dictionaries ― 辞書生成ツール
- akirakubo/mazegaki ― 交ぜ書き抑制辞書
- phoepsilonix/dict-to-mozc ― 辞書変換ツール
コミュニティ事例
- ArchWiki Mozc ― Linux での UT エコシステム
- Mozcdic-UT が終わった話と代替品を開発してる話
- Google日本語入力にお別れを告げて Microsoft IME へ移行した話 ― 「に → 二」問題の独立検証
EOFあとがき
本記事は Claude Code との 1 セッション(約 4 時間)で構築した。最初は場当たり的な対応の連鎖だった。途中で第一原理に戻り、/consult:research / /consult:thinking / /detector:ltd-bullshit の壁打ちエージェントで多角検証して、ようやく最終構成にたどり着いた。
副産物として、「研究エージェントの結論を鵜呑みにせず反証仮説まで踏まえる」「ユーザの違和感シグナルを仮説として高得点で評価する」というメタ認知パターンも手元に残った。これはこれで大きい。
macOS で mozc を使っている方、UT 辞書取り込みで詰まっている方、自分でツールチェーン構築する派の方にとって、本記事が時間短縮の役に立てば幸いです。