将 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的以下收费组件:

您可使用价格计算器根据您的预计使用量来估算费用。

Google Cloud 新用户可能有资格申请免费试用。

为避免继续计费,请在完成本文档中的任务后删除您创建的资源。如需了解详情,请参阅清理。

准备工作

在创建上下文集之前,请完成以下前提条件。

启用必需服务

为您的项目启用以下服务:

准备 Spanner 实例


本教程要求您的 Spanner 实例中有一个数据库。如需了解详情,请参阅创建数据库。

所需的角色和权限

  • 将 IAM 用户或服务账号添加到集群。如需了解详情,请参阅应用 IAM 角色。
  • 在项目级层向 IAM 用户授予 spanner.databaseReader 和 geminidataanalytics.queryDataUser 角色。如需了解详情,请参阅为项目添加 IAM 政策绑定。
  • 如需创建、上传和管理上下文集,请在项目级层向 IAM 用户授予 Dataplex Catalog Editor (roles/dataplex.catalogEditor) 或 Dataplex Catalog Admin (roles/dataplex.catalogAdmin) 角色。如需了解详情,请参阅上下文集权限。
  • 在项目级层向 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 内置的文本搜索功能,让 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. 在探索器窗格中,点击上下文集旁边的更多操作 ()。

  5. 点击创建情境集。

  6. 在上下文集名称中,输入 flights-assistant。

  7. 点击创建。

在 Studio 中测试 QueryData

在本部分中,您将使用通过提出自然语言问题设置的 flights-assistant 上下文来生成 SQL 查询。由于上下文集中未上传任何上下文集文件,即使在提出包含上下文的问题(例如 nighttime traffic)后,QueryData 生成的查询也并非最佳查询。

  1. 在探索器窗格中,点击上下文集旁边的更多操作 ()。
  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 代理上下文“flights-assistant”生成 SQL 窗口中,点击修改。

  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 中运行以下命令,并按照说明重新加载 Toolbox 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. 在探索器窗格中,点击上下文集旁边的操作 () 图标。

  5. 点击修改上下文集。

  6. 点击上传上下文集文件部分中的浏览,然后选择之前生成的上下文集文件。

  7. 点击保存。

使用 QueryData 生成 SQL 查询

在本部分中,您将使用上传的上下文设置文件提出自然语言问题。这样,您就可以验证 QueryData 是否正确理解并应用了 nighttime traffic 等术语及其他相关短语的定义。

如需生成 SQL 查询,请执行以下步骤:

  1. 在探索器窗格中,点击上下文集旁边的更多操作 ()。
  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 代理上下文“flights-assistant”生成 SQL 窗口中,点击修改。

  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 表提供了一个对话式界面。本教程还介绍了如何使用智能体开发套件 (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. 使用 MCP Toolbox 的 Python SDK 创建一个调用 Gemini 数据分析 QueryData 工具的 ADK 应用。如需详细了解如何使用 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 目录下运行以下命令,以启动应用并访问 http://127.0.0.1:8000 处的 ADK Web 服务器。

    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
    

    根据之前添加的值搜索上下文,智能体能够理解“Houston Intercontinental”与“George Bush Intercontinental Houston Airport”(机场代码 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 Web 界面,您可以检查 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. 在探索器窗格中,点击上下文集旁边的更多操作 ()。

  5. 在删除上下文集窗口中,在确认框中输入 flight-assistant。

  6. 点击确认。

删除实例

删除您在准备工作部分中创建的实例时,您创建的所有对象也会一并删除。

  1. 在 Google Cloud 控制台中,前往 Spanner 页面。

    转到 Spanner

  2. 点击要删除的实例的名称,例如 Test Instance。

  3. 点击删除实例。

  4. 输入实例名称,然后点击删除,以确认您要删除该实例。

后续步骤