Way Back Home, nivel 0: Identifícate

1. La señal de auxilio

Encabezado

Tu cápsula de escape atraviesa la atmósfera de un mundo desconocido. Las luces de advertencia parpadean en todos los paneles. El sistema de navegación está quemado. Las comunicaciones están inhabilitadas. A medida que se activan los protocolos de emergencia de la cápsula, el asistente de IA se activa:

"Se detectó un sobreviviente. El aterrizaje de emergencia se realizó correctamente. Se está iniciando el protocolo de baliza de rescate…".

"ADVERTENCIA: Se requiere verificación de identidad. La red de rescate galáctica no puede ubicar a los exploradores no registrados. Confirma tu identidad para activar el faro".

Miras por la ventana gráfica. Un paisaje alienígena se extiende hasta el horizonte: extrañas formaciones rocosas, vegetación desconocida y un cielo de color extraño. En algún lugar, otros sobrevivientes de tu misión están dispersos por la superficie de este planeta.

Pero primero lo primero: Debes existir en el sistema.

Qué compilará

En este nivel, crearás tu identidad única de explorador espacial con la generación de imágenes en varios turnos con los modelos de generación de imágenes de Gemini de Google (también conocidos como Nano Banana 🍌). Tu avatar aparecerá en el mapa de rescate global, visible para todos los demás sobrevivientes en el evento del taller.

arquitectura

Lo que aprenderá

Concepto

Descripción

Generación de imágenes en varios turnos

Cómo mantener la coherencia de los personajes en varias generaciones de imágenes con sesiones de chat

Ingeniería de instrucciones para imágenes

Cómo crear instrucciones eficaces para obtener resultados coherentes y estilizados con restricciones específicas

API de Gemini Image (Nano Banana)

Cómo usar las capacidades nativas de generación de imágenes de Gemini a través del SDK de Python

Sesiones de chat

Aprovechamiento del contexto de la conversación para el perfeccionamiento iterativo y la coherencia del personaje

Al final de este nivel, habrás hecho lo siguiente:

✅ Se generó un retrato de tu explorador con IA de texto a imagen.
✅ Se creó un ícono de mapa coherente con una conversación de varios turnos.
✅ Se registró tu identidad en la red de rescate.
✅ Apareciste en el mapa mundial en vivo junto con otros exploradores.

¡Te agregaremos al mapa! 📍

2. Prepara tu entorno

Accede a Cloud Shell

Primero, abriremos Cloud Shell, que es una terminal basada en el navegador con el SDK de Google Cloud y otras herramientas esenciales preinstaladas.

¿Necesitas créditos de Google Cloud?

Si asistes a un taller dirigido por un instructor: El instructor te proporcionará un código de crédito. Usa el que te proporcionen.
Si trabajas en este codelab por tu cuenta: Puedes canjear un crédito gratuito de Google Cloud para cubrir los costos del taller. Haz clic en este vínculo para obtener un crédito y sigue los pasos de la siguiente guía en video para aplicarlo a tu cuenta.
Mirar el video

Haz clic en Activar Cloud Shell en la parte superior de la consola de Google Cloud (es el ícono de terminal en la barra de navegación de la esquina superior derecha).

Cloud Shell

Busca tu ID del proyecto de Google Cloud:

  • Abre la consola de Google Cloud: https://console.cloud.google.com
  • Selecciona el proyecto que deseas usar para este taller en el menú desplegable de proyectos que se encuentra en la parte superior de la página.
  • Tu ID del proyecto se muestra en la tarjeta de información del proyecto en el panel
    project id

Una vez que se abra Cloud Shell, verifica que te hayas autenticado:

# Check that you are logged in
gcloud auth list

Deberías ver tu cuenta como (ACTIVE).

Clona el repositorio

Clona el repositorio de Way Back Home y navega al proyecto:

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

Instala las dependencias

Navega al nivel 0 y, luego, instala los paquetes de Python necesarios:

cd level_0
uv sync

Las dependencias clave son las siguientes:

Paquete

Objetivo

google-genai

Cliente de la API de Gemini para la generación de imágenes

requests

Cliente HTTP para llamadas a la API de Mission Control

Pillow

Procesamiento de imágenes y gestión de archivos

Verifica la configuración

Ejecuta una verificación rápida para asegurarte de que todo esté configurado correctamente:

uv run python ../scripts/verify_setup.py

Deberías ver lo siguiente:

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

Lo que acabas de completar

✓ Abriste Cloud Shell
✓ Te autenticaste en Google Cloud
✓ Clonaste el repositorio del codelab
✓ Instalaste las dependencias de Python con uv
✓ Verificaste tu configuración

Siguiente paso: Conéctate a Mission Control. La secuencia de comandos de configuración configurará automáticamente tu proyecto y tus APIs de Google Cloud.

3. Conéctate a Mission Control

Ejecuta la secuencia de comandos de configuración

La secuencia de comandos de configuración te conecta a la red de rescate Way Back Home y reserva tu identidad de explorador. Ejecútalo desde la raíz del proyecto:

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

Se te solicitarán dos datos.

Ingresa el código del evento

El código del evento identifica el evento del taller en el que participas.

Si estás en un taller: Ingresa el código del evento que se encuentra en el código QR, la diapositiva o el instructor del taller.

🚀 Welcome to Way Back Home!

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

Si estás aprendiendo por tu cuenta: Ingresa sandbox para unirte al entorno de aprendizaje público.

🚀 Welcome to Way Back Home!

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

Elige tu nombre de explorador

Elige un nombre único para tu explorador. Así aparecerás en el mapa mundial y en el ranking.

Choose your explorer name: AstroAyo
✓ Username available!

Si el nombre que elegiste ya lo usa otro participante en el mismo evento, haz lo siguiente:

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

Se completó la configuración

Una vez que se complete, verás la confirmación:

Initializing your explorer profile...

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

Next: cd level_0 && python customize.py

Ahora, navega al directorio Level 0 (las dependencias ya están instaladas desde el módulo 2):

cd level_0

Examina tu configuración

Observa lo que se guardó (config.json está en la raíz del proyecto):

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"
}

Los siguientes scripts usarán este archivo de configuración para identificarte en la red de rescate.

Lo que acabas de completar

✓ Conexión a la API de Mission Control
✓ Reserva de tu nombre de explorador único
✓ Recepción de tu ID de participante y coordenadas de inicio
✓ Configuración guardada para los pasos posteriores

Siguiente: Personaliza el aspecto del explorador.

4. Personaliza tu explorador

Ejecuta la secuencia de comandos de personalización

Antes de generar tu avatar, deberás tomar algunas decisiones sobre el aspecto de tu explorador:

uv run python customize.py

Selecciona el color de tu traje

Elige un color para el traje espacial del explorador:

🎨 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

Describe a tu explorador (opcional)

Puedes proporcionar una breve descripción de la apariencia de tu explorador o presionar Intro para que se asigne una apariencia aleatoria:

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

Si presionas Intro sin escribir nada, obtendrás rasgos aleatorios:

> 
✓ Random traits: confident expression, short styled hair

Se actualizó la configuración

Ahora se guardaron tus preferencias:

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

Verifica la configuración actualizada:

cat ../config.json

Verás que se agregaron tus preferencias:

{
    "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"
}

Lo que acabas de completar

✓ Seleccionaste el color de tu traje
✓ Definiste la apariencia de tu explorador
✓ La configuración está lista para la generación de imágenes

Siguiente: El evento principal: escribir el código de generación de imágenes

5. Cómo compilar el generador de avatares

Este es el módulo de aprendizaje principal. Escribirás código de Python que generará tu avatar de explorador único con las capacidades de generación de imágenes de varios turnos de Gemini (Nano Banana).

Abre el archivo del generador

Abre el generador de avatares en el editor de Cloud Shell:

cloudshell edit generator.py

O bien, haz clic en Abrir editor en Cloud Shell y navega a generator.py en la carpeta level_0.

Cómo comprender la estructura de archivos

El archivo tiene código de inicio y tres secciones de marcadores de posición en las que agregarás tu implementación:

"""
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']}")

Reemplazarás las tres secciones de TODO con tu implementación.

Paso 1: Crea la sesión de chat

Busca el marcador de posición MODULE_5_STEP_1_CREATE_CHAT_SESSION y reemplaza la línea chat = None # Replace this line por lo siguiente:

    # 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"]
        )
    )

Paso 2: Genera el retrato

Busca MODULE_5_STEP_2_GENERATE_PORTRAIT y reemplaza portrait_image = None # Replace this section por el siguiente código:

    # 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!")

Paso 3: Genera el ícono de mapa

Busca MODULE_5_STEP_3_GENERATE_ICON y reemplaza icon_image = None # Replace this section por lo siguiente:

    # 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!")

Tu código completado

Después de agregar las tres secciones, tu función generate_explorer_avatar() debería verse así:

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"
    }

Guarda el archivo

Asegúrate de guardar generator.py de la siguiente manera:

  • Editor de Cloud Shell: Ctrl + S (Windows/Linux) o Cmd + S (Mac)
  • vim: Presiona Escape, escribe :wq y presiona Intro.

Qué acabas de compilar

✓ Se creó una sesión de chat para la generación de imágenes de varios turnos
✓ Se elaboró una instrucción detallada para la generación de retratos con restricciones de estilo
✓ Se generó un ícono de mapa coherente con el contexto de la conversación
✓ Se aprendió a analizar los datos de imágenes de las respuestas de Gemini

Conceptos clave dominados:

Concepto

Qué aprendiste

Sesiones de chat

client.chats.create() mantiene el contexto en varios turnos

Modalidades de respuesta

["TEXT", "IMAGE"] habilita la generación de imágenes en las respuestas

Estructura de la instrucción

Asunto → Variables → Estilo → Restricciones técnicas

Coherencia de los personajes

La misma sesión de chat = el mismo personaje en todas las imágenes

Análisis de la respuesta

Cómo extraer imágenes de inline_data en partes de la respuesta

Siguiente: Ejecuta tu código y mírate en el mapa.

6. Generar y registrar

Establece el ID de tu proyecto

Asegúrate de que el ID del proyecto esté disponible como una variable de entorno:

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

Ejecuta Identity Creator

Ahora, ejecuta la secuencia de comandos principal que coordina la generación, la carga y el registro:

uv run python create_identity.py

Verás el progreso de la generación en tiempo real:

Nota: Es posible que tu avatar tarde hasta 5 segundos en aparecer en el mapa en vivo, así que actualiza la página si no te ves de inmediato.

🚀 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!   
                                                               
╚═══════════════════════════════════════════════════════════════╝

Cómo ver tu avatar generado

Consulta tus imágenes generadas de forma local:

# List the generated files
ls -la outputs/

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

También puedes verlos directamente en el editor de Cloud Shell. Para ello, navega a la carpeta outputs/ y haz clic en los archivos de imagen.

El retrato y el ícono generados se verán similares a estas imágenes:

Ejemplo de retratoícono de ejemplo

¡Mírate en el mapa!

Abre la URL del mapa mundial que se muestra en el resultado:

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

Por ejemplo: https://waybackhome.dev/e/devfest-nyc-26

¡Encuentra tu avatar en el mapa! En esta página verá lo siguiente:

  • El ícono que marca tu posición en la superficie del planeta
  • Tu nombre de explorador como etiqueta debajo de tu ícono
  • Un faro atenuado que parpadea lentamente alrededor del marcador

Ejemplo de avatar en el mapa

Haz clic en tu marcador para ver tu retrato completo en la tarjeta de detalles.

¿No te gusta tu avatar? ¡Regenera!

Si quieres un avatar diferente, puedes volver a generarlo:

# 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

Cada vez que ejecutas create_identity.py, se genera un avatar completamente nuevo (nueva sesión de chat = nuevo personaje) y se actualiza tu registro. No dudes en repetir el proceso hasta que el resultado te satisfaga.

Solución de problemas

Lo que acabas de completar

✓ Se generó tu retrato de explorador único
✓ Se creó un ícono de mapa coherente
✓ Se subieron recursos a Mission Control
✓ Se registró tu identidad en la red de rescate
✓ Apareciste en el mapa mundial en vivo.

¡Felicitaciones, explorador! Ahora formas parte de la red de rescate. Tu baliza está activa (aunque tenue) y los demás sobrevivientes pueden verte en el mapa.

7. Conclusión

Qué compilaste

En solo 10 minutos, creaste un sistema completo de generación de avatares con la generación de imágenes por IA en varios turnos:

┌─────────────────────────────────────────────────────────────┐
                     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                  
                                                             
└─────────────────────────────────────────────────────────────┘

Conclusiones clave

Lección

Por qué es importante

Las sesiones de chat mantienen el contexto

Esencial para generar personajes coherentes en varias imágenes sin desviación de la variación

La estructura de las instrucciones es importante

Las restricciones claras (fondo blanco, estilo específico, encuadre) producen resultados predecibles y listos para la producción.

Los turnos múltiples superan a las llamadas independientes

Cada mensaje de un chat se basa en el contexto anterior, lo que permite un perfeccionamiento y una coherencia iterativos.

Las modalidades de respuesta controlan el resultado

El parámetro de configuración ["TEXT", "IMAGE"] es obligatorio para la generación de imágenes. Sin él, solo obtendrás texto.

Resumen de costos

Para este nivel, generaste 2 imágenes con Gemini 2.5 Flash (Nano Banana):

Elemento

Tokens

Costo

Vertical (1024 × 1024)

Aproximadamente 1,290 tokens de salida

~$0.039

Ícono (1024 × 1024)

Aproximadamente 1,290 tokens de salida

~$0.039

Total

Aproximadamente 2,580 tokens

~$0.08

El viaje continúa

Se confirmó tu identidad de explorador, pero hay un problema: no se confirmó tu ubicación.

Mira el mapa mundial: tu baliza es tenue y parpadea lentamente. La red de rescate sabe que existes, pero no sabe exactamente dónde estás. Podrías estar en cualquier lugar dentro de una vasta región de la superficie del planeta.

En Nivel 1: Pinpoint Your Location, harás lo siguiente:

  • Crea un sistema multiagente con el Kit de desarrollo de agentes (ADK) de Google
  • Crea servidores de MCP para análisis geológicos, botánicos y astronómicos
  • Procesa la entrada multimodal (imágenes del lugar del accidente)
  • Genera un mapa topográfico de tu ubicación confirmada con IA.
  • Enciende tu baliza de verdad para que los equipos de rescate puedan encontrarte.

El nivel 1 presenta conceptos mucho más avanzados: la orquestación de varios agentes, el Protocolo de contexto del modelo (MCP) y los patrones de implementación de producción. Pasarás de usar una sola función del modelo a crear un sistema completo basado en agentes.

Limpieza (opcional)

Si quieres limpiar los archivos locales (ejecuta desde el directorio level_0):

rm -rf outputs/
deactivate  # Exit virtual environment

Tu registro en la red de rescate persiste: seguirás apareciendo en el mapa incluso después de borrar los archivos locales. Las imágenes se almacenan en la nube, no de forma local.

Recursos

Tu baliza está a la espera de confirmación. Nos vemos en el nivel 1, explorador. 🚀

8. Bonificación: Avatar basado en fotos (opcional)

Cuándo usar la función Foto a avatar

Quizás prefieras este enfoque en los siguientes casos:

  • Quieres que tu avatar se parezca a ti.
  • Tienes una foto específica que quieres estilizar.
  • Quieres explorar las capacidades de transformación de imagen a imagen de Gemini.

Cómo funciona

En lugar de generar un personaje solo a partir de una descripción de texto, puedes proporcionar una foto y pedirle a Gemini que la transforme y conserve el parecido de la persona:

Flujo de fotos a avatares

Sube tu foto

Primero, sube una foto a Cloud Shell:

  1. En Cloud Shell, haz clic en el menú de tres puntos (⋮) en la barra de herramientas de la terminal.
  2. Selecciona Subir.
  3. Elige una foto de rostro clara (JPEG o PNG).
  4. Anota la ruta de acceso cargada (p.ej., /home/your-username/my_photo.jpg

Modifica el generador

Para usar una foto, modificarás el paso de generación de retratos en generator.py. Reemplaza la instrucción solo de texto por una instrucción multimodal que incluya tu foto:

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

La coherencia de varios turnos sigue funcionando

El enfoque de varios turnos funciona de la misma manera con la generación basada en fotos:

  • Turno 1: Foto + instrucción → Retrato estilizado (tu imagen, ilustrada)
  • Turno 2: "Crea un ícono de este MISMO personaje" → Ícono coherente

Como la sesión de chat recuerda la versión estilizada que creó (no la foto original), el ícono coincidirá perfectamente con el retrato transformado.

Consideraciones de privacidad

Probar en Vertex AI Studio

También puedes experimentar con la transformación de fotos de forma interactiva en la consola de Google Cloud antes de escribir código:

  1. Ve a Vertex AI Studio.
  2. Selecciona un modelo de Gemini con capacidades de imagen
  3. Sube tu foto con el botón de adjuntar.
  4. Ingresa la instrucción de transformación
  5. Repite el proceso con el estilo hasta que estés conforme con el resultado.

Este enfoque interactivo es ideal para experimentar con instrucciones y ver los resultados en tiempo real antes de confirmar el código.

Qué aprendiste (bonificación)

✓ Cómo usar la transformación de imagen a imagen con Gemini
✓ Cómo enviar contenido multimodal (texto + imagen) en un solo mensaje
✓ Cómo preservar el parecido mientras se aplica la transferencia de estilo artístico
✓ Consideraciones de privacidad para la generación de IA basada en fotos