將 QueryData 整合至應用程式

本教學課程說明如何使用 Google Cloud 控制台,在 Spanner 中設定及使用 QueryData,並將其與應用程式整合。瞭解如何建構脈絡資料集檔案、建立使用該檔案的脈絡資料集、透過 MCP Toolbox 呼叫 Conversational Analytics API 的 QueryData 方法,為自然語言問題生成 SQL 查詢,並將其整合至應用程式。

詳情請參閱「QueryData 總覽」。

目標

  • 建立資料庫並填入資料。
  • 使用脈絡工程代理建立脈絡資料集檔案。
  • 建立脈絡資料集並上傳脈絡資料集檔案。
  • 在 Spanner Studio 中測試 QueryData 並產生 SQL 查詢。
  • 使用 MCP Toolbox 中的 Gemini 資料分析 QueryData 工具,將 QueryData 與應用程式整合。
  • 使用值搜尋查詢,為 LLM 回覆建立基準。

費用

在本文件中,您將使用下列 Google Cloud計費元件:

您可以使用 Pricing Calculator,根據預測用量估算費用。

初次使用 Google Cloud 的使用者可能符合免費試用期資格。

完成本文所述工作後,請刪除建立的資源,避免繼續計費。詳情請參閱「清除所用資源」一節。

事前準備

建立情境集前,請先完成下列前置作業。

啟用必要服務

為專案啟用下列服務:

準備 Spanner 執行個體


本教學課程需要 Spanner 執行個體中的資料庫。詳情請參閱「建立資料庫」。

必要角色和權限

  • 將 IAM 使用者或服務帳戶新增至叢集。詳情請參閱「套用 IAM 角色」。
  • 在專案層級,將 spanner.databaseReader 和 geminidataanalytics.queryDataUser 角色授予 IAM 使用者。詳情請參閱「新增專案的 IAM 政策繫結」。
  • 如要建立、上傳及管理情境集,請在專案層級,將 Dataplex Catalog 編輯者 (roles/dataplex.catalogEditor) 或 Dataplex Catalog 管理員 (roles/dataplex.catalogAdmin) 角色授予 IAM 使用者。詳情請參閱「情境組合權限」。
  • 在專案層級,為必要的資料庫授予 IAM 使用者角色和權限。

建立 flights 和 airports 結構定義和資料表

在本節中,您將建立本教學課程所需的 flights 和 airports 資料庫資料表。

  1. 前往 Google Cloud 控制台的「Spanner」頁面。

    前往「Spanner」頁面

  2. 從清單中選取執行個體,然後選取資料庫。

  3. 在導覽選單中,按一下「Spanner Studio」。

  4. 點選「開啟新的 SQL 編輯器分頁」或「新增分頁」,開啟新分頁。

  5. 如要建立 airports 資料表和結構定義,請執行下列 SQL 陳述式:

    CREATE TABLE IF NOT EXISTS airports (
      id INT64 PRIMARY KEY,
      iata STRING(MAX),
      name STRING(MAX),
      city STRING(MAX),
      country STRING(MAX)
    );
    
  6. 建立 flights 資料表和結構定義:

    CREATE TABLE flights (
      id INT64 NOT NULL,
      airline STRING(10),
      flight_number INT64,
      departure_airport STRING(5),
      arrival_airport STRING(5),
      departure_time TIMESTAMP,
      arrival_time TIMESTAMP,
      departure_gate STRING(10),
      arrival_gate STRING(10)
    ) PRIMARY KEY (id);
    

填入 flights 和 airports 資料表

在本節中,您將使用提供的 SQL 指令碼填入 flights 和 airports 資料表。

  1. 填入 airports 資料表。

  2. 在 flights 資料表中填入資料。

  3. 執行下列查詢,確認資料表已填入資料:

    SELECT * FROM flights LIMIT 10;
    SELECT * FROM airports LIMIT 10;
    

建立權杖化資料欄和搜尋索引

使用 Spanner 內建的 Text Search 功能,讓 QueryData 將非結構化自然語言詞組 (例如錯別字或部分名稱) 準確對應至資料庫中的特定值。這項操作會產生隱藏的 TOKENLIST 資料欄,將字串細分為 n-grams,並在該資料欄建立搜尋索引。

如要建立權杖化資料欄和搜尋索引,請執行下列 SQL 陳述式:

  1. 建立機場名稱的權杖欄和索引:

    ALTER TABLE `airports` ADD COLUMN `name_tokens` TOKENLIST AS (TOKENIZE_SUBSTRING(`name`)) STORED HIDDEN;
    CREATE SEARCH INDEX `airports_name_idx` ON `airports`(`name_tokens`);
    
  2. 為機場城市建立符記資料欄和索引:

    ALTER TABLE `airports` ADD COLUMN `city_tokens` TOKENLIST AS (TOKENIZE_SUBSTRING(`city`)) STORED HIDDEN;
    CREATE SEARCH INDEX `airports_city_idx` ON `airports`(`city_tokens`);
    

在 Spanner Studio 中建立脈絡資料集

在本節中,請建立名為 flights-assistant 的內容集。這個脈絡集不含任何上傳的脈絡集檔案。

  1. 前往 Google Cloud 控制台的「Spanner」頁面。

    前往 Spanner

  2. 從清單中選取執行個體,然後選取資料庫。

  3. 在導覽選單中,點選「Spanner Studio」。

  4. 在「Explorer」窗格中,點選「Context sets」旁的「更多動作」圖示 ()。

  5. 按一下「建立情境組合」。

  6. 在「Context set name」(脈絡資料集名稱) 中輸入 flights-assistant。

  7. 點選「建立」。

在 Studio 中測試 QueryData

在本節中,請使用flights-assistant透過自然語言問題設定的內容,生成 SQL 查詢。由於脈絡資料集沒有任何上傳的脈絡資料集檔案,即使在提問時提供脈絡 (例如 nighttime traffic),QueryData 仍會生成次佳查詢。

  1. 在「Explorer」窗格中,點選情境集旁邊的「更多動作」圖示 。
  2. 按一下「測試脈絡資料集」。
  3. 在查詢編輯器中,點選「使用 QueryData 生成 SQL 查詢,並搭配:flights-assistant」。
  4. 輸入下列自然語言問題來生成 SQL 查詢,然後點選「生成」。

    Find flights from SFO to JFK.
    

    查看 SQL 查詢。請注意,QueryData 會針對這個明確的問題生成正確的 SQL。

      SELECT
        *
      FROM
        flights
      WHERE
        departure_airport = 'SFO'
        AND arrival_airport = 'JFK';
    
  5. 在「使用 QueryData 生成 SQL 查詢:flights-assistant」視窗,點選「編輯」。

  6. 輸入下列自然語言問題來生成 SQL 查詢,然後按一下「更新」。

    Tell me flights that can help me beat nighttime traffic if traveling from New York
    

    資料庫無法理解「nighttime流量」一詞。這可能會導致系統無法生成 SQL 查詢,或生成的查詢忽略該字詞,如下列查詢所示。

    -- The database schema does not contain information about traffic.
    -- Returning all flights departing from New York airports.
    SELECT
      f.airline,
      f.flight_number,
      a.name AS departure_airport_name,
      f.departure_time,
      b.name AS arrival_airport_name,
      f.arrival_time
    FROM
      flights AS f
    JOIN
      airports AS a
      ON f.departure_airport = a.iata
    JOIN
      airports AS b
      ON f.arrival_airport = b.iata
    WHERE
      a.city = 'New York'
    ORDER BY
      f.departure_time;
    
  7. 在「使用 QueryData 生成 SQL 查詢:flights-assistant」視窗,點選「編輯」。

  8. 輸入下列自然語言問題來生成 SQL 查詢,然後按一下「更新」。

    Show me the flight to Houston Intercontinental
    

    內容設定邏輯會產生查詢,尋找名稱中含有「休士頓洲際」的機場。由於資料庫中沒有這類機場或城市,查詢不會傳回任何資料列。

    SELECT
      f.*
    FROM
      `flights` AS f
    JOIN
      `airports` AS a
    ON
      f.arrival_airport = a.id
    WHERE
      a.name LIKE '%Houston Intercontinental%';
    

為脈絡資料集生成脈絡

在本節中,您將準備環境並建立內容檔案,有助於提升內容集的查詢功能。

設定環境

您必須先準備環境,才能開始生成情境。

如要設定環境,請按照下列步驟操作:

  1. 安裝 Antigravity CLI。詳情請參閱「開始使用 Antigravity CLI」。
  2. 安裝 Google Cloud CLI。
  3. 設定應用程式預設憑證 (ADC)。在終端機中執行下列指令,進行驗證並選取專案:

    gcloud auth application-default login
  4. 安裝 uv,這是 Python 套件和專案管理工具,也是脈絡工程代理的必要條件。如果系統尚未安裝 Python,uv 可以為您安裝。

  5. 安裝內容比對引擎代理程式:

    agy plugin install https://github.com/GoogleCloudPlatform/db-context-enrichment/tree/main/plugin
  6. 在終端機啟動 Antigravity CLI。

    agy
  7. 使用 MCP Toolbox 設定資料庫連線,以便生成背景資訊。連線定義在 tools.yaml 設定檔中。

    如要在目前目錄中建立 tools.yaml 設定檔,請輸入類似以下的提示:

    Help me set up a database connection.
    

    按照技能提供的指示操作。如要進一步瞭解 tools.yaml 檔案,請參閱 MCP Toolbox 說明文件。

  8. 建立 tools.yaml 檔案後,如要重新載入設定,請在 Antigravity CLI 中執行下列指令,然後按照說明重新載入工具箱 MCP 伺服器:

    /mcp
    1. 選取「db-context-engineering_toolbox」。

    2. 選取「Restart」。

  9. 確認 MCP 工具箱和情境工程代理外掛程式已連線,可供使用。

    /mcp

產生範本內容

在本節中,為解決上一節的問題 (QueryData 無法辨識 nighttime traffic 字詞),請在內容集檔案中將該字詞定義為 5:00 PM 和 7:00 PM 之間發生的流量。

如要產生範本內容,請按照下列步驟操作:

  1. 在 Antigravity CLI 輸入下列提示詞:

    Generate a template for the question: "Tell me flights that can help me beat nighttime traffic if traveling from New York" with the following SQL query:
    
    SELECT
      f.airline,
      f.flight_number,
      a.name AS airport_name,
      f.departure_time
    FROM
      flights f
    JOIN
      airports a
      ON f.departure_airport = a.iata
    WHERE
      a.city = 'New York'
      AND (
        EXTRACT(HOUR FROM f.departure_time) < 17
        OR EXTRACT(HOUR FROM f.departure_time) >= 19
      )
    ORDER BY
      f.departure_time;
    
  2. 代理會將輸入內容轉換為特定格式,提升脈絡集在各種使用者查詢中的成效。詳情請參閱「情境集總覽」。

  3. 查看生成的查詢範本。您可以將查詢範本儲存為新的代理程式結構定義檔案,或附加至現有的代理程式結構定義檔案。

  4. 提示代理儲存範本:

    Save it to context_set.json.
    

    代理會在同一個目錄中建立檔案,並加入以下內容:

    {
      "templates": [
        {
          "nl_query": "Tell me flights that can help me beat nighttime traffic if traveling from New York",
          "sql": "SELECT f.airline, f.flight_number, a.name AS airport_name, f.departure_time FROM flights f JOIN airports a ON f.departure_airport = a.iata WHERE a.city = 'New York' AND (EXTRACT(HOUR FROM f.departure_time) < 17 OR EXTRACT(HOUR FROM f.departure_time) >= 19) ORDER BY f.departure_time;",
          "intent": "Tell me flights that can help me beat nighttime traffic if traveling from New York",
          "manifest": "Tell me flights that can help me beat nighttime traffic if traveling from a given city",
          "parameterized": {
            "parameterized_sql": "SELECT f.airline, f.flight_number, a.name AS airport_name, f.departure_time FROM flights f JOIN airports a ON f.departure_airport = a.iata WHERE a.city = ? AND (EXTRACT(HOUR FROM f.departure_time) < 17 OR EXTRACT(HOUR FROM f.departure_time) >= 19) ORDER BY f.departure_time;",
            "parameterized_intent": "Tell me flights that can help me beat nighttime traffic if traveling from ?"
          }
        }
      ]
    }
    

生成值搜尋內容

在本節中,您將產生值搜尋內容,協助內容集邏輯使用字串相似度 (三連字元比對),將值詞組對應至資料庫欄中儲存的特定值。舉例來說,如果使用者要求前往「休士頓洲際機場」的航班,值搜尋功能可將此要求對應至資料庫中的確切值「休士頓喬治布希洲際機場」。

如要產生值搜尋內容,請按照下列步驟操作:

  1. 在代理測試工具中輸入下列提示詞:

  2. 輸入 spanner,選取 Spanner 做為資料庫。

    Generate a value search on table "airports" for column "city" with concept "Airport City" using match function "TRIGRAM_STRING_MATCH".
  3. 查看產生的值搜尋定義。您可以將值搜尋定義儲存為新的情境集檔案,或附加至現有的情境集檔案。

  4. 對代理下達 Append the context to context_set.json 提示詞。這會將值搜尋定義新增至先前建立的內容檔案。

  5. 輸入資料庫執行個體和資料庫名稱,也就是產生情境集檔案的資料庫。

    現有的結構定義檔案會更新為值搜尋定義,內容如下:

      {
    "templates": [
      {
        "nl_query": "Tell me flights that can help me beat nighttime traffic if traveling from New York",
        "sql": "SELECT f.airline, f.flight_number, a.name AS airport_name, f.departure_time FROM flights f JOIN airports a ON f.departure_airport = a.iata WHERE a.city = 'New York' AND (EXTRACT(HOUR FROM f.departure_time) < 17 OR EXTRACT(HOUR FROM f.departure_time) >= 19) ORDER BY f.departure_time;",
        "intent": "Tell me flights that can help me beat nighttime traffic if traveling from New York",
        "manifest": "Tell me flights that can help me beat nighttime traffic if traveling from a given city",
        "parameterized": {
          "parameterized_sql": "SELECT f.airline, f.flight_number, a.name AS airport_name, f.departure_time FROM flights f JOIN airports a ON f.departure_airport = a.iata WHERE a.city = ? AND (EXTRACT(HOUR FROM f.departure_time) < 17 OR EXTRACT(HOUR FROM f.departure_time) >= 19) ORDER BY f.departure_time;",
          "parameterized_intent": "Tell me flights that can help me beat nighttime traffic if traveling from ?"
        }
      }
    ],
    "facets": [],
    "value_searches": [
      {
        "query": "SELECT CAST(T.`name` AS STRING) AS value, 'name' AS `columns`, 'airport name' AS concept_type, 1 - SCORE_NGRAMS(T.`name_tokens`, CAST($value AS STRING)) AS distance, JSON '{}' AS context FROM `airports` AS T WHERE SEARCH_NGRAMS(T.`name_tokens`, CAST($value AS STRING)) ",
        "concept_type": "airport name",
        "description": "String similarity using Spanner Search Indexes."
      },
      {
        "query": "SELECT CAST(T.`city` AS STRING) AS value, 'city' AS `columns`, 'airport city' AS concept_type, 1 - SCORE_NGRAMS(T.`city_tokens`, CAST($value AS STRING)) AS distance, JSON '{}' AS context FROM `airports` AS T WHERE SEARCH_NGRAMS(T.`city_tokens`, CAST($value AS STRING)) ",
        "concept_type": "airport city",
        "description": "String similarity using Spanner Search Indexes."
      }
    ]
    }
    

將脈絡資料集檔案上傳至 QueryData

在本節中,您會將脈絡資料集檔案上傳至 QueryData,提升 QueryData 在資料庫生成 SQL 的能力。

如要上傳背景資訊,請按照下列步驟操作:

  1. 前往 Google Cloud 控制台的「Spanner」頁面。

    前往「Spanner」頁面

  2. 從清單中選取執行個體,然後選取資料庫。

  3. 在導覽選單中,按一下「Spanner Studio」。

  4. 在「Explorer」窗格中,按一下「Context sets」旁邊的「Actions」圖示 。

  5. 按一下「Edit context set」。

  6. 按一下「Upload context set file」部分的「Browse」,然後選取先前產生的情境集檔案。

  7. 按一下 [儲存]。

使用 QueryData 生成 SQL 查詢

在本節中,您將使用上傳的情境集檔案,以自然語言提問。這樣您就能確認 QueryData 正確解讀並套用「nighttime traffic」等字詞和其他相關詞組的定義。

如要生成 SQL 查詢,請按照下列步驟操作:

  1. 在「Explorer」窗格中,按一下內容集旁邊的「更多動作」圖示 ()。
  2. 按一下「測試脈絡資料集」。
  3. 在查詢編輯器中,點選「使用 QueryData 生成 SQL 查詢,並搭配:flights-assistant」。
  4. 輸入下列自然語言問題來生成 SQL 查詢,然後點選「生成」。

    Tell me flights that can help me beat nighttime traffic if traveling from New York
    

    生成的 SQL 查詢大致如下:

    SELECT
      f.airline,
      f.flight_number,
      a.name AS airport_name,
      f.departure_time
    FROM
      flights f
    JOIN
      airports a ON f.departure_airport = a.iata
    WHERE
      a.city = 'New York'
      AND (
        EXTRACT(HOUR FROM f.departure_time) < 17
        OR EXTRACT(HOUR FROM f.departure_time) >= 19
      )
    ORDER BY
      f.departure_time;
    

    這個問題與您新增至 QueryData 內容的問題相同。您會發現 QueryData 現在可以準確解讀「nighttime traffic」一詞。

    雖然脈絡來自特定問題,但 QueryData 會使用這項資訊,強化生成 SQL 的能力,以便處理各種相似問題。

  5. 在「使用 QueryData 生成 SQL 查詢:flights-assistant」視窗,點選「編輯」。

  6. 輸入下列類似問題來生成 SQL 查詢,然後點選「更新」。

    What are the flights that can help me avoid evening traffic if departing from Boston
    

    由於問題將 nighttime traffic 一詞替換為類似的 evening traffic,QueryData 會套用相同的解讀方式,為這個問題提供一致的答案。

    生成的 SQL 查詢大致如下:

    -- What are the flights that can help me avoid evening traffic if departing from Boston
    SELECT
      f.airline,
      f.flight_number,
      a.name AS airport_name,
      f.departure_time
    FROM
      flights f
    JOIN
      airports a
    ON
      f.departure_airport = a.iata
    WHERE
      a.city = 'Boston'
      AND (
        EXTRACT(HOUR FROM f.departure_time) < 17
        OR EXTRACT(HOUR FROM f.departure_time) >= 19
      )
    ORDER BY
      f.departure_time;
    
  7. 輸入下列問題來生成 SQL 查詢,然後點選「更新」。

    Show me the flight to Houston Intercontinental
    

    生成的 SQL 查詢大致如下:

    SELECT
      f.*
    FROM
      flights AS f
    INNER JOIN
      airports AS a
    ON
      f.arrival_airport = a.iata
    WHERE
      a.name = 'George Bush Intercontinental Houston Airport'
    

    請注意,QueryData 現在可以準確解讀「Houston Intercontinental」與資料庫中的「George Bush Intercontinental Houston Airport」相關。

將 QueryData 整合至應用程式

在本節中,您將為航班搜尋應用程式建立資料代理。這個資料代理提供對話式介面,可存取您先前建立的 flights 和 airports 資料表。此外,您也會瞭解如何使用 Agent Development Kit (ADK)、Gemini 資料分析 QueryData MCP 工具和脈絡資料集,建立這類資料代理並整合至應用程式,提升回覆品質。

  1. 下載 MCP Toolbox 1.14.0 以上版本。MCP Toolbox 會將資料代理公開為工具,供應用程式連線。MCP Toolbox 與您先前安裝的脈絡工程代理不同,後者會生成脈絡。

  2. 設定應用程式預設憑證 (ADC)。

    gcloud auth application-default login
  3. 找出您先前建立的情境集 ID。如要進一步瞭解如何找出內容集 ID,請參閱「找出內容集 ID」。

  4. 將下列內容附加至 tools.yaml 設定,即可使用 MCP Toolbox 連線至資料代理程式。詳情請參閱「Gemini 資料分析來源」和「Gemini 資料分析 QueryData 工具」。

    kind: source
    name: gda-api-source
    type: cloud-gemini-data-analytics
    projectId: "PROJECT_ID"
    ---
    kind: tool
    name: cloud_gda_query_tool
    type: cloud-gemini-data-analytics-query
    source: gda-api-source
    description: Use this tool to send natural language queries to the Gemini Data Analytics API and receive SQL, natural language answers, and explanations.
    location: "REGION_ID"
    context:
      datasourceReferences:
        spannerReference:
          databaseReference:
            engine: "GOOGLE_SQL"
            projectId: "PROJECT_ID"
            instanceId: "INSTANCE_ID"
            databaseId: "DATABASE_ID"
          agentContextReference:
            contextSetId: "CONTEXT_SET_ID"
    generationOptions:
      generateQueryResult: true
      generateNaturalLanguageAnswer: true
      generateExplanation: true
      generateDisambiguationQuestion: true
    

    更改下列內容:

    • PROJECT_ID: Google Cloud 專案 ID。
    • REGION_ID:Spanner 執行個體所在的區域 (例如 us-central1)。
    • INSTANCE_ID:Spanner 執行個體的 ID。
    • DATABASE_ID:要連線的資料庫名稱。
    • CONTEXT_SET_ID:脈絡資料集 ID。如要進一步瞭解如何找出內容集 ID,請參閱「找出內容集 ID」。
  5. 使用 tools.yaml 檔案執行 MCP Toolbox 伺服器。

    ./toolbox --config autoctx/tools.yaml
  6. 建立 ADK 應用程式,使用 MCP Toolbox 的 Python SDK 叫用 Gemini 資料分析 QueryData 工具。如要進一步瞭解如何使用 MCP Toolbox 的 Python SDK,請參閱 Toolbox 快速入門導覽課程。如要瞭解 Python ADK,請參閱 ADK 快速入門導覽課程。

    1. 建立目錄來儲存應用程式,例如 flight-assistant-app。
    2. 將目錄變更為 flight-assistant-app 目錄。

      mkdir flight-assistant-app
      cd flight-assistant-app
    3. 在 flight-assistant-app 目錄下執行下列指令,建立虛擬環境並安裝必要元件。

      uv init
      uv add google-adk toolbox-core google-genai
    4. 設定 ADK 代理。

      1. 建立 ADK 代理。

        uv run adk create my_agent
      2. 選取 gemini-3.8-flash 以上版本。

      3. 選取「Google AI」,然後輸入 Gemini API 金鑰。如要進一步瞭解如何找出 API 金鑰,請參閱「使用 Gemini API 金鑰」。(或者,如果不需要免費試用,可以選取「Vertex AI」,並指定已啟用計費功能的 Google Cloud 專案)。

    5. 將 agent.py 檔案的內容,替換成下列「飛航資料助理」範例應用程式程式碼。

      from typing import cast
      
      from google.adk.agents.llm_agent import Agent
      from google.adk.agents.llm_agent import ToolUnion
      
      from toolbox_core import ToolboxSyncClient
      
      TOOLBOX_URL = "http://127.0.0.1:5000"
      
      INSTRUCTION = """
      # ROLE
      You are a friendly and factual flight data assistant. Your goal is to help users find the best flights for their needs by providing accurate information with a helpful, professional tone.
      - use the Query Data Tool to answer the user's question, if the tool fails to generate a valid query, ask the user to clarify their question.
      
      # OPERATIONAL CONSTRAINTS
      - TOOL LIMITATION: You only have access to the Query Data Tool. Do not claim to have capabilities beyond what this tool provides.
      - TRANSPARENCY POLICY: Maintain a seamless user experience. Never mention that you are using a tool, querying a database, or generating SQL. Frame all responses as your own direct assistance.
      - SCOPE MANAGEMENT: If a user asks for something beyond your capabilities, politely state that you cannot perform that specific task. Guide the user towards what you can help with.
      
      # COMMUNICATION STYLE
      - Be concise and scannable when listing answers.
      - Maintain a helpful, professional persona.
      
      =====
      
      # QUERY DATA TOOL
      
      Inputs:
      1. query: A natural language formulation of a database query.
      
      Outputs: (all optional)
      1. disambiguation_question: Clarification questions or comments where the tool needs the users' input.
      2. generated_query: The generated query for the user query.
      3. intent_explanation: An explanation for why the tool produced `generated_query`.
      4. query_result: The result of executing `generated_query`.
      5. natural_language_answer: The natural language answer that summarizes the `query` and `query_result`.
      
      Usage guidance:
      1. If `disambiguation_question` is produced, then solicit the needed inputs from the user and try the tool with a new `query` that has the needed clarification.
      2. If `natural_language_answer` is produced, use `intent_explanation` and `generated_query` to see if you need to clarify any assumptions for the user.
      3. If the tool output indicates failure or empty results, explain that clearly using the provided reasoning.
      """
      
      client = ToolboxSyncClient(TOOLBOX_URL)
      
      mcp_tool = client.load_tool("cloud_gda_query_tool")
      
      root_agent = Agent(
          model="gemini-3.8-flash",  # Or newer.
          name="root_agent",
          instruction=INSTRUCTION,
          tools=cast(list[ToolUnion], [mcp_tool]),
      )
      
  7. 在 flight-assistant-app 目錄下執行下列指令,啟動應用程式並存取 ADK 網路伺服器 (http://127.0.0.1:8000)。

    uv run adk web --port 8000
  8. 輸入任何文字 (例如 hello),開始與代理互動。

    ADK 代理會回答一般問題,並呼叫必要的 MCP 工具。

  9. 輸入下列航班相關問題。

    How many flights depart from the west side?
    

    系統呼叫 MCP 工具來回答這個問題。不過,由於「the west」一詞模稜兩可,且未指定任何機場,MCP 工具會傳回消歧問題,代理程式會使用該問題建構回應。

    I cannot determine how many flights depart from the 'west side' as the database does not contain information about which airports are considered to be on the 'west side'. However, I can help you with questions like:
    
    1. How many flights depart from a specific airport?
    
    2. What are the departure airports for all flights?
    
    3. How many flights depart from each airport? Would you like to rephrase your question based on these options?
    
  10. 輸入與為代理程式生成的查詢範本類似的問題。

    Help me find flights from San Francisco that avoid the evening rush hour.
    

    根據先前新增的 QueryData 脈絡,MCP 工具瞭解 evening traffic 發生在下午 5 點到 7 點之間。MCP 工具會傳回相關資料,供代理建構回覆。

    Here are the flights departing from San Francisco that avoid the evening rush hour (defined as 5 PM to 7 PM):
    
    * UA 1532 departing at 05:50:00
    * UA 1158 departing at 05:57:00
    * CY 922 departing at 06:38:00
    * OO 5441 departing at 07:08:00
    * UA 616 departing at 07:14:00
    * AA 24 departing at 07:14:00
    * B6 434 departing at 08:00:00
    * AA 242 departing at 08:18:00
    * UA 1739 departing at 08:22:00
    * OO 6336 departing at 08:32:00
    * US 1784 departing at 08:47:00
    * DL 1631 departing at 09:00:00
    * DL 1106 departing at 09:06:00
    * OO 5427 departing at 09:06:00
    * CY 352 departing at 09:25:00
    
  11. 根據您在 QueryData 代理程式脈絡中新增的概念類型,輸入問題。

    Show me the flight to Houston Intercontinental
    

    根據先前新增的值搜尋脈絡,代理程式會瞭解「休士頓洲際機場」與「喬治布希洲際休士頓機場」(機場代碼 IAH) 相關,並傳回相關聯的資料,供代理程式用於建構回覆。

    Here are the flights heading to Houston Intercontinental (IAH):
    
    * Flight UA 1285 departs from SFO and arrives at IAH on 2025-01-01 at 23:20:00Z.
    * Flight F9 1056 departs from SFO and arrives at IAH on 2025-01-02 at 20:09:00Z.
    * Flight UA 1722 departs from SFO and arrives at IAH on 2025-01-03 at 02:29:00Z.
    

反覆調整代理效能

您可以在 ADK 網頁 UI 檢查 Gemini 資料分析 QueryData MCP 工具的要求和回覆。您可以透過這項回覆觀察工具回覆,例如生成的 SQL 查詢、結果集、意圖說明、消歧問題和自然語言答案,確認代理的回覆是否正確。

舉例來說,針對您先前輸入的文字 How many flights depart from the west side?,請點選代理泡泡。在左側導覽面板的「事件」分頁中,展開 functionResponse 即可查看以下回應。

"{"disambiguationQuestion": ["[NOT_ENOUGH_INFO] The database schema does not
contain information about which airports are on the 'west side'. Therefore, I
cannot determine how many flights depart from the west side.Possible alternative
questions: 1. How many flights depart from a specific airport? 2. What are the
departure airports for all flights? 3. How many flights depart from each
airport?"]}"

提高回覆準確度

您可以新增額外背景資訊,持續提升 Gemini 資料分析 QueryData 工具回覆的準確度。使用脈絡工程代理生成脈絡資料,然後將更新後的脈絡資料集檔案上傳至現有的 flights-assistant 資料代理。詳情請參閱「在 Spanner Studio 中管理情境集」。上傳後,控制台會立即擷取新的背景資訊,讓您在不中斷應用程式的情況下,提高代理的準確度。

多個代理

在開發環境中,您可以為 tools.yaml 檔案中的工具指派不同名稱,對多個資料代理情境執行 A/B 測試。舉例來說,您可以定義兩個名稱不同的 cloud-gemini-data-analytics-query 工具 (例如 cloud_gda_query_tool_v1 和 cloud_gda_query_tool_v2),藉此建立專屬的 tools.yaml 設定。這樣一來,您就能實作應用程式邏輯,透過選擇對應的工具名稱,以程式輔助方式選取所需的內容版本。

以下範例 tools.yaml 說明如何為資料庫來源設定多個資料代理程式:

kind: source
name: gda-api-source
type: cloud-gemini-data-analytics
projectId: PROJECT_ID
---
kind: tool
name: cloud_gda_query_tool_v1
type: cloud-gemini-data-analytics-query
source: gda-api-source
context:
  datasourceReferences:
    DB_SOURCE:
      databaseReference: ...
      agentContextReference:
        contextSetId: "V1_YOUR_CONTEXT_SET_ID"
generationOptions: ...
---
kind: tool
name: cloud_gda_query_tool_v2
type: cloud-gemini-data-analytics-query
source: gda-api-source
context:
  datasourceReferences:
    DB_SOURCE:
      databaseReference: ...
      agentContextReference:
        contextSetId: "V2_YOUR_CONTEXT_SET_ID"
generationOptions: ...

更改下列內容:

  • PROJECT_ID: Google Cloud 專案 ID。
  • V1_YOUR_CONTEXT_SET_ID:版本 1 的情境集 ID。
  • V2_YOUR_CONTEXT_SET_ID:版本 2 的情境集 ID。

清除所用資源

完成本教學課程後,請刪除您建立的資源,以免持續產生費用。下列各節將說明如何刪除這些資源。

刪除脈絡資料集

刪除執行個體前,請先刪除您建立的脈絡資料集。

  1. 前往 Google Cloud 控制台的「Spanner」頁面。

    前往「Spanner」頁面

  2. 從清單中選取執行個體,然後選取資料庫。

  3. 在導覽選單中,按一下「Spanner Studio」。

  4. 在「Explorer」窗格中,按一下情境集旁邊的「更多動作」圖示 。

  5. 在「Delete context set」(刪除內容集) 視窗中,於確認方塊中輸入 flight-assistant。

  6. 按一下「確認」。

刪除執行個體

刪除「事前準備」一節中建立的執行個體時,您建立的所有物件也會一併刪除。

  1. 前往 Google Cloud 控制台的「Spanner」頁面。

    前往 Spanner

  2. 按一下要刪除的執行個體名稱,例如「Test Instance」(測試執行個體)。

  3. 點選「刪除執行個體」。

  4. 輸入執行個體名稱,然後按一下「刪除」,確認要刪除執行個體。

後續步驟