個人開発で壁紙アプリを運営していると、説明文の多言語展開は地味なわりに流入を左右する、無視できない工程です。App Store の検索結果でユーザーの目に触れるのは、結局のところこの数百文字の翻訳の質だからです。私自身、この工程を Gemini に任せ始めてから、コストと品質のあいだで何度も判断を迫られてきました。今回は Flash と Flash-Lite をどう使い分けたか、実測を交えてまとめます。
Flash 一択をやめた理由は、月末の請求書でした
最初はすべての翻訳を Gemini 2.5 Flash に投げていました。品質に不満はありません。ただ、運営アプリが増えて対象ロケールが10言語を超えたあたりから、説明文の改稿のたびに同じ文章を何度も流し直すようになり、月末の API 請求がじわじわと膨らみました。
説明文は1本あたり数百文字ですが、ストア最適化のために何度も書き直します。1本を10ロケールに展開し、月に複数回改稿すれば、呼び出し回数はあっという間に数千に届きます。「この翻訳に、本当に Flash の精度が要るのか」という問いを、コストの側から突きつけられた格好でした。
そこで Flash-Lite を同じ素材に通し、どこまで落ちるのかを自分の目で確かめることにしました。
何を、どのロケールで比べたか
検証の素材は、実際にストアで使っている壁紙アプリの説明文3種類です。短い訴求文(80文字程度)、機能リスト、そして世界観を伝える長めの紹介文(400文字程度)を用意しました。文章のタイプによって難易度が変わるはずだと考えたからです。
ロケールは、普段流入の多い英語・繁体字中国語・韓国語・ドイツ語・ブラジルポルトガル語の5つに絞りました。CJK と欧文の両方を含めることで、崩れ方の傾向が見えると考えました。
呼び出しはシンプルに、モデル名だけを差し替えて同じプロンプトを通します。
from google import genai
client = genai.Client(api_key="YOUR_GEMINI_API_KEY")
PROMPT = """次のアプリ説明文を{locale}向けに翻訳してください。
直訳ではなく、ストアで自然に読める文体にしてください。
固有名詞とアプリ名はそのまま残してください。
説明文:
{text}"""
def localize(text: str, locale: str, model: str) -> str:
res = client.models.generate_content(
model=model,
contents=PROMPT.format(locale=locale, text=text),
)
return res.text.strip()
# 同じ素材を2モデルに通して比較する
for model in ("gemini-2.5-flash", "gemini-2.5-flash-lite"):
out = localize(SHORT_PITCH, "繁体字中国語", model)
print(model, "→", out)特別な工夫はしていません。普段の運用に近い、素のプロンプトで比べることに意味があると考えました。
短い訴求文は、ほとんど差が出ませんでした
まず驚いたのは、80文字程度の短い訴求文では Flash-Lite の出力がほぼ実用水準だったことです。英語・ドイツ語・ポルトガル語では、Flash の出力と並べても、どちらがどちらか言い当てる自信がありませんでした。
コストの体感は、私の用途では1呼び出しあたりおおむね数分の一に収まりました。短文を大量に回す壁紙アプリのストア運用では、この差は無視できません。短い訴求文に関しては、Flash-Lite を既定にして問題ないという手応えを得ました。
機能リストのような箇条書きも同様で、Flash-Lite で十分でした。情報が構造化されている文章は、モデルの語彙力よりも忠実さが効くため、軽量モデルの不利が出にくいのだと感じています。
ひとつ注意したのは、短文でもロケールによっては Flash-Lite が原文の語順をそのまま引きずる場面があったことです。ドイツ語の訴求文では、英語の語順を残したまま訳す例が数回ありました。とはいえ、出力を毎回ざっと目視する運用にしていれば、修正はその場で済む軽微なものでした。チェック工程を省ける前提なら上位モデル、目視を挟める運用なら軽量モデル、という線引きも一つの判断軸になります。
崩れたのは、世界観を語る長文と CJK の組み合わせでした
差がはっきり出たのは、400文字程度の紹介文を繁体字中国語と韓国語へ訳したときです。Flash-Lite の出力は、意味こそ通じるものの、語尾が単調になり、原文の持っていた静かなトーンが平坦になりました。壁紙アプリの説明文は「眺めていたくなる空気」を伝えたいので、この平坦化は地味に痛い欠落でした。
具体的には、繁体字で「療癒」「沉浸」といった訴求語のニュアンスが、Flash-Lite では直訳寄りの硬い語に寄りがちでした。Flash は同じ箇所で、ストアの紹介文として自然な、こなれた言い回しを選んでいました。韓国語でも、敬体の揺れが Flash-Lite ではやや目立ちました。
文章が長く、語感やトーンが価値を持つほど、Flash の余力が効いてきます。逆に言えば、トーンが価値にならない文章では、その余力に課金している状態だったわけです。
今の使い分けは、文章タイプ×ロケールで分岐させています
検証を経て、いまは次のように分岐させています。短い訴求文・機能リスト・更新履歴のような実務的な文章は、全ロケールで Flash-Lite。世界観を語る長めの紹介文は、欧文ロケールは Flash-Lite、CJK ロケールだけ Flash に回す、という二段構えです。
def pick_model(text: str, locale: str) -> str:
cjk = locale in ("繁体字中国語", "簡体字中国語", "韓国語", "日本語")
long_form = len(text) > 200
# トーンが価値になる長文 × CJK のみ上位モデル
if long_form and cjk:
return "gemini-2.5-flash"
return "gemini-2.5-flash-lite"この単純な分岐だけで、翻訳まわりの API コストは体感で半分以下に落ち、ストアで読んだときの違和感もほぼ気にならなくなりました。全部を上位モデルに任せるのは安心ですが、その安心の多くは使われていなかった、というのが正直な実感です。
分岐をコードに落としておくと、新しいロケールを追加するときも判断が揺れません。文字数としきい値、CJK 判定の2軸だけなので、運用メンバーが私一人でも頭の中で再現できます。複雑なルールにするほど守られなくなる、というのは個人開発で何度も痛感してきたところでした。判断軸が少ないほど、忙しい日でも淡々と回せます。
言語の壁を越えてアプリを届けたい、という気持ちは、ローカライズ作業の根っこにいつもあります。だからこそ、品質を落とさずに展開できるロケールの幅を広げたい。モデルの使い分けは派手さのない工夫ですが、その幅を一段ずつ押し広げるための、実務的な足場になっていると感じています。
これから試したいこと
次は、長文 CJK でも Flash-Lite を使えないか、プロンプト側で詰めてみるつもりです。トーンの参照例を2〜3文だけ渡す few-shot を加えると、軽量モデルでも語感が引き上がる手応えが部分的にありました。ここを安定させられれば、上位モデルに回す割合をさらに下げられそうです。
同じように多言語展開でコストと品質のあいだを探っている方の、ひとつの実測サンプルになれば嬉しいです。お読みいただきありがとうございました。