Google Antigravity を使用して構築する

1. はじめに

Google Antigravity(このドキュメントでは Antigravity と表記)は、Google のエージェント型 IDE です。Antigravity を使ってみる Codelab では、Antigravity の基本を学ぶことができます。この Codelab では、Antigravity を使用して実際のアプリケーションを構築します。シンプルなウェブ検索から、フルスタック アプリケーションとエンタープライズ グレードの単体テストの生成まで、さまざまなタスクを実行できます。

前提条件:

  • Google Antigravity がインストールされ、構成されている。
  • Google Antigravity の基本的な理解。Codelab: Google Antigravity を使ってみるを完了することをおすすめします。

2. ユースケースについて

Antigravity の基本的な仕組みを理解できたので、実際のユースケースを見ていきましょう。Antigravity はエージェント ファーストのプラットフォームです。つまり、ほとんどの場合、エージェントに指示を出すだけで、エージェントは単独でタスクを実行し、必要に応じて権限を要求し、アーティファクトを生成し、タスクが完了したら通知します。そのため、次の各ユースケースでエージェントの会話のすべての出力を生成することはできません。手順と、想定される結果のスクリーンショットをいくつか共有しますが、結果は多少異なる可能性があります。

ここでは、外部サイトでのいくつかのタスクの自動化から、プロジェクトの単体テストケースの生成と検証、ウェブサイトの完全な開発まで、さまざまなユースケースについて説明します。始める

3. ニュース ハイライト

これはシンプルなユースケースですが、ウェブブラウザを使用してウェブサイトにアクセスし、情報を抽出し、アクションを実行して、ユーザーにデータを返すための基盤となります。

ここでは、Google ニュースのサイトにアクセスして、そこから情報を抽出します。ただし、任意のサイトで簡単にテストして、結果を確認できます。

次の図に示すように、Agent Manager にいて、Playground を選択していることを確認します。

cffa12c98a68cb6c.png

次に、次の指示を出します。

8513d489eea0b014.png

これにより、エージェント プロセスが開始され、ブラウザの起動が必要であると判断されます。思考プロセスをよく見て、エージェントがどのように作業を進めているかを確認してください。問題がなければ、Antigravity ブラウザが起動し、以下のようにサイトにアクセスします。サイトの周りの青い枠線は、エージェントがブラウザを制御し、サイトを移動して情報を取得していることを示しています。

9d594588f2ffe6bc.png

処理が完了すると、次のようにアーティファクトが生成されます。

dc6cf4e7d8425df8.png

エージェントによる実行の例を以下に示します。

fb7397cd2cce0682.png

左側に [思考プロセス] が表示されています。ポイントをスクロールして、再生やその他のデータを表示することもできます。

試してみたいこと

  • このことを理解したら、利用可能なウェブサイトを選択し、エージェントにアクセスしてデータを取得または要約してもらいます。ダッシュボードとグラフがあることがわかっているウェブサイトをいくつか指定して、いくつかの値を選択するように依頼します。
  • 次のプロンプトを試してみましょう。Visit https://docs.cloud.google.com/release-notes and get me a summary of the release notes, categorized by product.

4. Python + Flask で動的ウェブサイトを生成する

次に、完全なウェブ アプリケーションを生成します。作成するウェブ アプリケーションは、1 日の技術イベントに関する情報を提供するサイトです。このイベントでは、複数の講演者が 1 日を通して講演を行います。

もう一度、Agent Manager に移動し、Playground を選択していることを確認します。

次のプロンプトを入力します。

I would like to generate a website that is a 1-day technical conference informational site.

The website should have the following functionality:
        1. A home page that shows the current date, location, schedule and time table.
        2. The 1-day event is a list of 8 talks in total.
        3. Each talk has 1 or 2 max. speakers. 
        4. A talk has an ID, Title, Speakers, Category (1 or 2), Description and time of the talk.
        5. Each speaker has a First Name, Last Name and LinkedIn url.
        6. Allow for users to search by category, speaker, title.
        7. Give a lunch break of 60 minutes.
        8. Use dummy data for events and speakers, come up with a schedule, the event is about Google Cloud Technologies.
        9. Tech Stack: Python and Flask framework on server side. Front-end is basic HTML, CSS and JavaScript. 
        10. Test out the site on your own for all functionality and provide a detailed README on how to setup, run and make any further changes. 
11. Launch the web application for me to review. 

上記のプロンプトを入力して会話を開始します。

エージェントはタスクを実行する際に、アーティファクトの作成を進めます。

  • タスク アーティファクト
  • 実装アーティファクト
  • チュートリアル アーティファクト

以下のタスク アーティファクトは、エージェントが与えられたタスクに基づいて実行すべきと解釈したタスクの最初のシーケンスです。実行のスクリーンショットの例を以下に示します。

c95d82e1c040698f.png

[実装計画] アーティファクトをクリックします。以下に、スクリーンショットの例を示します。

632169a236bc62cc.png

最後に、ウォークスルー アーティファクトがあります。以下に示すように、エージェントが行ったすべての処理が含まれています。

e3f6152d6f54d4f9.png

サーバーが起動し、URL が提供されたことがわかります。この URL をクリックすると、アプリケーションが表示されます。以下のスクリーンショットに例を示します。

abf879f2ce53d055.png

エディタに切り替えると、Python Flask アプリケーションが生成されるフォルダが含まれていることが画面に表示されます。また、右側に Agent mode がタグ付けされているため、そこから会話を続けることもできます。

b0fea8aa65c3a1c5.png

ここで、イベントにさらにいくつかの講演を追加したいとします。エディタとエージェント パネルで、Add two more talks to the schedule などの指示を出すことができます。

これにより、エージェントが要件を分析し、タスクと実装計画を更新してから、更新された機能も検証します。会話の例を以下に示します。

ba8455e6f68973e9.png

必要に応じて、エージェント マネージャーに戻すことができます。このプロセスは、エージェント マネージャーから編集者に移行し、それに応じて変更を行うまでのプロセスを理解するのに役立ちます。

試してみたいこと

  • アプリケーションに追加したい機能を追加します。エージェントに詳細を提供し、タスクリスト、実装計画などを変更してタスクを進めていく様子を確認します。
  • エージェントに、アプリの README やその他のドキュメントを生成するよう依頼します。

5. シンプルな生産性向上アプリを生成する

ここでは、簡単なポモドーロ タイマー ウェブ アプリケーションを生成します。

Agent Manager に移動し、Playground を選択していることを確認します。次のプロンプトを入力します。

Create a productivity app that features a Pomodoro timer. Give a calm and aesthetic look to the application.

タスクリストと実装計画を作成し、それらに取り組む方法について説明しています。フローに注意してください。審査を求めるメッセージが表示される場合があります。以下に実行例を示します。

5be0a668e5a67d85.png

この場合、Antigravity ブラウザも起動し、独自のテストを実行して、テストが成功したことを確認する必要があります。生成されたものの 1 つに、検証の動画を含むメディア アーティファクトがあります。テスト内容を確認するのに最適な方法です。また、スタイル変更が反映されていなかったため、スタイル変更を提案したところ、反映されました。

完成したアプリは次のようになり、見栄えもかなり良くなりました。

c9ab6bca97a51a8c.png

アプリケーションに素敵なタイマー画像を追加してみましょう。必要な手順は次のとおりです。

Add an image to the application that displays a timer.

これにより、エージェントは Task アーティファクトに新しいタスクを追加しました。

498dd946d4e9ae55.png

タスクの実行中に画像が生成されました。

c291da9bdb37ff96.png

最終的に、アプリにはリクエストした画像が表示されました。

de8f418ba8e4600d.png

試してみたいこと

  • アプリケーションの砂時計アイコンの背景が透明になっていないことに注目してください。エージェントに透明化するよう指示してみてください。
  • 生成するアプリケーションのバリエーションをいくつか試してみます。スタイルや画像を試したり、変更をリクエストしたりします。

6. 単体テスト、モックスタブの生成、テストの検証

ここで試す最後のユースケースは、特定のコードファイルに対して単体テストを生成し、エージェントがテストを実行して検証するというものです。

このため、次のように 1 つの Python ファイルを含むワークスペースを作成します。

from typing import Dict

# --- Custom Exceptions ---
class InventoryShortageError(Exception):
    """Raised when there is not enough item stock."""
    pass

class PaymentFailedError(Exception):
    """Raised when the payment gateway rejects the transaction."""
    pass

class InvalidOrderError(Exception):
    """Raised when the order violates business rules."""
    pass

# --- External Service Interfaces (To be Mocked) ---
class InventoryService:
    def get_stock(self, product_id: str) -> int:
        """Connects to DB to check stock."""
        raise NotImplementedError("Real connection required")

    def decrement_stock(self, product_id: str, quantity: int):
        """Connects to DB to reduce stock."""
        raise NotImplementedError("Real connection required")

class PaymentGateway:
    def charge(self, amount: float, currency: str) -> bool:
        """Connects to Stripe/PayPal."""
        raise NotImplementedError("Real connection required")

# --- Main Business Logic ---
class Order:
    def __init__(self, 
                 inventory_service: InventoryService, 
                 payment_gateway: PaymentGateway,
                 customer_email: str,
                 is_vip: bool = False):
        
        self.inventory = inventory_service
        self.payment = payment_gateway
        self.customer_email = customer_email
        self.is_vip = is_vip
        self.items: Dict[str, Dict] = {} # {product_id: {'price': float, 'qty': int}}
        self.is_paid = False
        self.status = "DRAFT"

    def add_item(self, product_id: str, price: float, quantity: int = 1):
        """Adds items to the cart. Rejects invalid prices or quantities."""
        if price < 0:
            raise ValueError("Price cannot be negative")
        if quantity <= 0:
            raise ValueError("Quantity must be greater than zero")

        if product_id in self.items:
            self.items[product_id]['qty'] += quantity
        else:
            self.items[product_id] = {'price': price, 'qty': quantity}

    def remove_item(self, product_id: str):
        """Removes an item entirely from the cart."""
        if product_id in self.items:
            del self.items[product_id]

    @property
    def total_price(self) -> float:
        """Calculates raw total before discounts."""
        return sum(item['price'] * item['qty'] for item in self.items.values())

    def apply_discount(self) -> float:
        """
        Applies business logic:
        1. VIPs get flat 20% off.
        2. Regulars get 10% off if total > 100.
        3. No discount otherwise.
        """
        total = self.total_price
        
        if self.is_vip:
            return round(total * 0.8, 2)
        elif total > 100:
            return round(total * 0.9, 2)
        
        return round(total, 2)

    def checkout(self):
        """
        Orchestrates the checkout process:
        1. Validates cart is not empty.
        2. Checks stock for all items.
        3. Calculates final price.
        4. Charges payment.
        5. Updates inventory.
        """
        if not self.items:
            raise InvalidOrderError("Cannot checkout an empty cart")

        # 1. Check Inventory Logic
        for product_id, data in self.items.items():
            available_stock = self.inventory.get_stock(product_id)
            if available_stock < data['qty']:
                raise InventoryShortageError(f"Not enough stock for {product_id}")

        # 2. Calculate Final Price
        final_amount = self.apply_discount()

        # 3. Process Payment
        try:
            success = self.payment.charge(final_amount, "USD")
            if not success:
                raise PaymentFailedError("Transaction declined by gateway")
        except Exception as e:
            # Catching generic network errors from the gateway
            raise PaymentFailedError(f"Payment gateway error: {str(e)}")

        # 4. Decrement Stock (Only occurs if payment succeeded)
        for product_id, data in self.items.items():
            self.inventory.decrement_stock(product_id, data['qty'])

        self.is_paid = True
        self.status = "COMPLETED"
        
        return {"status": "success", "charged_amount": final_amount}

上記の Python ファイルがローカルのフォルダに保存されており、Antigravity でワークスペースとして読み込まれていることを確認します。

これは、checkout 関数に次の主な機能があるシンプルな Order サービスです。

  1. カートが空でないことを検証します。
  2. すべての商品の在庫を確認します。
  3. 最終価格を計算します。
  4. お支払いの請求。
  5. 在庫を更新します。

エージェントに単体テストケースの生成、モック実装の提供、テストの実行を割り当てて、テストが成功することを確認します。

特定のワークスペース フォルダを開くと、@ 記号を使用してファイルを参照できるようになっていることがわかります。たとえば、次のような処理を行います。

8368856e51a7561a.png

このファイルの説明が表示されます。

b69c217d3372d802.png

プロンプトを使用して、より優れた可視化を生成するように指示できます。

Can you visually show this class for better understanding

da5bd701323818d4.png

次のステップでは、単体テストを生成し、エージェントにテストを依頼します。次のプロンプトを入力します。

generate unit tests for this module and test it out with mock implementations.

次のタスク アーティファクトが生成され、タスクが実行されました。

21425379db336dc6.png

実行されたテストの詳細も確認できます。

48f3320cd76b5cd8.png

生成されたファイルの一つがテストファイルでした。以下にそのスクリーンショットを示します。

f962061f115c040f.png

試してみたいこと

独自のコードを使用して、機能の追加からコードの一部のリファクタリングまで、エージェントに何ができるかを確認します。

7. 完了

おめでとうございます!Google Antigravity を使用して、次の操作を行いました。

  • ウェブを自律的に調査します。
  • フルスタック ウェブ アプリケーションを構築して反復処理します。
  • アセットを生成し、UI の美しさを洗練させます。
  • モックを使用して複雑な単体テストを作成し、検証します。

これで、独自のプロジェクトで Antigravity を活用できるようになりました。

リファレンス ドキュメント