私たちは翻訳インフラを販売している。自社のマーケティングサイトも5言語で展開している。実際に配信しているJSONを監査してみたところ、最初に見つかったのはトーンの問題ではなかった。ドイツ語の複合語の中に紛れ込んだ、一見ほとんど違和感のない一文字の誤り――ラテン文字が入るべき場所にキリル文字が入っていたのだ。その単語は、コードポイントを確認するまでは用語集の見出し語のように普通に見えた。自社の翻訳すらまともに機能していないのに、なぜ製品を信頼してもらえるだろうか?
世に出してはいけなかった5つの不具合
ドイツ語UIテキストに紛れ込んだキリル文字。 ある用語集の一行に、文字種が混在した単語があった。語尾はラテン文字の「ar」に見えるが、実は一文字だけ違う文字が使われていたのだ。ネイティブスピーカーならすぐに気づく。スペルチェックは気づかない。
**The string:** …"Übersetzungsglossар"… (Cyrillic "р" in the compound)
**What it should be:** "Übersetzungsglossar"
**Why it matters:** It reads as corrupted text. It signals automated output nobody proofread in the target language.
ドイツ語とフランス語における敬称の逆転。 このサイトは開発者向けのツールだ。話し方も、エンジニアが実際にプロダクトUIで使う言葉遣いに合わせるべきだ。ところが私たちは、deとfrのあらゆる箇所で敬語表現を使ってしまっていた。これは些末な問題ではない。ごく一部の文字列だけでなく、サイト全体にわたってデフォルトの翻訳フローが誤った敬称レベルを選んでいたということを意味する。
**The string:** "… wie Sie …" / "vous pouvez …"
**What it should be:** informal "du" / "tu" voice for product and FAQ
**Why it matters:** Every screen sounded like enterprise procurement, not like the product we sell to vibe coders.
架空の通貨。 英語版ではドル表記だったのに、ドイツ語版では月額としてユーロが表示されていた。私たちは国によって価格を変えて請求してはいない。だがそのJSONは、あたかもそうしているかのように見せてしまっていた。
**The string:** "20 €/Monat" (and similar) next to "$20/mo" elsewhere
**What it should be:** one USD amount, formatted per locale via code (e.g. Intl), not hand-invented symbols in JSON
**Why it matters:** Pricing trust. Mixed symbols read as either a bug or a hidden price change.
「coding」の空似言葉(フォールスフレンド)問題。 3つの言語で、「coding environment(コーディング環境)」が「encoding(エンコーディング)」を意味する単語で訳されていた。FAQには、ユーザーが自分の「エンコーディング環境」にとどまっていられると書かれていたのだ。これはこの製品に関して、どう読んでも間違いだ。
**The string:** Spanish "codificación", Italian "codifica", German "Codierung" in the wrong sense
**What it should be:** development environment wording (e.g. entorno de desarrollo / ambiente di sviluppo / Entwicklungsumgebung)
**Why it matters:** It is a semantic bug. It reads like we do not understand our own domain.
郵送の意味に読めてしまった「ship」。 ドイツ語とイタリア語の文字列で、ソフトウェアのリリースではなく、小包の発送を連想させる動詞が使われていた。英語の原文は同じでも、選ばれた語彙のジャンルがまったく違っていた。これは意図的なスタイル選択ではなく、機械翻訳の提案がそのまま修正されずに残ってしまった結果だった。
**The string:** parcel-shipping verbs applied to "ship your app"
**What it should be:** release / deploy / deliver software wording
**Why it matters:** Developer trust. One wrong verb tells the reader the copy was never read by a developer in that language.
自動生成された翻訳がなぜズレていくのか
これは翻訳者を非難するための話ではない。サイトの多くの部分は、そもそも文字列単位で人間のチェックを一度も通っていなかった。汎用モデルは、デフォルトで敬体(フォーマルな表現)に傾く傾向がある。なぜなら、公開ウェブ上にある大量のバイリンガルテキストがそういう見た目をしているからだ。また、目的が「正しい文字種」ではなく「もっともらしい文字」であるとき、モデルは文字種をまたいだ似た形の文字(近似同形字)を混同してしまう。用語集がなければ、隣接するキー同士でも語の選び方がぶれていく。通貨のルールがなければ、モデルはもっともらしい現地通貨の記号を勝手に作り出す。分野固有のチェックがなければ、「encoding」と「coding」が衝突する。これこそ、私たちが圧縮しようとしている失敗パターンそのものだ。そして自社サイトも、顧客の視点で監査するまでは、まさにその失敗をそのまま世に出していた。
クリーンアップの後に構築したもの
一度きりの文言修正は、仕組みとは呼べない。長続きする部分は、チーム全員(そして今後の自動翻訳バッチ)が法として扱える小さなポリシーファイルと、マージ前に実行できる検証スクリプトだ。
ポリシー。 i18n/LOCALIZATION_POLICY.mdには、ロケールごとの敬称レベル、JSON内ではUSDのみを使う価格表記ルール、借用語に関する方針(例えば英語のままvibe codersを残すこと)、「coding」対「encoding」の空似言葉ルール、インラインリテラルの表記スタイルなどが記録されている。あえて短く保っている。ルールとして書かれていなければ、モデルはそれを一貫して推測することができない。
## Currency
- USD only in all locales. Use {monthlyPrice} and {overageRate} placeholders…
## False friends
- Coding environment is not encoding: Spanish desarrollo / Italian sviluppo / German Entwicklung…
検証。 scripts/verify-translations.shは、ラテン文字のロケールファイル内のキリル文字、ユーロ記号、過去に問題となった空似言葉の文字列、そしてmessages/en.jsonとの価格プレースホルダーの整合性をgrepで検出する。ripgrepがインストールされていればオプションのチェックも動く。このスクリプトは天井ではなく床、つまり最低限の保証だ。「一度直したから大丈夫」という状態が、次の一括編集で静かに崩れてしまわないようにするために存在している。
JSONでの当て推量ではなく、コードで解決する。 表示されるUSD金額をlib/pricing.tsに一元化し、formatUsdPerMonthとformatUsdOveragePer1kをホームページとFAQに組み込むことで、ロケールファイル側が数値を勝手に作り出さないようにした。バグの本質は間違った文字列そのものだけではなかった。規模が拡大する前に、ポリシーとフォーマッターの仕組みを整えていなかったこと自体がバグだったのだ。
AI支援によるi18nのために、あなたも取り入れるべきこと
モデルを使って翻訳を生成するなら、敬称レベル(レジスター)が最もばらつきの大きい変数になる。言語を増やす前に、ロケールごとにそれを固定しておくこと。通貨は文章の中ではなくコードの中で固定すること。ブランド用語や開発者用語もロックしておくこと。「後でざっと目視で確認する」ではなく、バッチ処理自体を失敗させる自動チェックを実行すること。「後で」は、最初の作業と同じ品質基準ではほぼ実現しない。
この監査の背景にあるアーキテクチャの話についてはAI生成アプリをローカライズする方法を、ツール比較についてはglobalize.now vs Lokalise vs Crowdinを参照してほしい。自分のリポジトリでi18nを構築していて、同じようなガードレールが欲しいなら、globalize.nowでリポジトリを接続すればいい。変換はアプリ内で一度だけ実行される。npx skills add globalize-now/globalize-skillsは、コードのすぐそばにインストールされるスキル向けに私たちが用意しているドキュメントの入り口だ。正直に言おう。私たちは自社製品を自ら使い、みっともないバグを見つけ、ポリシーを書き、ゲートを追加した。それこそが、あらゆる多言語ローンチが満たすべき基準だと私たちは考えている。
globalize.nowは、ハードコードされたアプリ内テキストを翻訳可能なロケールファイルに変換し、リリースのたびに自動で最新の状態を保ちます。
globalize.nowを無料で試す