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 ManagerPlayground を選択していることを確認します。

cffa12c98a68cb6c.png

次の指示を入力します。 "「news.google.com にアクセスして、現在のハイライトを取得してください。」"

8513d489eea0b014.png

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

9d594588f2ffe6bc.png

作業が完了すると、以下に示すようにアーティファクトが生成されます。

dc6cf4e7d8425df8.png

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

fb7397cd2cce0682.png

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

試してみたいこと

  • これを理解したら、Agent にアクセスしてデータを取得または要約してもらいたいウェブサイトを選択します。ダッシュボードやグラフがあるウェブサイトを選択して、いくつかの値を取得してもらいます。
  • 次のプロンプトを試します。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 ManagerPlayground を選択していることを確認します。最初からやり直すには、新しい Playground チャットを開始し、Planning モードを選択して、エージェントが実行前に計画を立てるようにします。

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

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

[Implementation Plan] アーティファクトをクリックします。スクリーンショットの例を以下に示します。

632169a236bc62cc.png

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

e3f6152d6f54d4f9.png

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

abf879f2ce53d055.png

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

b0fea8aa65c3a1c5.png

イベントに講演を追加するとします。エディタとエージェント パネルで、「Add two more talks to the schedule」などの指示を入力します。

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

ba8455e6f68973e9.png

必要に応じて、Agent Manager に戻ることができます。このプロセスでは、Agent Manager からエディタに切り替え、必要に応じて変更を加える方法などを理解できます。

試してみたいこと

  • アプリケーションに追加する機能を追加します。エージェントに詳細を提供し、タスクリスト、実装計画の順に変更してタスクを進める方法を確認します。
  • エージェントに、アプリケーションの README または詳細なドキュメントを生成してもらいます。

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

シンプルなポモドーロ タイマー ウェブ アプリケーションを生成します。

以下に示すように、Agent ManagerPlayground を選択していることを確認します。次のプロンプトを入力します。

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

タスクリストと実装計画を作成し、それに基づいて作業を進める方法を確認します。フローに注意してください。レビューを求めるメッセージが表示される場合があります。実行例を以下に示します。

5be0a668e5a67d85.png

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

最終的なアプリは次のようになり、非常に優れています。

c9ab6bca97a51a8c.png

アプリケーションにタイマーの画像を追加してみましょう。必要なのは、以下に示すようにフォローアップ指示を出すだけです。

Add an image to the application that displays a timer.

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

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 関数に次の主な機能があります。

  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 に独自のプロジェクトの重労働を任せることができます。

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