Gemini API の翻訳コストを約 9 割削減した実践記録

2026/7/7

代表

LLM を組み込んだサービスでは、機能を満たしたうえでコストをどこまで下げられるかが、運用上の課題になります。弊社が運営している hackernews.jp では翻訳・要約に Gemini API を利用しており、初期リリース時点でコスト削減の余地がありました。この記事では、コスト構造を切り分け、日額を約 9 割まで削減するに至った試行錯誤を、実測データとともに記録します。

TL;DR

  • コストの約 96% が出力トークンでした。最大の要因は、デフォルトで有効な思考(thinking)トークンです。
  • 思考トークンの無効化で日額を約 65% 削減し、さらに安価なモデルへの切り替えとプロンプト強化で、約 150 円/日 → 15 円前後/日(約 9 割減)まで下げられました。
  • 学びは、変換タスクでは思考を最小化する、構造化出力のスキーマは書式まで保証しない、検証は本番と同条件で行う、小型モデルは構成で補う、の 4 点です。

背景:翻訳・要約処理の構成

まず、コストが発生している処理を整理します。処理の流れは次のとおりです。

  1. 定期実行のバッチ処理が 30 分ごとに Hacker News のトップ記事を取得する
  2. まだ翻訳していない記事を抽出し、3 件ずつのバッチにまとめる
  3. 各バッチを Gemini API へ渡し、1 回のリクエストで タイトル訳・要約・カテゴリ・本文全文翻訳 の 4 項目を、JSON schema による構造化出力として受け取る
  4. 結果を保存する

「翻訳と要約」という、比較的単純に見える処理です。ここが後の伏線になります。

コスト構造の把握

運用データを見ると、当初の想定よりコストがかかっており、1 日あたり約 150 円、月に直すと約 4,500 円がかかっていました。まずバグや余計なリクエストを疑いましたが、成功率は 100% で、そうした異常は見当たりませんでした。

指標実測値(1 日あたり)
入力トークン約 144K
出力トークン約 400K
リクエスト回数約 50 回
成功率100%

注目すべきは、コストの約 96% が出力トークンだった点です。入力より出力が支配的であり、削減の鍵は出力トークンにあると分かりました。ここから原因の切り分けを始めました。

原因分析

出力トークンを押し上げていた要因は、1 つではありませんでした。順に見ていきます。

原因 1:デフォルトで有効な思考トークン

Gemini 2.5 Flash の出力は $2.50/1M トークンで課金され、この単価には思考(thinking)トークンも含まれます(出典は末尾)。そして Gemini 2.5 Flash は、思考がデフォルトで有効です。

翻訳や要約は、本来は入力を別の形へ変換するタスクで、複雑な推論(reasoning)を必要としません。それにもかかわらず、私たちはコード側で思考を無効化しておらず、不要な思考トークンが出力単価で積み上がっていました。これが出力トークン量を押し上げた主因です。

原因 2:出力が支配的な処理構造

加えて、本文の全文翻訳は出力が大きくなりがちで、処理する記事数も相応にありました。出力が支配的なワークロードそのものが、コストを底上げしていました。

つまり、思考トークンと出力の多さが重なってコストが膨らんでいた、というのが結論です。であれば、まず着手すべきは思考トークンの削減です。

対策 Stage 1:思考トークンの無効化

最初に取り組んだのは、変換タスクである翻訳・要約から、不要な思考トークンを取り除くことです。思考を無効化するには thinkingBudget を 0 に設定します。

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

const response = await ai.models.generateContent({
  model: "gemini-2.5-flash",
  contents: prompt,
  config: {
    responseMimeType: "application/json",
    responseSchema: translationSchema,
    thinkingConfig: { thinkingBudget: 0 }, // 思考を無効化
  },
});

結果

検証したところ、思考トークンは 1 リクエストあたり 667 → 0 に減り、翻訳・要約の品質に劣化は見られませんでした。実測の日額は約 150 円 → 約 50 円と、約 65% の削減です。変換タスクにおいて、思考トークンがいかにコストを押し上げていたかがはっきりしました。

対策 Stage 2:より安価なモデルへの切り替え

さらなる削減を狙い、出力単価が約 6 分の 1 の gemini-2.5-flash-lite への切り替えを検討しました。ここで、コストと品質のトレードオフという壁にぶつかります。

素の flash-lite でぶつかった壁

思考を無効にした素の flash-lite では、書式やルールの遵守が不安定でした。具体的には次のような症状です。

  • 本文全文翻訳が段落に分かれず、一塊のテキストになる
  • 本文取得に失敗したとき「本文が取得できません」という内部メッセージがそのままユーザーに露出する
  • 一部の英単語が訳されずに残る
  • カテゴリ分類が難しいケースを安易に「その他」に丸投げする

安いモデルに替えれば品質が下がる、という単純な話にも見えますが、公式のモデルカード(Model Card)等の一次情報にあたって原因を整理しました。

一次情報からの原因分析

  • 構造化出力の JSON schema は「フィールドが存在すること」は保証しますが、「文字列の中身の書式(段落分けなど)」までは保証しません。書式は結局プロンプトの指示頼みになります。
  • flash-lite は小型(sparse MoE 構成)で、複数の制約を同時に守る力が相対的に弱い傾向があります。
  • 私たちは、その小型モデルを思考なしという最も非力な構成で動かしていました。
  • サンプリングによる出力のばらつきもあります。
  • さらに交絡要因として、検証スクリプトが本番(3 件ずつ)と異なり 13 件を一括で投げており、条件が揃っていませんでした。

最後の点は重要で、検証条件が本番と違うと、モデルの良し悪しなのかバッチサイズの影響なのかを切り分けられません。

解決:少量の思考予算 + 低い temperature + プロンプト強化

これらを踏まえ、次の構成に落ち着きました。

const response = await ai.models.generateContent({
  model: "gemini-2.5-flash-lite",
  contents: prompt,
  config: {
    responseMimeType: "application/json",
    responseSchema: translationSchema,
    temperature: 0.3,                        // 出力を安定させる
    thinkingConfig: { thinkingBudget: 512 }, // ごく少量の思考を許可
  },
});

あわせてプロンプトを強化し、数値と単位の正確さ、英単語の翻訳、段落分け、装飾記法の抑制、取得失敗を本文に出さないこと、を明示的に指示しました。そのうえで、本番と同じ 3 件ずつの条件で 3 構成を比較したところ、flash-lite のこの構成で、flash と同等の品質をコスト約 5 分の 1 で達成できることを確認しました。書式は「モデル選択 × temperature × 指示」で担保する、という整理です。

各パラメーターの意味

config で指定した各パラメーターを、公式ドキュメントに沿って整理します。

  • responseMimeType: "application/json": 応答を必ず有効な JSON として返させる指定です。既定の text/plain(自由文)ではなく、機械的に扱える JSON を得るために使います。
  • responseSchema: 応答 JSON の構造(どのフィールドを持つか、各フィールドの型)を制約します。responseMimeType と組み合わせることで、「タイトル訳・要約・カテゴリ・本文訳の 4 フィールドを持つ配列」という形を守らせます。保証されるのは JSON の構造で、文字列内部の書式(段落など)は別途プロンプトで担保します。

このうち、この記事の肝は次の 2 つです。temperature は「出力のブレ」を、思考予算(thinkingBudget)は「思考にかけるコストと安定性」を制御するツマミで、品質とコストのバランスはこの 2 つで大きく変わります。

temperature: 0.3 は、出力のランダム性(ばらつき)を制御します。範囲は 0.0〜2.0 で、既定値は 1.0 です。値が低いほど出力は決定的で安定し、高いほど多様で創造的になります。

thinkingConfig: { thinkingBudget: 512 } は、モデルが最終的な回答を出す前に費やす「思考(thinking)」の量を、トークン数で指定します。思考トークンは出力トークンとして課金されるため、この値はコストに直結します。設定は次の 3 通りです。

  • 0: 思考を無効化する(対応モデルのみ)
  • -1: dynamic。要求の複雑さに応じてモデルが思考量を自動調整する
  • 正の整数: 思考量のおおよその上限をトークン数で指定する

今回は最小の 512 を指定しました。この temperature と thinkingBudget は、値の決め方でコストと品質が変わります。次に、それぞれをどう決めたかを、一般的な指針とあわせて説明します。

temperature をどう決めたか

なぜ 0.3 なのかを説明します。既定値の 1.0 のままだと、同じプロンプトでも実行ごとに出力がぶれ、段落分けや取得失敗時の扱いといったルールの守り方が安定しませんでした。翻訳・要約では、創造的な多様性よりも、毎回同じルールを守る一貫性のほうが重要です。そこで temperature を下げ、サンプリングのばらつきを抑えました。

ただし、下げれば下げるほど良いわけではありません。0 に近づけると再現性は上がる一方で、表現が単調・機械的になり、翻訳の自然さが損なわれることがあります。安定性と自然さのバランスを取る中間として 0.3 を選びました。

一般的な指針としては、出力に求めるものが「正確さ・一貫性」か「多様性・創造性」かで考えると整理しやすいです。

  • 低め(目安 0〜0.4): 翻訳・要約・分類・抽出・コード生成など、正確さと再現性を重視するタスク(今回はここ)
  • 中程度(目安 0.5〜1.0 前後): 一般的な対話や説明文など、自然さと安定性のバランスを取りたいタスク
  • 高め(目安 1.0 超): アイデア出しやコピー案の量産など、多様な発想がほしいタスク

temperature を上げるほど出力は多様になりますが、事実と異なる内容(ハルシネーション)のリスクも増えます。実務では、既定値から始めて、出力が不安定なら下げる、単調すぎるなら上げる、というように実データで調整するのが確実です。

thinkingBudget をどう決めたか

なぜ 512 なのか、という点を補足します。flash-lite の thinkingBudget は「0(無効)」または「512〜24576」の範囲で指定でき、512 は指定できる最小の思考量です。翻訳・要約は深い推論を必要としないため大きな budget は不要で、必要だったのは書式やルールを守るためのわずかな「計画の余地」だけでした。そこで最小の 512 から試したところ、前述の不安定さが解消したため、それ以上増やす理由はなく 512 を採用しました。思考トークンは出力レートで課金されるので、品質を満たす最小値に寄せるのが得策です。

一般的な指針としては、タスクが必要とする推論の深さで考えると整理しやすいです。

  • 0(無効): 事実抽出・分類・単純な変換など、推論をほぼ必要としないタスク。最も安く、速い。
  • -1(dynamic): 要求の複雑さに応じてモデルが思考量を自動調整する。難度がばらつくタスクの無難な既定値。
  • 小さめの固定値: 深い推論は不要だが、書式やルールを安定させるために少しだけ思考の余地がほしいタスク(今回の翻訳・要約がこれにあたります)。
  • 大きめの固定値: 高度なコーディング、数学、多段の計画など、推論が本質的に必要なタスク。

モデルごとに指定できる範囲は異なります。

モデルthinkingBudget の範囲無効化 (0)
gemini-2.5-pro128〜32768不可
gemini-2.5-flash0〜24576
gemini-2.5-flash-lite512〜24576

いずれのモデルでも、思考トークンは出力トークンとして課金されるため、budget を上げるほどコストとレイテンシが増えます。実務では、本番と同じ条件で「0・最小値・dynamic」などを比較し、品質要件を満たす最も安い設定を選ぶのが基本方針になります。

結果と学び

コスト推移

段階日額(概算)初期比の削減率
初期約 150 円
Stage 1(思考の無効化)約 50 円約 65% 減
Stage 2(flash-lite 最適化)15 円前後約 9 割減

Stage 2 適用後、数日間観察したところ、日額は 15 円前後で安定して推移しています。

学び

今回の試行錯誤から得られた示唆は次のとおりです。

  • 「思考する」モデルは思考トークンのコストを考慮します。翻訳のような変換タスクでは、思考は無効化するか最小化します。
  • 構造化出力のスキーマは、フィールドの存在は保証しても書式までは強制しません。書式ルールは「指示 + モデル選択 + temperature」で担保します。
  • 検証は本番と同じ条件で行います。バッチサイズなどの差が結論を歪めることがあります。
  • 小型モデルは安価ですが、多くの制約を同時に課すタスクでは不安定になりえます。少量の思考予算と低い temperature、プロンプトの強化で、実用的な品質まで引き上げられました。

コスト最適化と品質はトレードオフの関係にあります。一度に大きく変えるのではなく、段階的に検証しながら進めると、リスクを抑えながら着地点を探せます。

まとめ

LLM のコストは、モデルの挙動を正しく理解することで大きく変わります。私たちのケースでは、思考トークンの制御、モデル選択、そして本番同条件での検証という積み重ねで、日額を約 9 割削減できました。同じように LLM を組み込んだサービスのコストに悩む方の参考になれば幸いです。

LLM 導入・運用のコスト最適化についてのご相談は、つくばAIラボへお気軽にお問い合わせください。

出典

© 2026 つくばAIラボ株式会社