Как провести локальное тестирование агента ADK, который записывает данные в таблицу Google Sheets, перед развертыванием в Cloud Run.

1. Введение

Обзор

В этой статье вы создадите агента Gemini, используя Google Agent Development Kit (ADK) и FastAPI. Перед развертыванием вы настроите учетные данные приложения по умолчанию (ADC) для локального тестирования с использованием той же учетной записи службы, что и учетная запись службы Cloud Run.

Для взаимодействия с Google Sheets вашему приложению необходим токен доступа OAuth с соответствующей областью действия для доступа к электронной таблице. Вы узнаете, как получить этот токен доступа при локальном запуске и в Cloud Run с ADC:

Примечание по терминологии:

Возможно, вам больше знакомы термины «присвоение учетной записи» или «присвоение тех же прав доступа». В Google Cloud имитация учетной записи службы позволяет аутентифицированному субъекту получить доступ ко всему, к чему имеет доступ учетная запись службы. Только аутентифицированные субъекты с соответствующими правами могут имитировать учетные записи служб. Подробнее можно прочитать здесь: https://docs.cloud.google.com/iam/docs/service-account-overview#impersonation

Что вы узнаете

  • Как настроить учетные данные приложения по умолчанию (ADC) для вашей локальной среды
  • Как создать агент ADK, который может читать и записывать данные в таблицу Google Sheets.
  • Как развернуть агент в Cloud Run

2. Настройка и требования

Предварительные требования

  • Вы вошли в облачную консоль.
  • Вы уже развернули службу Cloud Run. Например, вы можете начать работу, следуя инструкциям по развертыванию службы Cloud Run .

Установка переменных среды

Вы можете установить переменные окружения, которые будут использоваться на протяжении всего этого практического занятия.

Идентификатор вашей таблицы можно найти в URL-адресе вашей таблицы Google, когда вы копируете ссылку для общего доступа, например: 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

Включите необходимые API Google Cloud.

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

Создать учетную запись службы

Сначала создайте учетную запись службы с помощью следующей команды.

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

Далее предоставьте учетной записи службы роль пользователя Vertex AI (необходимую для моделей Gemini в Vertex AI).

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

Предоставьте своему пользователю gcloud разрешение на использование учетной записи службы (необходимо для локальной разработки). Вы можете просмотреть список своих пользователей gcloud, выполнив 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. Откройте таблицу Google Sheets в браузере.
  2. Нажмите кнопку «Поделиться».
  3. Вставьте адрес электронной почты учетной записи службы $SERVICE_ACCOUNT_EMAIL и предоставьте ей доступ редактора.

3. Создайте приложение

Сначала создайте директорию для исходного кода и перейдите в неё с помощью команды `cd`.

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

Затем создайте файл main.py со следующим содержимым:

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))

Далее создайте файл requirements.txt со следующим содержимым:

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

4. Протестируйте сервис локально.

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

Теперь протестируйте своего агента с другого терминала:

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

Сервер должен ответить: {"response":"The spreadsheet at Sheet1!A1 has been updated with the value \"hello world\"."}

5. Развертывание в облаке

Теперь, когда вы знаете, что ваша служебная учетная запись имеет необходимые разрешения для доступа к электронной таблице, вы можете развернуть приложение в Cloud Run, используя служебную учетную запись в качестве идентификатора службы.

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

После завершения развертывания отправьте запрос в службу 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"}'

Вы должны получить ответ следующего содержания {"response":"OK. I've updated cell A1 in Sheet1 with \"hello world\"."}

Теперь откройте свою таблицу Google Sheets. В первой ячейке вы увидите значение "hello world".

6. Поздравляем!

Поздравляем с завершением практического занятия!

Что дальше?

Мы рекомендуем ознакомиться со следующей документацией, чтобы расширить возможности вашего агента:

Что мы рассмотрели

  • Как настроить учетные данные приложения по умолчанию (ADC) для вашей локальной среды
  • Как создать агент ADK, который может читать и записывать данные в таблицу Google Sheets.
  • Как развернуть агент в Cloud Run

7. Уборка

Чтобы избежать непреднамеренных списаний средств (например, если эта функция Cloud Run будет случайно вызвана больше раз, чем предусмотрено вашим ежемесячным лимитом вызовов Cloud Run в бесплатном тарифе ), вы можете либо удалить службу Cloud Run, либо удалить проект.

Чтобы удалить службу Cloud Run, перейдите в Cloud Run в консоли Cloud по адресу https://console.cloud.google.com/run/ и удалите службу local-adk-sheets-codelab которую вы создали в этом практическом задании.

Если вы решите удалить весь проект, перейдите по ссылке https://console.cloud.google.com/cloud-resource-manager , выберите проект, созданный на шаге 2, и нажмите «Удалить». После удаления проекта вам потребуется изменить проекты в вашем Cloud SDK. Список всех доступных проектов можно просмотреть, выполнив gcloud projects list .