Way Back Home - Level 0: Identify Yourself


Sygnał alarmowy

Czas trwania: 1 minuta

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! 📍

Przygotowywanie środowiska

Czas trwania: 2 minuty

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 podają.
• 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 poniższym filmie.
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).

Konfigurowanie projektu

Sprawdź, czy projekt jest prawidłowo skonfigurowany:

export PROJECT_ID=$(gcloud config get-value project)
echo "Using project: $PROJECT_ID"

Jeśli nie ustawiono projektu lub chcesz go zmienić:

gcloud config set project YOUR_PROJECT_ID

Włącz wymagane interfejsy API

Włącz interfejs Vertex AI API do generowania obrazów:

gcloud services enable aiplatform.googleapis.com

Klonowanie repozytorium

Sklonuj repozytorium Way Back Home i przejdź do projektu:

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

Instalowanie zależności

Przejdź do poziomu 0 i zainstaluj wymagane pakiety Pythona:

cd level_0
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Kluczowe zależności:

Pakiet Cel
google-genai Klient 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:

cd ~/way-back-home
python scripts/verify_setup.py

Zobaczysz, że:

✓ Google Cloud project configured: your-project-id
✓ Vertex AI API enabled
✓ Dependencies installed
✓ Ready to proceed!

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

✅ Otwórz Cloud Shell.
✅ Skonfiguruj projekt Google Cloud.
✅ Włącz interfejsy Vertex AI API.
✅ Sklonuj repozytorium z ćwiczeniami.
✅ Zainstaluj zależności Pythona.
✅ Sprawdź konfigurację.

Dalej: połącz się z Centrum Misji i zarezerwuj nazwę odkrywcy.

Łączenie się z Centrum sterowania

Czas trwania: 2 minuty

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 ~/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 uczestniczysz w warsztatach: wpisz kod wydarzenia z kodu QR, slajdu lub od prowadzącego warsztaty.

🚀 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.

Dostosowywanie eksploratora

Czas trwania: 1 minuta

Uruchamianie skryptu dostosowywania

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

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 eksplorera (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
Then run: python create_identity.py

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.

Tworzenie generatora awatarów

Czas trwania: 4 minuty

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 3 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,
Response Modalities ["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.

Generowanie i rejestrowanie

Czas trwania: 2 minuty

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ę:

python create_identity.py

Postęp generowania zobaczysz w czasie rzeczywistym:

🚀 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 portret ikona 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
python customize.py

# Option 2: Just regenerate with current settings
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.

Podsumowanie

Czas trwania: 1 minuta

Co utworzysz

W zaledwie 10 minut udało Ci się utworzyć kompletny system generowania awatarów za pomocą wieloetapowego generowania obrazów przez 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łabo widoczny i powoli pulsuje. Sieć ratownicza wie, że potrzebujesz pomocy, ale nie wie dokładnie, gdzie się znajdujesz. 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: koordynację 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/
rm ../config.json
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. 🚀

Dodatek: awatar na podstawie zdjęcia (opcjonalnie)

Czas trwania: 3 minuty

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. Zanotuj 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 w formie ilustracji)
  • 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 obrazowania
  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.
  6. Pobierz wynik i zapisz go jako outputs/portrait.png.
  7. Uruchom: python create_identity.py --skip-generation (jeśli ta flaga jest obsługiwana), aby przesłać wygenerowane ręcznie obrazy.

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

Czego się nauczyliś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ęć