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

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

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

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

Gemini 的 Managed Agents 把“会推理的模型”进一步包装成“可执行任务的运行单元”。调用方不需要自己准备容器、代码执行环境、文件系统和联网工具,发起一次 API 请求,就能拿到一个具备推理、规划、网页访问和代码执行能力的代理。

这类能力最适合那些本来就需要“先理解任务,再写代码,再运行代码,再整理结果”的场景,例如数据分析、报表生成、批量文件处理、轻量研究任务和自动化脚本执行。

下面从能力边界、计费、环境搭建、交互模式、文件传递方式到一个完整的数据分析 Agent 示例,系统走一遍。

Managed Agents 到底解决了什么问题

结论很直接:它解决的不是“模型回答问题”,而是“模型自己在隔离环境里把事情做完”。

普通的 LLM API 调用通常只返回文本。如果任务需要:

  • 写 Python 脚本
  • 安装依赖
  • 读取或生成文件
  • 在多轮中保留执行状态
  • 联网查信息
  • 把产物保存下来供后续下载

那么单纯的文本接口就不够了。Managed Agents 提供的是一个隔离的临时 Linux 环境,代理可以在里面自主完成这些操作。

它的核心能力包括:

  • 代码执行
    • 支持 Bash、Python、Node.js
    • 代理可以编写、调试并运行代码
  • 文件管理
    • 远程容器内有持久化文件系统
    • 多轮交互之间可以保留文件状态
  • Web 集成
    • 可接入 Google Search 做实时信息 grounding
    • 可抓取和解析非结构化在线数据

底层可视为基于 antigravity-preview-05-2026 这个通用 Agent 运行。对于开发者来说,重点不是底层实现细节,而是它已经把运行时、工具链和隔离环境都预先配置好了。

适合哪些场景

如果任务天然是“用自然语言描述,执行过程靠代码完成”,Managed Agents 就很合适。

一个典型例子是门店销售分析:

  1. 给代理访问销售数据
  2. 用自然语言提出分析需求
  3. 代理自行编写 Python 脚本
  4. 生成汇总报告和图表
  5. 把结果写回工作目录,供后续下载

这种模式的价值在于:调用方描述目标,代理处理步骤。

不适合哪些场景

如果任务只是一次性的短文本问答,或者本来已经有成熟、可控的后端流程,Managed Agents 未必划算。因为它的成本不仅来自模型 token,还来自托管运行环境和工具调用。

所以,只有当“自主规划 + 执行代码 + 状态保留 + 文件产出”这些能力真正有用时,它才值得上。

成本主要由什么决定

Managed Agents 的成本不能只看模型单价。至少有四部分:

  1. 模型 token 使用量

    • 输入 token
    • 输出 token
    • 中间过程生成的 token
    • 例如代理在内部写出 Python 脚本,这些脚本文本本身也会计费
  2. 基础设施和平台费用

    • 代理运行在 Google 集成环境中
    • 需要支付平台工具和托管运行成本
  3. 上下文缓存

    • 如果频繁复用相同数据,可利用 context caching
    • 命中缓存时成本通常明显低于标准输入 token 价格
  4. Grounding 服务

    • 例如 Google Search、Google Maps
    • 单独计费
    • 通常先有免费额度,之后按查询量收费
    • 一个常见量级是约 $14/1000 queries

本示例使用的是 antigravity-preview-05-2026,其背后由 Gemini 3.5 Flash 提供能力。对应 token 价格如下:

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

成本判断怎么做

如果任务会反复执行、每次都要读相同数据、并且需要生成脚本和图表,那么:

  • 使用缓存会有明显帮助
  • 让代理直接读取仓库或远程数据,比每次把大文件塞进 prompt 更合理
  • 多轮交互时复用同一个 environment,比每轮重新初始化更省

如何完成 API 和 Python 环境准备

结论:准备工作不复杂,但有两个地方不能漏——API Key 和 billing。

API Key 怎么配

先在 Google AI Studio 创建 API 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,就会出现版本描述不一致。以命令本身为准。

如何发起第一次 Managed Agent 交互

最小可运行例子可以非常简单:让代理安装 matplotlib,再回报安装版本。

最小示例代码

from dotenv import load_dotenv
from google import genai

# Load secure environment variables
load_dotenv()

# Initialize the GenAI Client
client = genai.Client()

# 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"
)

# 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

这个结果里最重要的字段是什么

最重要的是两个字段:

  • status
  • environment_id

其中 environment_id 尤其关键。它不是一个普通返回值,而是后续多轮交互、文件保留和结果下载的锚点。

沙箱环境能保留多久,如何复用

结论:环境不是永久的,但也不是“一轮即毁”。

每次交互都运行在一个临时沙箱里。这个环境在最后一次活动后,最多保留 7 天,之后会被删除。生命周期可以理解为:

  • Created / Active
  • Idle
  • Offline
  • Deleted

只要环境还没有被删除,就可以继续访问这个 environment,并在里面执行后续步骤。

为什么 environment_id 很重要

因为它同时关联了两类状态:

  1. 文件系统状态

    • 已生成的脚本
    • 已安装的依赖
    • 已下载的数据
    • 已输出的图表
  2. 对话上下文

    • 前面做过什么
    • 上一轮的分析目标是什么
    • 下一轮该继续哪一步

这使得“写脚本 -> 跑脚本 -> 取结果”可以拆成多轮完成,而不是逼着模型在一轮里全做完。

多轮交互应该怎么写

结论:要同时传两样东西——前一次交互 ID 和环境 ID。

下面这个例子先让代理写一个求和脚本,再在同一环境中执行它:

# 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 让代理知道前面对话历史
environment 让代理回到之前的同一个沙箱文件系统

如果只传 previous_interaction_id,代理可能“知道聊过什么”,但不一定还能访问之前生成的文件。

如果只传 environment,代理可能“还在原来的目录里”,但不一定理解上下文衔接。

这两个通常应一起传。

数据文件应该怎么交给 Agent

Managed Agents 支持多种数据共享方式:

  • Inline data
    • 把文件内容读取为字符串,直接随交互发送
  • Hosted file
    • 提供公开 URL,让代理自行下载
  • GitHub repository
    • 直接把公开仓库克隆到工作区
  • Google Cloud Bucket
    • 使用 GCS 存储,并为项目配置访问权限

哪种方式适合什么情况

结论如下:

  • 小文件、本地临时数据:用 inline
  • 大文件、代码与数据一起分发:用 GitHub repository
  • 正式生产数据:更适合对象存储或受控 URL

这里重点看两种最常用方式。

如何传内联文件

适用于小型本地文件。限制是:

  • 单个文件最多 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 用来声明注入到环境里的数据源
  • target 指定代理环境中的落盘位置
  • content 对于 inline 类型就是纯字符串内容
  • 文件应放在 workspace 目录下

如何共享 GitHub 仓库

如果文件较大,或者本来就想把“代码 + 数据 + 配置”一起交给代理,仓库方式更自然。

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

对于数据分析类任务,这通常比 inline 更实用,因为数据集、说明文件、脚本模板和配置文件都能一起带进去。

代理生成的图表和文件怎么取回本地

结论:通过下载整个环境快照最稳妥。

每个 workspace 都可以通过这个 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}")

这个方式的限制是什么

它适合“任务做完后整体取回结果”。

如果你的需求是:

  • 实时查看中间文件
  • 增量同步单个结果
  • 对工作区做细粒度文件管理

那还需要进一步封装自己的传输与监控逻辑。Managed Agents 本身更偏向“代理做完一批活,再把工作区打包拿走”。

如何创建一个专门做数据分析的 Agent

前面一直在直接调用基础代理 antigravity-preview-05-2026。如果想让代理带着固定角色、固定数据源和固定技能运行,就应该显式创建自己的 Agent。

这里构建一个 data-analyst

创建 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 自定义代理名,这里是 data-analyst
base_agent 指定基于哪个基础代理构建
base_environment 为该代理预加载文件、技能和仓库

这一步的重点不是“再包一层 API”,而是把代理运行所需的行为约束和资源预先固化下来。

AGENTS.md 应该写什么

结论:把它当成系统提示词文件,但写法要更工程化。

这个文件路径必须是:

.agents/AGENTS.md

它主要定义:

  • 代理角色
  • 主要任务目标
  • 行为边界
  • 可访问的数据源或工具
  • 输出格式和沟通方式
  • 遇到歧义时的处理策略

一个好用的 AGENTS.md 应该尽量:

  • 简洁
  • 明确
  • 分条列出
  • 避免互相冲突的要求

如果这里写得模糊,代理的行为就会漂。

SKILL.md 应该怎么组织

结论:可复用、可触发、步骤明确的能力,应该单独写成 skill。

每个 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>

这个结构里:

  • name 是技能名
  • description 说明什么时候应使用这个技能
  • 正文部分写具体执行步骤

数据分析示例里的 skill 是什么

这里给 data-analyst 配了一个 csv-aggregator 技能。

这个技能适用于:

  • 按某列分组
  • 对另一列做求和
  • 输出聚合结果
  • 进一步生成图表

例如分析 Netflix 数据集时,如果要找观看量最高的内容类别,就可以:

  • Genre 分组
  • Viewership 求和

把这套流程写进 SKILL.md 后,代理在遇到这类需求时就更容易稳定地走同一套步骤。

Agent 已存在时怎么处理

结论:Agent 是持久对象,不能每次无脑重复创建。

如果多次执行相同创建逻辑,通常会报错。因此更合理的做法是:

  • 先尝试创建
  • 如果已存在,就加载

可通过一个类似 load_or_create_agent() 的辅助函数封装:

  • client.agents.create()
  • client.agents.load()

这样脚本可以重复运行,而不需要每次手动清理代理资源。

如何把数据分析 Agent 跑起来

这里使用一个 Netflix 数据集进行测试,数据文件位于仓库的 data 目录下。

完整流程分三步:

  1. 初始化客户端并加载 Agent
  2. 在远程环境安装绘图库
  3. 调用 skill 生成分析脚本并执行
  4. 下载环境拿回图表

第一步:初始化客户端

from dotenv import load_dotenv
from google import genai
import utils

load_dotenv()
client = genai.Client()

第二步:加载或创建 data-analyst

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"
)

这里不再需要手动重新传仓库和配置文件,因为这些已经在 Agent 的 base_environment 里定义好了。

第四步:让代理分析 Netflix 数据

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
)

这里复用了 inter1.environment_id,让代理继续在同一个环境里工作。

第五步:执行前一步生成的脚本

按照技能定义,前一步会生成一个 genres.py。接着执行它:

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

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

utils.download_env(inter3.environment_id)

执行完成后,工作区里应该已经生成对应图表。下载环境归档后,就可以在本地查看结果。

这种 Agent 方案的优势和边界是什么

结论可以分两部分看。

优势在哪里

Managed Agents 最大的优势是把这几件事合并成了一个统一接口:

  • 推理
  • 规划
  • 写代码
  • 运行代码
  • 管理文件
  • 多轮保留状态

对于原本需要自己搭建容器沙箱、执行器、文件同步和上下文管理的系统,这是很明显的工程简化。

尤其在这些场景里价值很高:

  • 自动化分析任务
  • 研究型脚本执行
  • 需要文件产出的 Agent 工作流
  • 原型验证和内部工具

边界在哪里

但它也不是通用解法。

限制主要在:

  • 成本不只看 token
  • 运行环境是托管的,不是完全自控
  • 生命周期有限,环境最多保留 7 天
  • 更适合任务批处理,不是高频低延迟在线接口
  • 如果需求是严格确定性的生产流程,传统后端往往更稳定

所以最合理的定位是:把它当成“能自己动手的智能执行层”,而不是替代所有业务后端。

实践建议:什么时候该用,什么时候别用

最后给几个直接可执行的判断标准。

可以优先尝试的情况

如果同时满足下面几条,值得直接上 Managed Agents:

  • 任务需要多步推理
  • 中间必须运行代码
  • 结果要落地成文件或图表
  • 多轮交互需要保留工作区状态
  • 想快速验证 Agent 工作流,而不是先搭基础设施

不建议优先使用的情况

如果更接近下面这些条件,就先别急着上:

  • 只是简单问答或内容生成
  • 每次调用都要求强确定性和低延迟
  • 数据和执行环境必须完全内网可控
  • 成本预算对每次中间 token 都非常敏感
  • 已经有成熟的数据处理管道,只差一层自然语言入口

小结

Gemini Managed Agents 的价值不在“又一个模型接口”,而在“给模型一个可工作的执行环境”。只用一次 API 调用,就能拿到具备代码执行、文件管理和联网能力的代理,并且支持多轮环境复用。

如果只是拿它聊天,优势发挥不出来;如果任务本身要求代理自己写脚本、分析数据、生成图表并把结果保存下来,它就会非常顺手。

上面的数据分析示例已经覆盖了最关键的能力面:

  • 创建交互
  • 复用环境
  • 传递文件
  • 定义 Agent 行为
  • 加载 skill
  • 下载工作区结果

把这套流程跑通后,再往上扩展成更复杂的报表生成、分析助手或半自动研究代理,就有了可靠起点。

关于

关注我获取更多资讯

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