Google Antigravity로 빌드

1. 소개

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

이 Codelab에서는 Antigravity를 사용하여 실제 애플리케이션을 빌드합니다. 간단한 웹 조사부터 시작하여 풀 스택 애플리케이션과 엔터프라이즈급 단위 테스트를 생성하는 단계로 나아갑니다.

기본 요건:

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

2. 사용 사례 정보

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

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

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 Agent 인터페이스에서 새 프로젝트를 만들고 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-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를 사용하여 자체 프로젝트에서 무거운 작업을 처리할 수 있습니다.

참조 문서