首页 / 文章

一个分析工具,三种实现方式:Interactions API、ADK与Antigravity SDK的对比

同一款 Gemini 代理通过交互 API、Google ADK 以及 Antigravity SDK 这三种方式实现功能,分别从循环处理、工具支持、身份认证以及 Cloud Run 部署等方面进行了对比。

发布者:REACTAPP.TOP阅读约 8 分钟1853 词

来源: I built the same agent three ways: Interactions API, ADK, and the Antigravity SDK

Google 的技术栈目前提供了三种截然不同的方式来构建可运行的智能体:Interactions API 是 Gemini API 中面向智能体时代的接口,ADK 是一个完整的框架,而 Antigravity SDK 则是 Antigravity CLI 的底层支撑。比较这三种方式的合理方法是将同一个智能体构建三遍,观察其中的差异:谁负责控制智能体的运行循环,工具如何与智能体集成,以及哪些模型能够正常使用。每次构建完成后都会部署到 Cloud Run 上。

测试智能体

每次构建都会回答一种问题类型,即 Hacker News 上关于某个主题的公众观点。它读取来自 bigquery-public-data.hacker_news.full 的公共数据集,该数据集包含 4900 万篇文章和评论,数据更新速度比实时情况慢约一天。这三个版本都需要相同的三种功能:从简单问题中编写 SQL 语句、执行该语句并汇总返回的意见。

BigQuery 的连接方式每次都不同。Interactions API 使用手动编写的函数,ADK 使用其自有工具集,而 Antigravity SDK 则使用 MCP。

凭证

涉及两种类型的凭证:

export GOOGLE_API_KEY="..."   # get this at aistudio.google.com
gcloud auth application-default login

之所以存在两种凭证,是因为此架构中的 Interactions API 基于 Gemini API,而 Gemini API 需要密钥;而 ADK 与 Antigravity SDK 直接与云项目交互,完全无需密钥。

仔细查看 Interactions API:它接受 model= 参数,即普通的模型,或 agent= 参数,即由谷歌托管的智能体,其循环逻辑及可用工具均在平台上运行。当前版本中的工具为本地 Python 函数,因此不可能是托管型智能体,故应使用 model= 参数,且工具的循环逻辑也保留在本地代码中。谷歌的企业平台(原 Vertex AI)拥有该 API 的实验性版本,但用多种模型进行测试时,所有 model= 参数的调用都会被拒绝。

BigQuery的免费套餐每月提供1 TB的查询额度,足以应对那些大小在1到17 GB之间的演示查询。测试时使用的版本为google-genai 2.17.0、google-adk 2.6.2和google-antigravity 0.1.10,所使用的模型为gemini-3.6-flash。

方案一:Interactions API

通过pip install google-genai google-cloud-bigquery安装相关包。该工具实际上只是一个包含大约十行代码的普通函数:

def execute_sql(query: str) -> list[dict]:
    client = bigquery.Client()
    config = bigquery.QueryJobConfig(maximum_bytes_billed=20 * 10**9)
    rows = client.query_and_wait(query, job_config=config, max_results=50)
    return [{k: str(v) for k, v in dict(row).items()} for row in rows]

它会执行模型生成的任意 SQL 语句,并以普通字典的形式返回最多 50 行数据。maximum_bytes_billed 规定单次查询的扫描量上限为 20 GB,因此不会产生过高费用。由于 bigquery.Client() 会自动使用本地的 gcloud 登录信息,而在 Cloud Run 环境中则默认使用服务账户,因此无需手动处理凭据。

模型永远无法看到函数的具体实现内容,只能看到声明部分,因此声明中便包含了数据结构信息:

execute_sql_tool = {
    "type": "function",
    "name": "execute_sql",
    "description": (
        "Run a BigQuery Standard SQL SELECT query against "
        "`bigquery-public-data.hacker_news.full`, the public Hacker News "
        "dataset (stories and comments since 2006). Columns: id INT, "
        "type STRING (story/comment/job/poll), title STRING (stories only), "
        "text STRING (body, HTML-escaped), `by` STRING (username), score INT, "
        "parent INT, descendants INT, timestamp TIMESTAMP, url STRING, "
        "dead BOOL, deleted BOOL. Returns at most 50 rows."
    ),
    "parameters": {
        "type": "object",
        "properties": {"query": {"type": "string"}},
        "required": ["query"],
    },
}

parameters 部分保持简洁:仅需一个用于存储 SQL 的必填字符串。描述更为重要,因为它是模型了解表名及其列的唯一途径。更精准的描述能生成更好的查询语句。

剩下的就是工具循环部分,大约十几行代码:

while True:
    calls = [s for s in interaction.steps if s.type == "function_call"]
    if not calls:
        break
    results = [{
        "type": "function_result",
        "name": step.name,
        "call_id": step.id,
        "result": [{"type": "text", "text": json.dumps(execute_sql(**step.arguments))}],
    } for step in calls]
    interaction = client.interactions.create(
        model=MODEL,
        input=results,
        system_instruction=INSTRUCTION,
        tools=[execute_sql_tool],
        previous_interaction_id=interaction.id,
    )

每次循环会执行模型发出的每一个function_call操作,将输出作为下一轮的输入,如此循环直至回复中不再包含任何调用。有一个要点值得注意:历史记录不会被重新发送。服务器会存储这些记录,而previous_interaction_id仅用于引用前一次的交互,这样就能保持每个请求的规模较小。client对象是SDK连接Gemini API的入口,若不传入任何参数,它会从环境变量中获取GOOGLE_API_KEY。当该应用部署在Cloud Run上时,这个密钥会通过Secret Manager以环境变量的形式被加载。其余所有内容,包括要运行的SQL语句以及停止执行的时机,都由模型来决定。

目前这里还不支持MCP功能。Interactions API的文档将其列为一项限制,指出Gemini 3暂不支持远程MCP,不过这一功能即将推出。

结论:代码量最多,依赖项最少,且拥有完全控制权。

第二种方案:ADK

通过 pip install google-adk google-cloud-dataplex google-cloud-bigquery 进行安装。

import google.auth
from google.adk import Agent
from google.adk.integrations.bigquery import BigQueryCredentialsConfig, BigQueryToolset
from google.adk.integrations.bigquery.config import BigQueryToolConfig, WriteMode

credentials, _ = google.auth.default()
toolset = BigQueryToolset(
    credentials_config=BigQueryCredentialsConfig(credentials=credentials),
    bigquery_tool_config=BigQueryToolConfig(write_mode=WriteMode.BLOCKED),
)
root_agent = Agent(name="hn_opinion_agent", model=..., instruction=..., tools=[toolset])

ADK 提供了一个名为 BigQueryToolset 的现成 BigQuery 集成包。除了 execute_sql 外,它还提供了诸如 get_table_info 这样的元数据辅助函数,使得代理能够直接读取表结构而非通过提示获取。还有一个名为 WriteMode.BLOCKED 的设置,可将所有操作设置为只读模式。

整个系统中并未出现任何 API 密钥。BigQuery 工具集要求使用明确的凭据对象,该对象由 google.auth.default() 从本地 gcloud 登录过程中获取,同时还会附带一个项目 ID,但此版本会忽略该 ID。在模型端,仅需一个变量即可完成相关功能:GOOGLE_GENAI_USE_ENTERPRISE=TRUE 可让模型请求通过 Cloud 账户传输。一旦部署到 Cloud Run,查询和模型请求都将通过服务账户来执行。

该框架会运行循环,并将会话信息(包括多轮对话的历史记录)存储在内存中,需要在持久化存储时则存入数据库。

评价:代码量极少但功能极为强大,因为预置的工具让智能体能够独立处理数据。

第三种方案:Antigravity SDK

通过 pip install google-antigravity 进行安装。

from google.antigravity import Agent, LocalAgentConfig
from google.antigravity.types import McpStreamableHttpServer

bigquery_mcp = McpStreamableHttpServer(
    name="bigquery",
    type="http",
    url="https://bigquery.googleapis.com/mcp",
    headers={"Authorization": f"Bearer {token}",
             "x-goog-user-project": project},
    enabled_tools=["execute_sql_readonly", "get_table_info", ...],
)
config = LocalAgentConfig(system_instructions=..., mcp_servers=[bigquery_mcp])
async with Agent(config) as agent:
    response = await agent.chat(question)

该系统会为该工具组分配一个系统指令和一个MCP服务器,仅需一次agent.chat()调用即可完成规划、工具使用及总结生成。其底层是一个驱动Antigravity CLI运行的循环,该CLI包含各种文件处理和shell工具。

通过MCP可访问BigQuery,具体路径为bigquery.googleapis.com/mcp,这是由谷歌运行的托管端点,仅接受OAuth认证(通过gcloud auth print-access-token获取)。enabled_tools列表用于指定代理可调用的MCP工具范围。该端点提供了execute_sql和execute_sql_readonly两种功能,仅启用后者即可防止该代理进行写入操作。模型认证采用ADK机制,使用笔记本电脑上的云账户以及Cloud Run上的服务账户进行验证。

在选择该方案之前需注意两点:

  • 模型仅限于 Gemini。Antigravity IDE 还提供 Claude 和 GPT-OSS,而这些是 SDK 所没有的,不过可以使用类似 Ollama 的本地 OpenAI 兼容服务器来替代。
  • 项目 ID 应该放在系统指令中。托管端点上的每个工具都需要一个 projectId 参数,用于指定执行查询的 Cloud 项目,模型在调用工具时会自动填入该值。

评价:这是一种便捷的方式,可创建既能编辑文件又能运行 Shell 命令的智能体。

部署到 Cloud Run

这三种方案都可以部署到 Cloud Run,不同之处在于需要编写的服务代码量。

  • 交互 API:只需为该循环编写一个简单的 FastAPI 封装即可。由于对话由服务器保存,该服务本身不保留任何状态,调用方仅返回 previous_interaction_id。缺点是:此 API 仍无法以服务账户身份进行认证,因此它是唯一需要 API 密钥的服务,而该密钥需从 Secret Manager 获取。
  • ADK:服务器端无需做任何配置。adk api_server会在本地运行该程序,而adk deploy cloud_run则会生成服务器、容器以及部署配置。需要注意两个问题:首先,工具集中的额外包(bigquery和dataplex)需要被列在agent文件夹内的requirements.txt文件中;其次,环境变量在部署过程中不会被保留,因此必须事后在服务中添加GOOGLE_GENAI_USE_ENTERPRISE。对于那些不想自行维护服务的人,还有完全托管式的选项——Agent Runtime可供使用。
  • Antigravity SDK:需要手动封装agent.chat()功能,并将其打包为容器镜像。只有一个方面在服务时会有所变化:MCP授权头不能再来自笔记本电脑的gcloud登录,因此必须通过服务账户来生成并刷新令牌。
  • 限制访问并不复杂。使用 --no-allow-unauthenticated 参数部署即可将调用者限制为拥有 IAM 权限的用户。进行测试调用时,可通过 curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" 附加身份令牌,或启动 gcloud run services proxy;对于浏览器,则需在前面添加 IAP 机制。

    身份设置几乎无需成本。Cloud Run 服务始终以某种身份运行,除非另有指定,否则默认使用项目的计算服务账户。有一个身份负责为三个服务以及 ADK 和 Antigravity 的模型调用处理 BigQuery 相关操作。唯一需要手动授权的是为 Interactions 服务读取 API 密钥,为此需将 roles/secretmanager.secretAccessor 权限附加到该密钥本身上。

    不过不要盲目复制那种设置。默认账户被赋予了较宽泛的权限,通常还拥有项目级别的编辑者角色。一旦超出演示范围,就需要为每个服务创建专用服务账户,其权限仅限于部署时通过 --service-account 指定的必要角色。

    该选哪个

    对于大多数任务而言,Cloud Run 上的 ADK 是一个合理的起点。它提供了完整的工具集和 MCP 支持,简单的会话与历史记录管理功能,同时还允许用户选择任意模型,而不仅限于 Gemini 和 Gemma。Interactions API 能让开发者了解智能体实际的工作方式,因为其运行流程是完全公开的。当智能体需要编辑文件或运行 Shell 命令时,Antigravity SDK 是最佳选择。

    相关阅读

  • Google ADK Agents:从单个 Gemini Agent 到 Cloud Run 部署 — 通过 Google 的 Agent Development Kit 学习代理型 AI:相关工具、多代理组合、顺序流程、本地测试,以及向 Cloud Run 和 Agent Engine 的部署方法。
  • Android Studio 中的 11 种 Gemini 工作流:测试、预览、代理模式与崩溃处理 — Android Studio 中实用的 Gemini 使用技巧:AGENTS.md 文件、任务说明、测试与 Compose 预览生成、代理模式、依赖项更新、隐私保护以及检查清单。
  • Agents-A1:专为长期智能体任务设计的35B模型 — Agents-A1是通过微调实现的35B模型,它扩展的是智能体的任务处理范围而非参数数量。了解它在SEAL-0、IFBench和BrowseComp测试中的表现,以及何处可以获取GGUF格式的模型文件。