Tworzenie za pomocą Google Antigravity

1. Wprowadzenie

Google Antigravity (w dalszej części dokumentu nazywane Antigravity) to oparte na agentach środowisko IDE od Google. W tym kursie (dostępnym w języku angielskim) poznasz podstawy Antigravity. W tym ćwiczeniu w Codelabs użyjemy Antigravity do tworzenia prawdziwych aplikacji. Przejdziemy od prostych badań w internecie do generowania pełnych aplikacji i testów jednostkowych klasy korporacyjnej.

Wymagania wstępne:

2. Informacje o przypadkach użycia

Znasz już podstawy działania Antigravity, więc przyjrzyjmy się kilku przypadkom użycia, aby zobaczyć, jak działa ta funkcja. Pamiętaj, że Antigravity to platforma, która w pierwszej kolejności obsługuje agentów. Oznacza to, że w większości przypadków po prostu przekazujemy instrukcję agentowi, który następnie samodzielnie wykonuje zadanie, w razie potrzeby prosi o uprawnienia, tworzy artefakty i powiadamia nas o zakończeniu zadania. W związku z tym nie możemy w każdym z tych przypadków użycia wygenerować wszystkich wyników rozmowy z agentem. Udostępnimy instrukcje i kilka niezbędnych zrzutów ekranu z oczekiwanymi wynikami, ale Twoje wyniki mogą się nieco różnić.

Omówimy różne przypadki użycia, od automatyzacji kilku zadań w witrynach zewnętrznych po generowanie i weryfikowanie przypadków testów jednostkowych w projekcie oraz pełne tworzenie witryny. Do dzieła.

3. Najważniejsze informacje

To prosty przypadek użycia, ale może stanowić podstawę do korzystania z przeglądarki internetowej w celu odwiedzania witryn, wyodrębniania informacji, wykonywania działań i zwracania danych użytkownikowi.

W tym przypadku odwiedzimy witrynę Wiadomości Google i wyodrębnimy z niej pewne informacje. Możesz jednak łatwo przeprowadzić eksperyment na wybranej witrynie i sprawdzić, jak to działa.

Sprawdź, czy jesteś w sekcji Agent Manager i czy masz wybraną opcję Playground, jak pokazano poniżej:

cffa12c98a68cb6c.png

Następnie podaj tę instrukcję:

8513d489eea0b014.png

Spowoduje to uruchomienie procesu agenta, który stwierdzi, że musi uruchomić przeglądarkę itp. Zwróć szczególną uwagę na proces myślowy i zobacz, jak agent wykonuje swoją pracę. Jeśli wszystko pójdzie dobrze, uruchomi się przeglądarka Antigravity i otworzy witrynę, jak pokazano poniżej. Niebieska ramka wokół witryny oznacza, że Agent kontroluje teraz przeglądarkę i przegląda witrynę, aby uzyskać informacje.

9d594588f2ffe6bc.png

Po zakończeniu pracy powinny też zostać wygenerowane artefakty, jak pokazano poniżej:

dc6cf4e7d8425df8.png

Przykładowe wykonanie przez agenta jest pokazane poniżej:

fb7397cd2cce0682.png

Zwróć uwagę, że po lewej stronie znajduje się sekcja Proces myślowy. Możesz też przewijać punkty i wyświetlać odtwarzanie oraz inne dane.

Co możesz wypróbować

  • Gdy to zrozumiesz, wybierz dostępną witrynę, z której agent ma pobrać lub podsumować dane. Wybierz witrynę, która zawiera panele i wykresy, i poproś o wybranie kilku wartości.
  • Wypróbuj ten prompt: Visit https://docs.cloud.google.com/release-notes and get me a summary of the release notes, categorized by product.

4. Generowanie dynamicznej witryny za pomocą Pythona i Flask

Przejdźmy teraz do wygenerowania kompletnej aplikacji internetowej. Utworzona przez nas aplikacja internetowa będzie stroną z informacjami o 1-dniowym wydarzeniu technicznym, podczas którego wystąpi wielu prelegentów.

Jeszcze raz upewnij się, że jesteś w sekcji Agent Manager i masz wybraną opcję Playground.

Wpisz ten prompt:

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. 

Możesz rozpocząć rozmowę, wpisując powyższy prompt:

Podczas wykonywania zadania Agent będzie tworzyć artefakty:

  • Artefakt zadania
  • Artefakt implementacji
  • Artefakt przewodnika

Podany poniżej artefakt zadania był początkową sekwencją zadań, które agent powinien wykonać na podstawie otrzymanego zadania. Poniżej znajdziesz przykładowy zrzut ekranu z wykonania:

c95d82e1c040698f.png

Następnie możesz kliknąć artefakt Plan wdrożenia. Przykładowy zrzut ekranu znajdziesz poniżej:

632169a236bc62cc.png

Na koniec masz artefakt Przewodnik. Zawiera wszystkie działania wykonane przez agenta, jak pokazano poniżej:

e3f6152d6f54d4f9.png

Zauważ, że serwer został uruchomiony i wyświetlony został adres URL. Po kliknięciu tego adresu otworzy się aplikacja. Przykładowy zrzut ekranu znajdziesz poniżej:

abf879f2ce53d055.png

Jeśli przełączę się na Edytor, na ekranie zobaczę folder, w którym jest generowana aplikacja Python Flask. Zauważysz też, że po prawej stronie znajduje się tag Agent mode. Możesz tam kontynuować rozmowę.

b0fea8aa65c3a1c5.png

Załóżmy, że chcemy dodać do wydarzenia więcej prelekcji. Możemy pozostać w edytorze i w panelu agenta, a następnie wydać polecenie, np. Add two more talks to the schedule.

W rezultacie agent przeanalizuje wymagania, zaktualizuje zadanie i plan wdrożenia, a następnie zweryfikuje zaktualizowaną funkcję. Przykładowa rozmowa jest widoczna poniżej:

ba8455e6f68973e9.png

Jeśli chcesz, możesz wrócić do Menedżera agentów. Ten proces powinien pomóc Ci zrozumieć, jak przejść z roli menedżera agentów na rolę edytującego, wprowadzić odpowiednie zmiany itp.

Co możesz wypróbować

  • Dodaj dodatkowe funkcje, które chcesz mieć w aplikacji. Podaj szczegóły agentowi i obserwuj, jak wykonuje zadanie, najpierw modyfikując listę zadań, a potem plan wdrożenia itd.
  • Poproś agenta o wygenerowanie pliku README lub dodatkowej dokumentacji aplikacji.

5. Generowanie prostej aplikacji zwiększającej produktywność

Teraz wygenerujemy prostą aplikację internetową z timerem Pomodoro.

Sprawdź, czy jesteś w sekcji Agent Manager i czy masz wybraną opcję Playground. Wpisz ten prompt:

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

Zwróć uwagę, jak tworzy listę zadań i plan wdrożenia, a potem je realizuje. Zwracaj uwagę na proces, ponieważ w niektórych sytuacjach może on wymagać Twojej weryfikacji. Przykładowe wykonanie pokazano poniżej.

5be0a668e5a67d85.png

W takim przypadku powinna też uruchomić przeglądarkę Antigravity, przeprowadzić własne testy, a następnie potwierdzić, że się powiodły. Jednym z wygenerowanych przez nią elementów był artefakt multimedialny zawierający film z weryfikacji. To świetny sposób, aby sprawdzić, co zostało przetestowane. Zaproponowałem też zmiany stylu, ponieważ nie zostały one wprowadzone, a usługa mogła to zrobić.

Ostateczna wersja aplikacji wyglądała jak ta poniżej i prezentowała się całkiem dobrze.

c9ab6bca97a51a8c.png

Możemy dodać do aplikacji ładny obraz timera. Wystarczy, że wydamy dodatkowe polecenie w sposób podany poniżej:

Add an image to the application that displays a timer.

W rezultacie agent dodał nowe zadanie do artefaktu Zadanie:

498dd946d4e9ae55.png

Następnie wygenerował obraz w trakcie wykonywania zadania:

c291da9bdb37ff96.png

W końcu aplikacja wyświetliła obraz zgodnie z naszą prośbą:

de8f418ba8e4600d.png

Co możesz wypróbować

  • Zwróć uwagę, że tło ikony klepsydry w aplikacji nie jest przezroczyste. Spróbuj poprosić agenta, aby to wyjaśnił.
  • Wypróbuj kilka odmian dowolnej aplikacji, którą chcesz wygenerować. Eksperymentuj ze stylami i obrazami, proś o zmiany itp.

6. Generowanie testów jednostkowych, atrap i weryfikowanie testów

Ostatni przypadek użycia, który tu wypróbujemy, to generowanie testów jednostkowych dla konkretnego pliku z kodem, który mamy, oraz wykonywanie i weryfikowanie tych testów przez agenta.

W tym celu utworzymy przestrzeń roboczą z jednym plikiem Pythona, jak pokazano poniżej:

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}

Upewnij się, że powyższy plik Pythona znajduje się lokalnie w folderze i załaduj go jako obszar roboczy w Antigravity.

Jest to prosta usługa zamówień, która ma w funkcji checkout te kluczowe funkcje:

  1. Sprawdza, czy koszyk nie jest pusty.
  2. Sprawdź stan wszystkich produktów.
  3. Oblicza cenę końcową.
  4. Obciąża płatność.
  5. Aktualizuje asortyment.

Przypiszemy agentowi zadanie wygenerowania przypadków testów jednostkowych, dostarczenia implementacji Mock i przeprowadzenia testów, aby upewnić się, że zakończą się one powodzeniem.

Otworzymy konkretny folder obszaru roboczego i zauważysz, że do odwoływania się do pliku możemy teraz używać symbolu @. Możemy na przykład:

8368856e51a7561a.png

Pojawi się wyjaśnienie, czym jest ten plik:

b69c217d3372d802.png

Możemy poprosić o wygenerowanie lepszej wizualizacji za pomocą promptu:

Can you visually show this class for better understanding

da5bd701323818d4.png

Następnym krokiem jest wygenerowanie testów jednostkowych i poproszenie agenta o ich przetestowanie. Wpisuję ten prompt:

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

Wygenerował on ten artefakt zadania i przystąpił do jego realizacji.

21425379db336dc6.png

Możesz też zobaczyć szczegóły przeprowadzonych testów:

48f3320cd76b5cd8.png

Jednym z wygenerowanych przez niego plików był też plik testowy. Zrzut ekranu pokazujący ten widok znajdziesz poniżej:

f962061f115c040f.png

Co możesz wypróbować

Skorzystaj z własnego kodu i sprawdź, o co możesz poprosić agenta – od dodania większej liczby funkcji po refaktoryzację fragmentów kodu.

7. Gratulacje

Gratulacje! Udało Ci się użyć Google Antigravity do:

  • Samodzielnie przeszukuj internet.
  • Tworzenie i ulepszanie aplikacji internetowych full stack.
  • generować komponenty i dopracowywać estetykę interfejsu;
  • pisać i weryfikować złożone testy jednostkowe z użyciem atrap,

Możesz teraz powierzyć Antigravity ciężką pracę nad własnymi projektami.

Dokumentacja