エージェント型検索を使用して回答をストリーミングする

このページでは、エージェントによる検索について説明し、ストリーミング回答メソッドで使用する方法について説明します。

エージェントによる検索について

stream answers メソッドで使用されるエージェント検索では、特定のユースケースでより良い結果を得ることができます。たとえば、複数のデータストアを持つアプリでマルチパス検索を有効にしたり、さまざまなクラスのクエリに対して回答の生成をカスタマイズしたりできます。

エージェントベースの検索を使用すると、アプリの複雑さが増しますが、その代わりに結果をより細かく制御できます。

エージェント検索には、検索エンジンの動作をカスタマイズするために使用できる事前定義されたエージェントが含まれています。これにより、エージェント取得なしでアプリの構成 UI またはストリーミング回答メソッドで利用できるよりも多くのカスタマイズが可能になります。

エージェントによる検索とエージェントなしの検索を組み合わせた検索

エージェントによる検索は、ブレンド検索アプリで特に役立ちます。エージェントベースの検索がない場合、検索では、すべてのデータストアに一度にクエリを実行するシングルパス ファンアウトが使用されます。一方、エージェント型検索では、マルチパス検索が可能です。エージェントは検索を順番に計画して実行し、各ステップに最適なツールを選択します。複数のエージェント検索データストアの結果を結合し、Google 検索や Google マップなどのツールも使用できます。

たとえば、グローバルな会社ポリシーと地域オフィスの詳細に別々のデータストアがある場合です。ユーザーが「東京オフィスのコンプライアンス ルールは何ですか?」と質問します。

  • エージェントによる取得なし: クエリ文字列全体を使用して、ポリシー ストアと地域オフィス ストアの両方に同時にクエリを実行します。これにより、結果が断片化される可能性があります。

  • エージェントによる検索: エージェントが実行を計画します。まず、リージョン ストアから東京オフィスの詳細を取得します。次に、その特定のコンテキストを使用して、ポリシー ストアで 2 回目のターゲット検索を実行します。

    エージェントはこれらの結果を統合し、一貫性があり、より正確な回答を生成します。

また、エージェントベースの検索では、ブレンド検索アプリでマルチターンの検索クエリ(フォローアップの質問)を実行することもできます。エージェントベースの検索がない場合、複数ターンの検索は単一のデータストア アプリでのみ機能します。複数のターンにわたって会話コンテキストを永続化するには、必要に応じて、エージェントによる検索を Agent Platform セッションとペア設定します。

カスタムクエリの分類

回答メソッドとストリーミング回答メソッドは、ADVERSARIAL_QUERYNON_ANSWER_SEEKING_QUERY の 2 つのクエリ分類タイプを提供します。

エージェントによる検索では、ビジネス ワークフローに合わせて追加の分類タイプを定義できます。システムは分類器を使用してユーザーの意図を判断し、リクエストを適切なエージェント構成に転送します。

たとえば、クエリから、クエリの目的が注文の追跡であると判断し、TRACK_ORDER 分類を指定したとします。システムは、すべてのデータストアに対して一般的な検索を実行するのではなく、配送状況の取得に必要なツールとデータを備えた専用のエージェントを読み込みます。

エージェントによる検索を有効にして使用する方法

エージェントによる検索を有効にする方法は 2 つあります。

  • 事前定義された Google 回答エージェント: エージェント検索に検索アプリがすでに存在する場合は、アプリにクエリを送信するときに API リクエストで enable_agent_invocation=true を設定することで、エージェントによる検索を有効にできます。この場合、既存の検索サービング構成は維持されます。

  • カスタム AI モードアプリ: エージェント検索アプリを作成するときに、別のタイプのサービス構成(default_agent_answer サービス構成)を定義します。エージェント検索では「アプリ」と「エンジン」が同じ意味で使用されるため、カスタム AI モード エンジンと呼ばれることもあります。

始める前に

エージェントによる検索を使用する前に、次の操作を行います。

マルチターンのセッション用に推論エンジンを設定する

複数のターンにわたって会話のコンテキストを保持するには、Gemini Enterprise Agent Platform で Agent Runtime エンジン(推論エンジンとも呼ばれます)を作成する必要があります。

streamAnswer リクエストを行うときは、Agent Runtime のリソース名を streamAnswer リクエストの reasoningEngine フィールドとして渡します。

  1. Google Cloud プロジェクトで Agent Platform を有効にします。

  2. Agent Engine REST API(または Agent Development Kit)を使用して、Agent Runtime インスタンス(推論エンジンとも呼ばれます)を作成します。このインスタンスは、streamAnswer メソッドで使用されるセッションをホストします。

    インスタンス リソース名の形式は次のとおりです。

    projects/PROJECT_NUMBER/locations/LOCATION_ID/reasoningEngines/REASONING_ENGINE_ID
  3. Discovery Engine サービス アカウントに roles/aiplatform.reasoningEngineServiceAgent ロールを付与して、Discovery Engine サービス エージェントに推論エンジンへのアクセス権を付与します。

    service-PROJECT_NUMBER@gcp-sa-discoveryengine.iam.gserviceaccount.com

    ここで、PROJECT_NUMBER は推論エンジンをホストするプロジェクトの番号です。この権限により、ストリーミング回答バックエンドは、ユーザーに代わってセッションのイベントを作成、読み取り、追加できます。

  4. 該当する割り当てを確認します。Agent Runtime によってバックアップされたセッションは、Agent Platform API から割り当てを消費します。対象となる割り当ては次のとおりです。

    • aiplatform.googleapis.com/session_write_requests - 1 分あたりの Agent Runtime セッションの作成、削除、更新回数。

    • aiplatform.googleapis.com/session_event_append_requests - 1 分あたりの Agent Runtime セッションへのイベントの追加回数。

    詳細については、Gemini Enterprise Agent Platform Agent Engine の割り当てをご覧ください。

  5. streamAnswer リクエストの reasoningEngine フィールドとして渡す必要があるため、エージェント ランタイム リソース名をメモします。

省略可: カスタム AI モードアプリを設定する

デフォルトでは、エージェント ベースの検索は事前定義された Google 回答エージェントを使用します。このクラスは、クエリをインテント DEFAULT_ANSWER_SEEKINGDO_NOT_ANSWER に分類します。ツールをカスタマイズしたり、新しいクラスのクエリ インテントのサポートを追加したりする場合は、カスタム AI モードアプリを作成できます。各カスタム インテント(またはフレーム)は、エージェントがクエリをインテントに分類する条件と、エージェントがクエリを処理するために使用する手順とツールを宣言します。

  1. engine_config.answer_agent ブロックを使用して、engines.create REST メソッドでエンジンを作成します。

    構成は次のようになります。

    engine {
     name: "YOUR_AI_MODE_ENGINE"
     display_name: "YOUR_AI_MODE_ENGINE_DISPLAY_NAME"
     engine_config {
       answer_agent {
         frames {
           vertical_intent: "YOUR_CUSTOM_INTENT"
           vertical_intent_prompt {
             instructions: "Instructions for when to classify a user query as YOUR_CUSTOM_INTENT."
           }
           initial_prompt {
             instructions: "Instructions for the agent on how to process a user query classified as YOUR_CUSTOM_INTENT."
             tools {
               discovery_engine_search_tool_config {
                 serving_config: "YOUR_SEARCH_SERVING_CONFIG_1"
                 page_size: 10
               }
               tool_description: "This tool can help search corpus 1."
             }
             tools {
               discovery_engine_search_tool_config {
                 serving_config: "YOUR_SEARCH_SERVING_CONFIG_2"
                 page_size: 10
               }
               tool_description: "This tool can help search corpus 2."
             }
           }
         }
       }
     }
    }
    engine_id: "SAMPLE_MULTI_SEARCH_RETRIEVAL"
  2. エンジンを作成したら、その default_agent_answer サービング構成を介してリクエストをルーティングします。

    projects/*/locations/*/collections/*/engines/YOUR_AI_MODE_ENGINE/servingConfigs/default_agent_answer
  3. カスタム AI モードアプリの設計や登録についてサポートが必要な場合は、サポートにお問い合わせください。

エージェント検索を使用して回答をストリーミングする

次のコマンドは、エージェントによる検索を有効にしてストリーミング回答メソッドを呼び出す方法を示しています。エージェントによる検索なしの出力と同様に、この呼び出しは生成された回答を一連の JSON レスポンスの形式でストリーミングします。

推論エンジンを設定している場合は、そのリソース名を reasoningEngine フィールドに含めて、ターン間でセッションを永続化します。

REST

検索を行い、生成された回答をストリーミングで取得する方法を以下に示します。

  1. 次の curl コマンドを実行します。

    curl -X POST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json" \
      "https://discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/global/collections/default_collection/engines/APP_ID/servingConfigs/SERVING_CONFIG_ID:streamAnswer" \
      -d '{
            "query": { "text": "QUERY" },
            "session": "SESSION",
            "enableAgentInvocation": true,
            "userPseudoId": "USER_PSEUDO_ID",
            "reasoningEngine": "projects/PROJECT_NUMBER/locations/LOCATION_ID/reasoningEngines/REASONING_ENGINE_ID"
          }'
    

    次のように置き換えます。

    • PROJECT_ID: 実際の Google Cloud プロジェクト ID。
    • APP_ID: クエリする Agent Search アプリの ID。
    • SERVING_CONFIG_ID: カスタム AI モードアプリを使用するには、これを default_agent_answer に設定します。事前定義された Google 回答エージェントを使用するには、これを default_search に設定します。
    • PROJECT_NUMBER: 推論エンジンをホストするプロジェクトの番号。
    • QUERY: 質問または検索クエリを含むフリーテキストの文字列。
    • SESSION: 複数ターンの会話を継続する場合、これは前のターンのレスポンスで返されたセッション リソース名です(例: projects/PROJECT_ID/locations/global/collections/default_collection/engines/APP_ID/sessions/SESSION_ID)。会話を継続しない場合は、ハイフン(-)に設定します。
    • USER_PSEUDO_ID: 訪問者のトラッキングに使用される一意の識別子。
    • LOCATION_ID: 推論エンジンのロケーション。例: us-central1
    • REASONING_ENGINE_ID: 作成した Agent Engine インスタンスの ID。

Python

詳細については、Agent Search Python API リファレンス ドキュメントをご覧ください。

Agent Search に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、ローカル開発環境の認証の設定をご覧ください。

次のサンプルでは、Discovery Engine Python クライアントv1alpha)を使用して、エージェント呼び出しが有効になっている stream_answer_query を呼び出します。マルチターンのセッションの reasoning_engine フィールドを渡します。

from google.api_core.client_options import ClientOptions
from google.cloud import discoveryengine_v1alpha


def run_stream_answer_query():
    PROJECT_ID = "YOUR_PROJECT_ID"
    LOCATION = "global"  # or a specific region
    COLLECTION_ID = "default_collection"
    ENGINE_ID = "YOUR_ENGINE_ID"
    # Use "default_search" for the predefined Google answer agent, or
    # "default_agent_answer" if you have configured a custom AI_MODE app.
    SERVING_CONFIG_ID = "default_search"
    USER_ID = "user-id"
    QUERY_TEXT = "YOUR_QUERY_TEXT"
    REASONING_ENGINE_ID = "YOUR_REASONING_ENGINE_ID"
    # Use "-" to start a new session, or pass the sessionId returned in
    # the previous turn's response to continue an existing session.
    SESSION_ID = "-"

    SESSION_REF = (
        f"projects/{PROJECT_ID}/locations/{LOCATION}/collections/"
        f"{COLLECTION_ID}/engines/{ENGINE_ID}/sessions/{SESSION_ID}"
    )
    SERVING_CONFIG_ENGINE = (
        f"projects/{PROJECT_ID}/locations/{LOCATION}/collections/"
        f"{COLLECTION_ID}/engines/{ENGINE_ID}/servingConfigs/{SERVING_CONFIG_ID}"
    )
    REASONING_ENGINE = (
        f"projects/{PROJECT_ID}/locations/{LOCATION}/"
        f"reasoningEngines/{REASONING_ENGINE_ID}"
    )

    client_options = ClientOptions(
        api_endpoint="discoveryengine.googleapis.com"
    )

    client = discoveryengine_v1alpha.ConversationalSearchServiceClient(
        client_options=client_options
    )

    request = discoveryengine_v1alpha.AnswerQueryRequest(
        query=discoveryengine_v1alpha.Query(text=QUERY_TEXT),
        serving_config=SERVING_CONFIG_ENGINE,
        user_pseudo_id=USER_ID,
        enable_agent_invocation=True,
        session=SESSION_REF,
        reasoning_engine=REASONING_ENGINE,
    )

    print(f"Starting StreamAnswerQuery agentic session with: {request}")
    stream = client.stream_answer_query(request)

    try:
        for response in stream:
            print(f"Received response: {response}")
    except Exception as e:
        print(f"Error during streaming: {e}")


if __name__ == "__main__":
    run_stream_answer_query()

Discovery Engine SDK のプレビュー版を入手する

Discovery Engine SDK を使用すると、アプリケーションから Google Cloudサービスを簡単に操作できます。SDK は、エラー処理と認証を支援し、自動再試行、ページネーション処理、長時間実行オペレーションの管理などの機能を提供します。

エージェントによる検索機能は許可リストに登録されているため、この機能を使用するために必要な SDK は、一般提供されている Discovery Engine クライアント ライブラリとは異なります。

Discovery Engine SDK のプレビュー版を取得するには、次の操作を行います。

  1. プレビュー版 SDK の Google ドライブ フォルダにアクセスするには、サポートにお問い合わせください。

  2. 言語のパッケージをダウンロードします。

API の変更点

この機能は許可リストに登録されているため、ストリーミング回答メソッドのページにある API リファレンス ドキュメントには、ストリーム回答メソッドでエージェントによる検索を使用するために必要なすべてのフィールドが表示されません。欠落しているフィールドは次のように文書化されています。

リクエスト本文のフィールド

  • enableAgentInvocation(ブール値)- true を設定して、既存の検索サービング構成でエージェント処理に切り替えます。カスタム AI モードアプリで answer_agent サービング構成を指定する場合は、このフィールドは省略可能です。

  • reasoningEngine(文字列)- エージェント セッションをホストする Agent Runtime のリソース名(projects/*/locations/*/reasoningEngines/* 形式)。

レスポンスのフィールド

エージェントによる取得が有効になっている場合、生成された各 Answer.Reference には次のものが含まれます。

  • queries(繰り返し文字列) - エージェントがリファレンスを生成するために発行したクエリのリスト。

セッション サービス

セッション サービス REST API は、create メソッドまたは update メソッドをサポートしていません。ただし、listgetdelete などの他のメソッドはサポートしています。

セッション サービス RPC API は、マルチターンの会話に使用されるセッション リソースに対する Update オペレーションまたは Create オペレーションをサポートしていません。ただし、マルチターンの会話に使用されるセッション リソースに対する ListGetDelete オペレーションなど、他のサービスはサポートしています。