创作 Google Antigravity 技能

1. 简介

Google Antigravity 是 Google 的智能体 IDE。在此 Codelab 中,我们将使用 Antigravity 构建 Agent Skills,这是一种轻量级开放格式,用于利用专业知识和工作流来扩展 AI 智能体功能。您将能够了解什么是 Agent Skills、它们的优势以及如何构建它们。然后,您将构建多个 Agent Skills,包括 Git 格式化程序、模板生成器、工具代码基架等,所有这些都可以在 Antigravity 中使用。

前提条件

2. 为何要使用 Skills

现代 AI 智能体已从简单的监听器发展为复杂的推理器,可与本地文件系统和外部工具(通过 MCP 服务器)集成。但是,如果随意向智能体加载整个代码库和数百个工具,会导致上下文饱和 和“工具膨胀”。即使使用大型上下文窗口,将 40-50k 个未使用的工具令牌转储到活动内存中也会导致高延迟、财务浪费和“上下文腐烂”,即模型会被不相关的数据弄糊涂。

解决方案:Agent Skills

为了解决这个问题,Anthropic 推出了 Agent Skills,将架构从单体上下文加载转变为渐进式披露。这些功能不是在会话开始时强制模型“记住”每个特定的工作流(例如数据库迁移或安全审核),而是打包到模块化、可发现的单元中。

工作方式

模型最初仅公开一个轻量级的元数据“菜单”。只有当用户的意图与技能完全匹配时,它才会加载繁琐的过程知识(指令和脚本)。这可确保请求重构身份验证中间件的开发者获得安全上下文,而无需加载不相关的 CSS 流水线,从而保持上下文精简、快速且经济高效。

d3f4bcb065a19fea.png

3. Agent Skills 和 Antigravity

在 Antigravity 生态系统中,如果 Agent Manager 是大脑,Editor 是画布,那么 Skills 充当专门的训练模块,弥合了通用 Gemini 3 模型与您的特定上下文之间的差距。它们允许智能体仅在请求相关任务时“配备”一组已定义的指令和协议(例如数据库迁移标准或安全检查)。通过动态加载这些执行协议,Skills 可有效地将 AI 从通用程序员转变为严格遵守组织编纂的最佳实践和安全标准的专家。

Antigravity 中的 Skill 是什么?

在 Google Antigravity 的上下文中,Skill 是一个基于目录的软件包,其中包含定义文件 (SKILL.md) 和可选的支持性资产(脚本、参考资料、模板)。

它是一种按需扩展功能的机制。

  • 按需:与系统提示(始终加载)不同,只有当智能体确定 Skill 与用户的当前请求相关时,才会将其加载到智能体的上下文中。这可以优化上下文窗口,并防止智能体被不相关的指令分散注意力。在包含数十个工具的大型项目中,这种选择性加载对于性能和推理准确性至关重要。
  • 功能扩展:Skills 不仅可以提供指令,还可以执行操作。通过捆绑 Python 或 Bash 脚本,Skill 可以让智能体能够在本地机器或外部网络上执行复杂的、多步骤的操作,而无需用户手动运行命令。这会将智能体从文本生成工具转变为工具用户。

Skills 与生态系统(工具、规则和工作流)

虽然 Model Context Protocol (MCP) 充当智能体的“手”,为 GitHub 或 PostgreSQL 等外部系统提供持久的连接,但 Skills 充当指导它们的“大脑”。

MCP 处理有状态的基础架构,而 Skills 是轻量级的临时任务定义,用于打包使用这些工具的方法。这种无服务器方法允许智能体执行临时任务(例如生成变更日志或迁移),而无需运行持久进程的运营开销,仅在任务处于活动状态时加载上下文,并在任务结束后立即释放上下文。

在功能上,Skills 占据了“规则”(被动、始终开启的护栏)和“工作流”(主动、用户触发的宏)之间独特的中间地带。与需要特定命令(例如 /test)的工作流不同,Skills 是 智能体触发的:模型会自动检测用户的意图,并动态配备所需的特定专业知识。这种架构允许强大的可组合性;例如,全局规则可以在数据库更改期间强制使用“安全迁移”Skill,或者单个工作流可以编排多个 Skills 来构建强大的部署流水线。

4. 创建 Skills

在 Antigravity 中创建 Skill 遵循特定的目录结构和文件格式。这种标准化可确保 Skills 的可移植性,并确保智能体能够可靠地解析和执行它们。该设计有意简单,依赖于广泛理解的格式(如 Markdown 和 YAML),降低了希望扩展其 IDE 功能的开发者的入门门槛。

目录结构

Skills 可以在两个范围内定义,允许进行项目特定和用户特定的自定义:

  1. 工作区范围:位于 <workspace-root>/.agent/skills/ 中。这些 Skills 仅在特定项目中可用。这非常适合项目特定的脚本,例如部署到特定环境、该应用的数据管理,或为专有框架生成样板代码。
  2. 全局范围:位于 ~/.gemini/antigravity/skills/ 中。这些 Skills 在用户机器上的所有项目中都可用。这适用于通用实用程序,例如“格式化 JSON”“生成 UUID”“查看代码样式”或与个人效率工具集成。

典型的 Skill 目录如下所示:

my-skill/
├── SKILL.md # The definition file
├── scripts/ # [Optional] Python, Bash, or Node scripts
     ├── run.py
     └── util.sh
├── references/ # [Optional] Documentation or templates
     └── api-docs.md
└── assets/ # [Optional] Static assets (images, logos)

这种结构有效地分离了关注点。逻辑 (scripts) 与指令 (SKILL.md) 和知识 (references) 分离,反映了标准的软件工程实践。

SKILL.md 定义文件

SKILL.md 文件是 Skill 的大脑。它会告诉智能体 Skill 是什么、何时使用它以及如何执行它。

它由两部分组成:

  • YAML Frontmatter
  • Markdown 正文。

YAML Frontmatter

这是元数据层。它是智能体的高级路由器索引的唯一 Skill 部分。当用户发送提示时,智能体会根据所有可用 Skills 的说明字段对提示进行语义匹配。

---
name: database-inspector
description: Use this skill when the user asks to query the database, check table schemas, or inspect user data in the local PostgreSQL instance.
---

关键字段:

  • name:这不是强制性的。在范围内必须是唯一的。小写,允许使用连字符(例如 postgres-querypr-reviewer)。如果未提供,则默认为目录名称。
  • description:这是强制性字段,也是最重要的字段。它充当“触发短语”。它必须具有足够的描述性,以便 LLM 能够识别语义相关性。像“数据库工具”这样模糊的描述是不够的。像“针对本地 PostgreSQL 数据库执行只读 SQL 查询以检索用户或事务数据。使用此功能调试数据状态”这样精确的描述可确保正确选择 Skill。

Markdown 正文

正文包含指令。这是持久保存到文件的“提示工程”。激活 Skill 后,此内容会注入到智能体的上下文窗口中。

正文应包括:

  1. 目标:明确说明 Skill 的实现目标。
  2. 指令:分步逻辑。
  3. 示例:输入和输出的少样本示例,用于指导模型的性能。
  4. 限制:“禁止”规则(例如“禁止运行 DELETE 查询”)。

SKILL.md 正文示例

Database Inspector

Goal
To safely query the local database and provide insights on the current data state.

Instructions
- Analyze the user's natural language request to understand the data need.
- Formulate a valid SQL query.
 - CRITICAL: Only SELECT statements are allowed.
- Use the script scripts/query_runner.py to execute the SQL.
 - Command: python scripts/query_runner.py "SELECT * FROM..."
- Present the results in a Markdown table.

Constraints
- Never output raw user passwords or API keys.
- If the query returns > 50 rows, summarize the data instead of listing it all.

脚本集成

Skills 最强大的功能之一是能够将执行委托给脚本。这允许智能体执行 LLM 难以或无法直接执行的操作(例如二进制执行、复杂的数学计算或与旧版系统交互)。

脚本放置在 scripts/ 子目录中。SKILL.md 通过相对路径引用它们。

5. 编写 Skills

本部分的目标是构建集成到 Antigravity 中的 Skills,并逐步展示各种功能,例如资源/脚本等。

您可以从 Github 代码库下载 Skills: https://github.com/rominirani/antigravity-skills

我们可以考虑将每个 Skill 放置在 ~/.gemini/antigravity/skills 文件夹或 /.agent/skills 文件夹中。

第 1 级:基本路由器 ( git-commit-formatter )

让我们将其视为 Skills 的“Hello World”。

开发者通常会编写懒惰的提交消息,例如“wip”“fix bug”“updates”。手动强制执行“Conventional Commits”既繁琐又容易被遗忘。让我们实现一个强制执行 Conventional Commits 规范的 Skill。只需向智能体说明规则,我们就可以让它充当执行者。

git-commit-formatter/
└── SKILL.md  (Instructions only)

SKILL.md 文件如下所示:

---
name: git-commit-formatter
description: Formats git commit messages according to Conventional Commits specification. Use this when the user asks to commit changes or write a commit message.
---

Git Commit Formatter Skill

When writing a git commit message, you MUST follow the Conventional Commits specification.

Format
`<type>[optional scope]: <description>`

Allowed Types
- **feat**: A new feature
- **fix**: A bug fix
- **docs**: Documentation only changes
- **style**: Changes that do not affect the meaning of the code (white-space, formatting, etc)
- **refactor**: A code change that neither fixes a bug nor adds a feature
- **perf**: A code change that improves performance
- **test**: Adding missing tests or correcting existing tests
- **chore**: Changes to the build process or auxiliary tools and libraries such as documentation generation

Instructions
1. Analyze the changes to determine the primary `type`.
2. Identify the `scope` if applicable (e.g., specific component or file).
3. Write a concise `description` in an imperative mood (e.g., "add feature" not "added feature").
4. If there are breaking changes, add a footer starting with `BREAKING CHANGE:`.

Example
`feat(auth): implement login with google`

如何运行此示例

  1. 对工作区中的任何文件进行少量更改。
  2. 打开聊天并输入:Commit these changes。
  3. 智能体不仅会运行 git commit。它会先激活 git-commit-formatter Skill。
  4. 结果:系统将建议一条符合规范的 Git 提交消息。

例如,我让 Antigravity 向示例 Python 文件添加了一些注释,最终得到了一条 Git 提交消息,例如 docs: add detailed comments to demo_primes.py.

第 2 级:资产利用率 (license-header-adder)

这是“参考”模式。

公司项目中的每个源文件可能都需要特定的 20 行 Apache 2.0 许可标头。将此静态文本直接放入提示(或 SKILL.md)中是一种浪费。每次对 Skill 进行索引时,它都会消耗令牌,并且模型可能会在法律文本中“幻觉”出错别字。

将静态文本卸载到 resources/ 文件夹中的纯文本文件。技能指示智能体仅在需要时读取此文件。

license-header-adder/
├── SKILL.md
└── resources/
   └── HEADER_TEMPLATE.txt  (The heavy text)

SKILL.md 文件如下所示:

---
name: license-header-adder
description: Adds the standard open-source license header to new source files. Use involves creating new code files that require copyright attribution.
---

# License Header Adder Skill

This skill ensures that all new source files have the correct copyright header.

## Instructions

1. **Read the Template**:
  First, read the content of the header template file located at `resources/HEADER_TEMPLATE.txt`.

2. **Prepend to File**:
  When creating a new file (e.g., `.py`, `.java`, `.js`, `.ts`, `.go`), prepend the `target_file` content with the template content.

3. **Modify Comment Syntax**:
  - For C-style languages (Java, JS, TS, C++), keep the `/* ... */` block as is.
  - For Python, Shell, or YAML, convert the block to use `#` comments.
  - For HTML/XML, use `<!-- ... -->`.

如何运行此示例

  1. 创建一个新的虚拟 Python 文件:touch my_script.py
  2. 输入:Add the license header to my_script.py
  3. 智能体将读取 license-header-adder/resources/HEADER_TEMPLATE.txt
  4. 它会将内容完全逐字粘贴到您的文件中。

第 3 级:通过示例学习 (json-to-pydantic)

“少样本”模式。

将松散的数据(例如 JSON API 响应)转换为严格的代码(例如 Pydantic 模型)涉及数十个决策。我们应该如何命名类?我们应该使用 Optional 吗?snake_case 还是 camelCase?用英语写出这 50 条规则既繁琐又容易出错。

LLM 是模式匹配引擎。

向它们展示一个黄金示例(Input -> Output)通常比冗长的指令更有效。

json-to-pydantic/
├── SKILL.md
└── examples/
   ├── input_data.json   (The Before State)
   └── output_model.py   (The After State)

SKILL.md 文件如下所示:

---
name: json-to-pydantic
description: Converts JSON data snippets into Python Pydantic data models.
---

# JSON to Pydantic Skill

This skill helps convert raw JSON data or API responses into structured, strongly-typed Python classes using Pydantic.

Instructions

1. **Analyze the Input**: Look at the JSON object provided by the user.
2. **Infer Types**:
  - `string` -> `str`
  - `number` -> `int` or `float`
  - `boolean` -> `bool`
  - `array` -> `List[Type]`
  - `null` -> `Optional[Type]`
  - Nested Objects -> Create a separate sub-class.
 
3. **Follow the Example**:
  Review `examples/` to see how to structure the output code. notice how nested dictionaries like `preferences` are extracted into their own class.
 
  - Input: `examples/input_data.json`
  - Output: `examples/output_model.py`

Style Guidelines
- Use `PascalCase` for class names.
- Use type hints (`List`, `Optional`) from `typing` module.
- If a field can be missing or null, default it to `None`.

/examples 文件夹中,有 JSON 文件和输出文件(即 Python 文件)。两者如下所示:

input_data.json

{
   "user_id": 12345,
   "username": "jdoe_88",
   "is_active": true,
   "preferences": {
       "theme": "dark",
       "notifications": [
           "email",
           "push"
       ]
   },
   "last_login": "2024-03-15T10:30:00Z",
   "meta_tags": null
}

output_model.py

from pydantic import BaseModel, Field
from typing import List, Optional

class Preferences(BaseModel):
   theme: str
   notifications: List[str]

class User(BaseModel):
   user_id: int
   username: str
   is_active: bool
   preferences: Preferences
   last_login: Optional[str] = None
   meta_tags: Optional[List[str]] = None

如何运行此示例

  1. 向智能体提供 JSON 代码段(将其粘贴到聊天中或指向文件)。

{ "product": "Widget", "cost": 10.99, "stock": null }

  1. 输入:Convert this JSON to a Pydantic model
  2. 智能体查看 Skill 文件夹中的 examples 对。
  3. 它会生成一个 Python 类,该类完美地模仿了 output_model.py 的编码风格、导入和结构,包括将 null 库存处理为 Optional。

输出示例 (product_model.py) 如下所示:

from pydantic import BaseModel
from typing import Optional

class Product(BaseModel):
   product: str
   cost: float
   stock: Optional[int] = None

第 4 级:过程逻辑 (database-schema-validator)

这是“工具使用”模式。

如果您问 LLM“此架构是否安全?”,它可能会说一切正常,即使缺少关键的主键也是如此,仅仅因为 SQL 看起来正确。

让我们将此检查委托给确定性脚本。我们使用 Skill 将智能体路由到运行我们编写的 Python 脚本。该脚本提供二进制(True/False)真值。

database-schema-validator/
├── SKILL.md
└── scripts/
   └── validate_schema.py  (The Validator)

SKILL.md 文件如下所示:

---
name: database-schema-validator
description: Validates SQL schema files for compliance with internal safety and naming policies.
---

# Database Schema Validator Skill

This skill ensures that all SQL files provided by the user comply with our strict database standards.

Policies Enforced
1. **Safety**: No `DROP TABLE` statements.
2. **Naming**: All tables must use `snake_case`.
3. **Structure**: Every table must have an `id` column as PRIMARY KEY.

Instructions

1. **Do not read the file manually** to check for errors. The rules are complex and easily missed by eye.
2. **Run the Validation Script**:
  Use the `run_command` tool to execute the python script provided in the `scripts/` folder against the user's file.
 
  `python scripts/validate_schema.py <path_to_user_file>`

3. **Interpret Output**:
  - If the script returns **exit code 0**: Tell the user the schema looks good.
  - If the script returns **exit code 1**: Report the specific error messages printed by the script to the user and suggest fixes.

validate_schema.py 文件如下所示:

import sys
import re

def validate_schema(filename):
   """
   Validates a SQL schema file against internal policy:
   1. Table names must be snake_case.
   2. Every table must have a primary key named 'id'.
   3. No 'DROP TABLE' statements allowed (safety).
   """
   try:
       with open(filename, 'r') as f:
           content = f.read()
          
       lines = content.split('\n')
       errors = []
      
       # Check 1: No DROP TABLE
       if re.search(r'DROP TABLE', content, re.IGNORECASE):
           errors.append("ERROR: 'DROP TABLE' statements are forbidden.")
          
       # Check 2 & 3: CREATE TABLE checks
       table_defs = re.finditer(r'CREATE TABLE\s+(?P<name>\w+)\s*\((?P<body>.*?)\);', content, re.DOTALL | re.IGNORECASE)
      
       for match in table_defs:
           table_name = match.group('name')
           body = match.group('body')
          
           # Snake case check
           if not re.match(r'^[a-z][a-z0-9_]*$', table_name):
               errors.append(f"ERROR: Table '{table_name}' must be snake_case.")
              
           # Primary key check
           if not re.search(r'\bid\b.*PRIMARY KEY', body, re.IGNORECASE):
               errors.append(f"ERROR: Table '{table_name}' is missing a primary key named 'id'.")

       if errors:
           for err in errors:
               print(err)
           sys.exit(1)
       else:
           print("Schema validation passed.")
           sys.exit(0)
          
   except FileNotFoundError:
       print(f"Error: File '{filename}' not found.")
       sys.exit(1)

if __name__ == "__main__":
   if len(sys.argv) != 2:
       print("Usage: python validate_schema.py <schema_file>")
       sys.exit(1)
      
   validate_schema(sys.argv[1])

如何运行此示例

  1. 创建一个错误的 SQL 文件 bad_schema.sqlCREATE TABLE users (name TEXT);
  2. 输入:Validate bad_schema.sql
  3. 智能体不会猜测。它将调用脚本,该脚本失败(退出代码 1),并向我们报告“验证失败,因为表‘users’缺少主键”。

第 5 级:架构师 (adk-tool-scaffold)

此模式涵盖了 Skills 中提供的大部分功能。

复杂的任务通常需要一系列操作,这些操作结合了我们所看到的一切:创建文件、遵循模板和编写逻辑。为 ADK(智能体开发套件)创建新工具需要所有这些操作。

我们结合了:

  • 脚本(用于处理文件创建/脚手架)
  • 模板(用于处理资源中的样板)
  • 示例(用于指导逻辑生成)。
adk-tool-scaffold/
├── SKILL.md
├── resources/
   └── ToolTemplate.py.hbs (Jinja2 Template)
├── scripts/
   └── scaffold_tool.py    (Generator Script)
└── examples/
    └── WeatherTool.py      (Reference Implementation)

SKILL.md 文件如下所示。您可以参阅 Skills 的 代码库,以检查脚本、资源和示例文件夹中的文件。对于此特定 Skill,请转到 adk-tool-scaffold Skill。

---
name: adk-tool-scaffold
description: Scaffolds a new custom Tool class for the Agent Development Kit (ADK).
---

# ADK Tool Scaffold Skill

This skill automates the creation of standard `BaseTool` implementations for the Agent Development Kit.

Instructions

1. **Identify the Tool Name**:
  Extract the name of the tool the user wants to build (e.g., "StockPrice", "EmailSender").
 
2. **Review the Example**:
  Check `examples/WeatherTool.py` to understand the expected structure of an ADK tool (imports, inheritance, schema).

3. **Run the Scaffolder**:
  Execute the python script to generate the initial file.
 
  `python scripts/scaffold_tool.py <ToolName>`

4. **Refine**:
  After generation, you must edit the file to:
  - Update the `execute` method with real logic.
  - Define the JSON schema in `get_schema`.
 
Example Usage
User: "Create a tool to search Wikipedia."
Agent:
1. Runs `python scripts/scaffold_tool.py WikipediaSearch`
2. Editing `WikipediaSearchTool.py` to add the `requests` logic and `query` argument schema.

如何运行此示例

  1. 输入:Create a new ADK tool called StockPrice to fetch data from an API
  2. 第 1 步(脚手架):智能体运行 Python 脚本。这会立即创建 StockPriceTool.py,其中包含正确的类结构、导入和类名称 StockPriceTool
  3. 第 2 步(实现):智能体“读取”它刚刚创建的文件。它会看到 # TODO: Implement logic.
  4. 第 3 步(指导):它不确定如何为工具参数定义 JSON 架构。它会检查 examples/WeatherTool.py
  5. 完成:它会修改文件以添加 requests.get(...),并在架构中定义 ticker 参数,与 ADK 样式完全匹配。

6. 恭喜

您已成功完成 Antigravity Skills 实验,并构建了以下 Skills:

  • Git 提交格式化程序。
  • 许可标头添加程序。
  • JSON 到 Pydantic。
  • 数据库架构验证器。
  • ADK 工具基架。

Agent Skills 绝对是让 Antigravity 以您的方式编写代码、遵循规则和使用工具的绝佳方式。

参考文档