GEMINI LABEN
3.8FLASH — gemini-3.8-flash が9月2日に一般提供となりました。長く続く開発作業、自律エージェント、企業のワークフロー向けという位置づけですLYRIA3.5 — 音楽生成の lyria-3.5 がパブリックプレビューに入りました。フル尺の楽曲を 44.1 kHz ステレオで生成でき、テキストと画像の両方を入力に取れます9/30 — gemini-omni-flash-preview の停止まで残り15日です。後継は gemini-omni-1.1-flash で、8月27日に一般提供が始まっていますCACHE — 暗黙キャッシュの最小トークン数は公式には 4,096 ですが、12k を超えるまで発火しないという実測報告が出ています。効いているかどうかは自分で測るほかありませんNEW — BLOCK_NONE を入れても結果が変わらないとき。閾値で通る話と、下げても通らない話の境目を書きました403 — models の一覧は 200 で返るのに generateContent だけ 403 で拒まれる、という質問が毎週のように再発しています。課金を有効にした直後でも起こります3.8FLASH — gemini-3.8-flash が9月2日に一般提供となりました。長く続く開発作業、自律エージェント、企業のワークフロー向けという位置づけですLYRIA3.5 — 音楽生成の lyria-3.5 がパブリックプレビューに入りました。フル尺の楽曲を 44.1 kHz ステレオで生成でき、テキストと画像の両方を入力に取れます9/30 — gemini-omni-flash-preview の停止まで残り15日です。後継は gemini-omni-1.1-flash で、8月27日に一般提供が始まっていますCACHE — 暗黙キャッシュの最小トークン数は公式には 4,096 ですが、12k を超えるまで発火しないという実測報告が出ています。効いているかどうかは自分で測るほかありませんNEW — BLOCK_NONE を入れても結果が変わらないとき。閾値で通る話と、下げても通らない話の境目を書きました403 — models の一覧は 200 で返るのに generateContent だけ 403 で拒まれる、という質問が毎週のように再発しています。課金を有効にした直後でも起こります
記事一覧/最新情報
最新情報/2026-09-15中級

3.8 Flash と 3.7 Flash のどちらに寄せるかを、手元の20問で決めています

モデル ID を新しい世代へ書き換えたあと、同じ入力で答えが割れて見えることがあります。20問の質問集を1本だけ用意して、二つの世代を同じ条件で走らせ、充足率と自己一致率で判断するまでの手順をお伝えします。

gemini-3.8-flash2gemini-3.7-flashthinking_level2モデル選定6評価4

モデル ID を gemini-3.7-flash から gemini-3.8-flash へ書き換えたのは、Lab のカテゴリ説明文を整えるだけの小さな呼び出しでした。差分は一行です。夜のうちに流して、翌朝に出力を眺めましたら、同じ入力に対して前日とは違う組み立ての文章が並んでおりました。

どちらがよいのかを、その場で決められませんでした。並べてみれば新しいほうが丁寧に見えます。けれども丁寧さと、私がほしかった短さは別のものです。

——そして何より、前日の出力を私はもう持っておりませんでした。比べる材料を残していなかった、というだけの話でした。

公式は「3.7 Flash も引き続き使えます」と書いています

最初にお伝えしたいのは、新しい世代へ上げることが義務ではない、という一点です。

Gemini 3.8 Flash の What's new ページには、3.8 Flash が長期にわたるソフトウェア開発・自律エージェント・複雑な企業ワークフローに向けて設計されている旨が書かれています。難しい課題に対して推論の刻みを細かくし、ツールを繰り返し呼び、自分の出した答えを途中で検証する——そのぶんトークンを多く使うことがある、という説明が続きます。

そのうえで、すべてのワークフローにこの水準の検証が要るわけではない、と明記されています。日常的な処理では推論の労力を下げてよく、あるいは 3.7 Flash のままでも構わない、と。

項目gemini-3.8-flash
既定の thinking levelmedium
指定できる値low / medium / high
minimal非対応(指定するとエラーが返ります)
コンテキスト1M トークン
最大出力64k トークン
導入価格の期限2026年12月31日まで

つまり判断の材料は、公式が並べてくれている範囲では「速さと賢さのつまみが増えた」ところまでです。自分の仕事でどちらが良いかは、手元で確かめるほかにありません。

比べる前に、土俵を揃えます

ここで私は一度つまずきました。書き残しておきます。

3.8 Flash への移行チェックリストには、temperaturetop_ptop_k を生成設定から外すこと、thinking_budget を文字列の thinking_level に置き換えること、candidate_count を削除することが並んでいます。私は言われたとおりに 3.8 側のコードを直しました。そして 3.7 側は、既存の設定のまま走らせたのです。

結果は芳しくありませんでした。差は確かに出たのですが、それが世代の違いによるものなのか、外した temperature=0.2 のせいなのか、切り分けられなくなったのです。

いま思えば当たり前のことでした。比較の土俵は、新しいほうではなく、古いほうに合わせて作り直します。 3.7 側からもサンプリングパラメータを抜いて、両方を素の状態にしてから並べます。ここを省くと、あとの数字がすべて読めなくなります。

質問集は、間違えられた記録から作ります

質問集を新しく考えてはいけない、というのが二つめの線引きです。

思いついた「よい質問」は、たいてい自分が答えを知っている質問になります。そうではなく、過去に出力を直した箇所を集めます。レビューで書き戻した文、公開前に手で削った段落、アプリのストア説明文で語調が合わずに書き換えた行。私の場合は、それだけで20問がすぐに埋まりました。

形式は1行1問の JSONL にしております。判定を機械に任せたいので、期待する語と、出てほしくない語を添えます。

{"id": "cat-desc-01", "input": "壁紙アプリのカテゴリ「和風」の説明文を1文で書いてください。", "must_include": ["和"], "must_not_include": ["最高", "ぜひ"]}
{"id": "cat-desc-02", "input": "同じ説明文を、句点を1つだけ使って書き直してください。", "must_include": ["。"], "must_not_include": ["!"]}

must_not_include のほうが効きます。世代を上げたときに増えるのは、間違いよりも、頼んでいない装飾のほうだからです。

同じ質問を3回ずつ、二つの世代へ流します

1回ずつ比べても、答えが割れているのか自分が揺らしているのかは分かりません。そこで各問を3回繰り返し、判定が3回とも揃った問だけを「割れていない」と数えます。

import json
import statistics
import time
 
from google import genai
 
client = genai.Client()
 
MODELS = [
    {"name": "gemini-3.7-flash", "config": {}},
    {"name": "gemini-3.8-flash", "config": {"thinking_level": "medium"}},
]
REPEAT = 3
SYSTEM = "日本語で、箇条書きを使わず200字以内で答えてください。"
 
 
def ask(model, config, prompt):
    started = time.time()
    interaction = client.interactions.create(
        model=model,
        input=prompt,
        system_instruction=SYSTEM,
        generation_config=config,
    )
    usage = interaction.usage
    return {
        "text": interaction.output_text,
        "out_tokens": usage.total_output_tokens or 0,
        "thought_tokens": usage.total_thought_tokens or 0,
        "seconds": round(time.time() - started, 2),
    }
 
 
def judge(text, item):
    hit = all(word in text for word in item.get("must_include", []))
    miss = any(word in text for word in item.get("must_not_include", []))
    return hit and not miss
 
 
def run(path):
    with open(path, encoding="utf-8") as handle:
        items = [json.loads(line) for line in handle if line.strip()]
 
    for model in MODELS:
        passed = agreed = 0
        out_tokens, thoughts, seconds = [], [], []
 
        for item in items:
            runs = [ask(model["name"], model["config"], item["input"]) for _ in range(REPEAT)]
            verdicts = [judge(run_result["text"], item) for run_result in runs]
            passed += sum(verdicts)
            agreed += 1 if len(set(verdicts)) == 1 else 0
            out_tokens += [r["out_tokens"] for r in runs]
            thoughts += [r["thought_tokens"] for r in runs]
            seconds += [r["seconds"] for r in runs]
 
        total = len(items) * REPEAT
        print(
            model["name"],
            f"充足 {passed}/{total}",
            f"一致 {agreed}/{len(items)}",
            f"出力トークン中央値 {statistics.median(out_tokens):.0f}",
            f"思考トークン中央値 {statistics.median(thoughts):.0f}",
            f"秒の中央値 {statistics.median(seconds):.2f}",
        )
 
 
if __name__ == "__main__":
    run("eval_set.jsonl")

usage から取っている4つの値には、それぞれ役割があります。total_output_tokens は請求に直結する数、total_thought_tokens はモデルが考えるために使った数、そして経過秒数は体感に効く数です。平均ではなく中央値を出しているのは、20問のうち1問が長引いただけで平均が動いてしまうためです。

実行前に、両方のモデルで thinking_level を変えた回も回しておくと、判断がもう一段はっきりします。3.8 Flash を low にしたときの数字は、私にとっていちばん実務に近い列でした。

表にすると、迷いどころが2列に収まります

出てきた数字は、この5行に落として眺めております。

指標何を見ているか差が出たときの読み方
充足率期待語を満たし、禁止語を含まない回の割合ここが落ちたなら、世代を上げる理由がありません
自己一致率3回の判定が揃った問の数落ちていれば「答えが割れる」の正体は世代差です
出力トークン中央値請求に直結する量充足率が同じでここだけ伸びたなら、費用の判断になります
思考トークン中央値考えるために使った量伸びた分を thinking_level で戻せるか試します
秒の中央値待たされる体感対話的な画面では、充足率より重いことがあります

私の20問では、充足率はほぼ動かず、自己一致率も保たれたまま、出力トークンだけがはっきり伸びました。これは品質の問題ではなく費用の問題でしたので、thinking_levellow に下げて測り直したところ、伸びの大半が戻りました。単価が据え置きでも請求が増える仕組みについては、単価と請求は別の数字であるという話に分けて書いております。

一方で、自己一致率が落ちる問も2問だけありました。どちらも、こちらの指示が曖昧だった問です。世代を疑って測り始めたつもりが、自分の書いた指示の粗さを拾い直すことになりました。

私が引いた線引き

モデル ID は固定したままにして、上げるのは質問集が通った日だけ。 この順番だけは、急いでいる日でも崩さないようにしております。

新しい世代が出た日に上げたくなる気持ちは、私にもあります。けれども、その日に上げても得られるものは「新しい」という感触だけで、手元の仕事が良くなったかどうかは何も分かっておりません。20問を通してから上げれば、良くなった箇所と悪くなった箇所を、両方とも言葉にできます。

まずは5問だけ書き出してみてください。過去に自分で直した出力を思い出して、直す前の文を must_not_include に入れる——それだけで、次に世代が変わった日の朝が、かなり楽になります。

お読みいただきありがとうございました。私もまだ質問集を育てている途中で、20問はいまも増えたり減ったりしております。

シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

API / SDK2026-09-05
Gemini 3.8 Flash は単価が据え置きでも、請求が増えることがあります
Gemini 3.8 Flash の単価は 3.7 Flash と同じですが、モデルが手数を増やす設計のため出力トークンが伸びて請求が増えることがあります。切り替え前に測る数字と、年末年始の二本立てで見積もる手順をまとめます。
最新情報2026-09-10
9月14日の iOS 27 で、Gemini API の呼び出しは1行も変わりません — 変わるのは選択肢のほうです
iOS 27 の配信は9月14日です。新しい Siri が Gemini をベースにしていても、自分のアプリが叩いている Gemini API は変わりません。混ざりやすい三つの層を呼び出し口で分ける方法と、配信日までに済ませておく手順をまとめます。
最新情報2026-09-03
Wear OS と Android Auto では、失敗も声で返す必要がありました
9月4日から Google アシスタントが Gemini へ置き換わります。手の塞がる Wear OS と Android Auto では、失敗をトーストで伝えられません。メディアセッションのエラー状態として返す実装と、切り替え前に決めておくことを書き残します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます