Google Antigravity로 빌드

1. 소개

이 Codelab에서는 Google Antigravity에 관해 알아봅니다. Google Antigravity는 에이전트 시대에 개발할 수 있도록 설계된 에이전트 개발 플랫폼입니다. Antigravity는 AI 에이전트의 중앙 지휘소 역할을 하며 활동을 시작, 모니터링, 조정할 수 있는 통합 플랫폼을 제공합니다.

이 Codelab에서는 Antigravity를 사용하여 실제 애플리케이션을 빌드합니다. 간단한 웹 연구에서 풀 스택 애플리케이션 및 엔터프라이즈급 단위 테스트 생성으로 이동합니다.

기본 요건:

  • Antigravity 및 Antigravity IDE가 설치되고 구성되어 있어야 합니다.
  • Google Antigravity에 관한 기본적인 이해가 있어야 합니다. Google Antigravity 시작하기 Codelab을 완료하는 것이 좋습니다.

2. 사용 사례 정보

Antigravity에 관한 기본적인 이해가 있으므로 몇 가지 사용 사례를 살펴보겠습니다. Antigravity는 에이전트 우선 플랫폼입니다. 즉, 대부분의 경우 에이전트에 간단히 안내를 제공하면 에이전트가 자체적으로 작업을 실행하고, 필요한 경우 권한을 요청하고, 아티팩트를 생성한 후 작업이 완료되면 사용자에게 알립니다. 따라서 다음 사용 사례에서 에이전트 대화의 모든 출력을 생성할 수는 없습니다. 안내와 예상 결과의 몇 가지 필수 스크린샷을 공유하지만 결과는 약간 다를 수 있습니다.

다룰 사용 사례는 외부 사이트에서 몇 가지 작업을 자동화하는 것부터 프로젝트의 단위 테스트 사례를 생성하고 확인하는 것, 전체 웹사이트 개발에 이르기까지 다양합니다. 시작하기

3. 뉴스 하이라이트

이것은 간단한 사용 사례이지만 웹브라우저를 사용하여 웹사이트를 방문하고, 정보를 추출하고, 일부 작업을 실행한 후 사용자에게 데이터를 반환하는 기반이 될 수 있습니다.

이 경우 Google 뉴스 사이트를 방문하여 정보를 추출합니다. 하지만 원하는 사이트를 쉽게 실험하고 결과를 확인할 수 있습니다.

이 Codelab에서 볼 다양한 프로젝트를 만들 루트 폴더가 있다고 가정합니다. 머신의 이 루트 폴더 이름은 agy2-pprojects입니다.

먼저 위의 폴더에 news-highlights라는 폴더를 만들어 새로 시작합니다.

Antigravity를 실행하고 새 프로젝트를 만듭니다. news-highlights 폴더를 추가합니다.

새로 가져온 news-highlights 작업공간에서 새 대화를 시작합니다.

58c4419125240f8f.png

그런 다음 다음 안내를 제공합니다. "news.google.com을 방문하여 현재 하이라이트를 가져와줘."

69859175cdace3c2.png

이렇게 하면 에이전트 프로세스가 시작되고 news.google.com 사이트를 방문해야 하며 권한을 요청해야 한다고 판단합니다. URL을 읽기 위해 여러 번 메시지가 표시될 수 있으며 이 프로젝트에 대한 권한을 부여할 수 있습니다.

85f14eddde22704c.png

사고 프로세스에 주의를 기울이고 에이전트가 작업을 어떻게 진행하는지 확인해야 합니다. 다음은 에이전트의 샘플 실행입니다.

7be51d200fb1296f.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일 기술 이벤트에 관한 정보를 제공하는 사이트입니다.

다시 한번 conference-website이라는 새 폴더를 만듭니다. Antigravity 에이전트 인터페이스에서 새 프로젝트를 만들고 conference-website 폴더를 추가했는지 확인합니다.

아래와 같은 프롬프트를 제공하여 대화를 시작할 수 있습니다.

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. 

Antigravity는 요청을 분석하고 먼저 구현 계획을 제시합니다. 프롬프트에서 지정한 요구사항을 만들고 충족하는 방법을 검토할 수 있도록 implementation_plan.md라는 주요 아티팩트를 만듭니다. 다음은 샘플 출력입니다.

8f516fd94f4ad57.png

계속 진행하기 전에 구현 계획을 살펴보세요. 위의 implementation_plan.md 파일 링크를 클릭하거나 오른쪽 상단의 보조 창을 전환하여 확인할 수 있습니다. 그러면 아티팩트 뷰가 표시되고 현재 구현 계획을 검토할 수 있습니다.

e12b6e1270405137.png

실행을 위해 생성된 샘플 구현 계획은 다음과 같습니다.

5069ec7ab1ae6310.png

계획에 의견을 제공하고 에이전트에 다시 프롬프트를 표시하거나 지금은 구현 계획을 그대로 수락하고 대화 인터페이스에서 계속 버튼을 클릭하여 진행할 수 있습니다.

에이전트는 소스 코드 파일 생성을 진행하며 작업이라는 다른 아티팩트를 업데이트하는 것도 확인할 수 있습니다. 최종 결과를 달성하기 위해 실행해야 하는 작업 또는 작업 목록입니다.

언제든지 작업을 클릭하거나 아티팩트 목록을 방문하여 작업을 볼 수 있습니다. 다음은 샘플 목록입니다.

caf136694efc222f.png

최종 작업의 어느 시점에서 애플리케이션을 실행하고 확인하려고 하면 Antigravity는 Python 환경을 설정하고 환경 설정, 종속 항목 설치 등에 관한 권한을 요청합니다. 필요한 권한을 부여하세요.

확인이 완료되면 완료된 기능, 기술 스택, 유효성 검사 결과, 안내를 자세히 설명하는 또 다른 아티팩트인 둘러보기와 함께 세부정보가 강조표시됩니다.

d0f61eb85d348030.png

다음은 샘플 둘러보기 입니다.

fb18995f34c286ae.png

URL을 방문할 때 최종 웹사이트는 다음과 같습니다.

2b2ee3149d59da7a.png

생성된 코드를 보려면 오른쪽 상단의 IDE 열기 를 클릭합니다. 그러면 생성된 코드를 보는 데 사용할 수 있는 Antigravity IDE가 열립니다. 다음은 샘플 스크린샷입니다.

12798431169dd8cf.png

시도해 볼 만한 작업

  • 애플리케이션에 원하는 추가 기능을 추가합니다. 에이전트에 세부정보를 제공하고 먼저 할 일 목록을 수정한 다음 구현 계획 등을 수정하여 작업을 진행하는 방법을 확인합니다.
  • 이벤트 일정에 추가 데이터를 추가합니다. 예: Add two more talks to the schedule
  • 에이전트에 애플리케이션의 README 또는 추가 문서를 생성하도록 요청합니다.

5. 간단한 생산성 앱 생성

이제 간단한 Pomodoro 타이머 웹 애플리케이션을 생성해 보겠습니다.

pomodoro-timer 폴더를 만듭니다. Agent Manager에 있고 pomodoro-timer 작업공간을 가져와 선택했는지 확인합니다. 다음 프롬프트로 시작하세요.

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

구현 계획, 할 일 목록을 만들고 이를 진행하는 방법을 확인합니다. 흐름에 계속 주의를 기울이세요. 검토를 요청하는 상황이 있을 수 있습니다.

둘러보기 메시지와 작업이 포함된 샘플 실행은 다음과 같습니다.

df0db367ba475db2.png

최종 앱은 아래와 같으며 꽤 좋습니다.

ef8ac58d0677e56.png

시도해 볼 만한 작업

  • 애플리케이션에 이미지를 추가합니다. 예: 애플리케이션에 타이머 이미지를 추가합니다.
  • 생성하려는 애플리케이션의 몇 가지 변형을 사용해 보세요. 스타일, 이미지를 사용하고 변경을 요청합니다.

6. 단위 테스트, 모의 스텁 생성 및 테스트 유효성 검사

여기서 시도할 최종 사용 사례는 보유한 특정 코드 파일의 단위 테스트를 생성하고 에이전트가 테스트를 실행하고 유효성을 검사하는 것입니다.

이를 위해 아래와 같이 단일 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 파일 (order_service.py)이 새 폴더에 로컬로 있고 Antigravity에서 대화를 위해 해당 프로젝트가 열려 있는지 확인합니다.

다음과 같은 주요 기능이 checkout 함수에 있는 간단한 주문 서비스입니다.

  1. 카트가 비어 있지 않은지 확인합니다.
  2. 모든 항목의 재고를 확인합니다.
  3. 최종 가격을 계산합니다.
  4. 결제를 청구합니다.
  5. 인벤토리를 업데이트합니다.

에이전트에 단위 테스트 사례를 생성하고, 모의 구현을 제공하고, 테스트를 실행하여 성공하도록 하는 작업을 할당합니다.

특정 작업공간 폴더를 열면 이제 @ 기호를 사용하여 파일을 참조할 수도 있습니다. 예를 들어 @order를 입력하기 시작하면 order_service.py 파일이 표시됩니다.

c4331bee03c5512c.png

이 파일을 이해하는 데 도움이 되는 작업을 제공할 수 있습니다. 다음 프롬프트를 입력합니다.

Explain the @order_service.py file

이 파일의 용도에 관한 설명이 표시됩니다.

269ff8450d813970.png

프롬프트를 통해 더 나은 시각화를 생성하도록 요청할 수 있습니다.

Can you visually show this class for better understanding

Antigravity는 작업이 완료되었으며 시각화가 포함된 아티팩트를 생성했다고 언급합니다.

ea389f494786a9ad.png

아래와 같이 시각화를 확인할 수 있습니다.

70e6822a86f74de9.png

다음과 같습니다.

3ebd94221655a03f.png

다음 단계는 단위 테스트를 생성하고 에이전트에 테스트하도록 요청하는 것입니다. 다음 프롬프트를 입력합니다.

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

작업을 진행하고, 테스트를 생성하고, 실행하고, 버그도 수정했습니다. 다음은 출력입니다.

788cd07aadd09a4b.png

생성된 파일 중 하나는 테스트 파일이었습니다. 다음은 스크린샷입니다.

7a79d27eb34f0530.png

시도해 볼 만한 작업

자체 코드를 가져와서 에이전트에 추가 기능을 추가하는 것부터 코드의 일부를 리팩터링하는 것까지 무엇을 요청할 수 있는지 확인합니다.

7. 축하합니다

축하합니다. Google Antigravity를 사용하여 다음 작업을 완료했습니다.

  • 자율적으로 웹을 연구합니다.
  • 풀 스택 웹 애플리케이션을 빌드하고 반복합니다.
  • 모의를 사용하여 복잡한 단위 테스트를 작성하고 유효성을 검사합니다.

이제 Antigravity가 자체 프로젝트에서 어려운 작업을 처리하도록 할 수 있습니다.

참조 문서