日本語化率100%でも残る日本語検索の穴
UIを100%日本語化しても検索・名寄せ・表記ゆれは別層の問題として残り、最悪は無言で0件になる現象
定義
OSSのUI文言(メッセージカタログ)を100%日本語に訳しても、検索・並び替え・名寄せといったデータ層の日本語対応は別問題として残る現象。翻訳率は「画面に日本語が出るか」しか保証せず、「日本語で探せるか」は保証しない。極端な場合は、翻訳率100%のまま検索結果が1件も返らない。
kurage-articles-index のOSS日本語化シリーズと、kurage-products に並ぶ自社製品群の双方で、複数のプロダクトにまたがって繰り返し実測された。
なぜ起きるか — 三つの層の分離
| 層 | 対象 | 翻訳で解決するか |
|---|---|---|
| 表示層 | ボタン・メニュー・エラーメッセージ | する(=翻訳率) |
| 検索層 | 全文索引、トークナイザ、照合順序 | しない |
| データ層 | 和暦、全角半角、旧字体、Shift_JIS、OCR | しない |
翻訳率100%は最上段の達成にすぎない。検索層はDB側の設定(全文索引のアナライザ、n-gram、pg_bigm/textsearch_ja の有無、LIKE 検索のみか)に依存し、UIの言語設定とは独立している。
しかも原因はDBの設定だけではない。全文索引エンジン自体が空白区切り言語を前提としていることがある。Xapian のように語を空白で切る索引は、日本語の一文をまるごと一語として登録しうる。この場合、訳がどれだけ揃っていても語彙の一致が起こらず、検索は静かに0件を返す。
典型的な症状
- 一文が一語として索引され、1件も引けない — 日本語の全文検索が機能しない最重度の形。
- 部分一致でしか当たらない — スペース区切り言語前提の索引では「請求 書」のような分割が起きず、複合語が引けない。
- ひらがな/カタカナ/漢字の表記ゆれ — 「たなか」「タナカ」「田中」が別物として索引される。
- 全角半角・大文字小文字の正規化漏れ — 「ABC」「ABC」が別語になる。
- 並び替えが壊れる — 氏名のソートがコードポイント順になり、五十音順にならない。
- 名寄せ不能 — 検索結果の重複排除が表記ベースで失敗する。とくに日本語の事業所名は「ひまわり」「さくら」のような語が大量に重複する。
- 失敗が無言 — エラーも警告も出ないまま0件になる。訳した人は自分の作業が正しかったのか判断できない。
実測された事例(索引より)
検索そのものが成立しない
- TheyWorkForYou — 英国議会の議事録OSSを日本の国会会議録で動かした検証。素のままでは日本語が1件も引けない(Xapianが一文を一語として索引する)ことが最大の関門で、その解き方を含む5つの修正を手順として収録した。導入キットという商品形態そのものが「検索層の穴」を主内容にしている。→ theyworkforyou
翻訳100%でも穴が残る
- Docmost — 翻訳100%でも「日本語検索に穴がある」と明記。Notion/Confluence代替として自社サーバーに立てた検証で判明。→ docmost-japanese-kit
- Twenty CRM — 「構築して分かった日本語検索の穴」。スター数では測れない実用性の差。→ twenty-crm
- Vikunja — 翻訳の穴が9%(135キー)残っていたケース。翻訳率と検索品質を別々に測る必要を示す。→ vikunja-japanese-kit
- Zammad — 日本語が23%しかなく5,123エントリを全訳してWeblateを100%に。ただしヘルプデスクでは本文検索の日本語対応が別途効く。→ zammad
- Docspell — 画面1,056語を訳してElmで実装・コンパイルを通すまでの記録。表示層の作業量が可視化された事例。→ docspell-japanese-kit
- Krayin — 2,066キー全訳して本家PR。→ krayin-crm-japanese-kit
- Planka — 翻訳の穴56キーに加え、ライセンスの線引き(第三者向けホスティングは有料)という別種の「穴」。→ planka-japanese-kit
- Fess — Namazuから移行し45本のPDFを索引、ローカルLLMで10問実測(検索10/10・回答9/10)。検索層まで含めて日本語で機能した好例。→ fess
- paperless-ngx — 定番の
jpn+engOCR設定が見出しを「Ake」に壊す実測。縦書きのjpn_vertが無言でスキップされることも含め、データ層の落とし穴。→ paperless-ngx - OpenVPM — 和暦・Shift_JIS の移行を本番構成で確認。文字コードと暦は検索以前にデータ層の問題。→ openvpm
検索の穴を前提に設計された製品
kurage-app-store の製品群は、この穴が解けないまま納品されることを避ける設計を繰り返し採用している。
- 質問主意書アシスト — 衆参の質問主意書と政府答弁書を本文の中までことばで引く。加えて「意味の近い質問主意書」を事前計算の表から出す。索引の完全一致では届かない範囲を、埋め込みによる類似検索で塞ぐ。
- 議員発言ログ/国会トラッカー — 議員が「いつ・どの会議で・何を質問したか」を日付と会議録リンクつきで引く。要約も論評もしないので、検索結果がそのまま根拠になる。
- 訪問看護ナビ — 同名事業所(「ひまわり」49軒・「さくら」48軒)を住所で見分ける。日本語の名寄せを名前ではなく所在地で解く型。
- 取引先チェック — 会社名・13桁の法人番号・T+13桁の登録番号のどれでも照合し、名寄せの軸を表記から法人番号へ移す。
- 陳情ナビ — 所管委員会の判定にLLMを使わず語の一致で選び、何の語で判定したかを画面に出す。当たらなければ「判定できませんでした」と表示し、当てずっぽうで1つ選ばない。
- 学童保育ナビ — 学童の待機児童数は国の公表がPDFだけで、市区町村名で数字が出るのは50人以上の88市町村のみ。全国16,330人のうち31.4%はどこの市か分からない。公表されていない市町村は「未公表」と書き、推定した数字は出さない。→ administrative-data-publication-gap
対策の型
- 翻訳率と検索品質を別々に測る — 「訳した」「検索できた」を一つの達成度にまとめない。
- 日本語の実データで検索テストを先に書く — ひらがな・カタカナ・漢字・全角半角を混ぜたクエリセットを用意し、「訳した直後に0件を返さないこと」を合格条件にする。
- 索引側を直す — アナライザ/n-gram/正規化を設定する。Xapian等では一文一語になっている索引そのものを解体する。UIの翻訳では届かない。
- 引けないときに引けないと言う — 一致しなかったことを「該当なし」ではなく「判定できませんでした」と返す。無言の0件を作らない。→ unknown-vs-outside-distinction
- 完全一致の外側を別経路で塞ぐ — 埋め込みによる類似検索を併用する(事前計算の表でもよい)。ただし結果には根拠を添える。→ evidence-traceability
- 判定をAIに委ねない — 語の一致のような決定的な処理にし、使った語を画面に出す。→ deterministic-core
- 測った結果を上流に返す — 訳のPRと検索の修正提案を分けて出す。→ oss-upstream-contribution
関連
- oss-japanese-localization — 翻訳作業そのものの総論
- japanese-search-gap — 検索層に限定した隣接概念
- oss-upstream-contribution — 発見を本家に返す運用
- self-hosting — 自社サーバーに立てるからこそ索引設定を触れる
- rag — 検索品質の穴はRAGの回答品質に直結する(Fess+ローカルLLMの実測)
- local-llm — 検索結果を読ませる側の基盤
- administrative-data-publication-gap — 検索可能な形で公表されていないデータという、上流側の同種の穴
- deterministic-core — 語の一致で判定し、判定根拠を開示する設計
- evidence-traceability — 類似検索の結果にも根拠を添える
- unknown-vs-outside-distinction — 「引けなかった」と「存在しない」を混同しない
- theyworkforyou — 日本語が1件も引けない状態を実測した事例
- kurage-app-store — 検索の穴を前提に組んだ製品群
- kurage — 一連の検証を公開している主体
- kurage-articles-index — 出典となる記事索引
- kurage-products — 製品側の設計回答が並ぶ商品一覧
含意
OSS評価において「日本語対応」を翻訳率だけで判定すると、導入後に検索が使えず業務が回らない事故が起きる。しかもこの穴はエラーを出さないため、PoCの段階でも「動いている」と誤認されやすい。評価項目は少なくとも 表示・検索・データ の3層に分ける必要がある。この概念は saas-subscription-replacement の判断基準(乗り換えて実務に耐えるか)にも直接効く。
Kurage.AI に質問する
