5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Gemini APIのGoogleマップ・グラウンディングを検証!あり・なしで回答を比べてみた

5
Posted at

こんにちは!
KDDIアイレットの取り組みとして、6月22日〜7月3日の期間で開催中の「Google Cloud Next '26 / Google I/O やってみた系ブログリレー」、本日は8日目の投稿です。
「Gemini API の Google マップによるグラウンディング(Grounding with Google Maps)」を対象に、マップ参照あり・なしで回答がどう変わるかを実際に検証してみた様子をお届けします!

同じモデル(Flash)で【マップあり・なし】を比べてみたところ、口コミ評価やレビュー件数の回答の安定性にはっきり差が出ました。grounding_chunks での参照確認や、存在しない場所を聞いたときの挙動もまとめています!

前回までの記事はこちらです。

Google Cloud Next '26 で、Gemini 3 系でも Google マップによるグラウンディングが使えるようになりました。以前「Gemini APIで最新情報を取得する方法|Groundingあり・なしをPythonで比較してみた」で Google検索 によるグラウンディングを試したので、今回はその Google マップ版 です。最初は「近くの観光スポットを教えてくれるだけかな」と軽く考えていたのですが、口コミ評価やレビュー件数を聞いてみたら、ちょっと意外な挙動がありました。その様子をそのままお届けします。

マップ・グラウンディングとは

LLM(大規模言語モデル)は、学習した時点までの知識をもとに回答します。そのため、学習データに無い情報や、刻々と変わる情報(お店の今の営業時間、最新のレビュー件数など)は苦手で、それらしい答えをでっち上げてしまうことがあります(いわゆるハルシネーション)。

これを補うのが「グラウンディング(grounding)」です。回答を生成する前に外部の情報源を参照させて、その結果を踏まえて答えさせる仕組みで、「思いつきで答える」のではなく「裏取りしてから答える」イメージに近いです。

今回の Google マップによるグラウンディング(Grounding with Google Maps) は、情報源が Google Maps の場所データ(評価・レビュー件数・営業時間・経路など) になります。つまり「お店や場所に関する質問を、実際の Google Maps を参照して答えてもらう」機能です。

マップ・グラウンディング自体は2025年から提供されていますが、Next '26 で最新世代の Gemini 3 系に対応し、ルート機能なども強化されました。

では、さっそく動かしてみます。

環境準備(インストールとAPIキー設定)

前回と同様、手軽に試せる Google AI Studio のAPIキー方式でいきます。

pip install google-genai

Google AI Studio でAPIキーを発行して、環境変数にセットします。

export GEMINI_API_KEY="取得したAPIキー"

APIキーをコードに直書きするのは避けてください(記事やGitHubにうっかり載せる事故を防げます)。

まず動かしてみる

やることは、toolsgoogle_maps ツールを渡すだけです。前回の google_searchgoogle_maps に変わっただけ、という感覚ですね。

from google import genai
from google.genai import types

client = genai.Client()  # 環境変数 GEMINI_API_KEY を自動で読む

res = client.models.generate_content(
    model="gemini-3.5-flash",
    contents="天王寺駅の近くで、無料で楽しめる観光スポットを教えて",
    config=types.GenerateContentConfig(
        tools=[types.Tool(google_maps=types.GoogleMaps())]  # ★ これだけ
    ),
)
print(res.text)

実行すると、天王寺公園や四天王寺など、それらしいスポットがルート付きで返ってきました。普通に使えます。……が、これだけだと「マップを使わない普通のGeminiと何が違うの?」が正直わかりません。

面白そうなお題を考えてみる

そこで、ふと思いました。

「口コミ評価」や「レビュー件数」って、LLMはちゃんと答えられるんだろうか?

評価点や件数は、実際のGoogle Mapsを見ないと正確にはわからないはずの情報です。マップ連携なしのGeminiに聞いたら、何を答えるんでしょう。お題はこうしました。

大阪の天王寺駅周辺で、入場無料で楽しめる観光スポットを、
Google マップの口コミ評価が高い順に3つ選んでください。
それぞれの評価点(★)とレビュー件数を必ず明記してください。

これを、マップ連携なしありで比べてみます。

まずは「なし」で聞いてみる

普通のGemini(ツールなし)に聞くと、ちゃんと答えが返ってきました。

1. 一心寺   ★4.3(レビュー 約1,650件)
2. 堀越神社 ★4.3(レビュー 約1,150件)
3. 四天王寺 ★4.2(レビュー 約6,250件)

★の数も件数も入っていて、一見それっぽいです。「お、ちゃんと答えてくれるじゃん」と思いました。

……が、本当にこの数字、合っているんでしょうか。気になったので、同じ質問をもう一度投げてみました。

1. 一心寺   ★4.4(レビュー 1,940件)   ← さっきは★4.3 / 1,650件
2. 四天王寺 ★4.3(レビュー 7,430件)   ← さっきは★4.2 / 6,250件
3. 堀越神社 ★4.3(レビュー 1,100件)

数字が変わりました。 一心寺は1,650件→1,940件、四天王寺は6,250件→7,430件。星の数まで違います(★4.3→★4.4)。順位も入れ替わっています。

事実としてここで言えるのは、マップ連携なしでは、レビュー件数が実行ごとに変動したということです。実際のGoogle Mapsの値を参照しているわけではなく、その場で推定された値が返ってきている、と考えるのが自然そうです(モデル内部で実際に何が起きているかまでは、この検証だけでは断定できません)。

では「あり」で聞いてみる

同じ質問を、今度はマップ・グラウンディングありで投げます。

res = client.models.generate_content(
    model="gemini-3.5-flash",
    contents=prompt,
    config=types.GenerateContentConfig(
        tools=[types.Tool(google_maps=types.GoogleMaps())]
    ),
)

結果がこちらです。

1. 四天王寺 ★4.3(レビュー 12,894件)
2. 堀越神社 ★4.3(レビュー 1,703件)
3. 一心寺   ★4.2(レビュー 7,534件)

そして、もう一度実行しても四天王寺は12,894件のままでした。なし側があれだけブレていたのに、あり側はブレずに同じ値を返しています。

数字を並べてみると、差は一目瞭然でした。

スポット なし(1回目) なし(2回目) あり(マップ連携)
四天王寺 約6,250件 7,430件 12,894件(2回とも一致)
一心寺 ★4.3 / 約1,650件 ★4.4 / 1,940件 ★4.2 / 7,534件
堀越神社 ★4.3 / 約1,150件 ★4.3 / 1,100件 ★4.3 / 1,703件

※レビュー件数・評価点は変動します。本記事の数値はすべて検証時点(2026年6月)のものです。あり側の値が実際の Google Maps と一致しているかは、気になる方はご自身の Google Maps でも確認してみてください。

※本記事に登場する「あり(マップ連携)」側の評価・レビュー件数は、Grounding with Google Maps(Google マップによるグラウンディング)が Google Maps を参照して生成した回答です。

違いを一言でまとめると、こうなります。

比較 マップなし マップあり
レビュー件数 実行ごとに変わる 安定していた
grounding_chunks 0件 6件
回答の根拠 モデルの知識(推定) Google Maps を参照した回答

なし側の四天王寺は実行ごとに6,250〜7,430件とブレていましたが、あり側は2回とも12,894件で安定していました。なし側が出していた件数は、マップ参照時の値(あり側)と比べてかなり小さく、毎回違う数字でした。一見もっともらしい数字なので、言われないと気づけないのが地味に怖いところです。

ちなみに「評価が高い順」の並びも、なしとありで変わっています。なしは一心寺が1位、あり(マップ参照)では四天王寺が1位でした。ただ、星の数を見ると ★4.3 / ★4.3 / ★4.2 と同率が含まれており、モデルが同率をどう並べたか(件数で並べたのか等)まではこの出力からは断定できません。とはいえ、裏付けデータがあるかないかで、並び順が変わってしまうのは確かでした。

ついでに:存在しない場所を聞いてみる

「実在するが正確な数字を知らない」ものには、実行ごとに異なる値を返していました。では、そもそも実在しないスポットを聞いたらどうなるんでしょう。架空の名前を3つでっち上げて、なし・ありの両方で聞いてみました。

「大阪天王寺スカイドリームタワー」「大阪難波クリスタルパレス」「梅田エメラルドホール展望台」
……いずれも実在しない架空の名前です。

結果、3件すべてで、なし・あり両方とも「実在しない(登録がない)」と判定しました。

  • なし:「その名称のスポットは実在しない可能性が高い」と答え、評価や件数を作り出すことはありませんでした。代わりに、あべのハルカスや通天閣など、混同しそうな実在スポットを候補として挙げてきました。
  • あり:「Googleマップに登録がありません」と明言したうえで、名前が似ている実在スポットを評価・件数つきで提示してきました。

面白いのは、さっきは件数が実行ごとにブレていたなしが、"そもそも存在しない場所"に対しては数字を作らず踏みとどまった点です。「実在するが正確な数字を知らない」ものには推定値らしき数字を返し、「そもそも存在しない」ものは"無い"と答える、という温度差が見えました。

ただし、あり側が「混同候補」として挙げてきた実在スポットの評価・件数まで正確かどうかは、別問題です。実際、ある施設で「全体」と「展望台」で異なる件数が併記されるなど、あり側の数字も鵜呑みは禁物でした。マップを参照している(後述の grounding_chunks で確認できます)からといって、出てきた数字を無検証で信じてよいわけではなさそうです。

本当にMapsを見ているのか確認する

「あり側は数字が安定している」だけだと、たまたまかもしれません。実際にマップを参照したのかは、grounding_chunks で確認できます。

meta = res.candidates[0].grounding_metadata
if meta and meta.grounding_chunks:
    for c in meta.grounding_chunks:
        src = getattr(c, "maps", None) or getattr(c, "web", None)
        print(getattr(src, "title", None))

出力:

grounding_chunks = 6件
   - Shitennō-ji        https://maps.google.com/?cid=13162475560152948781
   - Horikoshi Jinja    https://maps.google.com/?cid=4492362297677695588
   - Isshin-ji Temple   https://maps.google.com/?cid=16774037374278318765
   - Tenshiba           https://maps.google.com/?cid=11455506768927424342
   - Turtle Pond        https://maps.google.com/?cid=7701688995967999181
   - Shitennoji         https://maps.google.com/?cid=12809558917620922089

回答に出てきたスポットが、参照元として grounding_chunks に含まれていました。名前だけでなく Google Maps への URL(cid 付きのリンク) も一緒に返ってきており、これが API の返すソース情報です。Google Maps が参照されたことを確認できます。なし側では、ここは常に0件です。マップを参照したかどうかを判定する材料として、この grounding_chunks は便利でした。

ハマりどころ:マップは毎回呼ばれるわけではない

触っていて一番意外だったのがここです。google_maps ツールを付けても、毎回マップが呼ばれるとは限りません。同じようにツールを付けていても、grounding_chunks が0件(=マップを使わず記憶だけで回答)になることが何度もありました。

今回試した範囲では、ざっくりこんな傾向がありました(少数回の体感ベースです)。

聞いたこと マップが呼ばれるか
口コミ評価・レビュー件数 呼ばれやすい
営業時間 呼ばれやすい
有名観光地のおすすめルート 呼ばれたり呼ばれなかったり
「大阪城ってどんな所?」 ほぼ呼ばれない(記憶で答える)

※体感ベースの傾向で、回数も多くないため厳密なものではありません。

モデルが「これは記憶で答えられる」と判断すると、ツールを付けていてもマップを使わないようです。評価・件数・営業時間のように、マップのデータ参照が期待される情報を明示的に求めると呼ばれやすくなる印象でした。実装するときは、ツールを付けたから安心ではなく、grounding_chunks が実際に返っているかを確認しておくと安全です。

結果を表示するときの注意(アプリに組み込む場合)

Grounding with Google Maps の結果をユーザー向けアプリに表示する場合は、Google Maps を根拠としたことが分かるように、API が返すソース情報(名称・URL)を回答の近くに併記することが求められています。

ここで効いてくるのが、さきほどの grounding_chunks です。マップを参照したか確認できるだけでなく、各ソースの名称と URL も入っているので、この情報を利用して帰属表示できます。表記やリンクの細かいガイドラインもあるので、組み込む際は公式ドキュメントを確認してください。

今回わかったこと

  • google_maps ツールを付けても、毎回マップが呼ばれるとは限らない。「評価」「営業時間」などマップ必須の情報を明示的に求めると呼ばれやすい。
  • レビュー件数のような情報は、マップ連携なしだと実行ごとに変動した。あり(マップ参照)の方が値は安定していた。
  • grounding_chunks を見れば、Google Maps が参照されたかを判定できる。0件なら参照なし(記憶のみ)。
  • ただしあり側の数字も完璧ではない。参照しているからといって無検証で信じない方がよさそう。

おわりに

「近くのスポットを教えてくれるだけかな」と思って触り始めたのですが、マップ連携なしのGeminiが、レビュー件数を実行ごとに違う数字で返していたのは、ちょっとした発見でした。もっともらしい数字が返ってくるぶん、「最新情報が古い」よりも誤りに気づきにくいと感じました。場所や評価を扱うなら、マップ・グラウンディングは入れる価値があると感じました(そのうえで、出てきた数字を鵜呑みにしない姿勢も大事そうです)。

前回の検索グラウンディングと合わせると、「調べ物は検索、場所はマップ」と使い分けられます。場所・評価・営業時間あたりを扱うアプリを作るときは、選択肢に入れてみてください。

ここまで読んでいただきありがとうございました。

※記載の施設名は各施設の名称であり、本記事はそれらの施設を推奨・批判するものではありません。評価・件数はすべて検証時点(2026年6月)のものです。

参考リンク

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?