Gemini API 托管 Agent 实战:用一次调用部署可执行代码的数据分析代理

系统讲清 Gemini Managed Agents 的运行方式、计费因素、环境持久化与文件共享方法,并通过 Python 实战搭建一个可分析 CSV、生成图表并下载结果的数据分析代理。

阅读时长: 10 分钟
共 4788字
作者: eimoon.com

Gemini API 托管 Agent 实战:用一次调用部署可执行代码的数据分析代理

Gemini 的托管 Agent 提供了一种更直接的 Agent 部署方式:不需要先搭云主机、配容器、接执行器,再把模型、文件系统和联网能力拼起来;只要一次 API 调用,就能启动一个具备推理、规划、联网、文件操作和代码执行能力的自治代理。

这类能力的价值不在“会聊天”,而在“能做事”。给它一份数据、一个目标和一个隔离环境,它可以自己写 Python、执行脚本、生成图表,并把结果保存在工作区里供后续下载。

下面按实际工程使用的顺序展开:先讲清楚托管 Agent 的能力边界与成本构成,再用 Python 从零搭一个可分析 CSV 数据并产出图表的数据分析代理。

托管 Agent 到底解决什么问题?

结论先说:它解决的是“把模型变成一个带运行时的执行单元”,适合需要多步操作、代码执行和文件产出的任务;如果只是普通问答或单轮文本生成,用标准模型调用更简单。

把一个 Agent 看成一个拥有独立电脑的自动执行者会比较准确。收到任务后,它不只是生成文本,而是会在隔离的 Linux 沙箱里自行完成这些动作:

  • 推理与规划任务步骤
  • 编写并执行代码
  • 读写和管理文件
  • 在多轮交互中保留工作区状态
  • 访问网络并使用 Google Search 做信息 grounding

底层运行能力来自一个通用 Agent 基座:antigravity-preview-05-2026。它在运行时直接提供了常见执行工具,因此不需要手工再搭一套执行基础设施。

这个运行时至少包含三类关键能力:

能力 说明 适用场景
代码执行 支持 Bash、Python、Node.js 数据分析、脚本处理、文件转换
文件管理 远端容器内持久文件系统,可跨多轮保留 中间产物保存、脚本复用、结果下载
Web 集成 可接入 Google Search,并抓取在线非结构化数据 实时信息查询、网页资料提取

一个典型用法是数据分析。比如门店销售分析:把销售数据源暴露给 Agent 后,只需发出自然语言请求,它就能自己写分析脚本、生成汇总结果,并把报告或图表保存到工作目录中。

这类 Agent 的成本怎么计算?

结论也很直接:成本不只来自输入输出 token,还包括中间推理产物、平台运行费用、上下文缓存和 grounding 调用。只看“最终回答长度”会低估实际成本。

计费主要由四部分组成:

  1. 模型 token 使用量

    • 包括输入 token
    • 包括输出 token
    • 还包括中间过程生成的内容,例如 Agent 写出的 Python 脚本本身也会计费
  2. 基础设施与平台费用

    • 托管 Agent 运行在集成环境中
    • 管理、调度与部署能力本身存在服务费用
  3. 上下文缓存

    • 若频繁复用相同数据,可通过 context caching 降低成本
    • 通常会比标准 token 价格便宜很多
  4. Grounding 费用

    • 如果调用 Google Search、Google Maps 等服务,会单独计费
    • 常见方式是先给免费额度,之后按每 1000 次查询收费,典型量级约为 $14/1,000 queries

这里使用的基座 Agent 是 antigravity-preview-05-2026,底层由 Gemini 3.5 Flash 驱动。对应 token 价格如下:

项目 价格(每百万 token)
Text Input $1.50
Text Output $9.00
Context Cache Hit (Input) $0.15

适用建议:

  • 如果任务需要反复读同一批数据,优先考虑缓存
  • 如果任务会触发联网搜索,先确认是否真的需要 grounding
  • 如果任务只是一次性小分析,不一定比本地脚本便宜

开始之前要准备什么?

结论:最少需要三样东西——API Key、已开启计费的项目、一个 Python 运行环境。少任何一项都跑不起来。

API Key 与计费

先在 Google AI Studio 创建 API Key。这个 Key 需要绑定一个 Google Cloud 项目,可以用已有项目,也可以新建一个,例如:

gemini-managed-agents

拿到 Key 后,在项目目录下创建 .env 文件:

GEMINI_API_KEY=<paste_your_api_key_here>

然后务必给这个 API Key 开启 billing。不开计费,请求会被直接拒绝。

Python 环境

这里使用 Anaconda 创建独立环境:

conda create --name gemini_agents python=3.12 -y

激活环境:

conda activate gemini_agents

安装依赖:

pip install google-genai requests python-dotenv

需要注意一点:命令里创建的是 python=3.12,如果文档或注释中提到 3.10,以命令本身为准。

第一次调用托管 Agent,最小可运行示例怎么写?

结论:最小示例只需要初始化客户端,调用 client.interactions.create(),并指定 agentinputenvironment="remote"

下面这个例子让 Agent 安装 matplotlib,然后回报版本号。

1. 加载环境变量并初始化客户端

from dotenv import load_dotenv
from google import genai

# Load secure environment variables
load_dotenv()
# Initialize the GenAI Client
client = genai.Client()

2. 创建一次基础交互

# Create a basic interaction with a managed agent
interaction = client.interactions.create(
    agent="antigravity-preview-05-2026",
    input="Install the matplotlib package, verify its version, and report back.",
    environment="remote"
)

3. 读取结果

# Output the status of the agent
print(f"Status: {interaction.status}")
print(f"Environment ID: {interaction.environment_id}")
print(f"Output:\n{interaction.output_text}")

一次典型输出如下:

Status: completed
Environment ID: 104ad7f8-32e0-4b8d-b344-24d92eb74eb6
Output:
I have successfully installed the matplotlib package in the sandbox environment and verified its installation.

Here are the details:
- **Installation Command:** python3 -m pip install --break-system-packages matplotlib
- **Installed Version:** 3.10.9

这段结果里最重要的不是版本号,而是 environment_id。后面要做多轮任务、复用文件系统、下载结果,都依赖这个标识。

环境为什么是核心概念?

结论:托管 Agent 的“连续性”不是靠本地会话,而是靠远端环境 ID。只要环境还没被删除,就能把后续交互接在同一个沙箱上继续执行。

每次交互都运行在一个临时环境中。这个环境在最后一次活动之后最多保留 7 天,之后会被删除。

这意味着:

  • 安装过的包可以在后续交互里继续使用
  • 之前生成的脚本和文件可以继续访问
  • 只要环境仍然存在,就能继续追加入新的操作

适用边界也很清楚:

  • 它不是永久环境
  • 不能把它当作长期仓库存储
  • 对需要长期保留的数据,应该主动下载归档

多轮交互怎么保留上下文和文件系统?

结论:要同时传两个东西——previous_interaction_id 保留对话历史,environment 保留工作区状态。少一个都可能让 Agent “记不住”。

下面是一个两步示例。第一步写脚本,第二步执行脚本。

# First interaction
inter1 = client.interactions.create(
    agent="antigravity-preview-05-2026",
    input="Write a Python script sum.py that adds all integers from 1 to 100.",
    environment="remote"
)

# Second interaction
inter2 = client.interactions.create(
    agent="antigravity-preview-05-2026",
    previous_interaction_id=inter1.id, # Passes the conversation history
    environment=inter1.environment_id, # Keeps the same filesystem state
    input="Execute 'sum.py' using Python and display the standard output."
)

# Output the status of the agent
print(f"Output:\n{inter2.output_text}")

这里两个参数的作用要区分开:

  • previous_interaction_id

    • 让 Agent 知道前面聊过什么
    • 用于延续任务语义和推理上下文
  • environment

    • 让 Agent 知道要进入哪个沙箱执行
    • 用于延续文件系统和已安装依赖

如果只传 previous_interaction_id,它可能知道有个 sum.py,但执行环境里未必真的有这个文件。
如果只传 environment,环境里有文件,但 Agent 不一定理解这一步和前一步的关系。

数据怎么喂给 Agent?

结论:小文件适合 inline,大文件更适合仓库或外部存储。这里最值得掌握的是两种:内联文件和 GitHub 仓库。

常见数据共享方式有四种:

  • Inline data:把文件内容读成字符串,直接随请求发送
  • Hosted file:提供公开 URL,让 Agent 下载
  • GitHub repository:把公开仓库克隆进工作区
  • Google Cloud Bucket:把文件放在 GCS 并授权访问

这里重点看前两种常用方式中的一种轻量方案和一种工程方案。

什么时候用 inline data?

适用范围:

  • 本地小文件
  • 单文件不超过 1 MB
  • 所有文件总量不超过 2 MB

示例:

inter = client.interactions.create(
    agent="antigravity-preview-05-2026",
    input="Add all the numbers in the /workspace/numbers.txt file.",
    environment={
        "type": "remote",
        "sources": [
            {
                "type": "inline",
                # The file where to store the data in the agent environment
                "target": "/workspace/numbers.txt",
                # Assumes that the file data/numbers.txt exists
                "content": utils.read_text_file("data/numbers.txt")
            }
        ]
    }
)

这里的关键配置在 sources

  • type: "inline" 表示直接注入内容
  • target 指定文件在 Agent 工作区中的落点
  • content 是实际文本内容

文件应放在 /workspace 下。这个例子里,数据会写到:

/workspace/numbers.txt

什么时候用 GitHub 仓库?

结论:只要数据比 inline 限制大,或者希望一次提供代码、配置、数据三者,仓库方式更合适。

示例:

inter = client.interactions.create(
    agent="antigravity-preview-05-2026",
    input="Add all the numbers in the /workspace/repository/numbers.txt file.",
    environment={
        "type": "remote",
        "sources": [
            {
                "type": "repository",
                "source": "https://github.com/fran-aubry/gemini-agents-tutorial",
                "target": "/workspace/repository"
            }
        ]
    }
)

这里会把仓库克隆到:

/workspace/repository

适用场景包括:

  • 数据集较大
  • 需要把脚本、数据、说明一起给 Agent
  • 希望 Agent 能复用仓库中的固定目录结构

限制也很明确:仓库需要可公开访问。

结果文件怎么从远端环境取回本地?

结论:通过环境下载接口直接拉取整个工作区快照,然后本地保存为 tar 包。适合拿图表、脚本、报告等产物。

每个工作区都可以通过下面这个 URL 下载:

https://generativelanguage.googleapis.com/v1beta/files/environment-<env_id>:download

<env_id> 替换成具体环境 ID 即可。

下面是一个可直接使用的 Python 下载函数:

def download_env(env_id, path="environments"):
    download_url = f"https://generativelanguage.googleapis.com/v1beta/files/environment-{env_id}:download"
    try:
        request_params = {"alt": "media"}  # Retrieves raw media binary
        request_headers = {"x-goog-api-key": os.environ.get("GEMINI_API_KEY")}
        # Download the environment
        print(f"Downloading environment: {env_id}")
        response = requests.get(
            download_url,
            params=request_params,
            headers=request_headers,
            allow_redirects=True
        )
        response.raise_for_status()
        # Save the compressed workspace archive locally
        archive_name = f"{env_id}.tar"
        output_path = os.path.join(path, archive_name)
        with open(output_path, "wb") as archive_file:
            archive_file.write(response.content)
        print(f"Successfully downloaded workspace snapshot archive: {output_path}")     
    except requests.exceptions.RequestException as error:
        print(f"Failed to download sandbox workspace via HTTP request: {error}")
    except tarfile.TarError as archive_error:
        print(f"Failed to unpack download tarball: {archive_error}")

这个函数依赖 requests,并通过请求头中的 API Key 认证。

适用建议:

  • 任务完成后立刻下载结果,避免环境过期
  • 对生成图表、导出 CSV、日志文件这类产物,这种方式很直接
  • 如果后续还要继续交互,不必立即销毁环境

怎么把基础 Agent 变成一个数据分析代理?

结论:核心做法不是“重新训练”,而是在基座 Agent 上叠加 AGENTS.mdSKILL.md,把角色、边界和专门技能写清楚。

这里构建一个 data-analyst 代理,用它分析一份 Netflix 数据集,并生成按类型聚合的观看量图表。数据集放在公开仓库的 data 目录下,供 Agent 直接访问。

创建 Agent

agent = client.agents.create(
            id=data-analyst,
            base_agent="antigravity-preview-05-2026",
            base_environment={
                "type": "remote",
                "sources": [
                    {
                        "type": "inline", 
                        "target": ".agents/AGENTS.md", 
                        "content": read_text_file(".agents/AGENTS.md")
                    },
                    # Explicitly load the skill
                    {
                        "type": "inline", 
                        "target": ".agents/skills/csv-aggregator/SKILL.md", 
                        "content": read_text_file(".agents/skills/csv-aggregator/SKILL.md")
                    },	
                    {
                        "type": "repository",
                        "source": "https://github.com/fran-aubry/gemini-agents-tutorial",
                        "target": "/workspace/repository"
                    }
                ]
            }
)

几个参数的作用如下:

参数 作用
id Agent 名称,这里是 data-analyst
base_agent 基座 Agent,这里是 antigravity-preview-05-2026
base_environment Agent 初始化时带上的文件与数据源

这个 base_environment 做了三件事:

  1. 注入 .agents/AGENTS.md
  2. 注入 .agents/skills/csv-aggregator/SKILL.md
  3. 挂载代码与数据仓库到 /workspace/repository

AGENTS.md 应该写什么?

结论:它本质上就是系统级行为说明书,负责定义角色、目标、边界和输出风格。适合放全局规则,不适合堆具体步骤。

文件路径固定在:

.agents/AGENTS.md

它通常应该包含这些内容:

  • Agent 的角色
  • 主要任务目标
  • 允许访问的工具和数据源
  • 工作时必须遵守的边界
  • 输出格式要求
  • 任务处理示例

写法上有一个经验很重要:规则越清楚越好,但不要堆太多互相冲突的要求。Agent 最怕的不是“规则少”,而是“规则多但难以执行”。

SKILL.md 应该写什么?

结论:Skill 文件用来定义可复用、可触发的专门能力。适合描述“什么时候用这个技能”和“具体怎么做”。

每个技能文件都应该放在:

.agents/skills/<skill_name>/SKILL.md

其基本结构如下:

---
name: <skill_name>
description: <description of when to use the skill>
---
<steps on how to perform the task>

这里给 data-analyst 增加了一个技能:csv-aggregator。它的作用是对 CSV 执行按列分组与聚合。

例如在 Netflix 数据集里,如果要看哪些 Genre 的观看量最高,就需要:

  • Genre 分组
  • Viewership 列求和
  • 生成排序后的结果
  • 进一步绘图

把这类稳定、重复的操作写成技能文件,比每次都靠 prompt 临时描述更可靠。

Agent 持久化后,重复创建怎么处理?

结论:托管 Agent 是持久对象,不适合每次脚本运行都盲目 create。工程里应该优先“存在则加载,不存在才创建”。

如果对同一个 id 重复调用创建,通常会报错。因此更合理的做法是封装一个 load_or_create_agent()

  • 先尝试创建
  • 如果已经存在,就改用 client.agents.load()

这类封装虽然只是小工具,但在脚本反复执行、CI 运行或团队共享开发时能省掉很多无意义失败。

一个完整的数据分析流程应该怎么串起来?

结论:把“安装依赖”“调用技能生成脚本”“执行脚本”“下载环境”拆成多轮交互最稳妥,因为每一步的结果都能复用,也更容易排查失败点。

先初始化:

from dotenv import load_dotenv
from google import genai
import utils

load_dotenv()
client = genai.Client()

加载或创建 Agent:

data_analyst = utils.load_or_create_agent(client, "data-analyst")
print(f"Agent '{data_analyst.id}' initialized.")

第一步:安装 matplotlib

inter1 = client.interactions.create(
    agent=data_analyst.id,
    input="Install the matplotlib package.",
    environment="remote"
)

这里直接用 "remote" 即可,因为 Agent 级别已经预先配置好了基础环境和数据源。

第二步:让 Agent 调用 csv-aggregator 分析数据

inter2 = client.interactions.create(
    agent=data_analyst.id,
    input="Use the csv-aggregator to plot the top 10 genres from /workspace/repository/data/netflix.csv in terms of viewership",
    environment=inter1.environment_id
)

这一步会沿用第一步环境,因此前面装好的包还能继续使用。

第三步:执行生成好的脚本

inter3 = client.interactions.create(
    agent=data_analyst.id,
    input="Execute the genres.py script using python.",
    environment=inter2.environment_id
)

这里之所以能直接执行 genres.py,是因为前一步技能文件已经指导 Agent 生成了这个脚本。

第四步:下载环境,取回图表

utils.download_env(inter3.environment_id)

执行完后,图表就会存在远端工作区中,下载环境压缩包后即可在本地查看。

这种方式适合什么任务,不适合什么任务?

结论:适合“需要工具链和中间状态”的任务,不适合“只要一个快速文本答案”的任务。

适合

  • 数据分析与可视化
  • 批量文件处理
  • 自动写脚本并执行
  • 需要多轮迭代的工作流
  • 需要联网查询并结合本地文件处理的任务

不适合

  • 超低延迟接口
  • 单轮短问答
  • 对成本极度敏感且可完全本地化的任务
  • 需要长期、稳定、永久工作区的场景

还有一个现实问题:这类能力目前仍在 beta 阶段。接口细节和行为可能演进,因此上线前最好做两件事:

  1. 把 Agent 行为约束写进 AGENTS.md 与技能文件
  2. 把关键步骤拆成可重试的多轮交互,而不是一条 prompt 包打天下

最后总结

托管 Agent 的关键价值不是“让模型更聪明”,而是“让模型带着沙箱、文件系统和工具去执行任务”。这会明显降低 Agent 系统的搭建门槛。

真正值得关注的工程点有四个:

  • 环境 ID 决定多轮任务是否连续
  • 文件注入方式决定数据规模与组织方式
  • AGENTS.mdSKILL.md 决定代理是否稳定可控
  • 下载环境决定结果能否顺利落地

如果只是验证想法,直接从 antigravity-preview-05-2026 开始就够了。
如果任务已经固定并且会重复执行,就应该尽快把行为沉淀进自定义 Agent 和技能文件里。

关于

关注我获取更多资讯

月球基地博客公众号二维码,扫码关注获取更多 AI 与编程资讯
📢 公众号
月球基地博客作者个人微信二维码,扫码交流 AI 与编程话题
💬 个人号
使用 Hugo 构建
主题 StackJimmy 设计