GEMINI LABEN
FLASH35 — Gemini 3.5 Flashが一般提供となり、gemini-flash-latestが指す実体になりました。日常的な生成を速く安価にこなせますAGENTS — Gemini APIのManaged Agentsがpublic previewに。Google管理の隔離Linuxサンドボックスで自律的なエージェントを構築できますMEDIA — Nano Banana 2 Lite(画像)とGemini Omni Flash(動画・会話的編集)がAI Studio・API・Enterprise Agent Platformで利用可能にTTS — gemini-3.1-flash-tts-previewの音声生成がstreamGenerateContent経由でストリーミング対応になりましたTRANSLATE — 新しい音声モデルが70以上の言語を自動判別し、話者の自然な抑揚を保ったままライブ音声翻訳を行いますSPENDCAP — AI Studioにプロジェクト単位の費用上限が導入され、支出を安全側に抑えられるようになりましたFLASH35 — Gemini 3.5 Flashが一般提供となり、gemini-flash-latestが指す実体になりました。日常的な生成を速く安価にこなせますAGENTS — Gemini APIのManaged Agentsがpublic previewに。Google管理の隔離Linuxサンドボックスで自律的なエージェントを構築できますMEDIA — Nano Banana 2 Lite(画像)とGemini Omni Flash(動画・会話的編集)がAI Studio・API・Enterprise Agent Platformで利用可能にTTS — gemini-3.1-flash-tts-previewの音声生成がstreamGenerateContent経由でストリーミング対応になりましたTRANSLATE — 新しい音声モデルが70以上の言語を自動判別し、話者の自然な抑揚を保ったままライブ音声翻訳を行いますSPENDCAP — AI Studioにプロジェクト単位の費用上限が導入され、支出を安全側に抑えられるようになりました
記事一覧/API / SDK
API / SDK/2026-06-27上級

Gemini の構造化出力でJSONのフィールド順がブレる — propertyOrdering で固定する実装メモ

responseSchema で型を縛っているのに、出力JSONのキーの並びが呼び出しごとに変わる。スナップショットテストが理由なく赤くなる原因はこれでした。propertyOrdering でフィールド順を固定し、few-shot の順序も揃え、差分ノイズを消すまでをコード付きでまとめます。

Gemini API182構造化出力11propertyOrderingスナップショットテスト2JSON Schema2

プレミアム記事

複数サイトのコンテンツ運用を自動化していると、Gemini に「記事のメタデータを構造化して返して」と頼む場面が増えます。タイトル・カテゴリ・タグ・要約を JSON で受け取り、そのまま後段の処理に流す、という使い方です。responseSchema で型を縛っているので安心していたのですが、ある日からスナップショットテストが理由もわからず赤くなり始めました。

差分を開いて拍子抜けしました。値は完全に同じで、変わっていたのは キーの並び順だけ だったのです。{"title": ..., "tags": ...} だった出力が、次の実行では {"tags": ..., "title": ...} になっている。型は正しい、値も正しい、それでもテキスト比較は不一致になります。

この記事は、その原因である「構造化出力のフィールド順は既定では保証されない」という仕様と、propertyOrdering での固定方法、そして few-shot を併用するときの落とし穴までを、私自身が個人開発のパイプラインで踏んだ順にまとめたものです。

なぜ順序が変わるのか — JSON スキーマの素直な性質

混乱の根っこは「JSON オブジェクトのキーには順序の概念がない」という JSON の定義そのものにあります。スキーマ(OpenAPI 由来の Schema オブジェクト)の properties は概念上は順序なしのマップで、モデルがどの順で書き出すかは生成時に決まります。temperature を 0 にしても、プロンプトを一字一句変えなくても、サンプリングの揺らぎで並びが入れ替わることがあります。

公式の構造化出力ガイドにも、順序を当てにするなら明示的に指定するように、という趣旨の注意があります。つまり「型は固定できるが、並びは別途固定する必要がある」という二段構えなのです。ここを取り違えると、私のように「型を縛ったのだから出力も完全に決まるはず」という思い込みで時間を溶かします。

具体的に、生 dict でスキーマを渡している典型コードを見てみます。

# pip install google-genai
from google import genai
from google.genai import types
 
client = genai.Client(api_key="YOUR_GEMINI_API_KEY")
 
# 順序を指定していない dict スキーマ
schema = {
    "type": "object",
    "properties": {
        "title": {"type": "string"},
        "category": {"type": "string"},
        "tags": {"type": "array", "items": {"type": "string"}},
        "summary": {"type": "string"},
    },
    "required": ["title", "category", "tags", "summary"],
}
 
resp = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="次の記事のメタデータを抽出してください: ...",
    config=types.GenerateContentConfig(
        response_mime_type="application/json",
        response_schema=schema,
    ),
)
print(resp.text)
# あるときは {"title":..., "category":..., "tags":[...], "summary":...}
# 別のときは {"summary":..., "title":..., "tags":[...], "category":...}

response_schema を渡しているのに、resp.text の生文字列のキー順は呼び出しごとに揺れます。json.loads でパースして値を取り出す分には何の問題もありません。問題が出るのは「生成された JSON テキストそのものを保存・比較する」ときだけです。私の場合はスナップショットテストと、生成結果を git に差分として残す運用がそれに当たりました。

propertyOrdering でキーの並びを固定する

解決策はシンプルで、Schema に propertyOrdering(REST/JSON では camelCase)を足して、出してほしい順にプロパティ名を列挙します。

schema = {
    "type": "object",
    "properties": {
        "title": {"type": "string"},
        "category": {"type": "string"},
        "tags": {"type": "array", "items": {"type": "string"}},
        "summary": {"type": "string"},
    },
    # ↓ これを足すだけ。出力はこの順で安定する
    "propertyOrdering": ["title", "category", "tags", "summary"],
    "required": ["title", "category", "tags", "summary"],
}
 
resp = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="次の記事のメタデータを抽出してください: ...",
    config=types.GenerateContentConfig(
        response_mime_type="application/json",
        response_schema=schema,
    ),
)
# 出力は常に title → category → tags → summary の順

propertyOrdering は「型の制約」ではなく「並びのヒント」です。欠けても型検証は通ってしまうため、生 dict でスキーマを書く運用では足し忘れが起こりやすい、というのが実感です。ネストしたオブジェクトがある場合は、子オブジェクト側の Schema にもそれぞれ propertyOrdering を書く必要があります。トップだけ書いて満足すると、ネストの中だけ並びが揺れて、また差分が出ます。

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

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
responseSchema を入れても順序が保証されない理由と、dict スキーマに propertyOrdering を1行足して固定する手順を today 手に入れられる
Pydantic を response_schema に渡すと宣言順が自動で propertyOrdering になる挙動と、その検証コードを習得できる
フィールド順のブレで赤くなっていたスナップショット回帰を、正規化と順序固定の二段構えで安定させられる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

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

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

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

関連記事

API / SDK2026-04-30
Gemini API の構造化出力を本番品質まで引き上げる設計図
Gemini API の構造化出力(Structured Output)を本番アプリケーションで安定稼働させるための実践的な設計図。スキーマ設計・エラー対応・パフォーマンス最適化まで体系化します。
API / SDK2026-06-29
Gemini APIのレスポンスをCIで守る — スナップショットと意味的回帰の検知設計
生成AIの非決定的なレスポンスを、pytestのスナップショットテストとembeddingベースの意味的回帰検知で守る実装手順。CI組み込み・flakyと本物の回帰の切り分け・スナップショット更新のガバナンスまでを実コードで解説します。
API / SDK2026-06-19
日英2版を1回の構造化出力でまとめて生成し、用語の対訳ブレを止める運用設計
日本語版と英語版を別々に生成すると用語の訳が記事ごとにブレます。Gemini 3.5 Flash の構造化出力で日英をペアにして1コールで生成し、用語集をピン留めしてブレを機械検出する運用を、実測値とともにまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →