GEMINI LABEN
NANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定ですNANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定です
記事一覧/高度な活用
高度な活用/2026-04-25上級

Gemini API で『自己批判するエージェント』を実装する — Reflection × Critic × Refiner で本番品質を継続的に上げる実装

Gemini 3 Pro と 2.5 Flash を組み合わせて自己批判するエージェントを構築する設計と本番運用ノウハウ。Reflection / Critic-Refiner パターンの実装、コスト上限、過剰修正の防ぎ方まで踏み込んで解説します。

gemini102gemini-3-pro4reflectionagent9production105self-improving

プレミアム記事

Gemini API を本番で運用していて、ワンショットの応答品質が頭打ちになる瞬間に出会ったことはないでしょうか。プロンプトを丁寧にチューニングし、temperature を下げ、Few-shot まで揃えた。それでも 10% 前後の応答が事実誤認・指示違反・形式崩れで落ちてくる。私自身、自分のアプリで顧客向けのメール下書き機能を作ったとき、まさにこの壁に突き当たりました。

その壁を越えるための実用的なパターンが Reflection と Critic-Refiner です。要するに「LLM に自分の出力を批判させてから書き直させる」という発想で、論文レベルでも実装レベルでも長年検証されてきた枠組みなのですが、本番で使おうとすると「無限ループ」「コストが3倍」「過剰修正で逆に劣化」といった具体的な落とし穴が現れます。

ここではGemini 3 Pro と 2.5 Flash を組み合わせて自己批判するエージェントを実装する手順を、私が実際にプロダクトに組み込んだ経験を踏まえて段階的に解説します。動くコードは3つ用意しました。コピーして温度感を確かめ、自分のユースケースに合わせて調整していただければと思います。

ワンショット推論の限界に最初にぶつかる場所

LLM のワンショット応答(プロンプトを1回投げて1回返ってくる方式)は、9割のタスクで十分な品質を出します。問題は、残り1割で落ちてくる応答が「無視できないコスト」を発生させるユースケースです。

たとえば次のようなケースです。

  • 顧客向けの文書を生成するアプリで、たまに相手の名前を間違える、指示にあった必須項目を抜かす
  • コードレビューエージェントで、明らかな脆弱性は指摘するのに、依存関係の壊れる変更を見落とす
  • 商品説明文の生成で、「絶対に書かないでください」と指示した競合ブランド名がたまに混入する

ワンショットでこれらを全て潰そうとすると、プロンプトが肥大化して逆に品質が落ちる現象が起きます。Gemini 2.5 Pro でも 3.1 Pro でも、プロンプトに 30 個以上の制約を詰め込むと、一部の制約だけが守られなくなる挙動を私は何度も観測してきました。

ここで考え方を切り替えます。「全ての制約をワンショットで満たす」のではなく、「生成 → 自己レビュー → 修正」という工程に分割するアプローチです。これが Reflection の出発点になります。

Reflection パターン — まず最小構成で試す

仕組み

Reflection の基本形は次の3ステップです。

  1. ユーザーの要求 → モデル A が初稿を生成
  2. 初稿 → モデル A(同じモデル)が「指示違反・事実誤認・形式崩れ」を指摘するレビューを生成
  3. 初稿 + レビュー → モデル A が修正稿を生成

シンプルですが、この3ステップを通すだけで品質が体感で2割ほど上がります。重要なのは、レビューの中身を構造化出力で受け取り、修正ステップが何を直すべきかを明示的に渡すことです。曖昧なフィードバックを渡すと、修正ステップで本来直す必要のなかった部分まで書き直してしまいます。

コード — Gemini 3 Pro 単体での Reflection ループ

何をするコードか: 任意のタスクと制約リストを受け取り、初稿生成 → レビュー → 修正稿生成の3段で品質を引き上げて返します。

# requirements: google-genai>=0.5.0, pydantic>=2.0
import os
from google import genai
from google.genai import types
from pydantic import BaseModel
from typing import List
 
client = genai.Client(api_key=os.environ["YOUR_GEMINI_API_KEY"])
MODEL = "gemini-3-pro"
 
class Issue(BaseModel):
    """レビューが検出した個別の問題"""
    category: str  # 例: "指示違反" / "事実誤認" / "形式崩れ" / "禁止語混入"
    snippet: str   # 問題のある箇所(最大80文字)
    suggestion: str  # どう直すべきか
 
class Review(BaseModel):
    issues: List[Issue]
    needs_revision: bool
 
def generate_first_draft(task: str, constraints: List[str]) -> str:
    """初稿を生成する。"""
    prompt = (
        f"次の要件を満たす本文を書いてください。\n\n要件:\n{task}\n\n"
        f"制約:\n" + "\n".join(f"- {c}" for c in constraints)
    )
    resp = client.models.generate_content(
        model=MODEL,
        contents=prompt,
        config=types.GenerateContentConfig(temperature=0.4),
    )
    return resp.text
 
def review_draft(draft: str, constraints: List[str]) -> Review:
    """初稿をレビューし、構造化された Issue リストを返す。"""
    prompt = (
        "次の本文を、以下の制約に照らしてレビューしてください。\n"
        "本物の問題のみを issues に列挙し、軽微な好みの違いは無視してください。\n"
        "問題が0件なら needs_revision を false にしてください。\n\n"
        f"制約:\n" + "\n".join(f"- {c}" for c in constraints) +
        f"\n\n本文:\n{draft}"
    )
    try:
        resp = client.models.generate_content(
            model=MODEL,
            contents=prompt,
            config=types.GenerateContentConfig(
                temperature=0.0,
                response_mime_type="application/json",
                response_schema=Review,
            ),
        )
        return Review.model_validate_json(resp.text)
    except Exception as e:
        # JSON パース失敗時は「修正不要」として安全側に倒す
        print(f"[review_draft] fallback: {e}")
        return Review(issues=[], needs_revision=False)
 
def revise_draft(draft: str, review: Review) -> str:
    """レビュー結果を踏まえて修正稿を生成する。"""
    issues_text = "\n".join(
        f"- [{i.category}] {i.snippet}{i.suggestion}" for i in review.issues
    )
    prompt = (
        "次の本文の、指摘されている箇所のみを最小限修正してください。\n"
        "指摘されていない箇所は変更しないでください。\n\n"
        f"修正点:\n{issues_text}\n\n元の本文:\n{draft}"
    )
    resp = client.models.generate_content(
        model=MODEL,
        contents=prompt,
        config=types.GenerateContentConfig(temperature=0.2),
    )
    return resp.text
 
def reflect_once(task: str, constraints: List[str]) -> str:
    """1回の Reflection ループを実行して最終本文を返す。"""
    draft = generate_first_draft(task, constraints)
    review = review_draft(draft, constraints)
    if not review.needs_revision:
        return draft
    return revise_draft(draft, review)
 
# 期待出力: 初稿よりも制約をより厳密に守った本文が返る
if __name__ == "__main__":
    final = reflect_once(
        task="新サービスの招待メール本文を200文字以内で書いてください。",
        constraints=[
            "200文字以内に厳密に収める",
            "宛先名は廣川さま とする",
            "競合の Acme Corp という単語を絶対に書かない",
            "敬体で統一する",
        ],
    )
    print(final)

なぜこう書くか: レビューを Pydantic で受け取り、修正ステップに渡す指示を「issues に列挙された問題だけ直してください」と明示的に絞っています。これを「全体的に直してください」と曖昧にすると、修正ステップが本来直す必要のなかった文章まで書き換える「過剰修正」が頻発します。曖昧さを許さない構造化が Reflection の安全装置になります。

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

この記事の続きを読む

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

この記事で得られること
ワンショット推論で品質が頭打ちになっていた人が、Reflection ループと Critic-Refiner の使い分けを今日手に入れられる
Gemini 3 Pro と 2.5 Flash を組み合わせて、品質を上げつつコストを 1.5〜2 倍以内に抑える設計と監視メトリクスを習得できる
自己批判ループの暴走(無限ループ・過剰修正・Critic 偏向)を防ぐガード設計と、本番で効果が落ちた兆候を検知する運用ノウハウを身につけられる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

高度な活用2026-07-11
Gemini の Function Calling に危険度別の承認ゲートを挟む実装
自律エージェントに全権を渡すのは怖い。Gemini の Function Calling ループで、危険度に応じてツール呼び出しを自動実行と承認待ちに振り分け、承認後に結果をモデルへ返す承認ゲートを実装します。
高度な活用2026-06-27
Gemini の完了イベントは二度届きます — Webhook と照合ポーラーを「実質1回」にする冪等な受け口
Gemini の長時間オペレーションを Webhook で受けつつ照合ポーラーで二重化すると、同じ完了イベントが二度届き、公開や課金が二度走ります。冪等キーの取り方と claim→実行→確定の三相で「実質1回」にする受け口を実装します。
高度な活用2026-06-18
長時間エージェント実行を途中から立て直す — Gemini 3.5 Flash の long-horizon タスクをステップ台帳で運用する設計
Gemini 3.5 Flash の long-horizon タスクは便利な一方、途中で落ちると最初からやり直しになりがちです。各ステップを追記専用の台帳に記録し、再開・重複防止・監査を同時に満たす設計を、動くPythonコードと実測値とともにまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →