こんにちは!
KDDIアイレットの取り組みとして、6月22日〜7月3日の期間で開催中の「Google Cloud Next '26 / Google I/O やってみた系ブログリレー」、本日は4日目の投稿です。 「Gemini APIで最新情報を取得するGrounding」を対象に、検索あり・なしで回答がどう変わるかを実際に検証してみた様子をお届けします!
同じモデル(Flash)で【検索あり・なし】を比べてみたところ、回答の鮮度にはっきり差が出ました。
料金面の注意点や、URL Contextとの使い分けもまとめています!
前回の記事はこちらです。
ざっくりまとめ
- LLMは、検索などの外部情報を使わない限り、学習時点以降の情報を保証できません。Gemini APIの Grounding(グラウンディング) を使うと、Google検索の結果をもとに、参照元つきで最新情報を答えてくれます。
- 同じモデル(gemini-3.5-flash)で比較したところ、Groundingなしは学習時点の情報、Groundingありは検索結果に基づく最新情報を返しました。
- 参照元の取り出し方には地味なクセがあって、
grounding_chunksが空でもsearch_entry_pointの方に情報が入っていることがあります。ここは結構ハマりどころだと思います。 - さらに、指定したURLを読ませる URL Context と組み合わせると、「広く検索する」と「このページを読む」を使い分けられます。
はじめに
ChatGPTやGeminiに「最新の〇〇は?」と聞いて、古い情報や“それっぽい嘘”が返ってきた経験、ありませんか。これはLLMが「学習した時点の知識」しか持っていないためで、仕組み上どうしても起きてしまう弱点です。
これを補ってくれるのが Grounding(グラウンディング) です。ざっくり言うと、LLMにGoogle検索をさせて、その結果をもとに答えさせる仕組みですね。回答には参照元(どのページを根拠にしたか)も付いてきます。
正確には、ブラウザを開いて検索しているわけではなく、内部の「Google Searchツール」を使って検索結果を取得し、それを踏まえて回答を生成しています。この記事では分かりやすさ優先で「Google検索」と表記しますが、仕組みとしてはツール利用です。
この記事では、Gemini APIのGroundingをPythonで実際に動かして、「使うと回答がどう変わるのか」を見ていきます。あわせて、指定したURLの中身を読ませる URL Context との違いも試してみました。
Gemini APIの環境準備(インストールとAPIキー設定)
今回は手軽に試せる Google AI Studio のAPIキー方式でいきます。
1. パッケージのインストール
pip install google-genai
2. APIキーの取得と設定
Google AI Studio でAPIキーを発行して、環境変数にセットします。
export GEMINI_API_KEY="取得したAPIキー"
本来、本番環境ではSecret Managerなどのシークレット管理サービスを使うのが望ましいですが、今回はそこが本題ではないので、シンプルに環境変数で進めます。いずれにせよ、APIキーをコードに直書きするのは避けてください(記事やGitHubにうっかり載せる事故を防げます)。
まずはGemini APIに接続してみる
最小コードで疎通確認します。せっかくなので、今回は執筆時点での最新世代であるgemini-3.5-flash の実力も兼ねて試します。
from google import genai
client = genai.Client() # 環境変数 GEMINI_API_KEY を自動で読む
response = client.models.generate_content(
model="gemini-3.5-flash",
contents="こんにちは。接続テストです。一言返してください。",
)
print(response.text)
こんにちは! のような返事が出れば成功です。
Gemini APIで、Groundingあり・なしを比較する
ここが本題です。同じモデル・同じ質問で、Groundingの有無だけを変えて比較します。条件を揃えないと「差がモデルのせいなのかGroundingのせいなのか」が分からなくなるので、ここは重要なポイントです。
from google import genai
from google.genai import types
client = genai.Client()
MODEL = "gemini-3.5-flash"
question = "Node.jsの最新のLTSバージョンはいくつですか?バージョン番号だけ簡潔に答えてください。"
# --- Groundingなし ---
res_off = client.models.generate_content(
model=MODEL,
contents=question,
)
# --- Groundingあり(google_search ツールを有効化)---
res_on = client.models.generate_content(
model=MODEL,
contents=question,
config=types.GenerateContentConfig(
tools=[types.Tool(google_search=types.GoogleSearch())]
),
)
print("=== Groundingなし ===")
print(res_off.text)
print("\n=== Groundingあり ===")
print(res_on.text)
結果
| 回答 | |
|---|---|
| Groundingなし |
v22.13.1(学習時点の古い情報) |
| Groundingあり |
v24.17.0(検証時点の最新LTS) |
※ いずれも検証時点の結果です。現在の最新バージョンとは異なる可能性があります。
同じ gemini-3.5-flash なのに、なし側は学習時点の知識に基づくLTSバージョンを返し、あり側は検索結果をもとに最新のLTSバージョンを返しました。興味深かったのは、検索なしでも回答を拒否するわけではなく、それらしい回答が返ってくる点です。最新情報を扱う場合は、この違いがそのまま回答品質の差につながると感じました。
注意点として、なし側が必ず v22.13.1 を返すわけではありません。モデルや実行時期によって結果は変わります。今回の結果は、あくまで検証時点での一例です。
Google Search Groundingの参照元を取得する
Groundingの大きな利点は「どこを根拠に答えたか」が分かることです。ただ、ここに少しクセがありました。
最初、短い質問(バージョン番号だけ聞く)では grounding_chunks が空で返ってきて戸惑いました。中身を確認すると、参照情報は search_entry_point(Google検索への導線情報)の方に入っていました。
そこで質問を「最新バージョンとその特徴を教えて」と少し説明を要する形に変えたところ、今度は grounding_chunks に参照元がしっかり入りました。
question = "2026年現在、Node.jsの最新のLTSバージョンと、その主な特徴を教えてください。"
res = client.models.generate_content(
model="gemini-3.5-flash",
contents=question,
config=types.GenerateContentConfig(
tools=[types.Tool(google_search=types.GoogleSearch())]
),
)
meta = res.candidates[0].grounding_metadata
# 実際に投げられた検索クエリ
print(meta.web_search_queries)
# 参照元(grounding_chunks があれば)
if meta.grounding_chunks:
for i, chunk in enumerate(meta.grounding_chunks, 1):
if chunk.web:
print(f"{i}. {chunk.web.title} - {chunk.web.uri}")
結果
実際に投げられた検索クエリ:
['Node.js 24 features', 'Node js latest LTS version 2026',
'Node.js 24 new features', 'Node js release schedule', 'Node.js v24 features']
参照元として nodejs.org nodesource.com logrocket.com など13件が取得できました。回答本文も、V8エンジンの更新やExplicit Resource Managementなどの新機能に加えて、「2026年6月に発表されたNode.jsのリリーススケジュール変更」という直近のニュースまで拾っていました。検索なしの素のモデルだと、こういう直近の情報は答えられません。
ハマりどころ:参照元は2つの形がある
ここが意外とハマったポイントでした。
-
grounding_chunks:回答の根拠になった個別サイトのリスト。URLやタイトルが取得できる。 -
search_entry_point:Google検索への導線情報(HTML)。grounding_chunksが空のときは、こちらに情報が入っていることがある。
今回試した範囲では、短い質問だと grounding_chunks が空で search_entry_point だけが返り、少し説明を要する質問だと grounding_chunks が返ってきました。ただ、今回確認した範囲では、どの条件でこうなるのかは明確には分かりませんでした。
なので実装するときは、grounding_chunks だけを見て「参照元が取れなかった」と判断せず、search_entry_point も合わせて確認しておくと安心です。私は最初 grounding_chunks だけ見ていたので、「参照元が返ってこないな……」と少しハマりました。
URL Contextと組み合わせる
Groundingが「広くGoogle検索する」のに対し、URL Context は「こちらが指定したURLの中身を読んで答える」機能です。役割が違うので、使い分けると便利です。
from google import genai
from google.genai import types
client = genai.Client()
url = "https://nodejs.org/en/blog"
question = f"{url} のページを読んで、最近のNode.js関連の発表を3つ、日本語で簡潔に教えてください。"
res = client.models.generate_content(
model="gemini-3.5-flash",
contents=question,
config=types.GenerateContentConfig(
tools=[types.Tool(url_context=types.UrlContext())]
),
)
print(res.text)
# どのURLを取得したか確認
print(res.candidates[0].url_context_metadata)
結果
指定したNode.js公式ブログを実際に読み込み、2026年6月18日付の発表(セキュリティリリース、Node.js 26.3.1 Currentのリリース、LTS版v24.17.0 / v22.23.0のアップデート)を正確に拾ってきました。
url_context_metadata には取得したURLとステータスが入ります:
url_metadata=[UrlMetadata(
retrieved_url='https://nodejs.org/en/blog',
url_retrieval_status=URL_RETRIEVAL_STATUS_SUCCESS
)]
URL_RETRIEVAL_STATUS_SUCCESS で、ちゃんと取得できたことが確認できます。
使い分けの整理
| Grounding (Google Search) | URL Context | |
|---|---|---|
| やること | 広くGoogle検索する | 指定したURLを読む |
| 向いている用途 | 「最新の〇〇は?」など探索的な質問 | 「このページを要約して」など対象が明確な質問 |
| メタデータ | grounding_metadata |
url_context_metadata |
ちなみに、GroundingとURL Contextは同時に有効化することもできます。
料金とモデルの選び方
Groundingは無料ではないので、本番で使う前に料金を押さえておきましょう(以下は2026年6月時点、Google公式の料金ページより)。
Grounding(Google Search)の料金
-
Gemini 3.x系(今回の
gemini-3.5-flash含む):月5,000プロンプトまで無料(Gemini 3ファミリー全体で共有)。超過後は 1,000検索クエリあたり $14。 - Gemini 2.5系(Pro / Flash / Flash-Lite):1,500 RPD(1日あたりリクエスト数)まで無料。超過後は 1,000グラウンディングプロンプトあたり $35。
ここでひとつ注意点があります。無料枠は「プロンプト(リクエスト)」単位でカウントされますが、課金は「検索クエリ」単位です。公式ドキュメントにも「1つのリクエストが複数のGoogle検索クエリを生むことがあり、実行された各検索クエリごとに課金される」と明記されています。実際、今回の検証でも1つの質問で複数の検索クエリが実行されていました。
トークン単価との「ねじれ」に注意
ここが意外と見落としがちなのですが、Grounding単価が安いモデルが、トークン単価でも安いとは限りません。今回検証した2モデルを並べると、こうなります。
| モデル | グラウンディング単価 | 入力(/1M) | 出力(/1M) |
|---|---|---|---|
gemini-3.5-flash |
$14 / 1,000クエリ | $1.50 | $9.00 |
gemini-2.5-flash-lite |
$35 / 1,000プロンプト | $0.10 | $0.40 |
グラウンディング単価は、3.x系(検索クエリ単位)と2.5系(プロンプト単位)で課金単位が違うため、単純な比較はできませんが、目安として並べています。
注目したいのはトークン単価で、出力で見ると20倍以上の差があります。つまり、入出力のトークン量が多いタスクでは、トークン単価が圧倒的に安いFlash-Liteのほうが総額で安くなりやすいです。Grounding単価だけ見て3.5 Flashを選ぶと、トークン単価の差に足をすくわれることがあるので、両方を見て判断するのがおすすめです。
Flash-Liteでもグラウンディングは動くのか
気になったので、gemini-2.5-flash-lite でも同じGroundingを試してみました。結論、Flash-Liteでもグラウンディングは問題なく動作しました。最新のNode.jsバージョンも正しく取得でき、参照元も取れました。
今回試した範囲では、3.5 Flashのほうが参照元の数や回答の情報量がやや多いケースもありましたが、検証回数が少ないので「傾向」と言い切れるほどではありません。少なくとも、Flash-Liteでも十分実用的に動く、とは言えそうです。最新情報を参照元つきで丁寧に取得したいなら3.5 Flash、コストを抑えて大量に処理したいならFlash-Lite、という使い分けが現実的だと思います。
なお、今回くらいの検証(数十回)なら、どちらも無料枠の中で十分収まります。
料金やモデルの仕様は頻繁に変わります。この記事の数字は2026年6月時点のものなので、実際に使う前に必ず公式の料金ページで最新を確認してください。
Gemini Groundingの注意点・ハマりどころまとめ
実際に触ってみて気づいた点・注意点をまとめます。
古いコードは動かない
- Web上の記事やサンプルコードで見かける
google_search_retrievalは現行モデルでは利用できず、google_searchを使う必要があります。
400 INVALID_ARGUMENT. google_search_retrieval is not supported;
please use google_search field instead.
エラーメッセージにある通り、現行は google_search ツールを使います。記事やサンプルコードをそのままコピペすると、ここでつまずきます。
参照元取得時は grounding_chunks だけでなく search_entry_point も確認する
- 今回の検証では、短い質問では
grounding_chunksが空で、代わりにsearch_entry_pointのみ返るケースがありました。
URL Contextは取得できないページがある
- robots.txt や安全性判定の影響で、URLを指定しても取得できない場合があります。
おわりに
実際に試してみて印象的だったのは、同じモデルでもGroundingの有無で回答の鮮度が大きく変わったことでした。最新情報を扱う用途では、Groundingを有効化するだけで得られるメリットはかなり大きいと感じます。
GroundingとURL Contextは、ざっくり「調べ物はGrounding(広くGoogle検索)、参照先が決まっているならURL Context(そのページを読む)」と使い分けられます。両方知っておくと、最新情報を扱うアプリの作り方の幅がかなり広がると思います。
今回はAI StudioのAPIキーで試しましたが、google-genai SDKはGoogle AI StudioとVertex AIの両方に対応しています。Vertex AIについてはまだ試せていないため、機会があれば別の記事で検証してみたいと思います。
ここまで読んでいただきありがとうございました。この記事が、Gemini APIで最新情報を扱いたい方の参考になれば嬉しいです。