Cloud Run에서 ADK 에이전트 배포, 관리, 관찰

이 Codelab 정보
schedule0분
subject최종 업데이트: 2025년 6월 19일
account_circle작성자: Alvin Prayuda Juniarta Dwiyantoro

이 튜토리얼에서는 Google Cloud Run에서 Agent Development Kit (ADK)로 빌드된 강력한 에이전트를 배포, 관리, 모니터링하는 방법을 안내합니다. ADK를 사용하면 복잡한 멀티 에이전트 워크플로를 실행할 수 있는 에이전트를 만들 수 있습니다. 완전 관리형 서버리스 플랫폼인 Cloud Run을 활용하면 기본 인프라에 대한 걱정 없이 확장 가능한 컨테이너화된 애플리케이션으로 상담사를 배포할 수 있습니다. 이 강력한 조합을 사용하면 에이전트의 핵심 로직에 집중하면서 Google Cloud의 강력하고 확장 가능한 환경을 활용할 수 있습니다.

이 튜토리얼에서는 ADK와 Cloud Run의 원활한 통합을 살펴봅니다. 에이전트를 배포하는 방법을 알아본 후 프로덕션과 유사한 설정에서 애플리케이션을 관리하는 실용적인 측면을 살펴봅니다. 트래픽을 관리하여 새 버전의 상담사를 안전하게 출시하는 방법을 알아봅니다. 이를 통해 전체 출시 전에 일부 사용자를 대상으로 새 기능을 테스트할 수 있습니다.

또한 상담사의 실적을 모니터링하는 방법을 직접 경험해 보게 됩니다. 부하 테스트를 실행하여 실제 시나리오를 시뮬레이션하고 Cloud Run의 자동 확장 기능이 작동하는 방식을 관찰합니다. 상담사의 동작과 실적에 대한 심층적인 통계를 얻기 위해 Cloud Trace로 추적을 사용 설정할 예정입니다. 이렇게 하면 요청이 상담사를 통과할 때의 세부적인 엔드 투 엔드 보기를 제공하여 성능 병목 현상을 파악하고 해결할 수 있습니다. 이 튜토리얼을 마치면 Cloud Run에서 ADK 기반 에이전트를 효과적으로 배포, 관리, 모니터링하는 방법을 종합적으로 이해하게 됩니다.

이 Codelab에서는 다음과 같이 단계별로 접근합니다.

  1. ADK Agent 데이터베이스 세션 서비스에 사용할 PostgreSQL 데이터베이스를 CloudSQL에 만듭니다.
  2. 기본 ADK 에이전트 설정
  3. ADK 런너에서 사용할 데이터베이스 세션 서비스 설정
  4. Cloud Run에 에이전트 초기 배포
  5. Cloud Run 자동 확장 부하 테스트 및 검사
  6. 새 상담사 버전 배포 및 새 버전으로의 트래픽 점진적 증가
  7. 클라우드 추적 설정 및 에이전트 실행 추적 검사

아키텍처 개요

5e38fc5607fb4543.jpeg

기본 요건

  • Python을 편안하게 사용
  • HTTP 서비스를 사용하는 기본 풀 스택 아키텍처 이해

학습할 내용

  • ADK 구조 및 로컬 유틸리티
  • 데이터베이스 세션 서비스로 ADK 에이전트 설정
  • 데이터베이스 세션 서비스에서 사용할 수 있도록 CloudSQL에서 PostgreSQL 설정
  • Dockerfile을 사용하여 Cloud Run에 애플리케이션 배포 및 초기 환경 변수 설정
  • 부하 테스트를 사용하여 Cloud Run 자동 확장 구성 및 테스트
  • Cloud Run을 통한 점진적 출시 전략
  • Cloud Trace로 ADK 에이전트 추적 설정

필요한 항목

  • Chrome 웹브라우저
  • Gmail 계정
  • 결제가 사용 설정된 Cloud 프로젝트

이 Codelab은 초보자를 포함한 모든 수준의 개발자를 위해 설계되었으며 샘플 애플리케이션에서 Python을 사용합니다. 하지만 Python 지식이 없어도 소개된 개념을 이해하는 데는 문제가 없습니다.

2. 시작하기 전에

Cloud 콘솔에서 활성 프로젝트 선택

이 Codelab에서는 결제가 사용 설정된 Google Cloud 프로젝트가 이미 있다고 가정합니다. 아직 계정이 없다면 아래 안내에 따라 시작할 수 있습니다.

  1. Google Cloud 콘솔의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.
  2. Cloud 프로젝트에 결제가 사용 설정되어 있어야 하므로 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

c714d4741fc97644.png

Cloud SQL 데이터베이스 준비하기

나중에 ADK 에이전트에서 사용할 데이터베이스가 필요합니다. Cloud SQL에서 PostgreSQL 데이터베이스를 만들어 보겠습니다. 먼저 Cloud 콘솔 상단 섹션의 검색창으로 이동하여 'cloud sql'을 입력합니다. 그런 다음 Cloud SQL 제품을 클릭합니다.

1005cb65520eb3fc.png

그런 다음 새 데이터베이스 인스턴스를 만들어야 합니다. 인스턴스 만들기를 클릭하고 PostgreSQL을 선택합니다.

7f2ad19bc246895d.png

ead4a98e7a8d8a39.png

새 프로젝트로 시작하는 경우 Compute Engine API를 사용 설정해야 할 수도 있습니다. 이 메시지가 표시되면 API 사용 설정을 클릭합니다.

724cf67681535679.png

다음으로 데이터베이스 사양을 선택하고 샌드박스 버전 사전 설정이 포함된 엔터프라이즈 버전을 선택합니다.

24aa9defed93a3ef.png

그런 다음 여기에서 사용자 postgres의 인스턴스 이름과 기본 비밀번호를 설정합니다. 원하는 사용자 인증 정보로 설정할 수 있지만 이 튜토리얼에서는 인스턴스 이름과 비밀번호 모두 'adk-deployment'를 사용합니다.

573719a4582f541c.png

이 튜토리얼에서는 단일 영역이 있는 us-central1을 사용하겠습니다. 그런 다음 데이터베이스 생성을 완료하고 인스턴스 만들기 버튼을 클릭하여 필요한 모든 설정을 완료할 수 있습니다.

773e2ea11d97369d.png

완료될 때까지 기다리는 동안 다음 섹션으로 넘어갈 수 있습니다.

Cloud Shell 터미널에서 Cloud 프로젝트 설정

  1. Google Cloud에서 실행되는 명령줄 환경인 Cloud Shell을 사용합니다. Google Cloud 콘솔 상단에서 Cloud Shell 활성화를 클릭합니다.

1829c3759227c19b.png

  1. Cloud Shell에 연결되면 다음 명령어를 사용하여 이미 인증되었는지, 프로젝트가 프로젝트 ID로 설정되어 있는지 확인합니다.
gcloud auth list
  1. Cloud Shell에서 다음 명령어를 실행하여 gcloud 명령어가 프로젝트를 알고 있는지 확인합니다.
gcloud config list project
  1. 프로젝트가 설정되지 않은 경우 다음 명령어를 사용하여 설정합니다.
gcloud config set project <YOUR_PROJECT_ID>

또는 콘솔에서 PROJECT_ID ID를 확인할 수도 있습니다.

4032c45803813f30.jpeg

이 아이콘을 클릭하면 오른쪽에 모든 프로젝트와 프로젝트 ID가 표시됩니다.

8dc17eb4271de6b5.jpeg

  1. 아래 명령어를 통해 필수 API를 사용 설정합니다. 이 작업은 몇 분 정도 걸릴 수 있으니 기다려 주시기 바랍니다.
gcloud services enable aiplatform.googleapis.com \
                       run.googleapis.com \
                       cloudbuild.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       sqladmin.googleapis.com

명령어 실행이 성공하면 아래와 유사한 메시지가 표시됩니다.

Operation "operations/..." finished successfully.

gcloud 명령어 대신 콘솔에서 각 제품을 검색하거나 이 링크를 사용하는 방법이 있습니다.

누락된 API가 있으면 구현 과정에서 언제든지 사용 설정할 수 있습니다.

gcloud 명령어 및 사용법은 문서를 참조하세요.

Cloud Shell 편집기로 이동하여 애플리케이션 작업 디렉터리 설정

이제 코딩 작업을 실행하도록 코드 편집기를 설정할 수 있습니다. 이 작업에는 Cloud Shell 편집기를 사용합니다.

  1. 편집기 열기 버튼을 클릭하면 Cloud Shell 편집기가 열리고 여기에 코드를 작성할 수 있습니다. b16d56e4979ec951.png
  2. Cloud Code 프로젝트가 아래 이미지에서 강조 표시된 것처럼 Cloud Shell 편집기의 왼쪽 하단 (상태 표시줄)에 설정되어 있고 결제가 사용 설정된 활성 Google Cloud 프로젝트로 설정되어 있는지 확인합니다. 메시지가 표시되면 승인합니다. 이미 이전 명령어를 따랐다면 버튼이 로그인 버튼 대신 활성화된 프로젝트로 직접 연결될 수도 있습니다.

f5003b9c38b43262.png

  1. 다음으로 GitHub에서 이 Codelab의 템플릿 작업 디렉터리를 클론합니다. 다음 명령어를 실행합니다. deploy_and_manage_adk 디렉터리에 작업 디렉터리가 생성됩니다.
git clone https://github.com/alphinside/deploy-and-manage-adk-service.git deploy_and_manage_adk
  1. 그런 다음 Cloud Shell 편집기 상단 섹션으로 이동하여 파일 -> 폴더 열기를 클릭하고 사용자 이름 디렉터리를 찾아 deploy_and_manage_adk 디렉터리를 찾은 다음 확인 버튼을 클릭합니다. 이렇게 하면 선택한 디렉터리가 기본 작업 디렉터리가 됩니다. 이 예시에서 사용자 이름은 alvinprayuda이므로 디렉터리 경로는 아래와 같습니다.

2c53696f81d805cc.png

a51615f22ba1690f.png

이제 Cloud Shell 편집기가 다음과 같이 표시됩니다.

228d4c1844790573.png

다음으로 Python 환경 설정을 구성할 수 있습니다.

환경 설정

Python 가상 환경 준비

다음 단계는 개발 환경을 준비하는 것입니다. 현재 활성 터미널 작업 디렉터리는 deploy_and_manage_adk 작업 디렉터리 내에 있어야 합니다. 이 Codelab에서는 Python 3.12를 활용하고 uv python project manager를 사용하여 Python 버전과 가상 환경을 만들고 관리하는 작업을 간소화합니다.

  1. 아직 터미널을 열지 않았다면 터미널 -> 새 터미널을 클릭하거나 Ctrl + Shift + C를 사용하여 터미널을 엽니다. 그러면 브라우저 하단에 터미널 창이 열립니다.

f8457daf0bed059e.jpeg

  1. uv를 다운로드하고 다음 명령어를 사용하여 Python 3.12를 설치합니다.
curl -LsSf https://astral.sh/uv/0.6.16/install.sh | sh && \
source $HOME/.local/bin/env && \
uv python install 3.12
  1. 이제 uv를 사용하여 가상 환경을 초기화해 보겠습니다. 이 명령어를 실행합니다.
uv sync --frozen

이렇게 하면 .venv 디렉터리가 생성되고 종속 항목이 설치됩니다. pyproject.toml을 살짝 살펴보면 다음과 같이 종속 항목에 관한 정보를 확인할 수 있습니다.

dependencies = [
    "google-adk==1.3.0",
    "locust==2.37.10",
    "pg8000==1.31.2",
    "python-dotenv==1.1.0",
]
  1. 가상 환경을 테스트하려면 새 파일 main.py를 만들고 다음 코드를 복사합니다.
def main():
   print("Hello from deploy_and_manage_adk!")

if __name__ == "__main__":
   main()
  1. 그런 다음 다음 명령어를 실행합니다.
uv run main.py

아래와 같은 출력이 표시됩니다.

Using CPython 3.12
Creating virtual environment at: .venv
Hello from deploy_and_manage_adk!

이는 Python 프로젝트가 올바르게 설정되고 있음을 나타냅니다.

설정 구성 파일

이제 이 프로젝트의 구성 파일을 설정해야 합니다.

.env.example 파일의 이름을 .env로 바꾸면 아래에 값이 표시됩니다. GOOGLE_CLOUD_PROJECT 값을 프로젝트 ID로 업데이트합니다.

# Google Cloud and Vertex AI configuration
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=global
GOOGLE_GENAI_USE_VERTEXAI=True

# Database connection for session service
# SESSION_SERVICE_URI=postgresql+pg8000://<username>:<password>@/<database>?unix_sock=/cloudsql/<instance_connection_name>/.s.PGSQL.5432

이 Codelab에서는 GOOGLE_CLOUD_LOCATIONGOOGLE_GENAI_USE_VERTEXAI.의 사전 구성된 값을 사용합니다. 지금은 SESSION_SERVICE_URI를 주석 처리된 상태로 둡니다.

이제 다음 단계로 넘어가서 상담사 로직을 검사하고 배포하겠습니다.

3. ADK 및 Gemini 2.5로 날씨 에이전트 빌드

ADK 디렉터리 구조 소개

먼저 ADK에서 제공하는 기능과 에이전트를 빌드하는 방법을 살펴보겠습니다. ADK 전체 문서는 이 URL에서 확인할 수 있습니다 . ADK는 CLI 명령어 실행 내에서 여러 유틸리티를 제공합니다. 그중 일부는 다음과 같습니다.

  • 에이전트 디렉터리 구조 설정
  • CLI 입력 출력을 통한 상호작용 빠르게 시도
  • 로컬 개발 UI 웹 인터페이스를 빠르게 설정합니다.

이제 weather_agent 디렉터리의 에이전트 구조를 확인해 보겠습니다.

weather_agent/
├── __init__.py
├── agent.py

init.pyagent.py를 검사하면 다음 코드가 표시됩니다.

# __init__.py

from weather_agent.agent import root_agent

__all__ = ["root_agent"]
# agent.py

import os
from pathlib import Path

import google.auth
from dotenv import load_dotenv
from google.adk.agents import Agent
from google.cloud import logging as google_cloud_logging

# Load environment variables from .env file in root directory
root_dir = Path(__file__).parent.parent
dotenv_path = root_dir / ".env"
load_dotenv(dotenv_path=dotenv_path)

# Use default project from credentials if not in .env
_, project_id = google.auth.default()
os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id)
os.environ.setdefault("GOOGLE_CLOUD_LOCATION", "global")
os.environ.setdefault("GOOGLE_GENAI_USE_VERTEXAI", "True")

logging_client = google_cloud_logging.Client()
logger = logging_client.logger("weather-agent")


def get_weather(city: str) -> dict:
    """Retrieves the current weather report for a specified city.

    Args:
        city (str): The name of the city (e.g., "New York", "London", "Tokyo").

    Returns:
        dict: A dictionary containing the weather information.
              Includes a 'status' key ('success' or 'error').
              If 'success', includes a 'report' key with weather details.
              If 'error', includes an 'error_message' key.
    """
    logger.log_text(
        f"--- Tool: get_weather called for city: {city} ---", severity="INFO"
    )  # Log tool execution
    city_normalized = city.lower().replace(" ", "")  # Basic normalization

    # Mock weather data
    mock_weather_db = {
        "newyork": {
            "status": "success",
            "report": "The weather in New York is sunny with a temperature of 25°C.",
        },
        "london": {
            "status": "success",
            "report": "It's cloudy in London with a temperature of 15°C.",
        },
        "tokyo": {
            "status": "success",
            "report": "Tokyo is experiencing light rain and a temperature of 18°C.",
        },
    }

    if city_normalized in mock_weather_db:
        return mock_weather_db[city_normalized]
    else:
        return {
            "status": "error",
            "error_message": f"Sorry, I don't have weather information for '{city}'.",
        }


root_agent = Agent(
    name="weather_agent",
    model="gemini-2.5-flash",
    instruction="You are a helpful AI assistant designed to provide accurate and useful information.",
    tools=[get_weather],
)

ADK 코드 설명

이 스크립트에는 다음을 초기화하는 에이전트 시작이 포함됩니다.

  • 사용할 모델을 gemini-2.5-flash로 설정합니다.
  • 날씨 에이전트로 에이전트 기능을 지원하는 도구 get_weather를 제공합니다.

웹 UI 실행

이제 에이전트와 상호작용하고 로컬에서 에이전트의 동작을 검사할 수 있습니다. ADK를 사용하면 개발 웹 UI를 통해 상호작용하고 상호작용 중에 진행되는 상황을 검사할 수 있습니다. 다음 명령어를 실행하여 로컬 개발 UI 서버를 시작합니다.

uv run adk web --port 8080

다음 예와 같은 출력이 생성됩니다. 즉, 이미 웹 인터페이스에 액세스할 수 있습니다.

INFO:     Started server process [xxxx]
INFO:     Waiting for application startup.

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://localhost:8080.                         |
+-----------------------------------------------------------------------------+

INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)

이제 Cloud Shell 편집기 상단 영역에서 웹 미리보기 버튼을 클릭하고 포트 8080에서 미리보기를 선택하여 확인합니다.

e7c9f56c2463164.png

다음 웹페이지가 표시됩니다. 여기에서 왼쪽 상단의 드롭다운 버튼을 클릭하여 사용 가능한 상담사 ( 이 경우 weather_agent)를 선택하고 봇과 상호작용할 수 있습니다. 왼쪽 창에 에이전트 런타임 중에 로그 세부정보에 관한 많은 정보가 표시됩니다.

d95b1e057315fee2.png

이제 상호작용해 보세요. 왼쪽 막대에서 각 입력의 트레이스를 검사하여 상담사가 최종 답변을 작성하기 전에 취한 각 작업에 걸리는 시간을 파악할 수 있습니다.

39c0a06ace937683.png

이는 ADK에 내장된 관측 가능성 기능 중 하나이며 현재 로컬에서 검사합니다. 나중에 Cloud Tracing에 통합되어 모든 요청의 trace가 중앙 집중화되는 방식을 살펴봅니다.

4. 백엔드 서버 스크립트

에이전트를 서비스로 액세스할 수 있도록 하려면 FastAPI 앱 내에 에이전트를 래핑합니다. 여기에서 프로덕션 목적으로 세션, 메모리 또는 아티팩트 서비스를 준비하는 등 에이전트를 지원하는 데 필요한 서비스를 구성할 수 있습니다. 다음은 사용될 server.py의 코드입니다.

import os

from dotenv import load_dotenv
from fastapi import FastAPI
from google.adk.cli.fast_api import get_fast_api_app
from pydantic import BaseModel
from typing import Literal
from google.cloud import logging as google_cloud_logging
from tracing import CloudTraceLoggingSpanExporter
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider, export


# Load environment variables from .env file
load_dotenv()

logging_client = google_cloud_logging.Client()
logger = logging_client.logger(__name__)

AGENT_DIR = os.path.dirname(os.path.abspath(__file__))

# Get session service URI from environment variables
session_uri = os.getenv("SESSION_SERVICE_URI", None)

# Prepare arguments for get_fast_api_app
app_args = {"agents_dir": AGENT_DIR, "web": True}

# Only include session_service_uri if it's provided
if session_uri:
    app_args["session_service_uri"] = session_uri
else:
    logger.log_text(
        "SESSION_SERVICE_URI not provided. Using in-memory session service instead. "
        "All sessions will be lost when the server restarts.",
        severity="WARNING",
    )

provider = TracerProvider()
processor = export.BatchSpanProcessor(CloudTraceLoggingSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)

# Create FastAPI app with appropriate arguments
app: FastAPI = get_fast_api_app(**app_args)

app.title = "weather-agent"
app.description = "API for interacting with the Agent weather-agent"


class Feedback(BaseModel):
    """Represents feedback for a conversation."""

    score: int | float
    text: str | None = ""
    invocation_id: str
    log_type: Literal["feedback"] = "feedback"
    service_name: Literal["weather-agent"] = "weather-agent"
    user_id: str = ""


@app.post("/feedback")
def collect_feedback(feedback: Feedback) -> dict[str, str]:
    """Collect and log feedback.

    Args:
        feedback: The feedback data to log

    Returns:
        Success message
    """
    logger.log_struct(feedback.model_dump(), severity="INFO")
    return {"status": "success"}


# Main execution
if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8080)

서버 코드 설명

다음은 server.py 스크립트에 정의된 항목입니다.

  1. get_fast_api_app 메서드를 사용하여 에이전트를 FastAPI 앱으로 변환합니다. 이렇게 하면 웹 개발 UI에 사용되는 것과 동일한 경로 정의를 상속받습니다.
  2. get_fast_api_app 메서드에 키워드 인수를 추가하여 필요한 세션, 메모리 또는 아티팩트 서비스를 구성합니다. 이 튜토리얼에서는 SESSION_SERVICE_URI env var를 구성하면 세션 서비스에서 이를 사용하고 그렇지 않으면 메모리 내 세션을 사용합니다.
  3. 다른 백엔드 비즈니스 로직을 지원하기 위해 맞춤 경로를 추가할 수 있습니다. 스크립트에서 의견 기능 경로 예시를 추가합니다.
  4. Cloud Tracing을 사용 설정하여 Google Cloud Trace로 트레이스 전송

5. Cloud Run에 배포

이제 이 에이전트 서비스를 Cloud Run에 배포하겠습니다. 이 데모에서는 이 서비스가 다른 사용자가 액세스할 수 있는 공개 서비스로 노출됩니다. 하지만 안전하지 않으므로 권장하지 않습니다.

5e38fc5607fb4543.jpeg

이 Codelab에서는 Dockerfile을 사용하여 Cloud Run에 에이전트를 배포합니다. 다음은 사용될 Dockerfile 콘텐츠입니다.

FROM python:3.12-slim

RUN pip install --no-cache-dir uv==0.7.13

WORKDIR /app

COPY . .

RUN uv sync --frozen

EXPOSE 8080

CMD ["uv", "run", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8080"]

이제 Cloud Run에 애플리케이션을 배포하는 데 필요한 모든 파일이 있으므로 배포해 보겠습니다. Cloud Shell 터미널로 이동하여 현재 프로젝트가 활성 프로젝트로 구성되어 있는지 확인합니다. 그렇지 않은 경우 gcloud configure 명령어를 사용하여 프로젝트 ID를 설정합니다.

gcloud config set project [PROJECT_ID]

그런 다음 다음 명령어를 실행하여 Cloud Run에 배포합니다.

gcloud run deploy weather-agent \
                  --source . \
                  --port 8080 \
                  --project {YOUR_PROJECT_ID} \
                  --allow-unauthenticated \
                  --add-cloudsql-instances {YOUR_DB_CONNECTION_NAME} \
                  --update-env-vars SESSION_SERVICE_URI="postgresql+pg8000://postgres:{YOUR_DEFAULT_USER_PASS}@postgres/?unix_sock=/cloudsql/{YOUR_DB_CONNECTION_NAME}/.s.PGSQL.5432",GOOGLE_CLOUD_PROJECT={YOUR_PROJECT_ID} \
                  --region us-central1

{YOUR_DB_CONNECTION_NAME} 값을 가져오려면 Cloud SQL로 다시 이동하여 만든 인스턴스를 클릭하면 됩니다. 인스턴스 페이지에서 '이 인스턴스에 연결' 섹션으로 아래로 스크롤하여 연결 이름을 복사하여 {YOUR_DB_CONNECTION_NAME} 값을 대체할 수 있습니다. 예를 들어 아래 이미지를 참고하세요.

5d7d6c6f17e559c1.png

Docker 저장소의 아티팩트 저장소 생성을 확인하라는 메시지가 표시되면 Y로 답변합니다. 이 애플리케이션은 데모 애플리케이션이므로 인증되지 않은 액세스를 허용합니다. 엔터프라이즈 및 프로덕션 애플리케이션에는 적절한 인증을 사용하는 것이 좋습니다.

배포가 완료되면 다음과 유사한 링크가 표시됩니다.

https://weather-agent-*******.us-central1.run.app

시크릿 창이나 휴대기기에서 애플리케이션을 사용해 보세요. 이미 게시되어 있어야 합니다.

6. 부하 테스트를 사용하여 Cloud Run 자동 확장 검사

이제 Cloud Run의 자동 확장 기능을 살펴보겠습니다. 이 시나리오에서는 인스턴스당 최대 동시 실행을 사용 설정하면서 새 버전을 배포해 보겠습니다. 다음 명령어를 실행합니다.

gcloud run deploy weather-agent \
                  --source . \
                  --port 8080 \
                  --project {YOUR_PROJECT_ID} \
                  --allow-unauthenticated \
                  --region us-central1 \
                  --concurrency 10

그런 다음 load_test.py 파일을 검사해 보겠습니다. 이 스크립트는 locust 프레임워크를 사용하여 부하 테스트를 실행하는 데 사용됩니다. 이 스크립트는 다음 작업을 실행합니다.

  1. 무작위로 생성된 user_id 및 session_id
  2. user_id의 session_id 만들기
  3. 생성된 user_id 및 session_id를 사용하여 엔드포인트 '/run_sse'를 호출합니다.

배포된 서비스 URL을 알려주셔야 합니다(누락된 경우). Cloud Run 콘솔로 이동하여 weather-agent 서비스를 클릭합니다.

f5cc953cc422de6d.png

그런 다음 weather-agent 서비스를 찾아 클릭합니다.

ddd0df8544aa2bfb.png

서비스 URL은 리전 정보 바로 옆에 표시됩니다. 예:

41b1276616379ee8.png

그런 다음 다음 명령어를 실행하여 부하 테스트를 실행합니다.

uv run locust -f load_test.py \
              -H {YOUR_SERVICE_URL} \
              -u 60 \
              -r 5 \
              -t 120 \
              --headless

이를 실행하면 다음과 같은 측정항목이 표시됩니다. ( 이 예에서는 모든 요청이 성공함)

Type     Name                                  # reqs      # fails |    Avg     Min     Max    Med |   req/s  failures/s
--------|------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
POST     /run_sse end                             813     0(0.00%) |   5817    2217   26421   5000 |    6.79        0.00
POST     /run_sse message                         813     0(0.00%) |   2678    1107   17195   2200 |    6.79        0.00
--------|------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
         Aggregated                              1626     0(0.00%) |   4247    1107   26421   3500 |   13.59        0.00  

그런 다음 Cloud Run에서 어떤 일이 일어났는지 확인하고 배포된 서비스로 다시 이동하여 대시보드를 살펴보겠습니다. 이렇게 하면 Cloud Run이 수신 요청을 처리하도록 인스턴스를 자동으로 확장하는 방법을 확인할 수 있습니다. 최대 동시 실행 수를 인스턴스당 10개로 제한하므로 Cloud Run 인스턴스는 이 조건을 자동으로 충족하도록 컨테이너 수를 조정하려고 시도합니다.

1ad41143eb9d95df.png

7. 새 버전 점진적 출시

다음과 같은 시나리오를 가정해 보겠습니다. 상담사의 프롬프트를 다음과 같이 업데이트하려고 합니다.

# agent.py

...

root_agent = Agent(
    name="weather_agent",
    model="gemini-2.5-flash-preview-05-20",
    instruction="You are a helpful AI assistant designed to provide accurate and useful information. You only answer inquiries about the weather. Refuse all other user query",
    tools=[get_weather],
)

그런 다음 새 버전을 출시하고 싶지만 모든 요청 트래픽이 새 버전으로 직접 이동하지 않도록 하려면 어떻게 해야 하나요? Cloud Run을 사용하여 점진적으로 출시할 수 있습니다. 먼저 –no-traffic 플래그를 사용하여 새 버전을 배포해야 합니다. 이전 에이전트 스크립트를 저장하고 다음 명령어를 실행합니다.

gcloud run deploy weather-agent \
                  --source . \
                  --port 8080 \
                  --project {YOUR_PROJECT_ID} \
                  --allow-unauthenticated \
                  --region us-central1 \
                  --no-traffic

완료되면 이전 배포 프로세스와 유사한 로그가 표시되며, 전송된 트래픽 수가 다릅니다. 게재된 트래픽이 0%로 표시됩니다.

다음으로 Cloud Run 제품 페이지로 이동하여 배포된 인스턴스를 찾습니다. 검색창에 cloud run을 입력하고 Cloud Run 제품을 클릭합니다.

f5cc953cc422de6d.png

그런 다음 weather-agent 서비스를 찾아 클릭합니다.

ddd0df8544aa2bfb.png

버전 탭으로 이동하면 배포된 버전 목록이 표시됩니다.

8519c5a59bc7efa6.png

새로 배포된 버전이 0% 게재되고 있는 것을 확인할 수 있습니다. 여기에서 케밥 버튼 (⋮)을 클릭하고 트래픽 관리를 선택합니다.

d4d224e20813c303.png

새로 팝업된 창에서 어떤 버전으로 트래픽이 전송될지 비율을 수정할 수 있습니다.

6df497c3d5847f14.png

잠시 기다리면 백분율 구성에 따라 트래픽이 비례적으로 전달됩니다. 이렇게 하면 새 버전에서 문제가 발생할 경우 이전 버전으로 쉽게 롤백할 수 있습니다.

8. ADK 추적

ADK로 빌드된 에이전트는 이미 에이전트에 삽입된 오픈 테레메트리를 사용하여 추적을 지원합니다. Cloud Trace를 사용하여 이러한 추적을 캡처하고 시각화할 수 있습니다. 이전에 배포된 서비스에서 이를 사용 설정하는 방법을 알아보려면 server.py를 살펴보겠습니다.

# server.py

from tracing import CloudTraceLoggingSpanExporter
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider, export

...

provider = TracerProvider()
processor = export.BatchSpanProcessor(CloudTraceLoggingSpanExporter())
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)

...

여기서 추적기와 내보내기 도구를 초기화합니다. 내보내기 도구의 세부정보는 tracing.py에서 검사할 수 있습니다 . 여기서는 클라우드 트레이스로 내보낼 수 있는 트레이스 데이터에 한도가 있으므로 맞춤 내보내기 도구를 만듭니다. 이 추적 기능에는 https://googlecloudplatform.github.io/agent-starter-pack/guide/observability.html의 구현을 사용합니다.

서비스 웹 개발자 UI에 액세스하고 상담사와 채팅해 보세요. 그런 다음 Cloud 콘솔 검색창으로 이동하여 'trace explorer'를 입력하고 Trace Explorer 제품을 선택합니다.

4353c0f8982361ab.png

트레이스 탐색기 페이지에 에이전트와의 대화 트레이스가 제출된 것을 확인할 수 있습니다. 스팬 이름 섹션에서 확인하고 Google 에이전트와 관련된 스팬 ( 이름이 agent_run [weather_agent]임)을 필터링할 수 있습니다.

c4336d117a3d2f6a.png

스팬이 이미 필터링된 경우 각 트레이스를 직접 검사할 수도 있습니다. 상담사가 취한 각 작업에 대한 세부적인 소요 시간이 표시됩니다. 예를 들어 아래 이미지를 참고하세요.

76a56dff77979037.png

1a3ce0a803d6061a.png

각 섹션에서 아래와 같이 속성의 세부정보를 검사할 수 있습니다.

2c87b6d67b0164a8.png

이제 문제를 디버그하는 데 도움이 되는 상담사와 사용자 간의 각 상호작용에 관한 관찰 가능성과 정보를 얻었습니다. 다양한 도구나 워크플로를 자유롭게 사용해 보세요.

9. 도전과제

멀티 에이전트 또는 에이전트 워크플로를 사용해 부하가 있을 때의 실적과 트레이스의 모양을 확인합니다.

10. 삭제

이 Codelab에서 사용한 리소스의 비용이 Google Cloud 계정에 청구되지 않도록 하려면 다음 단계를 따르세요.

  1. Google Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.
  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력하고 종료를 클릭하여 프로젝트를 삭제합니다.
  4. 또는 콘솔에서 Cloud Run으로 이동하여 방금 배포한 서비스를 선택하고 삭제할 수도 있습니다.