首页 / 文章

Gemini API中的托管代理:沙箱、技能与持久代理

深入详解 Google 的 Antigravity Managed Agents:远程 Linux 沙箱、出口代理、多轮状态处理、技能机制、命名代理以及生产环境应用模式。

发布者:REACTAPP.TOP阅读约 40 分钟9197 词

来源: Antigravity Managed Agents Tutorial: Ship Production AI Agents

每个智能体构建者都会遇到的障碍

任何开发过人工智能应用的人都知道这个难题。当让语言模型协助搭建网站时,它会给出结构良好的代码,但随后却毫无进展,因为该模型无法打开编辑器、保存文件或点击“运行”来验证代码是否正常工作。所有繁重的工作都落在了开发人员身上。

现有的智能体工具确实能处理更多任务,包括启动服务器和运行测试。但即便自行搭建,仍需处理多项工作:

  • 提供沙箱环境,让模型能够执行代码而不破坏你的文件
  • 编写用于在各个模块之间传输数据的代码
  • 配置相关工具,使模型能够调用它们、访问数据或运行脚本

随之而来的是更多的运营开销,所有这些都是为了确保系统安全运行。以下是模型需要编写并测试 Python 脚本时的具体情况。

from google import genai
import subprocess

client = genai.Client()

# Step 1: Ask the model for code
response = client.models.generate_content(
    model="gemini-2.5-flash",
    contents="Write a Python script that checks password strength and saves a report."
)

# Step 2: YOU must manually extract the code block from the text response
code = extract_code_from_markdown(response.text)  # You wrote this function

# Step 3: YOU must save the file and run it locally
with open("password_checker.py", "w") as f:
    f.write(code)

# ⚠️ Danger: Running untrusted AI-generated code on YOUR machine!
result = subprocess.run(["python3", "password_checker.py"], capture_output=True, text=True)
print(result.stdout)

开发者需要承担所有这些工作:从回复中提取代码、处理文件读写操作、执行存在风险的本地程序,以及当出现故障时必然会触发的错误处理循环。

是否可以通过一次 API 调用来完成所有这些任务?谷歌的Managed Agents框架及其核心代理 Antigravity正是为此设计的。该模型被转化为一种服务:它不再是一个仅能返回文本的聊天机器人,而是能够使用由谷歌管理的安全云计算机,以及连接至实时互联网的 Linux 工作环境。

下表对比了三种级别的 AI 系统。

核心代理循环

面对某项任务时,Antigravity 代理不会仅凭猜测行事,而是在由真实硬件支持的持续循环中工作。

┌────────────────────────────────────────┐
│          1. PLAN & REASON              │
│  (Analyzes objective & breaks it down) │
└───────────────────┬────────────────────┘
                    │
                    ▼
┌────────────────────────────────────────┐
│               2. ACT                   │
│ (Executes a tool: Bash, Python, Web)   │
└───────────────────┬────────────────────┘
                    │
                    ▼
┌────────────────────────────────────────┐
│             3. OBSERVE                 │
│ (Reads execution output, errors, data) │
└───────────────────┬────────────────────┘
                    │
                    └─── Loop back until task is complete

这不仅仅是一次提示与回复的简单过程。智能体会先编写脚本并执行它,如果在终端输出中出现SyntaxError错误,它会修复该问题后再次尝试,如此反复直至任务完成。

远程沙箱

每次调用智能体时,谷歌都会启动一个专用的工作空间。

这样就能在云端获得一台真正的Linux电脑,该电脑在智能体执行任务期间归其使用。

API背后的两个层面

使用托管智能体涉及两个独立的层面,两者均通过Gemini API进行访问。

                  ┌─────────────────────────────────┐
                  │           YOUR APP              │
                  └────────┬───────────────┬────────┘
                           │               │
      1. Define/Configure  │               │ 2. Run Task
      (System rules, ID)   │               │ (Send Prompt)
                           ▼               ▼
 ┌───────────────────────────────────┐   ┌───────────────────────────────────┐
 │        THE CONTROL PLANE          │   │         THE RUNTIME PLANE         │
 │          (Agents API)             │   │        (Interactions API)         │
 ├───────────────────────────────────┤   ├───────────────────────────────────┤
 │ Saves persistent identity, system │   │ Spawns the Ubuntu sandbox, logs   │
 │ instructions, and data mounts.    │   │ live traces, and processes loops. │
 └───────────────────────────────────┘   └───────────────────────────────────┘

控制平面即 Agents API,是配置和注册智能体的地方。这就好比填写员工档案:包括姓名、系统指令、自定义技能以及需要克隆的代码库。该接口会返回一个静态的Agent ID。

运行时平面即 Interactions API,是实际执行任务的地方。任务会以“交互”形式关联到某个 Agent ID,该平面负责准备沙箱环境、运行工具、记录推理过程,并驱动智能体循环。

通过出口代理实现安全

让自主智能体运行未经验证的脚本存在风险。Google 通过出口代理层来隔离该环境。

 ┌─────────────────────────┐
 │ REMOTE UBUNTU SANDBOX   │
 │ (No internal secrets)   │
 └───────────┬─────────────┘
             │ Agent attempts outbound API call
             ▼
 ┌─────────────────────────┐
 │   EGRESS PROXY LAYER    │ ◄── Checks Domain Allowlist
 ├─────────────────────────┤
 │ Intercepts connection,  │
 │ injects secrets securely│
 └───────────┬─────────────┘
             │ Safe, Authenticated Request Sent
             ▼
    [ External Target API ]

它提供三项保障:

  • 沙箱内无机密信息。 API密钥和数据库密码绝不会存储在代理的工作空间中。
  • 域名白名单。 您可以决定代理能够访问哪些外部域名。
  • 请求头转换。 对于向外部API的调用,代理会捕获请求,根据白名单检查域名,并自行添加认证令牌。数据会返回给代理,而私钥则对其保密。

大约五分钟即可创建第一个代理

要求

  • Python 3.10或更高版本,推荐使用3.12,因为它与沙箱运行环境匹配
  • google-genai SDK 2.0.0版本或更高(撰写本文时当前版本为2.8.0)
  • API密钥,可通过Google AI Studio的免费套餐获取
  • 任何操作系统(macOS、Linux、Windows或WSL),因为代码在本地运行,而代理则在Google的云端运行
  • 请搭建虚拟环境并安装SDK。

    python3 -m venv managed-agents-env
    source managed-agents-env/bin/activate   # On Windows: managed-agents-env\Scripts\activate
    # Install (or upgrade) the Google GenAI SDK
    pip install -U google-genai
    # Verify the version — must be 1.14.0 or later
    python3 -c "import google.genai; print(google.genai.__version__)"
    # Set your API key (get one at https://aistudio.google.com/apikey)
    export GEMINI_API_KEY="your-api-key-here"
    

    如果您不想进行本地设置,Google AI Studio 提供了“托管代理”模板功能,可在浏览器中作为交互式实验环境使用。

    运行示例

    这里的每个示例都是一个完整且独立的 Python 脚本。将其保存到文件中,然后运行即可。

    # 1. Save the code to a file (an example name used here is hello_agent.py
    vim hello_agent.py   # or use any editor
    
    # 2. Run it
    python3 hello_agent.py
    

    由于智能体需要启动沙箱、编写并运行代码、读取错误信息并进行迭代,每次交互所需时间从半分钟到三分钟不等,具体取决于任务复杂度。简单的任务可在一分钟内完成,而复杂的多轮交互则每轮可能需要两到三分钟。

    你好,托管智能体

    将之前那些繁琐的多步骤代码与托管智能体的实现方式对比一下吧。

    from google import genai
    
    client = genai.Client()
    
    # One API call. One autonomous agent. One remote Linux sandbox.
    interaction = client.interactions.create(
        agent="antigravity-preview-05-2026",
        input="Write a Python script that generates 100 random exam scores between 0 and 100, "
              "calculates the mean, median, and standard deviation, prints a summary, "
              "and saves a grade distribution histogram as grade_report.png using matplotlib.",
        environment="remote"  # This provisions a secure Linux sandbox hosted by Google
    )
    
    print(interaction.output_text)
    

    运行它。

    python3 hello_agent.py
    

    第一次交互产生了以下输出。由于数据是随机的,不同运行次数的数值会有所差异。

    I have successfully written and executed a Python script that generates 100 random exam scores, computes their key statistics, and plots a grade distribution histogram.
    
    ### 1. Generated Python Script (`generate_report.py`)
    
    Here is the Python script, which is saved in the environment as `generate_report.py`. It uses `numpy` for data generation, `statistics` conventions for calculation (such as sample standard deviation), and `matplotlib` to generate a high-quality visualization.
    
    ```python
    import numpy as np
    import matplotlib.pyplot as plt
    import statistics
    
    def generate_and_analyze_grades():
        # Set a random seed for reproducibility
        np.random.seed(42)
    
        # Generate 100 random exam scores between 0 and 100 (inclusive)
        scores = np.random.randint(0, 101, size=100)
    
        # Calculate statistics using Python's standard statistics module and NumPy
        # (Using ddof=1 for sample standard deviation, which is standard for student grade samples)
        mean_val = np.mean(scores)
        median_val = np.median(scores)
        std_val = np.std(scores, ddof=1)
    
        # Print summary to console
        print("=========================================")
        print("         EXAM GRADE REPORT SUMMARY       ")
        print("=========================================")
        print(f"Number of Students : {len(scores)}")
        print(f"Minimum Score      : {np.min(scores)}")
        print(f"Maximum Score      : {np.max(scores)}")
        print(f"Mean Score         : {mean_val:.2f}")
        print(f"Median Score       : {median_val:.2f}")
        print(f"Standard Deviation : {std_val:.2f}")
        print("=========================================")
    
        # Create the histogram plot
        plt.figure(figsize=(10, 6))
    
        # Customize the grid and style
        plt.grid(axis='y', linestyle='--', alpha=0.7, zorder=0)
    
        # Draw the histogram with bins of size 10 (0-10, 10-20, ..., 90-100)
        bins = range(0, 111, 10)
        plt.hist(scores, bins=bins, color='#4A90E2', edgecolor='black', rwidth=0.85, zorder=3)
    
        # Add labels and title
        plt.title('Distribution of Exam Scores', fontsize=16, fontweight='bold', pad=15)
        plt.xlabel('Exam Scores', fontsize=12, labelpad=10)
        plt.ylabel('Number of Students', fontsize=12, labelpad=10)
    
        # Mark Mean and Median with vertical lines
        plt.axvline(mean_val, color='#D0021B', linestyle='dashed', linewidth=2, zorder=4, label=f'Mean: {mean_val:.2f}')
        plt.axvline(median_val, color='#F5A623', linestyle='dotted', linewidth=2, zorder=4, label=f'Median: {median_val:.2f}')
    
        # Set x-ticks to align with bins
        plt.xticks(range(0, 101, 10))
    
        # Add a legend
        plt.legend(fontsize=11, loc='upper left')
    
        # Add details text box on the plot
        textstr = '\n'.join((
            f'Total Students: {len(scores)}',
            f'Mean: {mean_val:.2f}',
            f'Median: {median_val:.2f}',
            f'Std Dev: {std_val:.2f}'
        ))
        props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)
        plt.gca().text(0.05, 0.75, textstr, transform=plt.gca().transAxes, fontsize=10,
                verticalalignment='top', bbox=props)
    
        # Adjust layout and save the figure
        plt.tight_layout()
        output_filename = 'grade_report.png'
        plt.savefig(output_filename, dpi=300)
        print(f"\nHistogram successfully saved to '{output_filename}'")
    
    if __name__ == '__main__':
        generate_and_analyze_grades()
    ```
    
    ---
    
    ### 2. Output Statistics Summary
    
    Upon running the script in the sandbox environment, it produced the following output:
    
    ```text
    =========================================
             EXAM GRADE REPORT SUMMARY
    =========================================
    Number of Students : 100
    Minimum Score      : 1
    Maximum Score      : 100
    Mean Score         : 51.31
    Median Score       : 53.50
    Standard Deviation : 29.70
    =========================================
    
    Histogram successfully saved to 'grade_report.png'
    ```
    
    ---
    
    ### 3. Generated Histogram Details (`grade_report.png`)
    
    The script successfully outputted `grade_report.png` in high-resolution format (300 DPI) containing:
    - **Clean Grid & Styling**: Standard light-gray horizontal grids to easily identify column heights.
    - **Grade Bins**: Defined score ranges of size 10 (e.g., 0–10, 10–20, ..., 90–100) using custom spacing to give the columns a professional look.
    - **Key Metrics Highlighted**:
      - A red dashed line representing the **Mean** (`51.31`).
      - A yellow dotted line representing the **Median** (`53.50`).
    - **An Info Legend and Box**: In the top-left area summarizing all descriptive statistics for easy offline reference.
    
    ### How to Run it Yourself
    If you want to run this script in another environment, ensure you have the required packages installed:
    ```bash
    pip install matplotlib numpy
    python generate_report.py
    ```
    

    返回的是通俗易懂的英文总结,而非程序输出。它会描述智能体的操作,即它编写的代码、安装的软件包以及最终结果,而脚本和图表文件本身仍保留在远程沙箱中。

    那只是几行易于理解的代码。在幕后,智能体执行了以下操作:

    1. 启动了一个 Ubuntu Linux 沙箱
    2. 编写了一个 Python 脚本来生成随机数据并计算统计值
    3. 在未被要求的情况下自行安装了 matplotlib
    4. 运行脚本并将直方图保存为 grade_report.png
    5. 返回包含统计数据的总结以及图表已保存的确认信息

    更复杂的任务则需要多种工具协同完成。

    from google import genai
    client = genai.Client()
    
    interaction = client.interactions.create(
        agent="antigravity-preview-05-2026",
        input="""
        Research the top 5 most popular Python web frameworks in 2026.
        For each framework:
        1. Find the latest version number and release date
        2. Count the GitHub stars
        3. Write a comparison table in Markdown
        """,
        environment="remote"
    )
    
    print(interaction.output_text)
    

    在本次运行中,该代理通过网页浏览在谷歌上搜索,利用代码执行处理数据,并通过文件管理存储结果,所有操作均在一次API调用之内独立完成。其输出如下。

    The landscape of Python web development in **2026** is marked by a fascinating split [1, 2]. On one side, classic **backend-first** and **API-focused** frameworks (Django, FastAPI, Flask) remain the dominant standards for enterprise applications and microservices [3, 5]. On the other side, **pure-Python UI and full-stack** frameworks (Streamlit, Reflex) have seen explosive growth—driven by the need to build interactive web apps, data dashboards, and AI/ML interfaces without writing JavaScript or TypeScript [1, 2].
    
    Below is an in-depth research report on the **top 5 most popular Python web frameworks in 2026**, ranked by GitHub stars and overall developer adoption.
    
    ---
    
    ### Detailed Breakdown of the Top 5 Python Web Frameworks
    
    #### 1. FastAPI (99,034 GitHub Stars)
    *   **Latest Version:** `0.136.3` (Released: **May 23, 2026**)
    *   **Architecture Type:** ASGI (Asynchronous Server Gateway Interface)
    *   **Primary Focus:** High-Performance APIs and Microservices [4]
    *   **Core Philosophy:** FastAPI is designed to build APIs quickly with standard Python type hints. It leverages **Pydantic v2** for extremely fast data validation and serialization, and **Starlette** for high-concurrency async handling [3, 4]. It natively auto-generates interactive Swagger UI and ReDoc documentation.
    *   **Ideal Use Case:** AI/ML model deployment, backend APIs for single-page applications (React/Vue/Svelte), and low-latency microservices [5].
    
    #### 2. Django (87,811 GitHub Stars)
    *   **Latest Version:** `6.0.6` (Released: **June 3, 2026**)
    *   **Architecture Type:** WSGI & ASGI (Fully async-supported)
    *   **Primary Focus:** "Batteries-Included" Monolithic Web Applications [4]
    *   **Core Philosophy:** As an 18-year industry standard, Django remains the premier full-featured web framework [2]. It handles everything—database routing (via its powerful ORM), administration panels, user authentication, form validation, and robust security defaults (SQLi, CSRF, XSS protection) [1]. In 2026, Django 6.x is highly optimized with full native asynchronous views and type hints [4].
    *   **Ideal Use Case:** Large-scale enterprise applications, content management systems, e-commerce platforms, and fast SaaS MVP development where you need a complete, secure architecture out of the box [2, 5].
    
    #### 3. Flask (71,638 GitHub Stars)
    *   **Latest Version:** `3.1.3` (Released: **February 19, 2026**)
    *   **Architecture Type:** WSGI
    *   **Primary Focus:** Lightweight, Flexible Microframework [4]
    *   **Core Philosophy:** Flask provides a minimalist core, leaving the choice of database ORM, form handling, and security components completely up to the developer [1, 2]. Paired with modern 2026 extensions (SQLAlchemy 2.x, Pydantic), it represents a simple, un-opinionated foundation that never gets in the developer's way [3].
    *   **Ideal Use Case:** Small utility applications, lightweight APIs, microservices, and custom projects where developers want total control over their system design [1, 5].
    
    #### 4. Streamlit (44,895 GitHub Stars)
    *   **Latest Version:** `1.58.0` (Released: **May 28, 2026**)
    *   **Architecture Type:** UI-First Scripting Paradigm
    *   **Primary Focus:** Rapid Data and Machine Learning Applications [1]
    *   **Core Philosophy:** Streamlit turns standard Python scripts into interactive, beautiful web apps in a matter of minutes. It handles the entire frontend and backend flow by re-running the script from top to bottom whenever a user interacts with a widget.
    *   **Ideal Use Case:** Quick data dashboards, machine learning model prototypes, and internal analytical tools for teams without frontend resources [1, 2].
    
    #### 5. Reflex (28,467 GitHub Stars)
    *   **Latest Version:** `0.9.4` (Released: **June 4, 2026**)
    *   **Architecture Type:** Full-Stack Async React-Compiled
    *   **Primary Focus:** Interactive, Pure-Python Full-Stack Apps [2]
    *   **Core Philosophy:** Formerly known as Pynecone, Reflex compiles Python code into a high-performance **React/Next.js frontend** and a **FastAPI backend**, using real-time WebSockets to synchronize states between them [1, 2]. It bypasses JavaScript entirely, offering 60+ pre-built Radix UI components with native Tailwind integration [1, 2].
    *   **Ideal Use Case:** Complex, interactive web applications, real-time streaming dashboards (e.g., AI chat applications, financial trackers), and user-facing SaaS applications built entirely in Python [2].
    
    ---
    
    ### Other Honorable Mentions in 2026
    While they didn't make the top 5 by GitHub stars, these frameworks are heavily utilized:
    *   **Tornado** (22,182 stars, v6.5.7, Released June 8, 2026): A mature, asynchronous networking framework ideal for long-lived WebSocket connections [4].
    *   **Sanic** (18,629 stars, v25.12.1, Released May 31, 2026): An ASGI web framework built for extreme speed and Flask-like simplicity, running on its own high-performance web server.
    *   **Litestar** (8,269 stars, v2.23.0, Released May 29, 2026): A highly structured, strict, and enterprise-grade ASGI alternative to FastAPI [3, 4].
    
    ---
    
    ### 2026 Python Web Frameworks Comparison Table
    
    | Framework | GitHub Stars | Latest Version | Release Date | Architecture | Best For | Key Strength | Learning Curve |
    | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
    | **FastAPI** | ~99,034 | `0.136.3` | May 23, 2026 | ASGI (Async) | High-performance API development & AI model deployments [4, 5] | Autogenerated Swagger docs, native Pydantic v2 validation [4] | **Easy / Moderate** |
    | **Django** | ~87,811 | `6.0.6` | Jun 03, 2026 | WSGI / ASGI | Enterprise apps, content-heavy websites, secure SQL backends [1, 2] | "Batteries-included" (built-in admin, ORM, security, auth) [1, 2] | **Moderate / Hard** |
    | **Flask** | ~71,638 | `3.1.3` | Feb 19, 2026 | WSGI (Sync-first) | Microservices, custom MVPs, lightweight apps [1, 5] | Unrivaled design flexibility, minimal core overhead [1] | **Very Easy** |
    | **Streamlit**| ~44,895 | `1.58.0` | May 28, 2026 | Scripted Reactive | Data visualization dashboards & ML interactive tools [1] | Zero frontend experience needed; fast prototyping [1] | **Very Easy** |
    | **Reflex** | ~28,467 | `0.9.4` | Jun 04, 2026 | Async React-compiled | Interactive, real-time SaaS & full-stack apps in pure Python [2] | True multi-page routing, state management without JavaScript [2] | **Moderate** |
    
    ---
    
    ### Guidance: Which Framework Should You Choose in 2026?
    
    1.  **Choose FastAPI** if you are building modern REST/GraphQL APIs, backend microservices, or deploying AI/ML models with high concurrency and automatic documentation [3, 5].
    2.  **Choose Django** if you are building database-driven business platforms or SaaS architectures where user authentication, administrative interfaces, and built-in security are paramount [1, 2].
    3.  **Choose Flask** if you need to build simple backend services or you want to hand-select every tool in your stack (e.g., combining custom database layers with external identity providers) [1].
    4.  **Choose Streamlit** if your core team consists of data scientists or business analysts who need to quickly present internal analytics, charts, and interactive widgets without building a complex web architecture [1, 2].
    5.  **Choose Reflex** if you want to build a fully interactive, production-ready full-stack application (with complex states, WebSocket interactions, and beautiful custom styles) but do not want to divide your team between Python and JavaScript [2].
    
    ---
    
    ### Sources & References
    *   [1] [Best Python Web Frameworks 2026 Compared - Reflex](https://reflex.dev/blog/top-python-web-frameworks/)
    *   [2] [Django vs Flask vs Reflex (April 2026) - Reflex](https://reflex.dev/blog/django-vs-flask-vs-reflex-comparison/)
    *   [3] [12 Modern Python Frameworks to Try in 2026 - Medium](https://medium.com/the-pythonworld/12-modern-python-frameworks-to-try-in-2026-e7089305bb19)
    *   [4] [5 top Python web frameworks of 2026 - Educative.io](https://www.educative.io/blog/top-python-web-frameworks)
    *   [5] [The Python Backend Framework Decision Guide for 2026 - Rollbar](https://rollbar.com/blog/python-backend-frameworks/)
    

    具有持久状态的多轮对话

    默认情况下,每次调用 interactions.create() 都会创建一个全新的空白沙箱。为让智能体能够基于之前的工作继续处理,需将两个 ID 传回。

    from google import genai
    client = genai.Client()
    
    # Turn 1: Research and create a report
    interaction_1 = client.interactions.create(
        agent="antigravity-preview-05-2026",
        input="Research the current state of carbon capture technology in 2026. "
              "Write a comprehensive 500-word report and save it as report.md",
        environment="remote"
    )
    print(f"Environment ID: {interaction_1.environment_id}")
    print(f"Interaction ID: {interaction_1.id}")
    print(interaction_1.output_text)
    
    # Turn 2: Build on the previous work - same sandbox, same files
    interaction_2 = client.interactions.create(
        agent="antigravity-preview-05-2026",
        environment=interaction_1.environment_id,       # ← Re-attaches to same Ubuntu sandbox
        previous_interaction_id=interaction_1.id,       # ← Preserves conversation memory
        input="Convert that report.md file into a clean index.html webpage "
              "with modern inline CSS styling and responsive design."
              " Please output the contents of the index.html file"
    )
    print(interaction_2.output_text)
    

    第一次交互生成了一个report.md文件。

    Environment ID: 5eb9b4b8-c02f-4a8f-b7a0-c90a796c01a6
    Interaction ID: v1_ChdidXNuYXJLQkF1eWlqdU1QODRmUjJRZxIXYnVzbmFyS0JBdXlpanVNUDg0ZlIyUWc
    I have researched the state of carbon capture, utilization, and storage (CCUS)
    technology in 2026 and compiled a comprehensive 494-word report.
    The report has been successfully saved to your environment as **`report.md`**.
    
    Below is the full text of the report,
    highlighting how the CCUS sector has transitioned from pilot-stage
    demonstrations to industrial infrastructure in 2026.
    
    ***
    
    # The State of Carbon Capture Technology in 2026: From Pilot to Infrastructure
    
    ## Executive Summary
    ....
    
    ## Point-Source Capture: The Current Backbone
    ...
    
    ## Scaling Direct Air Capture (DAC)
    ...
    
    ## Infrastructure, Transport, and Policy
    ...
    
    ## Key Challenges
    ...
    
    ***
    
    ### Sources Cited
    
    * **[1] S&P Global:** [2026 CCUS: Navigating the tides of the great realignment](https://www.spglobal.com/energy/en/news-research/blog/energy-transition/041426-2026-ccus-navigating-the-tides-of-the-great-realignment) (April 2026)
    * **[2] Carbon Herald:** [What's Next For Carbon Capture, Utilization & Storage (CCUS) In 2026](https://carbonherald.com/whats-next-for-carbon-capture-utilization-storage-ccus-in-2026/) (January 2026)
    * **[3] Nature Tech Memos:** [Top 10 Carbon Capture Startups for Corporate Partnerships in 2026](https://www.naturetechmemos.com/p/top-10-carbon-capture-startups-for-corporate-partnerships-in-2026) (April 2026)
    .....
    

    第二次交互使用了之前的环境和交互方式,要求生成报告的HTML版本index.html,并且明确指示在回复中包含HTML内容。

    I have successfully converted your `report.md` file into a clean, modern, and highly responsive **`index.html`** webpage!
    
    ### What was done:
    1. **Designed a cohesive palette:** Implemented a modern climate-tech inspired aesthetic using Slate (`#1e293b`) and a range of deep and light teals (`#0f766e`, `#14b8a6`, `#115e59`).
    2. **Added an Interactive Stat Dashboard:** Created a high-level statistical summary card grid displaying key 2026 data at a glance (e.g., global Mtpa capacity, Stratos targets, US Section 45Q tax credits).
    3. **Structured visual highlights:** Embedded two distinct grid comparison cards for the **Climeworks Mammoth** and **1PointFive Stratos** facilities, as well as a custom callout block highlighting the trans-European **Northern Lights** shipping route.
    4. **Professionalized the typography & chemistry:** Used system-ui fonts for excellent loading speeds and correctly formatted all chemical formulas to standard subscripts (e.g., **CO<sub>2</sub>**).
    5. **Citations & Interactivity:** Mapped the original references into clickable, superscript citation numbers (e.g., `[1]`) that link smoothly down to a beautifully bulleted "Sources Cited" section with custom index bullet styling.
    
    The full HTML contents of the newly created `index.html` are shown below:
    
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>The State of Carbon Capture Technology in 2026</title>
        <style>
            :root {
                --primary: #0f766e;
                --primary-light: #14b8a6;
                --primary-dark: #115e59;
                --bg: #f8fafc;
                --card-bg: #ffffff;
                --text-main: #1e293b;
                --text-muted: #475569;
                --accent: #0284c7;
                --border: #e2e8f0;
                --shadow: 0 4px 6px -1px rgba(15, 118, 110, 0.05), 0 2px 4px -2px rgba(15, 118, 110, 0.05);
                --shadow-md: 0 10px 15px -3px rgba(15, 118, 110, 0.1), 0 4px 6px -4px rgba(15, 118, 110, 0.1);
            }
            * {
                box-sizing: border-box;
            }
            body {
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
                background-color: var(--bg);
                color: var(--text-main);
                line-height: 1.8;
                margin: 0;
                padding: 0;
                -webkit-font-smoothing: antialiased;
            }
    
            <!-- LOTS MORE CSS STUFF :-) -->
    
            footer {
                text-align: center;
                color: var(--text-muted);
                font-size: 0.875rem;
                margin-top: 4rem;
                padding-top: 2rem;
                border-top: 1px solid var(--border);
            }
        </style>
    </head>
    <body>
    
        <header>
            <div class="header-content">
                <span class="meta">Special Intelligence Report</span>
                <h1>The State of Carbon Capture Technology in 2026</h1>
                <p>From Pilot to Infrastructure</p>
            </div>
        </header>
    
        <main>
            <!-- Key Metrics Dashboard -->
            <div class="stats-grid">
                <div class="stat-card">
                    <div class="stat-num">~73 Mtpa</div>
                    <div class="stat-label">Global Operational Capacity</div>
                </div>
                <div class="stat-card">
                    <div class="stat-num">500k Tons</div>
                    <div class="stat-label">Stratos DAC Annual Target</div>
                </div>
                <div class="stat-card">
                    <div class="stat-num">Up to $180</div>
                    <div class="stat-label">US 45Q Subsidy per Ton</div>
                </div>
                <div class="stat-card">
                    <div class="stat-num">36,000 T</div>
                    <div class="stat-label">Mammoth Iceland Capacity</div>
                </div>
            </div>
    
            <div class="content-wrapper">
                <!-- Executive Summary -->
                <section id="executive-summary">
                    <h2>Executive Summary</h2>
                    <p>
                        In 2026, the Carbon Capture, Utilization, and Storage (CCUS) industry is undergoing an "industrial hardening" phase, transitioning decisively from demonstration-stage pilots to commercial-scale infrastructure<sup><a href="#ref-1" class="citation-link">[1]</a></sup>. Global operational capture capacity has reached approximately 73 million metric tons per annum (Mtpa) as of mid-2026, up from 50 Mtpa in early 2025<sup><a href="#ref-1" class="citation-link">[1]</a></sup><sup><a href="#ref-2" class="citation-link">[2]</a></sup>. This momentum is propelled by robust climate policies, corporate carbon-removal commitments, and the commissioning of megaton-scale facilities.
                    </p>
                </section>
    
                <!-- Point-Source Capture -->
                <section id="point-source">
                    <h2>Point-Source Capture: The Current Backbone</h2>
                    <p>
                        Point-source carbon capture remains the commercial backbone of CCUS<sup><a href="#ref-2" class="citation-link">[2]</a></sup>. Technologies deployed at industrial and energy facilities—such as cement, steel, chemicals, and refining—now represent the vast majority of active capture capacity. Post-combustion chemical absorption using amine-based solvents is the most widely deployed technology<sup><a href="#ref-2" class="citation-link">[2]</a></sup>. Companies like Carbon Upcycling Technologies are successfully integrating capture systems with utilization, converting captured carbon dioxide (CO<sub>2</sub>) into high-quality construction materials, turning emissions from cement manufacturers into a low-carbon concrete feedstock<sup><a href="#ref-3" class="citation-link">[3]</a></sup>.
                    </p>
                </section>
    
                <!-- Scaling Direct Air Capture -->
                <section id="dac">
                    <h2>Scaling Direct Air Capture (DAC)</h2>
                    <p>
                        Direct Air Capture is experiencing a dramatic scale-up<sup><a href="#ref-4" class="citation-link">[4]</a></sup>. Climeworks' "Mammoth" facility in Iceland, operational since May 2024, captures up to 36,000 tons of CO<sub>2</sub> annually, storing it permanently underground via Carbfix mineralization<sup><a href="#ref-4" class="citation-link">[4]</a></sup><sup><a href="#ref-5" class="citation-link">[5]</a></sup>. Meanwhile, 1PointFive's (a subsidiary of Occidental Petroleum) "Stratos" facility in Ector County, Texas, is entering active operation in 2026<sup><a href="#ref-4" class="citation-link">[4]</a></sup>. Designed to capture up to 500,000 tons of atmospheric CO<sub>2</sub> annually using liquid solvent technology licensed from Carbon Engineering, Stratos is currently the world’s largest DAC plant<sup><a href="#ref-4" class="citation-link">[4]</a></sup><sup><a href="#ref-6" class="citation-link">[6]</a></sup>.
                    </p>
    
                    <div class="highlight-grid">
                        <div class="highlight-box">
                            <h4>Climeworks: Mammoth (Iceland)</h4>
                            <p>Nameplate capacity of 36,000 tons/year. Relies on solid-sorbent collectors powered by clean geothermal energy with deep Carbfix basaltic storage.</p>
                        </div>
                        <div class="highlight-box">
                            <h4>1PointFive: Stratos (Texas)</h4>
                            <p>World's largest facility with 500,000 tons/year target. Employs liquid-solvent infrastructure designed for rapid regional scalability.</p>
                        </div>
                    </div>
    
                    <p>
                        Major technology firms (including Microsoft, Google, Meta, and Amazon) have signed multi-year offtake agreements for high-quality, durable carbon credits, paying between $200 and $300 per ton, though current baseline DAC capture costs remain high, between $400 and $1,000 per ton<sup><a href="#ref-3" class="citation-link">[3]</a></sup><sup><a href="#ref-7" class="citation-link">[7]</a></sup>.
                    </p>
                </section>
    
                <!-- Infrastructure, Transport, and Policy -->
                <section id="infrastructure">
                    <h2>Infrastructure, Transport, and Policy</h2>
                    <p>
                        The commercial viability of carbon capture relies heavily on dedicated transportation and storage networks<sup><a href="#ref-2" class="citation-link">[2]</a></sup>. In Europe, 2026 marks the active operation of Norway’s "Northern Lights" project, the world's first open-source CO<sub>2</sub> transport and storage network<sup><a href="#ref-8" class="citation-link">[8]</a></sup>. For example, Yara's flagship Sluiskil ammonia plant in the Netherlands is liquefying up to 800,000 tons of CO<sub>2</sub> annually to be shipped by Northern Lights for permanent undersea storage<sup><a href="#ref-8" class="citation-link">[8]</a></sup>. Concurrently, Denmark’s "Greensand" offshore storage initiative is beginning operations<sup><a href="#ref-2" class="citation-link">[2]</a></sup>.
                    </p>
    
                    <div class="callout">
                        <div class="callout-title">The Trans-European Shipping Pathway</div>
                        <p>Northern Lights bridges emission-heavy inland industrial sites like Yara Sluiskil in the Netherlands directly with permanent injection storage wells beneath the North Sea seabed.</p>
                    </div>
    
                    <p>
                        On the policy front, the sector is heavily anchored by government subsidies. In the United States, the Inflation Reduction Act’s (IRA) modified Section 45Q tax credit provides up to $180 per metric ton for DAC and $85 per metric ton for point-source capture<sup><a href="#ref-9" class="citation-link">[9]</a></sup>. In the European Union, the Net Zero Industry Act has accelerated cross-border transport approvals, providing regulatory certainty.
                    </p>
                </section>
    
                <!-- Key Challenges -->
                <section id="challenges">
                    <h2>Key Challenges</h2>
                    <p>
                        Despite rapid progress, critical bottlenecks persist. Chief among these is the high energy intensity of DAC, which requires 1.5 to 2.5 megawatt-hours (MWh) of zero-carbon energy per ton of captured CO<sub>2</sub><sup><a href="#ref-7" class="citation-link">[7]</a></sup>. Permitting delays for geologic injection wells—specifically the EPA’s rigorous Class VI permits in the United States—also restrict how fast captured carbon can be sequestered<sup><a href="#ref-4" class="citation-link">[4]</a></sup>. Overcoming these economic and infrastructure hurdles remains essential to achieving megaton targets by 2030.
                    </p>
                </section>
    
                <!-- Sources Cited -->
                <div class="sources-section">
                    <h3>Sources Cited</h3>
                    <ul class="sources-list">
                        <li id="ref-1" data-index="1"><strong>S&P Global:</strong> <a href="https://www.spglobal.com/energy/en/news-research/blog/energy-transition/041426-2026-ccus-navigating-the-tides-of-the-great-realignment" target="_blank">2026 CCUS: Navigating the tides of the great realignment</a> (April 2026)</li>
                        <li id="ref-2" data-index="2"><strong>Carbon Herald:</strong> <a href="https://carbonherald.com/whats-next-for-carbon-capture-utilization-storage-ccus-in-2026/" target="_blank">What's Next For Carbon Capture, Utilization & Storage (CCUS) In 2026</a> (January 2026)</li>
                        <li id="ref-3" data-index="3"><strong>Nature Tech Memos:</strong> <a href="https://www.naturetechmemos.com/p/top-10-carbon-capture-startups-for-corporate-partnerships-in-2026" target="_blank">Top 10 Carbon Capture Startups for Corporate Partnerships in 2026</a> (April 2026)</li>
                        <li id="ref-4" data-index="4"><strong>Senken:</strong> <a href="https://www.senken.io/blog/top-direct-air-capture-carbon-removal-projects-buyers-guide" target="_blank">The Top 3 Direct Air Capture Carbon Removal Projects</a> (February 2026)</li>
                        <li id="ref-5" data-index="5"><strong>Climeworks:</strong> <a href="https://climeworks.com/plant-mammoth" target="_blank">Mammoth: our newest direct air capture and storage facility</a> (May 2024)</li>
                        <li id="ref-6" data-index="6"><strong>Carbon Credits:</strong> <a href="https://carboncredits.com/top-3-carbon-capture-leaders-to-drive-the-net-zero-race-in-2026/" target="_blank">Top 3 Carbon Capture Leaders to Drive the Net-Zero Race in 2026</a> (January 2026)</li>
                        <li id="ref-7" data-index="7"><strong>Energy Solutions Intelligence:</strong> <a href="https://energy-solutions.co/articles/sub/carbon-capture-direct-air-dac-cost-analysis" target="_blank">Direct Air Capture in 2026: Cost, Scale, and Path to $200/tCO2</a> (January 2026)</li>
                        <li id="ref-8" data-index="8"><strong>World Economic Forum:</strong> <a href="https://www.weforum.org/stories/2026/01/scale-carbon-capture-storage-climate-action/" target="_blank">How to scale carbon capture and storage for climate action</a> (January 2026)</li>
                        <li id="ref-9" data-index="9"><strong>International Energy Agency (IEA):</strong> <a href="https://www.iea.org/policies/16255-inflation-reduction-act-2022-sec-13104-extension-and-modification-of-credit-for-carbon-oxide-sequestration" target="_blank">Inflation Reduction Act 2022: Sec. 13104 Extension and Modification of Credit for Carbon Oxide Sequestration</a> (February 2026)</li>
                    </ul>
                </div>
    
                <footer>
                    <p style="text-align: center; color: var(--text-muted); font-size: 0.875rem; margin: 0;">&copy; 2026 Carbon Capture Intelligence. Compiled June 2026.</p>
                </footer>
            </div>
        </main>
    
    </body>
    </html>
    ```
    

    生成的报告如下所示。

    两个ID

    如表格所示,这两个ID承担不同的功能。

    一个小贴士:environment_id可以不搭配previous_interaction_id一起使用。这样虽然会复用现有文件和已安装的包,但会开启新的对话流程,适合为新任务创建工作空间分支。

    下载文件

    可以让智能体在回复中包含文件内容,但这通常并非最佳选择。更常见的是让文件直接从沙箱中获取。下方的示例重现了之前生成Markdown报告和HTML版本的多轮对话过程,并在最后添加了用于将整个环境快照下载为tar文件并解压到本地文件夹的代码。这正是当前Managed Agents环境所支持的功能。

    import os
    import requests
    import tarfile
    from google import genai
    client = genai.Client()
    
    # Turn 1: Research and create a report
    interaction_1 = client.interactions.create(
        agent="antigravity-preview-05-2026",
        input="Research the current state of carbon capture technology in 2026. "
              "Write a comprehensive 500-word report and save it as report.md",
        environment="remote"
    )
    print(f"Environment ID: {interaction_1.environment_id}")
    print(f"Interaction ID: {interaction_1.id}")
    print(interaction_1.output_text)
    
    # Turn 2: Build on the previous work - same sandbox, same files
    interaction_2 = client.interactions.create(
        agent="antigravity-preview-05-2026",
        environment=interaction_1.environment_id,       # ← Re-attaches to same Ubuntu sandbox
        previous_interaction_id=interaction_1.id,       # ← Preserves conversation memory
        input="Convert that report.md file into a clean index.html webpage "
              "with modern inline CSS styling and responsive design."
              " Please output the contents of the index.html file"
    )
    print(interaction_2.output_text)
    
    env_id = interaction_2.environment_id
    api_key = os.environ.get("GEMINI_API_KEY")
    
    response = requests.get(
        f"https://generativelanguage.googleapis.com/v1beta/files/environment-{env_id}:download",
        params={"alt": "media"},
        headers={"x-goog-api-key": api_key},
        allow_redirects=True,
    )
    
    with open("snapshot_env.tar", "wb") as f:
        f.write(response.content)
    
    os.makedirs("extracted_env_snapshot", exist_ok=True)
    with tarfile.open("snapshot_env.tar") as tar:
        tar.extractall(path="extracted_env_snapshot")
    

    在撰写本文时,尚无对应的 SDK 方法,因此快照是通过直接的 REST 调用获取的。运行程序后,提取出的文件会出现在本地文件夹中。

    使用技能与角色定制智能体

    Antigravity 并非使用一个庞大的提示词字符串,而是采用基于文件系统的配置系统。当沙箱启动时,它会查找一个隐藏的 .agents/ 目录。

    📁 Your-Project-Directory/
    └── 📁 .agents/
        ├── 📄 AGENTS.md        ← Global system instructions (persona, rules, standards)
        └── 📁 skills/
            └── 📁 data-cleaner/
                └── 📄 SKILL.md ← Specific skill with step-by-step instructions
    

    AGENTS.md 作为角色设定

    该文件包含了智能体的基本规则、行为限制以及项目背景,就像 README 一样,会在执行每项任务前被读取。

    SKILL.md 用于模块化技能

    技能将领域专业知识整合为可复用的单元,使用YAML 前置数据存储元数据,用 Markdown 编写操作指令。

    ---
    name: data-cleaner
    description: Use when the user needs to clean, normalize, or validate tabular data files.
    ---
    # Data Cleaner
    ## When to Use
    - User provides CSV, Excel, or JSON files that need cleaning
    - Data has missing values, inconsistent formatting, or duplicate rows
    ## Steps
    1. Load the data file using pandas
    2. Profile the data: count nulls, duplicates, and type mismatches
    3. Apply cleaning rules (fill nulls, normalize strings, deduplicate)
    4. Save the cleaned output and generate a summary report
    

    核心理念是渐进式披露。只有当代理判断某项技能对当前任务重要时,才会加载SKILL.md的完整内容。在启动时,它仅读取前端数据中的name和description,这样就能保持上下文窗口的整洁。

    如果某项技能未能在预期时触发,原因几乎总在于其前端数据中的description。应更明确地指定该技能应在何时激活。

    创建持久化代理

    在正式环境中,可以一次性注册持久化代理配置,从而无需重复操作。Agents API会创建一个带名称的代理,在此示例中即为使用上一节中的数据清洗技能的代理。

    from google import genai
    
    client = genai.Client()
    
    # Register a reusable, named agent with the data-cleaner skill baked in
    agent = client.agents.create(
        id="my-csv-cleaner",
        base_agent="antigravity-preview-05-2026",
        system_instruction="You are a data quality engineer. Always use pandas for data manipulation. "
                           "Always generate a before/after summary showing what changed.",
        base_environment={
            "type": "remote",
            "sources": [
                {
                    "type": "inline",
                    "target": ".agents/AGENTS.md",
                    "content": (
                        "# Data Quality Agent\n\n"
                        "## Standards\n"
                        "- Never drop rows silently — log every removal with a reason\n"
                        "- Normalize all string columns to lowercase, stripped of whitespace\n"
                        "- Output cleaned files in UTF-8 CSV format\n"
                        "- Always print a summary table at the end\n"
                    )
                },
                {
                    "type": "inline",
                    "target": ".agents/skills/data-cleaner/SKILL.md",
                    "content": (
                        "---\n"
                        "name: data-cleaner\n"
                        "description: Use when the user needs to clean, normalize, or validate tabular data files.\n"
                        "---\n"
                        "# Data Cleaner\n\n"
                        "## When to Use\n"
                        "- User provides CSV, Excel, or JSON files that need cleaning\n"
                        "- Data has missing values, inconsistent formatting, or duplicate rows\n\n"
                        "## Steps\n"
                        "1. Load the data file using pandas\n"
                        "2. Profile the data: count nulls, duplicates, and type mismatches\n"
                        "3. Apply cleaning rules (fill nulls, normalize strings, deduplicate)\n"
                        "4. Save the cleaned output and generate a summary report\n"
                    )
                }
            ]
        }
    )
    
    print(f"Agent created with ID: {agent.id}")
    

    将代码保存为create_csv_cleaner_agent.py并运行后,会注册一个可通过其IDmy-csv-cleaner调用的持久化代理。

    要使其开始工作,首先需要创建一个包含故意设计得混乱的客户记录的CSV文件,命名为messy_customers.csv。

    name,email,phone,country
    John Smith,john@example.com,+14155551234,US
    jane doe, JANE@EXAMPLE.COM ,4155559999,
    John Smith,john@example.com,+14155551234,US
    Bob Wilson,bob@@invalid,+442071234567,
    María García,maria@test.com,+34612345678,Spain
      alice brown ,alice@example.com,,US
    Charlie Lee,charlie@test.com,+61412345678,AU
    jane doe,jane@example.com,+14155559999,
    

    这样,就可以通过脚本如 run_csv_cleaner_agent.py,从应用程序的任何位置根据编号调用该代理。

    from google import genai
    
    client = genai.Client()
    
    # Read your local CSV file
    with open("messy_customers.csv", "r") as f:
        csv_content = f.read()
    
    # Inject the file into the sandbox and tell the agent to clean it
    interaction = client.interactions.create(
        agent="my-csv-cleaner",
        input="Clean the file at data/customers.csv. "
              "Remove duplicate rows by email (case-insensitive), "
              "standardize phone numbers to E.164 format, "
              "fill missing 'country' fields by looking up the phone country code, "
              "and flag any rows where the email format is invalid. "
              "Generate a before/after summary showing what changed.",
        environment={
            "type": "remote",
            "sources": [
                {
                    "type": "inline",
                    "target": "data/customers.csv",   # ← Path inside the sandbox
                    "content": csv_content             # ← Your local file contents
                }
            ]
        }
    )
    
    print(interaction.output_text)
    

    该脚本中的sources数组会在代理启动之前将文件加载到沙箱中。对代理而言,data/customers.csv只是其Linux文件系统中的普通文件,它并不知道该文件是从本地机器上传的。任何格式的文件都可以使用,包括CSV、JSON、XML、Python脚本以及配置文件。

    请注意,说明中并未提及pandas、UTF-8或日志记录规范。这些细节早已记载在随该代理一同提供的AGENTS.md和SKILL.md文件中,而且由于任务描述与数据清洗技能的description相匹配,该技能会自动被启用。下文将展示一次示例运行过程。

    I have successfully cleaned the customer dataset at `data/customers.csv` using Python and `pandas`.
    
    Below is a detailed report and before/after summary of the transformations applied.
    
    ---
    
    ### Summary of Transformations
    
    1. **whitespace Trimming:** Stripped all leading and trailing whitespace from both column names and text values (e.g., `  alice brown ` became `alice brown`).
    2. **Email Normalization & Validation:**
       - Converted all email addresses to lowercase and trimmed whitespace.
       - Added a new column `email_invalid` (boolean) to flag emails with an invalid format.
       - Identified `bob@@invalid` as an invalid format (due to a duplicate `@` symbol and lack of a top-level domain).
    3. **Phone Number Standardization:**
       - Standardized all valid phone numbers to the international **E.164** format using the `phonenumbers` library.
       - Converted `4155559999` (with a default US region fallback) to `+14155559999`.
       - Ignored the missing phone number for `alice brown` while leaving it empty.
    4. **Country Code Lookup:**
       - Looked up and populated missing `country` values based on the telephone country code prefix.
       - Filled `jane doe`'s country as `US` (derived from prefix `+1`).
       - Filled `Bob Wilson`'s country as `GB` (derived from prefix `+44`).
       - Kept existing valid country entries (e.g., `Spain`, `US`, `AU`) intact.
    5. **Deduplication:**
       - Removed duplicate rows by performing a case-insensitive match on the cleaned `email` column, keeping the first occurrence.
       - Safely removed the duplicate row for `john@example.com` (Row 3).
       - Safely removed the duplicate row for `jane@example.com` (Row 8).
    
    ---
    
    ### Before/After Summary
    
    #### 1. Data Quality Metrics
    
    | Metric | Before Clean | After Clean | Change Description |
    | :--- | :---: | :---: | :--- |
    | **Total Rows** | 8 | 6 | 2 duplicate rows were removed. |
    | **Duplicates Removed** | 0 | 2 | Dropped rows 3 (`john@example.com`) and 8 (`jane@example.com`). |
    | **Invalid Emails Flagged** | 0 | 1 | Flagged `bob@@invalid` as invalid (`email_invalid = True`). |
    | **Standardized Phone Numbers** | 1 | 5 | All numbers formatted to E.164 (e.g., `4155559999` -> `+14155559999`). |
    | **Filled Country Fields** | 5 | 6 | Filled 2 missing country values (`US` and `GB`) via phone prefix lookups. |
    
    #### 2. Row-by-Row Comparison
    
    Below is the row-by-row evolution from the raw file to the cleaned output:
    
    | Row # | Name (Before) | Name (After) | Email (Before) | Email (After) | Phone (Before) | Phone (After) | Country (Before) | Country (After) | Email Invalid Flag | Action Taken / Status |
    | :---: | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :---: | :--- |
    | **1** | `John Smith` | `John Smith` | `john@example.com` | `john@example.com` | `+14155551234` | `+14155551234` | `US` | `US` | `False` | Retained as first unique instance. |
    | **2** | `jane doe` | `jane doe` | ` JANE@EXAMPLE.COM ` | `jane@example.com` | `4155559999` | `+14155559999` | *Missing* | `US` | `False` | Email normalized; Phone formatted to E.164; Country populated from `+1` prefix. |
    | **3** | `John Smith` | — | `john@example.com` | — | `+14155551234` | — | `US` | — | — | **Removed** (Duplicate email). |
    | **4** | `Bob Wilson` | `Bob Wilson` | `bob@@invalid` | `bob@@invalid` | `+442071234567` | `+442071234567` | *Missing* | `GB` | `True` | Country populated from `+44` prefix; Email flagged as invalid. |
    | **5** | `María García` | `María García` | `maria@test.com` | `maria@test.com` | `+34612345678` | `+34612345678` | `Spain` | `Spain` | `False` | Retained; Email valid; Preserved existing country. |
    | **6** | `  alice brown ` | `alice brown` | `alice@example.com` | `alice@example.com` | *Missing* | *Missing* | `US` | `US` | `False` | Name whitespace stripped; Phone left empty; Preserved existing country. |
    | **7** | `Charlie Lee` | `Charlie Lee` | `charlie@test.com` | `charlie@test.com` | `+61412345678` | `+61412345678` | `AU` | `AU` | `False` | Retained; Email valid. |
    | **8** | `jane doe` | — | `jane@example.com` | — | `+14155559999` | — | *Missing* | — | — | **Removed** (Duplicate email). |
    
    ---
    
    ### Cleaned Dataset Output
    
    The cleaned data has been written back to `data/customers.csv` and contains the following records:
    
    ```csv
    name,email,phone,country,email_invalid
    John Smith,john@example.com,+14155551234,US,False
    jane doe,jane@example.com,+14155559999,US,False
    Bob Wilson,bob@@invalid,+442071234567,GB,True
    María García,maria@test.com,+34612345678,Spain,False
    alice brown,alice@example.com,,US,False
    Charlie Lee,charlie@test.com,+61412345678,AU,False
    ```
    

    实际应用场景

    在基础框架搭建完成后,几个智能体展示了各组件如何协同工作,同时每個智能体都带来了新的功能。

    应用场景一:代码重构与测试修复

    假设有一个包含过时代码且测试失败的Python项目。普通的大型语言模型只会提供代码片段,开发者需手动复制这些片段、运行测试、调试并反复修改。而使用Antigravity后,智能体会复制代码、运行测试套件、读取终端错误信息、修复源代码后再重新运行测试,不断循环直至所有测试通过。

    作为测试目标的代码库中刻意设置了错误代码,其中存在三个根本性缺陷,共同导致了六次测试失败:

    1. utils.py文件中的calculate_total()函数直接对字符串类型的tax_rate进行运算,未将其转换为浮点数。
  • utils.py 中的 normalize_name() 函数在接收到 None 值时会崩溃,因为没有进行空值检查。
  • models.py 中的 Invoice.summary() 方法直接引用了方法对象 self.total,而非调用 self.total()。
  • 处理该问题的代理函数定义如下。

    from google import genai
    client = genai.Client()
    
    system_instructions = """
    You are an expert QA and Refactoring Engineer. Your workflow is:
    1. Clone the target repository into the workspace
    2. Install all dependencies from requirements.txt
    3. Run the full pytest suite and capture all output
    4. For each failing test:
       a. Read the error traceback carefully
       b. Open the source file causing the failure
       c. Diagnose the root cause
       d. Apply the minimal fix
    5. Re-run pytest after each fix to confirm resolution
    6. Continue until ALL tests pass (0 failures)
    7. Generate a summary of every change you made
    IMPORTANT: Make the minimal possible change to fix each test.
    Do not refactor working code unnecessarily.
    """
    interaction = client.interactions.create(
        agent="antigravity-preview-05-2026",
        system_instruction=system_instructions,
        input="""
        Clone this repository: https://github.com/rominirani/uc1-legacy-app
        Run the pytest suite to check for environment or code failures.
        Isolate the bugs causing test failures and fix them one by one.
        Keep running the tests until you achieve a 100% pass rate.
        When done, provide:
        1. A list of all files modified with a diff summary
        2. The final pytest output showing all tests passing
        3. Any dependency changes you had to make
        """,
        environment="remote"
    )
    print(interaction.output_text)
    

    将其保存为 uc1_refactor.py,然后运行它。

    python3 uc1_refactor.py
    

    以下为预期输出结果。

    I have successfully diagnosed and resolved all the issues causing test failures in the `uc1-legacy-app` repository. Below is a detailed summary of the findings, modifications, and the final test execution output.
    
    ---
    
    ### 1. Modified Files & Diff Summary
    
    #### File: `src/models.py`
    - **Issue**: In the `Invoice.summary()` method, the `self.total` method itself was passed to `format_currency()` as an object, instead of being invoked (`self.total()`). This led to a `TypeError` during format evaluation.
    - **Fix**: Changed `self.total` to `self.total()`.
    - **Diff Summary**:
    ```diff
    @@ -23,7 +23,7 @@ class Invoice:
    """Return a one-line summary of the invoice."""
    from src.utils import format_currency, normalize_name
    name = normalize_name(self.customer_name)
    -        return f"Invoice {self.invoice_id}: {name} - {format_currency(self.total)}"
    +        return f"Invoice {self.invoice_id}: {name} - {format_currency(self.total())}"
    ```
    
    #### File: `src/utils.py`
    - **Issues**:
    1. **`calculate_total()`**: When `tax_rate` is received as a string, Python fails to perform multiplication of float/string (`TypeError: can't multiply sequence by non-int of type 'float'`).
    2. **`normalize_name()`**: When passed a `None` value (common in CSV imports), the code raised `AttributeError: 'NoneType' object has no attribute 'strip'`.
    - **Fixes**:
    1. Explicitly cast `subtotal` and `tax_rate` to `float` prior to calculating the tax.
    2. Add a safeguard to return an empty string (`""`) when `name` is `None`.
    - **Diff Summary**:
    ```diff
    @@ -11,8 +11,10 @@ def calculate_total(subtotal, tax_rate):
    Returns:
    The total as a float rounded to 2 decimal places.
    """
    -    tax = subtotal * tax_rate / 100
    -    return round(subtotal + tax, 2)
    +    subtotal_val = float(subtotal)
    +    tax_rate_val = float(tax_rate)
    +    tax = subtotal_val * tax_rate_val / 100
    +    return round(subtotal_val + tax, 2)
    
    def format_currency(amount):
    @@ -36,6 +38,8 @@ def normalize_name(name):
    Returns:
    Cleaned, title-cased name.
    """
    +    if name is None:
    +        return ""
    return name.strip().title()
    ```
    
    ---
    
    ### 2. Dependency Changes
    No additional packages or dependency changes were made. All required libraries from `requirements.txt` (consisting of `pytest>=7.0.0`) were successfully installed and utilized without modification.
    
    ---
    
    ### 3. Final Pytest Output
    Running the full suite confirms that all 10 tests now pass:
    
    ```
    ============================= test session starts ==============================
    platform linux -- Python 3.12.3, pytest-9.0.3, pluggy-1.6.0
    rootdir: /uc1-legacy-app
    plugins: anyio-4.13.0
    collected 10 items
    
    tests/test_models.py ....                                                [ 40% ]
    tests/test_utils.py ......                                               [100% ]
    
    ============================== 10 passed in 0.02s ==============================
    ```
    

    在没有任何指导的情况下,该智能体会:

    1. 在沙箱终端中运行 git clone
    2. 在沙箱的 Python 环境中执行 pip install -r requirements.txt
    3. 运行 pytest -v 并读取所有输出,包括错误回溯信息
    4. 打开出错的源文件并定位有问题的逻辑
    5. 编写补丁,保存文件后再次运行 pytest
    6. 重复上述步骤,直到输出显示无错误为止

    这就是“计划、执行、观察”循环的体现。该智能体不仅会生成代码,还会实际运行它,读取真实的终端输出,并自行修正错误。

    第二种应用场景:竞争分析

    假设某个团队需要对竞争对手的产品进行全面的竞争分析。手动抓取数据既繁琐又效率低下,而且固定的抓取工具还经常出故障。此时,该自动化工具会利用其浏览功能在谷歌上搜索,爬取竞争对手的网站,应对不同的页面布局,编写自己的pandas脚本来整理数据,最终导出完整的电子表格。

    from google import genai
    client = genai.Client()
    
    system_instructions = """
    You are a precise Business Intelligence Analyst. Your workflow:
    1. Use web search to find current, real-time information
    2. Navigate to official product/pricing pages for each competitor
    3. Extract: pricing tiers, key features, target audience, notable limitations
    4. Structure ALL findings into a pandas DataFrame
    5. Export to both CSV and a formatted Markdown comparison table
    6. Include the date/time of research and source URLs for every data point
    Rules:
    - Only report data you can verify from official sources
    - If pricing isn't publicly available, note "Contact Sales" - don't guess
    - Use USD for all pricing normalization
    """
    interaction = client.interactions.create(
        agent="antigravity-preview-05-2026",
        system_instruction=system_instructions,
        input="""
        Research the pricing models and core feature matrices of the top 3 alternative
        platforms to Vercel for frontend deployment:
        1. Netlify
        2. Cloudflare Pages
        3. Cloud Run
        For each, extract:
        - Free tier limits (bandwidth, builds, sites)
        - Pro/paid tier pricing and what it unlocks
        - Key differentiating features
        - Notable limitations or complaints from developer communities
        Create:
        1. A competitive_matrix.csv spreadsheet with all data
        2. A competitive_analysis.md report with a formatted comparison table
           and a "Recommendation" section at the bottom
        """,
        environment="remote"
    )
    print(interaction.output_text)
    

    它生成这份报告。

    As a Business Intelligence Analyst, I have conducted a precise competitive analysis of the top three frontend deployment alternatives to Vercel: **Netlify**, **Cloudflare Pages**, and **Google Cloud Run**.
    
    All findings have been structured using `pandas` and exported to `/` (the current working directory) as:
    1. `competitive_matrix.csv` — The raw, structured dataset.
    2. `competitive_analysis.md` — A comprehensive, reader-ready report including a detailed markdown comparison matrix, architectural breakdowns, limitation analyses, and a tailored recommendation framework.
    
    All data has been verified against official vendor pricing, product, and developer documentation as of **June 9, 2026**. All currency values are normalized in **USD**.
    
    ---
    
    ### Core Finding Highlights
    
    #### 1. Netlify
    * **The Architectural Shift (April 2026):** Netlify made a massive strategic update to its Pro plans, moving from a seat-based model ($19/member/month) to a **flat $20/month per organization** [10]. This includes unlimited team members (Owners, Developers, Reviewers, and Git Contributors) [10], which is highly disruptive compared to Vercel's strict per-seat billing.
    * **The Credits Trap:** Usage is now managed entirely via a unified credit-based model (300 credits/mo free, 3,000 on Pro) [2, 10]. However, credits are consumed fast: bandwidth costs 20 credits per GB [2, 10] (meaning Free tier is only **~15 GB max** and Pro is only **~150 GB max** if solely used for traffic). If Free tier credits run out, **all site traffic pauses immediately** (no auto-recharge is supported on Free) [2, 11].
    * **Capabilities:** Highly integrated features like Netlify Database (managed Postgres via Neon) [4], Blob storage, Forms, and Auth [10]. Serverless timeout is 10s on Free/Personal [2] and 26s on Pro [2].
    
    #### 2. Cloudflare Pages
    * **Unmetered Freedom:** Genuinely **unlimited and unmetered static bandwidth and requests** across all tiers (including the $0 Free tier) [24, 25, 27].
    * **The Pro Tier ($20/mo billed annually / $25/mo monthly):** Tied directly to Cloudflare's Workers Paid plan [25, 27]. It increases build limits from 500/mo to 5,000/mo, concurrent builds from 1 to 5, and the file-count ceiling per project from 20,000 to 100,000 assets [31] (unlocked via the `PAGES_WRANGLER_MAJOR_VERSION=4` env variable) [31].
    * **Edge Isolates Constraints:** While running serverless code on Cloudflare's global network of 310+ cities is blazingly fast with zero cold starts [24, 33], it uses a **strict V8 edge runtime** [24]. Standard Node.js library modules (`fs`, `path`, native `crypto`) do not run natively [24], forcing developers to compile meta-frameworks like Next.js via edge adapters (e.g., `@cloudflare/next-on-pages` or OpenNext) [24] which restricts certain features like Incremental Static Regeneration (ISR).
    
    #### 3. Google Cloud Run
    * **Pure Container Portability:** Cloud Run runs any application, language, or compiled binary (Node.js, Python, Go, Rust) packaged in a standard Docker container [37, 39]. It runs full Node.js natively [39], ensuring 100% Next.js feature parity (ISR, Server Actions, dynamic image optimization) with zero edge-runtime workarounds [39].
    * **No Monthly Base Fee:** Operates on a pure pay-as-you-go serverless model (billed in granular vCPU-seconds and GiB-seconds) [41], backed by a generous Always Free tier (2 million requests/mo, 180,000 vCPU-seconds, 360,000 GiB-seconds, and 120 daily Cloud Build minutes free) [37, 38, 41].
    * **The Infrastructure Overhead:** Not a standard "push-to-deploy" platform. Developers must write Dockerfiles, configure Artifact Registry, and manage IAM and networking [37, 39]. It is regionally hosted; to get a global CDN with SSL mapping, you must set up Cloud CDN and a Global HTTP Load Balancer [37] (~$20-$30/mo base fee) and navigate container cold starts (2 to 10+ seconds) [37] and expensive internet egress rates ($0.085 - $0.12 per GB) [37].
    
    ---
    
    ### Structure of Generated Files
    
    #### 1. `competitive_matrix.csv`
    A raw, tabular CSV structured for business intelligence pipelines, featuring the following schema:
    - `Platform Name`
    - `Free Tier Pricing (USD)`
    - `Free Tier Bandwidth Limit`
    - `Free Tier Build Limit`
    - `Free Tier Sites/Projects Limit`
    - `Free Tier Key Specs & Features`
    - `Paid/Pro Tier Price (USD)`
    - `Paid/Pro Tier Features Unlocked`
    - `Key Differentiating Features`
    - `Notable Limitations & Developer Complaints`
    - `Date of Research`
    - `Source URLs`
    
    #### 2. `competitive_analysis.md`
    A professionally formatted report including:
    * **Executive Summary:** Contextualizing why frontend teams are exploring alternatives to Vercel in 2026.
    * **Structured Comparison Table:** Transposed for high-density reading and side-by-side comparison.
    * **Deep-Dive Section:** Dedicated analyses of the Free limits, paid features, unique differentiators, and community complaints for Netlify, Cloudflare Pages, and Google Cloud Run.
    * **Architectural Recommendation Flowchart & Matrix:** Tailored decision pathways based on project profile:
      * *Static / JAMstack / Zero-Budget* $\rightarrow$ **Cloudflare Pages**
      * *Collaborative Teams / Rapid Prototyping / Seat-Free DX* $\rightarrow$ **Netlify**
      * *Complex Server-Side Rendering / Backend Pipelines / Custom Docker* $\rightarrow$ **Google Cloud Run**
    
    ---
    
    ### Source Verification & Citations
    
    1. **Netlify:**
       - [Official Pricing & Plans](https://www.netlify.com/pricing/)
       - [Introducing Seat-Free Collaborative Billing (April 14, 2026)](https://www.netlify.com/blog/pricing-netlify-for-3-billion-builders/)
       - [Credit-Based Pricing Documentation](https://docs.netlify.com/manage/accounts-and-billing/billing/billing-for-credit-based-plans/credit-based-pricing-plans/)
       - [Netlify Free Tier Credit Analysis (Temps)](https://temps.sh/compare/vs-netlify)
    
    2. **Cloudflare Pages:**
       - [Workers & Pages Pricing Matrix](https://www.cloudflare.com/plans/developer-platform/)
       - [Official Pages Limits Documentation](https://developers.cloudflare.com/pages/platform/limits/)
       - [Cloudflare Pages Platform Features](https://pages.cloudflare.com/)
       - [Cloudflare Pages Edge Limitations (Temps)](https://temps.sh/compare/vs-cloudflare-pages)
    
    3. **Google Cloud Run:**
       - [Official Cloud Run Pricing Breakdown](https://cloud.google.com/run/pricing)
       - [Google Cloud Free Tier Inclusions](https://cloud.google.com/free)
       - [Cloud Run Quotas & Limits](https://docs.cloud.google.com/run/quotas)
       - [Cloud Run Cost Optimization & Egress Guide (Cloudchipr)](https://cloudchipr.com/blog/cloud-run-pricing)
    
    The generated files are saved directly in your working directory and are immediately available for download or integration into your reporting pipelines. Let me know if you would like me to modify the analysis parameters or explore a specific platform further!
    

    后续操作可以复用之前的环境和交互,获取生成的 competitive_matrix.csv 文件并将其转换为可视化图表。下面的代码仅获取文本回复,但之前展示的下载方法可以从沙箱中提取生成的文件。

    # Follow-up: generate a visual chart from the data we just collected
    interaction_2 = client.interactions.create(
        agent="antigravity-preview-05-2026",
        environment=interaction.environment_id,
        previous_interaction_id=interaction.id,
        input="""
        Using the competitive_matrix.csv you just created:
        1. Create a grouped bar chart comparing the free tier limits across all 3 platforms
        2. Create a pricing comparison chart for the paid tiers
        3. Save both charts as PNG files with clear labels and a professional color scheme
        4. Add the charts as embedded images in the competitive_analysis.md report
        """
    )
    print(interaction_2.output_text)
    

    这里的理念是在单个任务中结合网页浏览与代码执行。智能体先在实时互联网上搜索,然后编写 Python 代码来整理并可视化所找到的内容,整个过程一气呵成。

    在实际应用中可行的模式

    要做好重新构建的准备。 模型的性能提升很快,因此设计智能体时应假设它们很快就会基于更新的模型被重新构建。保持配置的模块化,因为 AGENTS.md 和 SKILL.md 文件很容易更换,同时也不要过度设计协调层。

    将大型智能体拆分。 避免使用包含2,000字系统提示的庞大智能体,应将复杂问题分解为专门的子智能体。

    将错误视为输入而非崩溃。在合理的智能体设计中,错误是智能体用来反思并纠正问题的数据。它会读取TypeError,分析其原因并加以修复。避免使用会掩盖错误的通用try/except块,应让智能体能够看到这些错误。

    使用评估而非单元测试。智能体的行为并非确定性的,因此测试应侧重于评估指标,而非精确的输出匹配。

    # ❌ Don't: Assert exact output
    assert agent_output == "The answer is 42"
    
    # ✅ Do: Evaluate behavioral success rate
    results = [run_agent(task) for _ in range(20)]
    success_rate = sum(1 for r in results if r.meets_criteria) / len(results)
    assert success_rate >= 0.85  # Agent succeeds at least 85% of the time
    

    关注令牌成本。由于智能体会运行自主推理循环,一个提示词可能触发许多内部操作,因此每项任务的成本差异很大。此表可提供大致参考。

    在开发过程中应设置严格的超时时间并监控跟踪长度,同时使用system_instruction要求智能体在无需冗长推理时保持简洁。

    做好失败应对准备。此处总结了常见故障情况的错误处理方式。

    其底层工作原理

    以下几种机制解释了上述行为:

    • 通过一次API调用interactions.create()即可启动服务器端的协调循环。Gemini Flash模型会持续进行推理、选择工具、运行代码并检查结果,直至任务完成。
  • 每次交互都会使用一个独立的 Ubuntu 容器,该容器配置有 4 个 vCPU 和 16 GB 内存,模型可在其中安装软件包、运行脚本和管理文件。
  • 将返回的 environment_id 传递给后续调用,可在不同交互之间保留文件和状态,从而避免每次都创建新的沙箱环境。
  • 当智能体配置稳定后,包括其系统指令和基于文件的技能,可通过 client.agents.create() 将其永久保存,并通过 ID 在任何地方调用。
  • 下一个智能体的设计思路

    • 一种 CI/CD 智能体,可监控 GitHub 仓库,在每次代码推送时运行测试,并为失败案例自动创建修复 PR
    • 一种文档生成器,能够读取代码库并编写完整的 API 文档
    • 一种数据管道协调器,可连接数据仓库、执行数据处理操作并验证输出结果
    • 一名支持分诊员,负责阅读工单、评估问题严重程度、起草回复以及将紧急问题上报。
    • 一名研究助理,负责选定主题、搜索相关论文和文章,并撰写带有引用信息的文献综述。

    有哪些变化

    托管型智能体改变了人工智能的开发方式。开发者不再围绕模型构建基础设施,而是仅为其设定目标并提供一个工作沙箱。该沙箱是抽象层,智能体循环驱动其运行,而交互 API 则是唯一的入口点。合理的起步方式是从小型项目开始,严格限制智能体在无人监督情况下可执行的任务范围,然后再逐步扩展。