Laboratorium 3. Od prototypu do produkcji – wdrażanie agenta ADK w Cloud Run z GPU

1. Wprowadzenie

Opis

W tym module wdrożysz gotowego do użytku produkcyjnego agenta Agent Development Kit (ADK) z backendem Gemma akcelerowanym przez GPU. Skupiamy się na najważniejszych wzorcach wdrażania: konfigurowaniu usług Cloud Run z obsługą GPU, integrowaniu backendów modeli z agentami ADK i obserwowaniu zachowania autoskalowania pod obciążeniem.

Jakie zadania wykonasz

W tym module skupisz się na najważniejszych aspektach wdrażania w środowisku produkcyjnym:

  1. Wdrażanie Gemma w Cloud Run z GPU – skonfigurujesz backend modelu Gemma o wysokiej wydajności
  2. Integracja wdrożenia Gemma z agentem ADK – połączysz agenta z modelem akcelerowanym przez GPU.
  3. Testowanie za pomocą interfejsu internetowego ADK – sprawdzisz, czy agent konwersacyjny działa prawidłowo.
  4. Przeprowadzanie testu obciążenia – zaobserwujesz, jak instancje Cloud Run automatycznie skalują się pod obciążeniem.

Skupiamy się na wzorcach wdrożeń produkcyjnych, a nie na rozbudowanym tworzeniu agentów.

Czego się nauczysz

  • Wdrażanie modeli Gemma z akceleracją GPU w Cloud Run do użytku produkcyjnego
  • Integrowanie wdrożeń modeli zewnętrznych z agentami ADK
  • Konfigurowanie i testowanie wdrożeń agentów AI gotowych do użycia w środowisku produkcyjnym
  • Rozumienie zachowania autoskalowania Cloud Run pod obciążeniem
  • Obserwowanie, jak wiele instancji Cloud Run koordynuje działania podczas nagłych wzrostów ruchu
  • Przeprowadzanie testów obciążenia w celu sprawdzenia wydajności i autoskalowania

2. Konfiguracja projektu

  1. Jeśli nie masz jeszcze konta Google, musisz je utworzyć.
    • Użyj konta osobistego zamiast konta służbowego lub szkolnego. Konta służbowe i szkolne mogą mieć ograniczenia, które uniemożliwiają włączenie interfejsów API potrzebnych w tym module.
  2. Zaloguj się w konsoli Google Cloud.
  3. Włącz płatności w konsoli Google Cloud.
  4. Utwórz nowy projekt lub użyj już istniejącego.

3. Otwórz edytor Cloud Shell

  1. Kliknij ten link, aby przejść bezpośrednio do edytora Cloud Shell
  2. Jeśli w dowolnym momencie pojawi się prośba o autoryzację, kliknij Autoryzuj, aby kontynuować. Kliknij, aby uwierzytelnić się w Cloud Shell
  3. Jeśli terminal nie pojawia się u dołu ekranu, otwórz go:
    • Kliknij Wyświetl.
    • Kliknij TerminalOtwieranie nowego terminala w edytorze Cloud Shell
  4. W terminalu ustaw projekt za pomocą tego polecenia:
    • Format:
      gcloud config set project [PROJECT_ID]
      
    • Przykład:
      gcloud config set project lab-project-id-example
      
    • Jeśli nie pamiętasz identyfikatora projektu:
      • Aby wyświetlić listę wszystkich identyfikatorów projektów, użyj tego polecenia:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Ustawianie identyfikatora projektu w terminalu edytora Cloud Shell
  5. Powinien wyświetlić się ten komunikat:
    Updated property [core/project].
    
    Jeśli widzisz symbol WARNING i pojawia się pytanie Do you want to continue (Y/n)?, prawdopodobnie identyfikator projektu został wpisany nieprawidłowo. Naciśnij n, a następnie Enter i spróbuj ponownie uruchomić polecenie gcloud config set project.

4. Włączanie interfejsów API i ustawianie regionu domyślnego

Zanim wdrożymy usługi Cloud Run z obsługą procesora graficznego, musimy włączyć wymagane interfejsy Google Cloud API i skonfigurować ustawienia projektu.

  1. W terminalu włącz interfejsy API:
gcloud services enable \
  run.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  aiplatform.googleapis.com

Jeśli pojawi się pytanie o autoryzację, kliknij Autoryzuj, aby przejść dalej. Kliknij, aby uwierzytelnić się w Cloud Shell

Wykonanie tego polecenia może potrwać kilka minut, ale powinno ostatecznie wyświetlić komunikat o sukcesie podobny do tego:

Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
  1. Ustaw domyślny region Cloud Run.
gcloud config set run/region europe-west1

5. Przygotowywanie projektu w Pythonie

Skonfigurujmy kod początkowy, który zawiera podstawową strukturę zarówno backendu Gemma, jak i usług agenta ADK.

  1. Sklonuj repozytorium początkowe:
    git clone https://github.com/amitkmaraj/accelerate-ai-lab3-starter.git
    cd accelerate-ai-lab3-starter
    
  2. Sprawdź strukturę projektu:
    ls -la
    
    Powinna pojawić się ta struktura początkowa:
    accelerate-ai-lab3-starter/
    ├── README.md                    # Project overview
    ├── ollama-backend/              # Ollama backend (separate deployment)
    │   └── Dockerfile               # Backend container (🚧 to implement)
    └── adk-agent/                   # ADK agent (separate deployment)
        ├── pyproject.toml           # Python dependencies (✅ completed)
        ├── env.template             # Environment template (✅ completed)
        ├── server.py                # FastAPI server (🚧 to implement)
        ├── Dockerfile               # Container config (🚧 to implement)
        ├── load_test.py             # Load testing (🚧 to implement)
        └── production_agent/        # Agent implementation
            ├── __init__.py         # Package init (✅ completed)
            └── agent.py            # Agent logic (🚧 to implement)
    

6. Omówienie architektury

Zanim wdrożysz architekturę 2 usług, zapoznaj się z nią:

Moduł 3. Architektura z 2 usługami

Kluczowa obserwacja: podczas testów obciążeniowych zauważysz, że obie usługi skalują się niezależnie – backend GPU (usługa stanowiąca wąskie gardło) skaluje się do 1–3 instancji na potrzeby obciążenia związanego z wnioskowaniem, a agent ADK pozostaje na poziomie 1 instancji na potrzeby obsługi żądań.

7. Wdrażanie backendu Gemma w Cloud Run z GPU

Moduł 3. Usługa Gemma

Pierwszym ważnym krokiem jest wdrożenie akcelerowanego przez GPU modelu Gemma, który będzie mózgiem agenta ADK. Oddzielny, wdrożony model LLM może być korzystny w architekturach, w których potrzebujesz osobnego dostrojonego modelu lub izolowanego skalowania.

  1. Przejdź do katalogu backendu Ollama:
    cd ollama-backend
    
  2. Otwórz i wdroż plik Dockerfile Ollamy:
    cloudshell edit Dockerfile
    
    Zastąp komentarze TODO tym kodem:
    FROM ollama/ollama:latest
    
    # Listen on all interfaces, port 8080
    ENV OLLAMA_HOST 0.0.0.0:8080
    
    # Store model weight files in /models
    ENV OLLAMA_MODELS /models
    
    # Reduce logging verbosity
    ENV OLLAMA_DEBUG false
    
    # Never unload model weights from the GPU
    ENV OLLAMA_KEEP_ALIVE -1
    
    # Store the model weights in the container image
    ENV MODEL gemma3:4b
    RUN ollama serve & sleep 5 && ollama pull $MODEL
    
    # Start Ollama
    ENTRYPOINT ["ollama", "serve"]
    
    🔧 Co to robi:
    • Korzysta z oficjalnego obrazu Ollamy jako podstawy.
    • Ustawia OLLAMA_HOST tak, aby akceptował połączenia z dowolnego adresu IP.
    • Udostępnia port 8080.
  3. Wdróż backend Gemy z obsługą GPU. Uwaga: wdrożenie może potrwać do 10 minut. Jest to spowodowane pobieraniem większego modelu otwartego, takiego jak Gemma 3 4B. Dodatkowo udostępnianie GPU trwa nieco dłużej niż instancji Cloud Run obsługującej tylko CPU.
    gcloud run deploy ollama-gemma34b-gpu \
      --source . \
      --region europe-west1 \
      --concurrency 4 \
      --cpu 8 \
      --set-env-vars OLLAMA_NUM_PARALLEL=4 \
      --gpu 1 \
      --gpu-type nvidia-l4 \
      --max-instances 3 \
      --memory 32Gi \
      --allow-unauthenticated \
      --no-cpu-throttling \
      --no-gpu-zonal-redundancy \
      --timeout=600 \
      --labels=dev-tutorial=codelab-agent-gpu
    
    ⚙️ Wyjaśnienie kluczowych ustawień:
    • GPU: NVIDIA L4, wybrany ze względu na doskonały stosunek ceny do wydajności w przypadku zbiorów zadań wymagających wnioskowania. L4 ma 24 GB pamięci GPU i zoptymalizowane operacje tensorowe, dzięki czemu idealnie nadaje się do modeli z 4 miliardami parametrów, takich jak Gemma.
    • Pamięć: 32 GB pamięci systemowej do obsługi wczytywania modelu, operacji CUDA i zarządzania pamięcią przez Ollamę.
    • CPU: 8 rdzeni do optymalnego obsługiwania wejścia/wyjścia i zadań przetwarzania wstępnego
    • Równoczesność: 4 żądania na instancję równoważą przepustowość z wykorzystaniem pamięci przez GPU.
    • Czas oczekiwania: 600 sekund na początkowe wczytanie modelu i uruchomienie kontenera.
    💰 Koszty: instancje GPU są znacznie droższe niż instancje tylko z CPU (ok. 2–4 USD za godzinę w porównaniu z ok. 0,10 USD za godzinę). Ustawienie --max-instances 1 pomaga kontrolować koszty, zapobiegając niepotrzebnemu skalowaniu instancji GPU.
  4. Poczekaj na zakończenie wdrażania i zanotuj adres URL usługi:
    export OLLAMA_URL=$(gcloud run services describe ollama-gemma34b-gpu \
        --region=europe-west1 \
        --format='value(status.url)')
    
    echo "🎉 Gemma backend deployed at: $OLLAMA_URL"
    

8. Wdrażanie integracji agenta ADK

Teraz utwórzmy minimalnego agenta ADK, który łączy się z wdrożonym backendem Gemma.

  1. Przejdź do katalogu agenta ADK:
    cd ../adk-agent
    
  2. Otwórz i wdroż konfigurację agenta:
    cloudshell edit production_agent/agent.py
    
    Zastąp wszystkie komentarze TODO tą minimalną implementacją:
    import os
    from pathlib import Path
    
    from dotenv import load_dotenv
    from google.adk.agents import Agent
    from google.adk.models.lite_llm import LiteLlm
    import google.auth
    
    # Load environment variables
    root_dir = Path(__file__).parent.parent
    dotenv_path = root_dir / ".env"
    load_dotenv(dotenv_path=dotenv_path)
    
    # Configure Google Cloud
    try:
        _, project_id = google.auth.default()
        os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id)
    except Exception:
        pass
    
    os.environ.setdefault("GOOGLE_CLOUD_LOCATION", "europe-west1")
    
    # Configure model connection
    gemma_model_name = os.getenv("GEMMA_MODEL_NAME", "gemma3:4b")
    
    # Production Gemma Agent - GPU-accelerated conversational assistant
    gemma_agent = Agent(
       model=LiteLlm(model=f"ollama_chat/{gemma_model_name}"),
       name="gemma_agent",
       description="A production-ready conversational assistant powered by GPU-accelerated Gemma.",
       instruction="""You are 'Gem', a friendly, knowledgeable, and enthusiastic zoo tour guide.
       Your main goal is to make a zoo visit more fun and educational for guests by answering their questions.
    
       You can provide general information and interesting facts about different animal species, such as:
       - Their natural habitats and diet. 🌲🍓
       - Typical lifespan and behaviors.
       - Conservation status and unique characteristics.
    
       IMPORTANT: You do NOT have access to any tools. This means you cannot look up real-time, specific information about THIS zoo. You cannot provide:
       - The names or ages of specific animals currently at the zoo.
       - The exact location or enclosure for an animal.
       - The daily schedule for feedings or shows.
    
       Always answer based on your general knowledge about the animal kingdom. Keep your tone cheerful, engaging, and welcoming for visitors of all ages. 🦁✨""",
       tools=[],  # Gemma focuses on conversational capabilities
    )
    
    # Set as root agent
    root_agent = gemma_agent
    
    🔧 Co to robi:
    • Łączy się z wdrożonym backendem Gemma za pomocą LiteLLM.
    • Tworzy prostego agenta konwersacyjnego.
    • Konfiguruje integrację z Google Cloud.
  3. Otwórz i wdroż serwer FastAPI:
    cloudshell edit server.py
    
    Zastąp wszystkie komentarze TODO:
    import os
    from dotenv import load_dotenv
    from fastapi import FastAPI
    from google.adk.cli.fast_api import get_fast_api_app
    
    # Load environment variables
    load_dotenv()
    
    AGENT_DIR = os.path.dirname(os.path.abspath(__file__))
    app_args = {"agents_dir": AGENT_DIR, "web": True}
    
    # Create FastAPI app with ADK integration
    app: FastAPI = get_fast_api_app(**app_args)
    
    # Update app metadata
    app.title = "Production ADK Agent - Lab 3"
    app.description = "Gemma agent with GPU-accelerated backend"
    app.version = "1.0.0"
    
    @app.get("/health")
    def health_check():
        return {"status": "healthy", "service": "production-adk-agent"}
    
    @app.get("/")
    def root():
        return {
            "service": "Production ADK Agent - Lab 3",
            "description": "GPU-accelerated Gemma agent",
            "docs": "/docs",
            "health": "/health"
        }
    
    if __name__ == "__main__":
        import uvicorn
        uvicorn.run(app, host="0.0.0.0", port=8080, log_level="info")
    
    🔧 Co to robi:
    • Tworzy serwer FastAPI z integracją ADK.
    • Włącza interfejs internetowy do testowania.
    • Udostępnia punkty końcowe kontroli stanu.
  4. Otwórz i wdroż plik Dockerfile:
    cloudshell edit Dockerfile
    
    Zastąp wszystkie komentarze TODO:
    FROM python:3.13-slim
    
    # Copy uv from the official image
    COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
    
    # Install system dependencies
    RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
    
    # Set working directory
    WORKDIR /app
    
    # Copy all files
    COPY . .
    
    # Install Python dependencies
    RUN uv sync
    
    # Expose port
    EXPOSE 8080
    
    # Run the application
    CMD ["uv", "run", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8080"]
    
    Wyjaśnienie wyboru technologii:
    • uv: nowoczesny system zarządzania pakietami Pythona, który jest 10–100 razy szybszy niż pip. Korzysta z globalnej pamięci podręcznej i pobierania równoległego, co znacznie skraca czas tworzenia kontenera.
    • Python 3.13-slim: najnowsza wersja Pythona z minimalnymi zależnościami systemowymi, co zmniejsza rozmiar kontenera i powierzchnię ataku.
    • Wielostopniowe tworzenie: kopiowanie uv z oficjalnego obrazu zapewnia uzyskanie najnowszej zoptymalizowanej wersji binarnej.

9. Konfigurowanie środowiska i wdrażanie agenta

Teraz skonfigurujemy agenta ADK, aby połączyć go z wdrożonym backendem Gemma, i wdrożymy go jako usługę Cloud Run. Obejmuje to skonfigurowanie zmiennych środowiskowych i wdrożenie agenta z odpowiednią konfiguracją.

Uwaga: przed rozpoczęciem tej sekcji sprawdź, czy jesteś w katalogu /adk-agent.

  1. Skonfiguruj środowisko:
    cat << EOF > .env
    GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
    GOOGLE_CLOUD_LOCATION=europe-west1
    GEMMA_MODEL_NAME=gemma3:4b
    OLLAMA_API_BASE=$OLLAMA_URL
    EOF
    

Zmienne środowiskowe w Cloud Run

Zmienne środowiskowe to pary klucz-wartość, które konfigurują aplikację w czasie działania. Są one szczególnie przydatne w przypadku:

  • punktów końcowych interfejsu API i adresów URL usług (np. naszego backendu Ollama);
  • konfiguracji, która zmienia się w zależności od środowiska (deweloperskiego, testowego, produkcyjnego);
  • danych wrażliwych, które nie powinny być zakodowane na stałe.

✅ Sprawdzone metody na podstawie dokumentacji zmiennych środowiskowych Cloud Run:

  1. Unikaj zarezerwowanych zmiennych: nie ustawiaj zmiennej PORT (Cloud Run ustawia ją automatycznie) ani zmiennych zaczynających się od X_GOOGLE_.
  2. Używaj opisowych nazw: dodawaj do zmiennych prefiksy, aby uniknąć konfliktów (np. GEMMA_MODEL_NAME zamiast MODEL).
  3. Zastąp przecinki: jeśli wartości zawierają przecinki, użyj innego separatora: --set-env-vars "^@^KEY1=value1,value2@KEY2=..."
  4. Aktualizacja a zastępowanie: użyj --update-env-vars, aby dodać lub zmienić określone zmienne bez wpływu na inne.

Jak ustawić zmienne w Cloud Run:

  • Z pliku: gcloud run deploy SERVICE_NAME --env-vars-file=.env --labels=dev-tutorial=codelab-adk (wczytuje wiele zmiennych z pliku)
  • Wiele flag: powtórz --set-env-vars w przypadku złożonych wartości, których nie można rozdzielić przecinkami.

Wdróż agenta ADK:

export PROJECT_ID=$(gcloud config get-value project)

gcloud run deploy production-adk-agent \
   --source . \
   --region europe-west1 \
   --allow-unauthenticated \
   --memory 4Gi \
   --cpu 2 \
   --max-instances 1 \
   --concurrency 10 \
   --timeout 300 \
   --set-env-vars GOOGLE_CLOUD_PROJECT=$PROJECT_ID \
   --set-env-vars GOOGLE_CLOUD_LOCATION=europe-west1 \
   --set-env-vars GEMMA_MODEL_NAME=gemma3:4b \
   --set-env-vars OLLAMA_API_BASE=$OLLAMA_URL \
   --labels=dev-tutorial=codelab-agent-gpu

⚙️ Kluczowa konfiguracja:

  • Autoskalowanie: stała liczba instancji – 1 (lekkie przetwarzanie żądań)
  • Równoczesność: 10 żądań na instancję
  • Pamięć: 4 GB w przypadku agenta ADK
  • Środowisko: łączy się z backendem Gemy.

🔒 Uwaga dotycząca bezpieczeństwa: w tym module dla uproszczenia używamy --allow-unauthenticated. W wersji produkcyjnej zaimplementuj odpowiednie uwierzytelnianie za pomocą:

  • uwierzytelniania między usługami Cloud Run za pomocą kont usługi,
  • zasad zarządzania tożsamościami i dostępem (uprawnień),
  • kluczy interfejsu API lub OAuth na potrzeby dostępu zewnętrznego,
  • Rozważ użycie gcloud run services add-iam-policy-binding do kontrolowania dostępu.
  1. Uzyskaj adres URL usługi agenta:
    export AGENT_URL=$(gcloud run services describe production-adk-agent \
        --region=europe-west1 \
        --format='value(status.url)')
    
    echo "🎉 ADK Agent deployed at: $AGENT_URL"
    

🔧 INFORMACJE: Zarządzanie zmiennymi środowiskowymi po wdrożeniu

Jeśli później musisz zaktualizować zmienne środowiskowe (co jest powszechne w przypadku środowisk produkcyjnych), możesz to zrobić bez ponownego wdrażania:

  1. Zaktualizuj określone zmienne:
    # Update the Ollama backend URL if it changes
    gcloud run services update production-adk-agent \
        --update-env-vars OLLAMA_API_BASE=$OLLAMA_URL
    
    Pojawi się prośba o wybranie regionu. Możesz wybrać 17 (europe-west1) i kontynuować.
  2. Wyświetl bieżące zmienne środowiskowe:
    gcloud run services describe production-adk-agent \
        --region=europe-west1 \
        --format="value(spec.template.spec.template.spec.containers[0].env[].name,spec.template.spec.template.spec.containers[0].env[].value)"
    
  3. Usuń zmienne (w razie potrzeby):
    # Remove a specific environment variable
    gcloud run services update production-adk-agent \
        --remove-env-vars VARIABLE_NAME
    

Dzięki temu tworzysz nową wersję bez ponownego tworzenia kontenera, co sprawia, że aktualizacje konfiguracji są szybkie i wydajne.

10. Testowanie za pomocą interfejsu internetowego ADK

Po wdrożeniu obu usług możesz sprawdzić, czy agent ADK może komunikować się z akcelerowanym przez GPU backendem Gemma i odpowiadać na zapytania użytkowników.

  1. Przetestuj punkt końcowy stanu:
    curl $AGENT_URL/health
    
    Powinno pojawić się:
    { "status": "healthy", "service": "production-adk-agent" }
    
  2. Uruchom serwer proxy, aby uzyskać dostęp do interfejsu internetowego:
    gcloud run services proxy production-adk-agent --port=8080
    
    Pozostaw to działające w terminalu. Jeśli pojawi się prośba o określenie regionu, wybierz europe-west1 (17).
  3. Otwórz link, klikając przycisk Web Preview u góry terminala. Możesz też przytrzymać klawisz Ctrl/Command na klawiaturze i kliknąć link localhost:8080. Powinien pojawić się interfejs internetowy ADK.
  4. Wypróbuj agenta, korzystając z tych przykładowych rozmów:
    • „Co zwykle jedzą pandy rude na wolności?”
    • „Możesz mi powiedzieć coś ciekawego o irbisach?”
    • „Dlaczego żaby z rodziny drzewołazów są tak jaskrawo ubarwione?”
    • „W którym zoo urodziły się małe kangurzątka?”
    👀 Co obserwować:
    • Agent odpowiada, korzystając z wdrożonego modelu Gemma. Możesz to sprawdzić, obserwując logi wdrożonej usługi Gemma. Zrobimy to w następnej sekcji.
    • Odpowiedzi są generowane przez backend z akceleracją GPU.
    • Interfejs internetowy zapewnia przejrzystą obsługę czatu.

Testowanie pakietu ADK w module 3

11. Wdrażanie i przeprowadzanie testów obciążenia

Moduł 3. Testowanie obciążenia

Aby sprawdzić, jak wdrożenie produkcyjne radzi sobie z ruchem w rzeczywistym świecie, przeprowadzimy kompleksowe testy obciążeniowe, które spowodują automatyczne skalowanie agenta ADK i usług backendu GPU.

  1. Otwórz nowy terminal (zachowaj działający serwer proxy) i przejdź do projektu:
    cd accelerate-ai-lab3-starter/adk-agent
    
  2. Otwórz i wdroż skrypt testu obciążenia:
    cloudshell edit load_test.py
    
    Zastąp wszystkie komentarze TODO tym kodem:
    import random
    import uuid
    from locust import HttpUser, task, between
    
    class ProductionAgentUser(HttpUser):
        """Load test user for the Production ADK Agent."""
    
        wait_time = between(1, 3)  # Faster requests to trigger scaling
    
        def on_start(self):
            """Set up user session when starting."""
            self.user_id = f"user_{uuid.uuid4()}"
            self.session_id = f"session_{uuid.uuid4()}"
    
            # Create session for the Gemma agent using proper ADK API format
            session_data = {"state": {"user_type": "load_test_user"}}
    
            self.client.post(
                f"/apps/production_agent/users/{self.user_id}/sessions/{self.session_id}",
                headers={"Content-Type": "application/json"},
                json=session_data,
            )
    
        @task(4)
        def test_conversations(self):
            """Test conversational capabilities - high frequency to trigger scaling."""
            topics = [
                "What do red pandas typically eat in the wild?",
                "Can you tell me an interesting fact about snow leopards?",
                "Why are poison dart frogs so brightly colored?",
                "Where can I find the new baby kangaroo in the zoo?",
                "What is the name of your oldest gorilla?",
                "What time is the penguin feeding today?"
            ]
    
            # Use proper ADK API format for sending messages
            message_data = {
                "app_name": "production_agent",
                "user_id": self.user_id,
                "session_id": self.session_id,
                "new_message": {
                    "role": "user",
                    "parts": [{
                        "text": random.choice(topics)
                    }]
                }
            }
    
            self.client.post(
                "/run",
                headers={"Content-Type": "application/json"},
                json=message_data,
            )
    
        @task(1)
        def health_check(self):
            """Test the health endpoint."""
            self.client.get("/health")
    
    🔧 Co to robi:
    • Tworzy sesję: używa prawidłowego formatu interfejsu API ADK z żądaniem POST do /apps/production_agent/users/{user_id}/sessions/{session_id}. Po utworzeniu session_iduser_id można wysłać do agenta żądanie.
    • Format wiadomości: zgodny ze specyfikacją ADK dla obiektów app_name, user_id, session_id i uporządkowanego obiektu new_message.
    • Punkt końcowy konwersacji: używa punktu końcowego /run do zbierania wszystkich zdarzeń naraz (zalecane w przypadku testów obciążeniowych).
    • Realistyczne obciążenie: tworzy obciążenie konwersacyjne z krótszymi czasami oczekiwania, aby aktywować autoskalowanie.
    📚 Więcej informacji o punktach końcowych interfejsu ADK API i wzorcach testowania znajdziesz w przewodniku po testowaniu ADK.
  3. Zainstaluj zależności:
    uv sync
    mkdir -p .results
    pip install locust
    
  4. Ponownie ustaw projekt i adres URL agenta (ponieważ jesteśmy w nowym terminalu).
    export PROJECT_ID=$(gcloud config get-value project)
    export AGENT_URL=$(gcloud run services describe production-adk-agent \
       --region=europe-west1 \
       --format='value(status.url)')
    
    echo "🎉 ADK Agent deployed at: $AGENT_URL"
    
  5. Locust to narzędzie open source do testowania obciążenia oparte na Pythonie, które służy do testowania wydajności i obciążenia aplikacji internetowych i innych systemów. Jego kluczową cechą jest to, że scenariusze testowe i zachowania użytkowników są definiowane za pomocą standardowego kodu w Pythonie, co zapewnia dużą elastyczność i wyrazistość w porównaniu z narzędziami opartymi na graficznych interfejsach użytkownika lub językach specyficznych dla domeny. Będziemy używać narzędzia Locust do symulowania ruchu użytkowników w naszych usługach. Uruchom test obciążeniowy.
    # Run a load test to trigger auto-scaling
    locust -f load_test.py \
       -H $AGENT_URL \
       --headless \
       -t 50s \
       -u 3 \
       -r 1
    
    Spróbuj zmienić parametry testu i obserwuj dane wyjściowe. Zauważysz, że liczba wystąpień ollama-gemma34b-gpu wzrosła do 2–3. 📊 Parametry testu obciążeniowego:
    • Czas trwania: 50 sekund
    • Użytkownicy: 3 użytkowników jednocześnie
    • Szybkość pojawiania się: 1 użytkownik na sekundę
    • Cel: wywoływanie autoskalowania w przypadku obu usług.

12. Obserwowanie zachowania autoskalowania

Podczas testu obciążenia będziesz mieć możliwość obserwowania działania autoskalowania Cloud Run. W tym miejscu zobaczysz najważniejsze zalety architektoniczne oddzielenia agenta ADK od backendu GPU.

Podczas testu obciążenia monitoruj w konsoli, jak skalują się obie usługi Cloud Run.

  1. W konsoli Cloud otwórz:
    • Cloud Run → production-adk-agent → Wskaźniki
    • Cloud Run → ollama-gemma34b-gpu → Wskaźniki

👀 Na co zwrócić uwagę:

🤖 Usługa agenta ADK:

  • Powinna utrzymywać się na poziomie 1 instancji, gdy ruch wzrasta.
  • Wykorzystanie procesora i pamięci gwałtownie rośnie podczas dużego natężenia ruchu.
  • Skutecznie zarządza sesjami i kieruje żądania.

🎮 Usługa backendu Gemma (wąskie gardło):

  • Skaluje od 1 do 3 instancji na podstawie zapotrzebowania na wnioskowanie.
  • Wykorzystanie GPU znacznie wzrasta pod obciążeniem.
  • Ta usługa staje się wąskim gardłem ze względu na wnioskowanie modelu wymagające dużej mocy obliczeniowej GPU.
  • Czasy wnioskowania modelu pozostają spójne dzięki akceleracji GPU.

💡 Kluczowe obserwacje:

  • Wąskim gardłem jest backend GPU, który skaluje się bardziej agresywnie (1–3 instancje).
  • Agent pakietu ADK zachowuje spójność
  • Obie usługi skalują się niezależnie od siebie na podstawie indywidualnych charakterystyk obciążenia.
  • Autoskalowanie pomaga utrzymać wydajność w różnych warunkach obciążenia

13. Podsumowanie

Gratulacje! Udało Ci się wdrożyć gotowego do użytku produkcyjnego agenta ADK z akcelerowanym przez GPU backendem Gemma i zaobserwować zachowanie autoskalowania.

✅ Co udało Ci się osiągnąć

  • ✅ Wdrożenie backendu modelu Gemma z akceleracją GPU w Cloud Run.
  • ✅ Utworzenie i wdrożenie agenta ADK, który integruje się z backendem Gemma.
  • ✅ Przetestowanie agenta za pomocą interfejsu internetowego ADK.
  • ✅ Obserwowanie zachowania autoskalowania w przypadku 2 skoordynowanych usług Cloud Run

💡 Najważniejsze obserwacje z tego modułu

  1. 🎮 Akceleracja GPU: procesor graficzny NVIDIA L4 znacznie zwiększa wydajność wnioskowania modelu.
  2. 🔗 Koordynacja usług: 2 usługi Cloud Run mogą ze sobą bezproblemowo współpracować.
  3. 📈 Niezależne skalowanie: każda usługa jest skalowana na podstawie indywidualnych charakterystyk obciążenia.
  4. 🚀 Gotowość do wdrożenia wersji produkcyjnej: architektura skutecznie obsługuje rzeczywiste wzorce ruchu.

🔄 Dalsze kroki

  • Eksperymentuj z różnymi wzorcami obciążenia i obserwuj zachowanie skalowania.
  • Wypróbuj różne rozmiary modelu Gemma (dostosuj pamięć i procesor graficzny).
  • Wdrażaj monitorowanie i alerty w przypadku wdrożeń produkcyjnych.
  • Poznaj wdrożenia w wielu regionach, aby zapewnić globalną dostępność.

🧹 Czyszczenie

Aby uniknąć obciążenia konta opłatami, po zakończeniu pracy usuń zasoby:

gcloud run services delete production-adk-agent --region=europe-west1
gcloud run services delete ollama-gemma34b-gpu --region=europe-west1

📖 Zasoby