はじめに
Google Agentspaceは、Googleが提供するSaaS型のAIエージェントサービスです。
サービスが提供するUIを用いてエージェントを利用するのが基本的な使い方かと思いますが、実はAPI経由でAgentspaceを呼び出すことが可能です。
本記事では、主に以下についてお伝えしていきます!
- APIでAgentspaceを呼び出す方法
- ADK(Agent Development Kit)で構築したエージェントにAgentspaceを組み込む方法
Agentspaceの詳細についてはこちら
API呼び出しの概要とメリット
AgentspaceのAPIを利用すると、次のようなメリットがあります。
- 業務アプリに組み込みやすい:既存のワークフローやポータルに組み込み可能
- RAG検索に活用できる:ナレッジベースから検索して回答を生成
- ADKエージェントとの連携:エージェントがAgentspaceをツールとして呼び出し→RAG検索を実行
基本的には、RAG検索として使うのがベーシックな使い方かと思います。
一からRAG検索の仕組みを構築するより、GCPコンソール上でAgentspaceアプリを作成してそれを呼び出す方が簡単かつ速く実装できます。
Agentspace APIの呼び出し方
呼び出し方法は主に2つあります。
- curlコマンドで呼び出し
- discoveryengineを使用して呼び出し(Python)
まず共通して設定するべきは以下の3つ。
-
location
: Agentspaceアプリのリージョン -
project-id
: GCPのプロジェクトID -
engine-id
: AgentspaceアプリのID
1. curlコマンドで呼び出し
① 検索結果の取得のみ
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://discoveryengine.googleapis.com/v1alpha/projects/{project-id}/locations/{location}/collections/default_collection/engines/{engine-id}/servingConfigs/default_search:search" \
-d '{"query":"<QUERY>","pageSize":10,"queryExpansionSpec":{"condition":"AUTO"},"spellCorrectionSpec":{"mode":"AUTO"},"relevanceScoreSpec":{"returnRelevanceScore":true},"languageCode":"ja","contentSearchSpec":{"snippetSpec":{"returnSnippet":true}},"naturalLanguageQueryUnderstandingSpec":{"filterExtractionCondition":"ENABLED"},"userInfo":{"timeZone":"Asia/Tokyo"},"session":"projects/{project-id}/locations/{location}/collections/default_collection/engines/{engine-id}/sessions/-"}'
② 検索結果+回答生成
curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://discoveryengine.googleapis.com/v1alpha/projects/{project-id}/locations/{location}/collections/default_collection/engines/{engine-id}/servingConfigs/default_search:search" \
-d '{"query":"tesuto","pageSize":10,"queryExpansionSpec":{"condition":"AUTO"},"spellCorrectionSpec":{"mode":"AUTO"},"relevanceScoreSpec":{"returnRelevanceScore":true},"languageCode":"ja","contentSearchSpec":{"snippetSpec":{"returnSnippet":true}},"naturalLanguageQueryUnderstandingSpec":{"filterExtractionCondition":"ENABLED"},"userInfo":{"timeZone":"Asia/Tokyo"},"session":"projects/{project-id}/locations/{location}/collections/default_collection/engines/{engine-id}/sessions/-"}'
このcurlコマンドはGCPのコンソール上で、AI Application → Agentspaceアプリ選択 → 統合 → APIから確認することができます。
API呼び出し時の認証方法についてはこちら
2. discoveryengineを使用して呼び出し
pythonで呼び出す方法として、discoveryengine1を利用する方法があります。
今回は以下のコードサンプルを参考にして、検索結果を取得するsearchメソッドを使ってみました。基本的には、ほぼそのまま流用すれば良さそうです。
今回は実施しませんでしたが、回答もあわせて取得する場合のコードサンプルはこちら
パッケージインストール
「google-cloud-discoveryengine」をインストール
$ pip install google-cloud-discoveryengine
プログラム作成
searchメソッドを使用して、2種類のパターンで検索を実行してみます。
- 検索結果のsummaryを表示
- 構造化データを想定して、検索にヒットしたレコードを表示
① 検索結果のsummaryを表示
from typing import List
from google.api_core.client_options import ClientOptions
from google.cloud import discoveryengine_v1 as discoveryengine
# 環境変数の設定
PROJECT_ID = "YOUR_PROJECT_ID"
LOCATION = "YOUR_LOCATION"
ENGINE_ID = "YOUR_APP_ID"
search_query = "YOUR_SEARCH_QUERY"
def search_sample(search_query: str):
client_options = (
ClientOptions(api_endpoint=f"{location}-discoveryengine.googleapis.com")
if location != "global"
else None
)
# クライアントを作成
client = discoveryengine.SearchServiceClient(client_options=client_options)
# 使用するプロジェクトおよびアプリケーションを定義(Agentspace)
serving_config = f"projects/{PROJECT_ID}/locations/{LOCATION}/collections/default_collection/engines/{ENGINE_ID}/servingConfigs/default_config"
# sunippetやsummaryなど検索オプションを設定
content_search_spec = discoveryengine.SearchRequest.ContentSearchSpec(
# スニペット(検索クエリに関連するテキストの抜粋)を含めるように指定
snippet_spec=discoveryengine.SearchRequest.ContentSearchSpec.SnippetSpec(
return_snippet=True
),
# サマリーの設定
summary_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec(
summary_result_count=5,
include_citations=True,
ignore_adversarial_query=True,
ignore_non_summary_seeking_query=True,
model_prompt_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec.ModelPromptSpec(
preamble="YOUR_CUSTOM_PROMPT" # 出力形式などプロンプト設定を追加
),
model_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec.ModelSpec(
version="stable",
),
),
)
# 検索リクエストの詳細を設定
request = discoveryengine.SearchRequest(
serving_config=serving_config,
query=search_query,
page_size=10, # 検索でヒットするドキュメントの数
content_search_spec=content_search_spec,
query_expansion_spec=discoveryengine.SearchRequest.QueryExpansionSpec(
condition=discoveryengine.SearchRequest.QueryExpansionSpec.Condition.AUTO,
), # 自動クエリ拡張
spell_correction_spec=discoveryengine.SearchRequest.SpellCorrectionSpec(
mode=discoveryengine.SearchRequest.SpellCorrectionSpec.Mode.AUTO
),
)
response = client.search(request)
# responseからsummaryを取得
summary = response.summary.summary_text
print(summary)
return response
LOCATION
などの環境変数や検索クエリを設定するのはcurlコマンドと同様です。
# 環境変数の設定
PROJECT_ID = "YOUR_PROJECT_ID" # プロジェクトID
LOCATION = "YOUR_LOCATION" # リージョン
ENGINE_ID = "YOUR_APP_ID" # AgentspaceアプリのID
search_query = "YOUR_SEARCH_QUERY" # 検索クエリ
クライアントの作成、アプリケーション定義は公式のコードサンプルをそのまま活用してしまいましょう。
次にContentSearchSpec
内でSummarySpec
を指定することで検索結果の要約を行ってくれます。
# sunippetやsummaryなど検索オプションを設定
content_search_spec = discoveryengine.SearchRequest.ContentSearchSpec(
# スニペット(検索クエリに関連するテキストの抜粋)を含めるように指定
snippet_spec=discoveryengine.SearchRequest.ContentSearchSpec.SnippetSpec(
return_snippet=True
),
# サマリーの設定
summary_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec(
summary_result_count=5,
include_citations=True,
ignore_adversarial_query=True,
ignore_non_summary_seeking_query=True,
model_prompt_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec.ModelPromptSpec(
preamble="YOUR_CUSTOM_PROMPT" # 出力形式などプロンプト設定を追加
),
model_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec.ModelSpec(
version="stable",
),
),
)
とりあえずコードサンプルに従ってパラメータを設定しましたが、これで基本は十分そうな感じです。
ModelPromptSpec
については例えば、「検索結果をリスト形式で示してください」などと指定するとそれに合わせて出力してくれます。
最後に、SearchRequest
で検索要件を設定します。
# 検索リクエストの詳細を設定
request = discoveryengine.SearchRequest(
serving_config=serving_config,
query=search_query,
page_size=10, # 検索でヒットするドキュメントの数
content_search_spec=content_search_spec,
query_expansion_spec=discoveryengine.SearchRequest.QueryExpansionSpec(
condition=discoveryengine.SearchRequest.QueryExpansionSpec.Condition.AUTO,
), # 自動クエリ拡張
spell_correction_spec=discoveryengine.SearchRequest.SpellCorrectionSpec(
mode=discoveryengine.SearchRequest.SpellCorrectionSpec.Mode.AUTO
),
)
QueryExpansionSpec
に関しては少し注意が必要です。
これは検索クエリに対して自動的に関連語句を追加して検索エンジンの有効性を向上させるものになりますが、Agentspaceに複数データストアが紐づいている場合はこれをAUTO
に設定するとエラーが発生する場合があります。
私自身実装している際にこのエラーにハマってしまったのですが、サポートセンターに問い合わせたところ、「複数のデータストアをご利用の場合には、明示的に設定しなくとも、デフォルトで有効化されている可能性がある」とのことでした。
もし複数データストアでエラーが出た場合は、単純にQueryExpansionSpec
の設定を外せば問題ないかと思います。
② 構造化データを想定して、検索にヒットしたレコードを表示
JSONLファイルなど構造化されたデータをデータストアとして紐づけた場合に、検索結果のsummaryではなく、ヒットしたレコード情報自体を取得したい場合があると思います。
JSONLファイル:1行ごとに独立した有効なJSONオブジェクトが記述されているファイル形式。各行がそれぞれ個別のデータとして扱われる。
その場合は、①をベースに不要なContentSearchSpec
の部分を削除してしまえばOKです。
def search_sample2(search_query: str):
client_options = (
ClientOptions(api_endpoint=f"{LOCATION}-discoveryengine.googleapis.com")
if LOCATION != "global"
else None
)
# クライアントの作成
client = discoveryengine.SearchServiceClient(client_options=client_options)
# 使用するプロジェクトおよびアプリケーションを定義(Agentspace)
serving_config = f"projects/{PROJECT_ID}/locations/{LOCATION}/collections/default_collection/engines/{ENGINE_ID}/servingConfigs/default_config"
# 検索リクエストの詳細を設定
request = discoveryengine.SearchRequest(
serving_config=serving_config,
query=search_query,
page_size=5,
query_expansion_spec=discoveryengine.SearchRequest.QueryExpansionSpec(
condition=discoveryengine.SearchRequest.QueryExpansionSpec.Condition.DISABLED,
),
spell_correction_spec=discoveryengine.SearchRequest.SpellCorrectionSpec(
mode=discoveryengine.SearchRequest.SpellCorrectionSpec.Mode.AUTO
),
)
response = client.search(request)
search_result = []
# 必要最低限のカラムのみを抽出
for result in response.results:
document = result.document
if document and document.struct_data:
struct_data = document.struct_data
# JSON文字列に変換
encoded_item = json.dumps(
{
"key1": struct_data["key1"],
"key2": struct_data["key2"],
"key3": struct_data["key3"],
},
ensure_ascii=False,
)
# JSON文字列をリストに追加
search_result.append(encoded_item)
return search_result
response
の中身を見てもらうとわかるのですが、中身の構造はわりと複雑です。
検索でヒットしたレコードの中で、指定したkeyの情報だけ取得するには以下のような形で記述してあげます。
# 必要最低限のカラムのみを抽出
for result in response.results:
document = result.document
if document and document.struct_data:
struct_data = document.struct_data
key1 = struct_data["key1"] # 取得したいkeyを指定
ADKで構築したエージェントとの連携
エージェントにRAG検索を実行させたい場合があると思います。
そのような場合は、tools
としてRAG検索関数を呼び出してあげればOK。
from google.adk.agents import Agent
def search_sample(query):
"""
discoveryengineを用いてAgentspaceをAPI経由で呼び出し
(詳細省略)
"""
return response
root_agent = Agent(
name="RootAgent",
model="gemini-2.5-pro",
description="""入力内容に回答するRAG検索エージェント""",
instruction="""入力として与えられた内容をqueryとし、tool: search_sampleを呼び出して回答してください""",
tools=[search_sample], # Agentspace呼び出し関数を指定
output_key=None
)
ADKエージェントでRAG検索を行う場合、Vertex AI RAG Engineなど他の機能もありますが、
- 色んなデータソースにデータが存在する
- 簡単にRAG検索を実装したい
- 細かい設定は不要
などであれば、Agentspaceを呼び出す方が良いのではないかと思います。
おわりに
AgentspaceをAPIで呼び出す方法についてまとめてみました。
API呼び出し出来るようになると、さらにAgentspaceの利用範囲が広がっていくと思います!