Cómo realizar pruebas locales de un agente del ADK que escribe en una hoja de cálculo de Google antes de implementarlo en Cloud Run

1. Introducción

Descripción general

En esta publicación, crearás un agente de Gemini con el Kit de desarrollo de agentes (ADK) de Google y FastAPI. Antes de la implementación, configurarás las credenciales predeterminadas de la aplicación (ADC) para realizar pruebas locales con la misma cuenta de servicio que la identidad del servicio de Cloud Run.

Para comunicarse con Hojas de Cálculo de Google, tu aplicación necesita un token de acceso de OAuth con el permiso adecuado para acceder a la hoja de cálculo. Aprenderás a obtener este token de acceso cuando ejecutes de forma local y en Cloud Run con las ADC:

  • Localmente: ADC encuentra las credenciales, tal como las generó el comando gcloud auth application-default. Aquí puedes encontrar más información.
  • En Cloud Run: ADC usa el servidor de metadatos para obtener credenciales. Aquí puedes encontrar más información.

Nota sobre la terminología:

Es posible que te resulten más familiares los términos "suplantación de identidad" o "asunción de los mismos permisos". En Google Cloud, actuar en nombre de una cuenta de servicio permite que una principal autenticada acceda a lo que puede acceder la cuenta de servicio. Solo las principales autenticadas con los permisos adecuados pueden suplantar cuentas de servicio. Puedes obtener más información aquí: https://docs.cloud.google.com/iam/docs/service-account-overview#impersonation

Qué aprenderás

  • Cómo configurar las credenciales predeterminadas de la aplicación (ADC) para tu entorno local
  • Cómo crear un agente del ADK que pueda leer y escribir en una hoja de cálculo de Google
  • Cómo implementar el agente en Cloud Run

2. Configuración y requisitos

Requisitos previos

  • Accediste a la consola de Cloud.
  • Ya implementaste un servicio de Cloud Run. Por ejemplo, puedes seguir los pasos para implementar un servicio de Cloud Run para comenzar.

Configura variables de entorno

Puedes establecer variables de entorno que se usarán a lo largo de este codelab.

Puedes encontrar el ID de tu hoja en la URL de tu Hoja de cálculo de Google cuando copies el vínculo para compartir, p.ej., https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID/edit?usp=sharing

PROJECT_ID=<YOUR-PROJECT-ID>
REGION=<YOUR_REGION>
SPREADSHEET_ID=<YOUR_SPREADSHEET_ID>
SA_NAME=sheet-agent-sa
SERVICE_ACCOUNT_EMAIL=$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com

Habilita las APIs de Google Cloud requeridas

gcloud services enable \
  sheets.googleapis.com \
  aiplatform.googleapis.com \
  artifactregistry.googleapis.com \
  cloudbuild.googleapis.com \
  run.googleapis.com \
  logging.googleapis.com \
  --project=$PROJECT_ID

Crear una cuenta de servicio.

Primero, crea la cuenta de servicio con el siguiente comando.

gcloud iam service-accounts create $SA_NAME \
    --description="Service account for spreadsheet agent codelab" \
    --display-name="Spreadsheet Agent Service Account" \
    --project=$PROJECT_ID

A continuación, otorga el rol de usuario de Vertex AI a la cuenta de servicio (necesario para los modelos de Gemini en Vertex AI).

gcloud projects add-iam-policy-binding $PROJECT_ID \
    --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
    --role="roles/aiplatform.user"

Otorga permiso a tu identidad de gcloud para suplantar la cuenta de servicio (necesario para el desarrollo local). Para ver tus identidades de gcloud, ejecuta gcloud auth list.

USER_EMAIL=$(gcloud config get-value account)

gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_EMAIL \
    --member="user:$USER_EMAIL" \
    --role="roles/iam.serviceAccountTokenCreator" \
    --project=$PROJECT_ID
  1. Abre la hoja de cálculo de Google en el navegador.
  2. Haz clic en el botón Compartir.
  3. Pega el correo electrónico de la cuenta de servicio $SERVICE_ACCOUNT_EMAIL y otórgale acceso de editor.

3. Crea la app

Primero, crea un directorio para el código fuente y ábrelo con el comando cd.

mkdir local-adk-sheets-codelab && cd $_

Luego, crea un archivo main.py con el siguiente contenido:

import os
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from google.auth import default
from googleapiclient.discovery import build
from google.adk.agents.llm_agent import Agent
from google.adk.runners import InMemoryRunner

# 1. Environment and Global Google Sheets Client Setup (ADC)
SPREADSHEET_ID = os.environ.get("SPREADSHEET_ID")
if not SPREADSHEET_ID:
    raise ValueError("SPREADSHEET_ID environment variable is missing. Please set it before running.")

credentials, _ = default(scopes=['https://www.googleapis.com/auth/spreadsheets'])
sheets_api = build('sheets', 'v4', credentials=credentials).spreadsheets()

# 2. Tools
def read_spreadsheet(range_name: str) -> dict:
    """Reads values from the Google Spreadsheet for a given range.
   
    Args:
        range_name: The A1 notation or R1C1 notation of the range to retrieve, e.g., 'Sheet1!A1:D10'.
    """
    return sheets_api.values().get(spreadsheetId=SPREADSHEET_ID, range=range_name).execute()

def update_spreadsheet(range_name: str, values: list[list[str]]) -> dict:
    """Updates the Google Spreadsheet range with the specified grid of values.
   
    Args:
        range_name: The A1 notation or R1C1 notation of the range to update, e.g., 'Sheet1!C2'.
        values: A list of lists of strings representing the grid of values to write.
    """
    return sheets_api.values().update(
        spreadsheetId=SPREADSHEET_ID,
        range=range_name,
        valueInputOption="USER_ENTERED",
        body={"values": values}
    ).execute()

# 3. Agent Definition
MODEL_NAME = os.environ.get("GEMINI_MODEL", "gemini-3.1-flash-lite")
root_agent = Agent(
    name="spreadsheet_agent",
    model=MODEL_NAME,
    instruction="""You are a helpful spreadsheet assistant.
    You can read and write to the user's Google Spreadsheet using the tools provided.
    Always use the appropriate tools when the user asks you to read or update a spreadsheet.
    When updating a range, make sure the values parameter is a list of lists (e.g. [[value]]).
    Be concise and helpful in your responses.""",
    description="An agent that can read and write to a specific Google Spreadsheet.",
    tools=[read_spreadsheet, update_spreadsheet]
)

# 4. FastAPI Application Setup
app = FastAPI()

class ChatRequest(BaseModel):
    prompt: str

@app.post("/chat")
async def chat_endpoint(request: ChatRequest):
    try:
        async with InMemoryRunner(app_name="sheets_agent_app", agent=root_agent) as runner:
            events = await runner.run_debug(request.prompt, quiet=True)
           
            # Extract the final response text
            texts = [
                "".join(p.text for p in e.content.parts if p.text)
                for e in reversed(events) if e.content and e.content.parts
            ]
            return {"response": next((t for t in texts if t), "No response from agent.")}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

A continuación, crea un archivo requirements.txt con el siguiente contenido:

fastapi>=0.100.0
uvicorn>=0.22.0
google-adk>=1.27.1
google-auth
google-api-python-client

4. Prueba el servicio de forma local

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_EMAIL
GOOGLE_GENAI_USE_VERTEXAI=1 GOOGLE_CLOUD_PROJECT=$PROJECT_ID SPREADSHEET_ID=$SPREADSHEET_ID uvicorn main:app --host 0.0.0.0 --port 8080

Ahora, prueba tu agente desde otra terminal:

curl -X POST http://localhost:8080/chat \
    -H "Content-Type: application/json" \
    -d '{"prompt": "Update spreadsheet '$SPREADSHEET_ID' at range Sheet1!A1 with the value hello world"}'

El servidor debe responder: {"response":"The spreadsheet at Sheet1!A1 has been updated with the value \"hello world\"."}

5. Implementa en Cloud Run

Ahora que sabes que tu cuenta de servicio tiene los permisos adecuados para acceder a la hoja de cálculo, realizarás la implementación en Cloud Run con la cuenta de servicio como identidad del servicio.

gcloud run deploy local-adk-sheets-codelab \
    --source . \
    --region=$REGION \
    --set-env-vars GOOGLE_GENAI_USE_VERTEXAI=1,GOOGLE_CLOUD_PROJECT=$PROJECT_ID,GOOGLE_CLOUD_LOCATION=global,SPREADSHEET_ID=$SPREADSHEET_ID \
    --service-account $SERVICE_ACCOUNT_EMAIL \
    --no-allow-unauthenticated \
    --project=$PROJECT_ID

Cuando finalice la implementación, envía una instrucción a tu servicio de Cloud Run.

# Retrieve the Service URL
SERVICE_URL=$(gcloud run services describe local-adk-sheets-codelab --region $REGION --format 'value(status.url)')
curl -X POST $SERVICE_URL/chat \
    -H "Authorization: bearer $(gcloud auth print-identity-token)" \
    -H "Content-Type: application/json" \
    -d '{"prompt": "Update spreadsheet '$SPREADSHEET_ID' at range Sheet1!A1 with the value hello world"}'

Deberías recibir una respuesta de {"response":"OK. I've updated cell A1 in Sheet1 with \"hello world\"."}.

Ahora abre tu hoja de cálculo de Google. Verás el valor "hello world" en la primera celda.

6. ¡Felicitaciones!

¡Felicitaciones por completar el codelab!

¿Qué sigue?

Te recomendamos que explores la siguiente documentación para ampliar las capacidades de tu agente:

Temas abordados

  • Cómo configurar las credenciales predeterminadas de la aplicación (ADC) para tu entorno local
  • Cómo crear un agente del ADK que pueda leer y escribir en una hoja de cálculo de Google
  • Cómo implementar el agente en Cloud Run

7. Limpia

Para evitar cargos involuntarios (por ejemplo, si esta función de Cloud Run se invoca de forma involuntaria más veces que tu asignación mensual de invocaciones de Cloud Run en el nivel gratuito), puedes borrar el servicio de Cloud Run o el proyecto.

Para borrar un servicio de Cloud Run, ve a Cloud Run en Cloud Console en https://console.cloud.google.com/run/ y borra el servicio local-adk-sheets-codelab que creaste en este codelab.

Si decides borrar todo el proyecto, puedes ir a https://console.cloud.google.com/cloud-resource-manager, seleccionar el proyecto que creaste en el paso 2 y elegir Borrar. Si borras el proyecto, deberás cambiar de proyecto en el SDK de Cloud. Para ver la lista de todos los proyectos disponibles, ejecuta gcloud projects list.