Way Back Home - Level 0: Identify Yourself

1. Sygnał alarmowy

Nagłówek

Twoja kapsuła ratunkowa przebija się przez atmosferę nieznanego świata. Na każdym panelu migają kontrolki ostrzegawcze. System nawigacji jest zepsuty. Komunikacja nie działa. Gdy włączają się protokoły awaryjne kapsuły, asystent AI ożywa:

„Wykryto ocalałego. Awaryjne lądowanie zakończone pomyślnie. Uruchamiam protokół sygnału ratunkowego…

„OSTRZEŻENIE: wymagana jest weryfikacja tożsamości. Galaktyczna sieć ratunkowa nie może zlokalizować niezarejestrowanych odkrywców. Potwierdź swoją tożsamość, aby aktywować lokalizator”.

Wyglądasz przez okno. Obcy krajobraz rozciąga się aż po horyzont – dziwne formacje skalne, nieznana roślinność, niebo o dziwnym kolorze. Gdzieś na powierzchni tej planety są rozproszeni inni ocalali z Twojej misji.

Najpierw jednak musisz być w systemie.

Co utworzysz

Na tym poziomie stworzysz swoją niepowtarzalną tożsamość odkrywcy kosmosu, korzystając z wielokrotnego generowania obrazów za pomocą modeli generowania obrazów Gemini od Google (znanych też jako Nano Banana 🍌). Twój awatar pojawi się na globalnej mapie ratunkowej, widocznej dla wszystkich innych ocalałych podczas warsztatów.

architektura

Czego się nauczysz

Pomysł

Opis

Generowanie obrazów w wielu turach

Jak zachować spójność postaci w wielu wygenerowanych obrazach za pomocą sesji czatu

Tworzenie promptów do generowania obrazów

Tworzenie skutecznych promptów do uzyskiwania stylizowanych, spójnych wyników z określonymi ograniczeniami

Gemini Image API (Nano Banana)

Korzystanie z natywnych funkcji generowania obrazów w Gemini za pomocą pakietu Python SDK

Sesje czatu

Wykorzystywanie kontekstu rozmowy do iteracyjnego ulepszania i zachowania spójności postaci

Po ukończeniu tego poziomu:

✅ Wygenerowano portret Twojego odkrywcy za pomocą AI do tworzenia obrazów na podstawie tekstu.
✅ Utworzono spójną ikonę mapy za pomocą wieloetapowej rozmowy.
✅ Zarejestrowano Twoją tożsamość w sieci ratowniczej.
✅ Pojawiłeś(-aś) się na mapie świata na żywo obok innych odkrywców.

Umieśćmy Cię na mapie! 📍

2. Przygotowywanie środowiska

Dostęp do Cloud Shell

Najpierw otworzymy Cloud Shell, czyli terminal w przeglądarce z zainstalowanym pakietem Google Cloud SDK i innymi niezbędnymi narzędziami.

Potrzebujesz środków w Google Cloud?

• Jeśli uczestniczysz w warsztatach prowadzonych przez instruktora: instruktor przekaże Ci kod kredytu. Użyj tego, który Ci udostępnią.
• Jeśli wykonujesz ten Codelab samodzielnie: możesz wykorzystać bezpłatne środki w Google Cloud, aby pokryć koszty warsztatów. Aby otrzymać środki, kliknij ten link i postępuj zgodnie z instrukcjami w filmie poniżej, aby zastosować je na swoim koncie.
Obejrzyj film

Kliknij Aktywuj Cloud Shell u góry konsoli Google Cloud (jest to ikona terminala na pasku nawigacyjnym w prawym górnym rogu).

Cloud Shell

Znajdź identyfikator projektu Google Cloud:

  • Otwórz konsolę Google Cloud: https://console.cloud.google.com
  • Wybierz projekt, którego chcesz użyć w tych warsztatach, z menu u góry strony.
  • Identyfikator projektu jest wyświetlany na karcie Informacje o projekcie w panelu
    identyfikator projektu.

Po otwarciu Cloud Shell sprawdź, czy masz uwierzytelnienie:

# Check that you are logged in
gcloud auth list

Twoje konto powinno być widoczne jako (ACTIVE).

Klonowanie repozytorium

Sklonuj repozytorium Way Back Home i przejdź do projektu:

git clone https://github.com/google-americas/way-back-home.git
cd way-back-home

Instalowanie zależności

Przejdź do poziomu 0 i zainstaluj wymagane pakiety Pythona:

cd level_0
uv sync

Główne zależności:

Pakiet

Cel

google-genai

Klient interfejsu Gemini API do generowania obrazów

requests

Klient HTTP do wywołań interfejsu API w Mission Control

Pillow

Przetwarzanie obrazów i obsługa plików

Weryfikacja konfiguracji

Przeprowadź szybką weryfikację, aby sprawdzić, czy wszystko jest poprawnie skonfigurowane:

uv run python ../scripts/verify_setup.py

Zobaczysz, że:

 Authenticated as: your-email@google.com
 Python environment ready (uv)
 Ready to proceed!

Co zostało właśnie ukończone

✓ Otwórz Cloud Shell
✓ Uwierzytelnij się w Google Cloud
✓ Sklonuj repozytorium z ćwiczeniami
✓ Zainstaluj zależności Pythona za pomocą uv
✓ Sprawdź konfigurację

Dalej: połącz się z Mission Control – skrypt konfiguracji automatycznie skonfiguruje Twój projekt Google Cloud i interfejsy API.

3. Łączenie się z Centrum sterowania

Uruchamianie skryptu konfiguracji

Skrypt konfiguracji łączy Cię z siecią ratunkową Way Back Home i rezerwuje Twoją tożsamość odkrywcy. Uruchom go w katalogu głównym projektu:

cd $HOME/way-back-home
chmod +x scripts/setup.sh
./scripts/setup.sh

Poprosimy Cię o podanie 2 informacji.

Wpisz kod wydarzenia

Kod wydarzenia określa, w którym warsztacie bierzesz udział.

Jeśli jesteś na warsztatach: wpisz kod wydarzenia z kodu QR, slajdu lub od instruktora warsztatów.

🚀 Welcome to Way Back Home!

Enter event code (from QR/slide): devfest-nyc-26
Validating event...
✓ Connected to: DevFest NYC 2026

Jeśli uczysz się samodzielnie: wpisz sandbox, aby dołączyć do publicznego środowiska szkoleniowego.

🚀 Welcome to Way Back Home!

Enter event code (from QR/slide): sandbox
Validating event...
✓ Connected to: Way Back Home Sandbox

Wybierz nazwę eksploratora

Wybierz niepowtarzalną nazwę eksploratora. Tak będziesz widoczny(-a) na mapie świata i w tabeli wyników.

Choose your explorer name: AstroAyo
✓ Username available!

Jeśli wybrana nazwa jest już używana przez innego uczestnika tego samego wydarzenia:

Choose your explorer name: SpaceExplorer
⚠️  That name is taken. Try another.
Choose your explorer name: SpaceExplorer42
✓ Username available!

Konfiguracja ukończona

Po zakończeniu zobaczysz potwierdzenie:

Initializing your explorer profile...

✓ Environment configured!
  Explorer ID: a1b2c3d4
  Starting coordinates: (47, 23)

Next: cd level_0 && python customize.py

Teraz przejdź do katalogu poziomu 0 (zależności zostały już zainstalowane w module 2):

cd level_0

Sprawdzanie konfiguracji

Sprawdź, co zostało zapisane (plik config.json znajduje się w katalogu głównym projektu):

cat ../config.json
{
    "event_code": "devfest-nyc-26",
    "event_name": "DevFest NYC 2026",
    "username": "AstroAyo",
    "participant_id": "a1b2c3d4",
    "starting_x": 47,
    "starting_y": 23,
    "api_base": "https://api.waybackhome.dev",
    "project_id": "your-project-id"
}

Ten plik konfiguracji będzie używany przez kolejne skrypty do identyfikowania Cię w sieci ratunkowej.

Co zostało właśnie ukończone

✓ Połączono z interfejsem Mission Control API
✓ Zarezerwowano unikalną nazwę odkrywcy
✓ Otrzymano identyfikator uczestnika i współrzędne początkowe
✓ Konfiguracja została zapisana na potrzeby kolejnych kroków

Dalej: dostosuj wygląd eksploratora.

4. Dostosowywanie strony Eksplorator

Uruchamianie skryptu dostosowywania

Zanim wygenerujesz awatara, musisz podjąć kilka decyzji dotyczących wyglądu odkrywcy:

uv run python customize.py

Wybierz kolor garnituru

Wybierz kolor skafandra:

🎨 Let's create your explorer identity!

Select suit color:
  1. Deep Blue
  2. Crimson Red
  3. Forest Green
  4. Royal Purple
  5. Solar Gold
  6. Silver

Choice [1-6, default=6]: 1
✓ Deep Blue selected

Opisz swojego eksploratora (opcjonalnie)

Możesz podać krótki opis wyglądu odkrywcy lub nacisnąć Enter, aby przypisać go losowo:

Brief description of your explorer (or Enter for random):
Example: 'short dark hair, glasses, friendly smile'
> short dark hair, glasses, determined expressionPreferences saved!

Jeśli naciśniesz Enter bez wpisywania czegokolwiek, otrzymasz losowe cechy:

> 
✓ Random traits: confident expression, short styled hair

Konfiguracja została zaktualizowana

Ustawienia zostały zapisane:

✓ Preferences saved!
Next: Open generator.py and follow the codelab instructions

Sprawdź zaktualizowaną konfigurację:

cat ../config.json

Zobaczysz dodane preferencje:

{
    "event_code": "devfest-nyc-26",
    "event_name": "DevFest NYC 2026",
    "username": "AstroAyo",
    "participant_id": "a1b2c3d4",
    "starting_x": 47,
    "starting_y": 23,
    "api_base": "https://api.waybackhome.dev",
    "project_id": "your-project-id",
    "suit_color": "deep blue with silver accents",
    "appearance": "short dark hair, glasses, determined expression"
}

Co zostało właśnie ukończone

✓ Wybrano kolor skafandra
✓ Określono wygląd odkrywcy
✓ Konfiguracja gotowa do wygenerowania obrazu

Dalej: główne wydarzenie – pisanie kodu generowania obrazu.

5. Tworzenie generatora awatarów

To jest podstawowy moduł szkoleniowy. Napiszesz kod w Pythonie, który wygeneruje Twój niepowtarzalny awatar odkrywcy, korzystając z możliwości wieloetapowego generowania obrazów w Gemini (Nano Banana).

Otwieranie pliku generatora

Otwórz generator awatarów w edytorze Cloud Shell:

cloudshell edit generator.py

Możesz też kliknąć Otwórz edytor w Cloud Shell i przejść do pliku generator.py w folderze level_0.

Struktura pliku

Plik zawiera kod początkowy i 3 sekcje z symbolami zastępczymi, w których dodasz implementację:

"""
Level 0: Avatar Generator

This module generates your unique space explorer avatar using
multi-turn image generation with Gemini (Nano Banana) for
character consistency across portrait and icon.
"""

from google import genai
from google.genai import types
from PIL import Image
import json
import os
import io

# Load configuration from setup (config.json is in project root)
CONFIG_PATH = "../config.json"

with open(CONFIG_PATH) as f:
    config = json.load(f)

USERNAME = config["username"]
SUIT_COLOR = config["suit_color"]
APPEARANCE = config["appearance"]

# Initialize the Gemini client for Vertex AI
client = genai.Client(
    vertexai=True,
    project=os.environ.get("GOOGLE_CLOUD_PROJECT", config.get("project_id")),
    location="us-central1"
)


def generate_explorer_avatar() -> dict:
    """
    Generate portrait and icon using multi-turn chat for consistency.
    
    The key technique here is using a CHAT SESSION rather than independent
    API calls. This allows Gemini to "remember" the character it created
    in the first turn, ensuring the icon matches the portrait.
    
    Returns:
        dict with portrait_path and icon_path
    """
    
    # MODULE_5_STEP_1_CREATE_CHAT_SESSION
    # TODO: Create a chat session for multi-turn generation
    chat = None  # Replace this line
    
    # MODULE_5_STEP_2_GENERATE_PORTRAIT
    # TODO: Generate the explorer portrait
    portrait_image = None  # Replace this section
    
    # MODULE_5_STEP_3_GENERATE_ICON
    # TODO: Generate a consistent map icon
    icon_image = None  # Replace this section
    
    return {
        "portrait_path": "outputs/portrait.png",
        "icon_path": "outputs/icon.png"
    }


if __name__ == "__main__":
    # Create outputs directory if it doesn't exist
    os.makedirs("outputs", exist_ok=True)
    
    print(f"Generating avatar for {USERNAME}...")
    result = generate_explorer_avatar()
    print(f"✅ Avatar created!")
    print(f"   Portrait: {result['portrait_path']}")
    print(f"   Icon: {result['icon_path']}")

Zastąp trzy sekcje TODO swoją implementacją.

Krok 1. Utwórz sesję czatu

Znajdź symbol zastępczy MODULE_5_STEP_1_CREATE_CHAT_SESSION i zastąp wiersz chat = None # Replace this line tym kodem:

    # MODULE_5_STEP_1_CREATE_CHAT_SESSION
    # Create a chat session to maintain character consistency across generations.
    # The chat session preserves context between turns, so Gemini "remembers"
    # what it generated and can create consistent variations.
    chat = client.chats.create(
        model="gemini-2.5-flash-image",  # Nano Banana - Gemini with image generation
        config=types.GenerateContentConfig(
            response_modalities=["TEXT", "IMAGE"]
        )
    )

Krok 2. Wygeneruj portret

Znajdź MODULE_5_STEP_2_GENERATE_PORTRAIT i zastąp portrait_image = None # Replace this section tym kodem:

    # MODULE_5_STEP_2_GENERATE_PORTRAIT
    # First turn: Generate the explorer portrait.
    # This establishes the character that will be referenced in subsequent turns.
    portrait_prompt = f"""Create a stylized space explorer portrait.

Character appearance: {APPEARANCE}
Name on suit patch: "{USERNAME}"
Suit color: {SUIT_COLOR}

CRITICAL STYLE REQUIREMENTS:
- Digital illustration style, clean lines, vibrant saturated colors
- Futuristic but weathered space suit with visible mission patches
- Background: Pure solid white (#FFFFFF) - absolutely no gradients, patterns, or elements
- Frame: Head and shoulders only, 3/4 view facing slightly left
- Lighting: Soft diffused studio lighting, no harsh shadows
- Expression: Determined but approachable
- Art style: Modern animated movie character portrait (similar to Pixar or Dreamworks style)

The white background is essential - the avatar will be composited onto a map."""

    print("🎨 Generating your portrait...")
    portrait_response = chat.send_message(portrait_prompt)
    
    # Extract the image from the response.
    # Gemini returns a response with multiple "parts" - we need to find the image part.
    portrait_image = None
    for part in portrait_response.candidates[0].content.parts:
        if part.inline_data is not None:
            # Found the image! Convert from bytes to PIL Image and save.
            image_bytes = part.inline_data.data
            portrait_image = Image.open(io.BytesIO(image_bytes))
            portrait_image.save("outputs/portrait.png")
            break
    
    if portrait_image is None:
        raise Exception("Failed to generate portrait - no image in response")
    
    print("✓ Portrait generated!")

Krok 3. Wygeneruj ikonę mapy

Znajdź MODULE_5_STEP_3_GENERATE_ICON i zastąp icon_image = None # Replace this section:

    # MODULE_5_STEP_3_GENERATE_ICON
    # Second turn: Generate a consistent icon for the map.
    # Because we're in the same chat session, Gemini remembers the character
    # from the portrait and will maintain visual consistency.
    icon_prompt = """Now create a circular map icon of this SAME character.

CRITICAL REQUIREMENTS:
- SAME person, SAME face, SAME expression, SAME suit — maintain perfect consistency with the portrait
- Tighter crop: just the head and very top of shoulders
- Background: Pure solid white (#FFFFFF)
- Optimized for small display sizes (will be used as a 64px map marker)
- Keep the exact same art style, colors, and lighting as the portrait
- Square 1:1 aspect ratio

This icon must be immediately recognizable as the same character from the portrait."""

    print("🖼️  Creating map icon...")
    icon_response = chat.send_message(icon_prompt)
    
    # Extract the icon image from the response
    icon_image = None
    for part in icon_response.candidates[0].content.parts:
        if part.inline_data is not None:
            image_bytes = part.inline_data.data
            icon_image = Image.open(io.BytesIO(image_bytes))
            icon_image.save("outputs/icon.png")
            break
    
    if icon_image is None:
        raise Exception("Failed to generate icon - no image in response")
    
    print("✓ Icon generated!")

Ukończony kod

Po dodaniu wszystkich 3 sekcji funkcja generate_explorer_avatar() powinna wyglądać tak:

def generate_explorer_avatar() -> dict:
    """
    Generate portrait and icon using multi-turn chat for consistency.
    
    The key technique here is using a CHAT SESSION rather than independent
    API calls. This allows Gemini to "remember" the character it created
    in the first turn, ensuring the icon matches the portrait.
    
    Returns:
        dict with portrait_path and icon_path
    """
    
    # MODULE_5_STEP_1_CREATE_CHAT_SESSION
    # Create a chat session to maintain character consistency across generations.
    # The chat session preserves context between turns, so Gemini "remembers"
    # what it generated and can create consistent variations.
    chat = client.chats.create(
        model="gemini-2.5-flash-image",  # Nano Banana - Gemini with image generation
        config=types.GenerateContentConfig(
            response_modalities=["TEXT", "IMAGE"]
        )
    )
    
    # MODULE_5_STEP_2_GENERATE_PORTRAIT
    # First turn: Generate the explorer portrait.
    # This establishes the character that will be referenced in subsequent turns.
    portrait_prompt = f"""Create a stylized space explorer portrait.

Character appearance: {APPEARANCE}
Name on suit patch: "{USERNAME}"
Suit color: {SUIT_COLOR}

CRITICAL STYLE REQUIREMENTS:
- Digital illustration style, clean lines, vibrant saturated colors
- Futuristic but weathered space suit with visible mission patches
- Background: Pure solid white (#FFFFFF) - absolutely no gradients, patterns, or elements
- Frame: Head and shoulders only, 3/4 view facing slightly left
- Lighting: Soft diffused studio lighting, no harsh shadows
- Expression: Determined but approachable
- Art style: Modern animated movie character portrait (similar to Pixar or Dreamworks style)

The white background is essential - the avatar will be composited onto a map."""

    print("🎨 Generating your portrait...")
    portrait_response = chat.send_message(portrait_prompt)
    
    # Extract the image from the response.
    # Gemini returns a response with multiple "parts" - we need to find the image part.
    portrait_image = None
    for part in portrait_response.candidates[0].content.parts:
        if part.inline_data is not None:
            # Found the image! Convert from bytes to PIL Image and save.
            image_bytes = part.inline_data.data
            portrait_image = Image.open(io.BytesIO(image_bytes))
            portrait_image.save("outputs/portrait.png")
            break
    
    if portrait_image is None:
        raise Exception("Failed to generate portrait - no image in response")
    
    print("✓ Portrait generated!")
    
    # MODULE_5_STEP_3_GENERATE_ICON
    # Second turn: Generate a consistent icon for the map.
    # Because we're in the same chat session, Gemini remembers the character
    # from the portrait and will maintain visual consistency.
    icon_prompt = """Now create a circular map icon of this SAME character.

CRITICAL REQUIREMENTS:
- SAME person, SAME face, SAME expression, SAME suit — maintain perfect consistency with the portrait
- Tighter crop: just the head and very top of shoulders
- Background: Pure solid white (#FFFFFF)
- Optimized for small display sizes (will be used as a 64px map marker)
- Keep the exact same art style, colors, and lighting as the portrait
- Square 1:1 aspect ratio

This icon must be immediately recognizable as the same character from the portrait."""

    print("🖼️  Creating map icon...")
    icon_response = chat.send_message(icon_prompt)
    
    # Extract the icon image from the response
    icon_image = None
    for part in icon_response.candidates[0].content.parts:
        if part.inline_data is not None:
            image_bytes = part.inline_data.data
            icon_image = Image.open(io.BytesIO(image_bytes))
            icon_image.save("outputs/icon.png")
            break
    
    if icon_image is None:
        raise Exception("Failed to generate icon - no image in response")
    
    print("✓ Icon generated!")
    
    return {
        "portrait_path": "outputs/portrait.png",
        "icon_path": "outputs/icon.png"
    }

Zapisywanie pliku

Pamiętaj, aby zapisać generator.py:

  • Edytor Cloud Shell: Ctrl+S (Windows/Linux) lub Cmd+S (Mac)
  • vim: naciśnij Escape, a potem wpisz :wq i naciśnij Enter.

Co właśnie zostało utworzone

✓ Utworzono sesję czatu do generowania obrazów w wielu turach.
✓ Przygotowano szczegółowy prompt do generowania portretów z ograniczeniami dotyczącymi stylu.
✓ Wygenerowano spójną ikonę mapy na podstawie kontekstu rozmowy.
✓ Nauczono się analizować dane obrazu z odpowiedzi Gemini.

Opanowane kluczowe pojęcia:

Pomysł

Czego się dowiedziałeś(-aś)

Sesje czatu

client.chats.create() zachowuje kontekst w wielu turach,

Sposoby odpowiedzi

["TEXT", "IMAGE"] włącza generowanie obrazów w odpowiedziach.

Struktura prompta

Temat → Zmienne → Styl → Ograniczenia techniczne

Spójność postaci

Ta sama sesja czatu = ta sama postać na wszystkich obrazach

Parsowanie odpowiedzi

Wyodrębnianie obrazów z inline_data w częściach odpowiedzi

Dalej: uruchom kod i zobacz swoją lokalizację na mapie.

6. Generowanie i rejestrowanie

Ustawianie identyfikatora projektu

Sprawdź, czy identyfikator projektu jest dostępny jako zmienna środowiskowa:

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

Uruchomienie narzędzia do tworzenia tożsamości

Teraz uruchom główny skrypt, który koordynuje generowanie, przesyłanie i rejestrację:

uv run python create_identity.py

Postęp generowania zobaczysz w czasie rzeczywistym:

Uwaga: pojawienie się awatara na mapie na żywo może potrwać do 5 sekund, więc jeśli nie widzisz siebie od razu na mapie, odśwież ją.

🚀 Creating identity for AstroAyo...

🎨 Generating your portrait...
 Portrait generated!
🖼️  Creating map icon...
 Icon generated!

☁️  Uploading to mission database...
 Avatar uploaded!

📍 Registering with rescue network...
 Registration complete!

╔═══════════════════════════════════════════════════════════════╗
                     IDENTITY CONFIRMED!                      
╠═══════════════════════════════════════════════════════════════╣
                                                               
  Explorer: AstroAyo                                           
  Location: (47, 23)  unconfirmed                             
                                                               
  🗺️  You're now on the map!                                   ║
  https://waybackhome.dev/e/devfest-nyc-26                     
                                                               
  NEXT: Proceed to Level 1 to pinpoint your exact location!   
                                                               
╚═══════════════════════════════════════════════════════════════╝

Wyświetlanie wygenerowanego awatara

Sprawdź wygenerowane obrazy lokalnie:

# List the generated files
ls -la outputs/

# Download to view on your local machine
cloudshell download outputs/portrait.png
cloudshell download outputs/icon.png

Możesz też wyświetlić je bezpośrednio w edytorze Cloud Shell, przechodząc do folderu outputs/ i klikając pliki obrazów.

Wygenerowany portret i ikona będą wyglądać podobnie do tych na obrazach:

przykładowy portretikona przykładu

Zobacz siebie na mapie

Otwórz adres URL mapy świata wyświetlany w danych wyjściowych:

https://waybackhome.dev/e/{your-event-code}

Na przykład: https://waybackhome.dev/e/devfest-nyc-26

Znajdź swój awatar na mapie. Zobaczysz:

  • Ikona oznaczająca Twoją pozycję na powierzchni planety
  • Nazwa eksploratora jako etykieta pod ikoną
  • Przyciemniony sygnał powoli pulsujący wokół Twojego znacznika

przykładowy awatar na mapie

Kliknij swój znacznik, aby zobaczyć pełny portret na karcie szczegółów.

Nie podoba Ci się Twój awatar? Wygeneruj ponownie

Jeśli chcesz mieć inny awatar, możesz go wygenerować ponownie:

# Option 1: Change your appearance settings first
uv run python customize.py

# Option 2: Just regenerate with current settings
uv run python create_identity.py

Za każdym razem, gdy uruchamiasz create_identity.py, generuje on całkowicie nowego awatara (nowa sesja czatu = nowa postać) i aktualizuje Twoją rejestrację. Możesz powtarzać ten proces, aż uzyskasz zadowalający efekt.

Rozwiązywanie problemów

Co zostało właśnie ukończone

✓ Wygenerowano Twój niepowtarzalny portret odkrywcy
✓ Utworzono spójną ikonę mapy
✓ Przesłano zasoby do Centrum dowodzenia
✓ Zarejestrowano Twoją tożsamość w sieci ratowniczej
✓ Pojawiłeś(-aś) się na mapie świata na żywo!

Gratulacje, odkrywco! Jesteś teraz w sieci ratowniczej. Lokalizator jest aktywny (choć słabo widoczny), a inni ocaleni mogą Cię zobaczyć na mapie.

7. Podsumowanie

Co utworzysz

W zaledwie 10 minut udało Ci się utworzyć kompletny system generowania awatarów za pomocą wieloetapowego generowania obrazów AI:

┌─────────────────────────────────────────────────────────────┐
                     Your Creation                           
├─────────────────────────────────────────────────────────────┤
                                                             
   📝 Input                       🖼️  Output                  
   ──────────                     ────────                    
    Explorer name                 Stylized portrait         
    Suit color                    Consistent map icon       
    Appearance description        Live map presence         
                                                              
├─────────────────────────────────────────────────────────────┤
                                                             
   🧠 Techniques You Used                                     
   ──────────────────────                                    
    Multi-turn chat sessions for character consistency      
    Structured prompt engineering with style constraints    
    Response parsing to extract generated images            
    API integration for cloud registration                  
                                                             
└─────────────────────────────────────────────────────────────┘

Podsumowanie

Lekcja

Dlaczego to jest ważne

Sesje czatu zachowują kontekst

Niezbędne do generowania spójnych postaci na wielu obrazach bez odchyleń.

Struktura promptu ma znaczenie

Jasne ograniczenia (białe tło, określony styl, kadrowanie) zapewniają przewidywalne wyniki gotowe do produkcji.

Wielokrotne wywołania są lepsze od niezależnych wywołań

Każda wiadomość na czacie opiera się na poprzednim kontekście, co umożliwia iteracyjne dopracowywanie i zachowanie spójności.

Tryby odpowiedzi kontrolują dane wyjściowe

Ustawienie ["TEXT", "IMAGE"] jest wymagane do generowania obrazów – bez niego otrzymasz tylko tekst.

Podsumowanie kosztów

Na tym poziomie wygenerowano 2 obrazy za pomocą Gemini 2.5 Flash (Nano Banana):

Element

Tokeny

Koszt

Orientacja pionowa (1024 × 1024)

~1290 tokenów wyjściowych

~0,039 USD

Ikona (1024 × 1024)

~1290 tokenów wyjściowych

~0,039 USD

Łącznie

około 2580 tokenów,

~0,08 USD

Niekończąca się podróż

Twoja tożsamość odkrywcy została potwierdzona, ale wystąpił problem: Twoja lokalizacja nie została potwierdzona.

Spójrz na mapę świata – Twój lokalizator jest słaby i powoli pulsuje. Sieć ratownicza wie, że potrzebujesz pomocy, ale nie zna Twojej dokładnej lokalizacji. Możesz znajdować się w dowolnym miejscu na rozległym obszarze powierzchni planety.

W sekcji Poziom 1. Określ swoją lokalizację:

  • Tworzenie systemu z wieloma agentami za pomocą pakietu Agent Development Kit (ADK) od Google
  • Tworzenie serwerów MCP do analiz geologicznych, botanicznych i astronomicznych
  • Przetwarzanie danych multimodalnych (zdjęć z miejsca wypadku)
  • Wygeneruj mapę topograficzną potwierdzonej lokalizacji za pomocą AI.
  • Włącz sygnał, aby ekipy ratownicze mogły Cię znaleźć.

Poziom 1 wprowadza znacznie bardziej zaawansowane koncepcje: orkiestrację wielu agentów, protokół kontekstu modelu (MCP) i wzorce wdrażania w środowisku produkcyjnym. Przejdziesz od korzystania z pojedynczej funkcji modelu do budowania kompletnego systemu opartego na agentach.

Czyszczenie (opcjonalnie)

Jeśli chcesz wyczyścić pliki lokalne (uruchom z katalogu level_0):

rm -rf outputs/
deactivate  # Exit virtual environment

Rejestracja w sieci ratowniczej pozostanie aktywna – nadal będziesz widoczny(-a) na mapie nawet po usunięciu plików lokalnych. Obrazy są przechowywane w chmurze, a nie lokalnie.

Zasoby

Beacon czeka na potwierdzenie. Do zobaczenia na poziomie 1, odkrywco. 🚀

8. Dodatek: awatar na podstawie zdjęcia (opcjonalnie)

Kiedy używać funkcji Photo-to-Avatar

To podejście może Ci się spodobać, jeśli:

  • Chcesz, aby Twój awatar był do Ciebie podobny
  • masz konkretne zdjęcie, które chcesz stylizować;
  • Chcesz poznać możliwości Gemini w zakresie przekształcania obrazów

Jak to działa

Zamiast generować postać wyłącznie na podstawie opisu tekstowego, możesz przesłać zdjęcie i poprosić Gemini o jego przekształcenie z zachowaniem podobieństwa do osoby:

proces przekształcania zdjęcia w awatara,

Prześlij zdjęcie

Najpierw prześlij zdjęcie do Cloud Shell:

  1. W Cloud Shell kliknij menu z 3 kropkami (⋮) na pasku narzędzi terminala.
  2. Kliknij Prześlij.
  3. Wybierz wyraźne zdjęcie profilowe (JPEG lub PNG).
  4. Zapisz przesłaną ścieżkę (np. /home/your-username/my_photo.jpg)

Modyfikowanie generatora

Aby użyć zdjęcia, zmodyfikuj krok generowania portretu w generator.py. Zastąp prompt tekstowy promptem multimodalnym, który zawiera Twoje zdjęcie:

    # MODULE_5_STEP_2_GENERATE_PORTRAIT (Photo-based version)
    
    # Load your photo
    photo_path = "/home/your-username/my_photo.jpg"  # Update this path!
    user_photo = Image.open(photo_path)
    
    # Convert photo to bytes for the API
    photo_buffer = io.BytesIO()
    user_photo.save(photo_buffer, format="JPEG")
    photo_bytes = photo_buffer.getvalue()
    
    portrait_prompt = f"""Transform this person into a stylized space explorer portrait.

PRESERVE from the original photo:
- The person's facial features, face shape, and likeness
- Their general expression and personality
- Any distinctive features (glasses, facial hair, etc.)

TRANSFORM with this style:
- Digital illustration style, clean lines, vibrant saturated colors
- Add a futuristic space suit with the name "{USERNAME}" on a shoulder patch
- Suit color: {SUIT_COLOR}
- Background: Pure solid white (#FFFFFF) - no gradients or elements
- Frame: Head and shoulders, 3/4 view
- Lighting: Soft diffused studio lighting
- Art style: Modern animated movie character (Pixar/Dreamworks aesthetic)

The result should be clearly recognizable as THIS specific person, but illustrated as a heroic space explorer."""

    print("🎨 Transforming your photo into an explorer portrait...")
    
    # Send both the prompt AND the image
    portrait_response = chat.send_message([
        portrait_prompt,
        types.Part.from_bytes(data=photo_bytes, mime_type="image/jpeg")
    ])
    
    # Rest of the extraction code stays the same...

Spójność w wielu turach nadal działa

Wieloetapowe podejście działa tak samo w przypadku generowania na podstawie zdjęć:

  • Tura 1: zdjęcie + prompt → stylizowany portret (Twoja podobizna, ilustracja)
  • Tura 2: „Utwórz ikonę TEJ SAMEJ postaci” → spójna ikona

Sesja czatu zapamiętuje utworzoną stylizowaną wersję (a nie oryginalne zdjęcie), więc ikona będzie idealnie pasować do przekształconego portretu.

Kwestie dotyczące prywatności

Wypróbuj w Vertex AI Studio

Przed napisaniem kodu możesz też interaktywnie eksperymentować z przekształcaniem zdjęć w konsoli Google Cloud:

  1. Otwórz Vertex AI Studio.
  2. Wybierz model Gemini z funkcjami obrazu
  3. Prześlij zdjęcie za pomocą przycisku załącznika
  4. Wpisz prompt dotyczący przekształcenia
  5. Eksperymentuj ze stylem, aż uzyskasz zadowalający efekt.

To interaktywne podejście świetnie się sprawdza do eksperymentowania z promptami i wyświetlania wyników w czasie rzeczywistym przed zatwierdzeniem kodu.

Czego się dowiedzieliśmy (bonus)

✓ Jak używać przekształcania obrazu w obraz za pomocą Gemini
✓ Wysyłanie treści multimodalnych (tekst + obraz) w jednej wiadomości
✓ Zachowywanie podobieństwa podczas stosowania przenoszenia stylu artystycznego
✓ Kwestie związane z prywatnością w przypadku generowania treści przez AI na podstawie zdjęć