1. 소개
개요
이 Codelab에서는 ADK 에이전트를 백엔드 서비스로 Cloud Run에 배포한 다음 ADK 에이전트의 gradio 프런트엔드를 두 번째 Cloud Run 서비스로 배포합니다. 이 Codelab에서는 ADK 에이전트 서비스에 인증을 요구하고 gradio 프런트엔드 서비스에서 인증된 호출을 만드는 방법을 보여줍니다.
학습할 내용
- ADK 에이전트를 Cloud Run에 배포하는 방법
- Cloud Run에 Gradio 앱을 배포하는 방법
- Cloud Run에서 인증된 서비스 간 호출을 수행하는 방법
2. API 사용 설정
먼저 Google Cloud 프로젝트를 설정합니다.
gcloud config set project <YOUR_PROJECT_ID>
다음 명령어를 실행하여 Google Cloud 프로젝트를 확인할 수 있습니다.
gcloud config get-value project
이 Codelab에서는 다음 API를 사용 설정해야 합니다.
gcloud services enable run.googleapis.com \
compute.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com
3. 설정 및 요구사항
이 섹션에서는 서비스 계정을 몇 개 만들고 적절한 IAM 역할을 부여합니다. 각 Cloud Run 서비스에는 자체 서비스 계정이 있습니다.
먼저 이 Codelab 전체에서 사용할 이 Codelab의 환경 변수를 설정합니다.
export PROJECT_ID=<YOUR_PROJECT_ID>
export REGION=<YOUR_REGION>
export SERVICE_ACCOUNT_ADK="adk-agent-cr"
export SERVICE_ACCOUNT_ADDRESS_ADK=$SERVICE_ACCOUNT_ADK@$PROJECT_ID.iam.gserviceaccount.com
export SERVICE_ACCOUNT_GRADIO="adk-agent-gradio"
export SERVICE_ACCOUNT_ADDRESS_GRADIO=$SERVICE_ACCOUNT_GRADIO@$PROJECT_ID.iam.gserviceaccount.com
export AGENT_APP_NAME="multi_tool_agent"
다음으로 ADK 에이전트의 서비스 계정을 만듭니다.
gcloud iam service-accounts create $SERVICE_ACCOUNT_ADK \
--display-name="Service account for adk agent on cloud run"
ADK 서비스 계정에 'Vertex AI 사용자' 역할을 부여합니다.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_ADDRESS_ADK" \
--role="roles/aiplatform.user"
이제 Gradio 프런트엔드의 서비스 계정을 만듭니다.
gcloud iam service-accounts create $SERVICE_ACCOUNT_GRADIO \
--display-name="Service account for gradio frontend cloud run"
또한 Gradio 프런트엔드에 Cloud Run 호출자 역할을 부여하여 Cloud Run에서 호스팅되는 ADK 에이전트를 호출할 수 있도록 합니다.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_ADDRESS_GRADIO" \
--role="roles/run.invoker"
4. ADK 앱 만들기
다음 단계에서는 ADK 빠른 시작 애플리케이션의 코드를 만듭니다.
참고: 실습이 끝나면 파일 구조는 다음과 같아야 합니다.
- codelab-gradio-adk <-- you'll deploy the ADK agent from here
- gradio-frontend
- app.py
- requirements.txt
- multi_tool_agent <-- you'll deploy the gradio app from here
- __init__.py
- agent.py
- requirements.txt
먼저 전체 Codelab의 디렉터리를 만듭니다.
mkdir codelab-gradio-adk
cd codelab-gradio-adk
이제 ADK 에이전트 서비스의 디렉터리를 만듭니다.
mkdir multi_tool_agent && cd multi_tool_agent
다음 콘텐츠로 __init__.py이라는 파일을 만듭니다.
from . import agent
requirements.txt 파일을 만듭니다.
google-adk
agent.py라는 파일을 만듭니다.
import datetime
from zoneinfo import ZoneInfo
from google.adk.agents import Agent
def get_weather(city: str) -> dict:
"""Retrieves the current weather report for a specified city.
Args:
city (str): The name of the city for which to retrieve the weather report.
Returns:
dict: status and result or error msg.
"""
if city.lower() == "new york":
return {
"status": "success",
"report": (
"The weather in New York is sunny with a temperature of 25 degrees"
" Celsius (77 degrees Fahrenheit)."
),
}
else:
return {
"status": "error",
"error_message": f"Weather information for '{city}' is not available.",
}
def get_current_time(city: str) -> dict:
"""Returns the current time in a specified city.
Args:
city (str): The name of the city for which to retrieve the current time.
Returns:
dict: status and result or error msg.
"""
if city.lower() == "new york":
tz_identifier = "America/New_York"
else:
return {
"status": "error",
"error_message": (
f"Sorry, I don't have timezone information for {city}."
),
}
tz = ZoneInfo(tz_identifier)
now = datetime.datetime.now(tz)
report = (
f'The current time in {city} is {now.strftime("%Y-%m-%d %H:%M:%S %Z%z")}'
)
return {"status": "success", "report": report}
root_agent = Agent(
name="weather_time_agent",
model="gemini-2.5-flash",
description=(
"Agent to answer questions about the time and weather in a city."
),
instruction=(
"You are a helpful agent who can answer user questions about the time and weather in a city."
),
tools=[get_weather, get_current_time],
)
5. ADK 에이전트 배포
이 섹션에서는 ADK 에이전트를 Cloud Run에 배포합니다. 그런 다음 ADK에서 제공하는 개발자 웹 UI를 사용하여 배포가 작동하는지 확인합니다. 마지막으로 이 서비스에 인증된 호출이 필요합니다.
상위 폴더로 이동합니다.
참고: ADK 에이전트 코드에는 multi_tool_agent 폴더가 루트 폴더로 포함되어야 합니다.
cd ..
먼저 Cloud Run 서비스를 만듭니다.
참고: --with_ui는 다음 단계에 표시된 대로 개발자 UI로 테스트하는 데 선택사항입니다.
참고: -- 명령어를 사용하면 명령줄 플래그를 기본 gcloud run deploy 명령어에 전달할 수 있습니다.
참고: uvx --from는 google-adk 패키지에서 명령어를 실행합니다. uvx는 임시 가상 환경을 만들고, 여기에 google-adk를 설치하고, 지정된 명령어를 실행한 다음 환경을 해체합니다.
uvx --from google-adk \
adk deploy cloud_run \
--project=$PROJECT_ID \
--region=$REGION \
--service_name=adk-agent-cr \
--with_ui \
./multi_tool_agent \
-- \
--service-account=$SERVICE_ACCOUNT_ADDRESS_ADK \
--allow-unauthenticated
그런 다음 이 Codelab의 두 번째 부분에서 사용할 URL을 환경 변수로 저장합니다.
AGENT_SERVICE_URL=$(gcloud run services describe adk-agent-cr --region $REGION --format 'value(status.url)')
이제 에이전트를 사용해 보세요.
웹브라우저에서 서비스 URL을 열고 tell me about the weather in new york라고 질문합니다. '뉴욕의 날씨는 맑고 기온은 섭씨 25도 (화씨 77도)입니다.'와 비슷한 응답이 표시됩니다.
마지막으로 에이전트 보안
이제 에이전트에 대한 액세스를 보호해 보겠습니다. 다음 섹션에서는 이 백엔드 서비스에 인증된 호출을 실행하는 Cloud Run 서비스를 배포합니다.
gcloud run services remove-iam-policy-binding adk-agent-cr \
--member="allUsers" \
--role="roles/run.invoker" \
--region=$REGION
6. Gradio 프런트엔드 배포
이 단계에서는 ADK 에이전트의 gradio 프런트엔드를 만듭니다.
참고: ADK 에이전트와 동일한 서비스에 gradio 앱을 둘 수 있습니다. 이 Codelab에서는 Cloud Run에서 인증된 서비스 간 호출을 수행하는 방법을 보여주는 2개의 별도 서비스를 제공합니다.
먼저 multi_tool_agent 폴더와 함께 앱을 만듭니다.
mkdir gradio-frontend && cd gradio-frontend
그런 다음 다음을 포함하는 requirements.txt 파일을 만듭니다.
gradio
requests
google-auth
이제 app.py 파일을 만듭니다.
import gradio as gr
import requests
import json
import uuid
import os
import google.auth.transport.requests
import google.oauth2.id_token
# https://weather-time-service2-392295011265.us-west4.run.app
BASE_URL = os.environ.get("AGENT_SERVICE_URL")
# multi_tool_agent
APP_NAME = os.environ.get("AGENT_APP_NAME")
# Generate a unique user ID for each session of the Gradio app
USER_ID = f"gradio-user-{uuid.uuid4()}"
# API Endpoints
CREATE_SESSION_URL = f"{BASE_URL}/apps/{APP_NAME}/users/{USER_ID}/sessions"
RUN_SSE_URL = f"{BASE_URL}/run_sse"
def get_id_token():
"""Get an ID token to authenticate with the other Cloud Run service."""
audience = BASE_URL
request = google.auth.transport.requests.Request()
id_token = google.oauth2.id_token.fetch_id_token(request, audience)
return id_token
def create_session() -> str | None:
"""Creates a new session and returns the session ID."""
try:
id_token = get_id_token()
headers = {"Authorization": f"Bearer {id_token}"}
response = requests.post(CREATE_SESSION_URL, headers=headers)
response.raise_for_status()
return response.json().get("id")
except Exception as e:
print(f"Error creating session: {e}")
return None
def query_agent(prompt: str):
"""Sends a prompt to the agent and returns the streamed response."""
session_id = create_session()
if not session_id:
return "Error: Could not create a session."
id_token = get_id_token()
headers = {
"Content-Type": "application/json",
"Accept": "text/event-stream",
"Authorization": f"Bearer {id_token}",
}
payload = {
"app_name": APP_NAME,
"user_id": USER_ID,
"session_id": session_id,
"new_message": {"role": "user", "parts": [{"text": prompt}]},
"streaming": True
}
full_response = ""
try:
with requests.post(RUN_SSE_URL, headers=headers, json=payload, stream=True) as response:
response.raise_for_status()
for chunk in response.iter_lines():
if chunk and chunk.decode('utf-8').startswith('data:'):
json_data = chunk.decode('utf-8')[len('data:'):].strip()
try:
data = json.loads(json_data)
text = data.get("content", {}).get("parts", [{}])[0].get("text", "")
if text:
full_response = text
except json.JSONDecodeError:
pass # Ignore chunks that are not valid JSON
return full_response
except requests.exceptions.RequestException as e:
return f"An error occurred: {e}"
iface = gr.Interface(
fn=query_agent,
inputs=gr.Textbox(lines=2, placeholder="e.g., What's the weather in new york?"),
outputs="text",
title="Weather and Time Agent",
description="Ask a question about the weather or time in a specific location.",
)
if __name__ == "__main__":
iface.launch()
7. Gradio 앱 배포 및 테스트
이 단계에서는 프런트엔드 Gradio 앱을 Cloud Run에 배포합니다.
현재 위치가 gradio 앱 디렉터리인지 확인합니다.
pwd
codelab-gradio-adk/gradio-frontend이 표시되어야 합니다.
이제 Gradio 앱을 배포합니다.
참고: 이 Gradio 프런트엔드 서비스는 공개적으로 제공되는 웹사이트이지만 백엔드 서비스에는 인증이 필요합니다. 이 작업을 수행하는 이유를 설명하기 위해 이 프런트엔드 서비스에 사용자 인증 (예: Firebase 인증)을 추가한 다음 로그인한 사용자만 백엔드 서비스를 호출하도록 허용할 수 있습니다.
gcloud run deploy my-adk-gradio-frontend \
--source . \
--region $REGION \
--allow-unauthenticated \
--set-env-vars AGENT_SERVICE_URL=$AGENT_SERVICE_URL,AGENT_APP_NAME=$AGENT_APP_NAME \
--service-account=$SERVICE_ACCOUNT_ADDRESS_GRADIO
배포 후 what's the weather in new york?에 질문하면 The weather in New York is sunny with a temperature of 25 degrees Celsius (77 degrees Fahrenheit).과 비슷한 대답을 얻을 수 있습니다.
8. 축하합니다.
축하합니다. Codelab을 완료했습니다.
AI 앱 및 에이전트 호스팅에 관한 문서를 검토하는 것이 좋습니다.
학습한 내용
- ADK 에이전트를 Cloud Run에 배포하는 방법
- Cloud Run에 Gradio 앱을 배포하는 방법
- Cloud Run에서 인증된 서비스 간 호출을 수행하는 방법
9. 삭제
예를 들어 Cloud Run 서비스가 무료 등급의 월별 Cloud Run 호출 할당량보다 더 많이 호출되는 경우와 같이 의도치 않은 요금이 청구되지 않도록 하려면 6단계에서 만든 Cloud Run 서비스를 삭제하면 됩니다.
Cloud Run 서비스를 삭제하려면 https://console.cloud.google.com/run에서 Cloud Run Cloud Console로 이동하여 my-adk-gradio-frontend 및 adk-agent-cr 서비스를 삭제합니다.
전체 프로젝트를 삭제하려면 리소스 관리로 이동하여 2단계에서 만든 프로젝트를 선택하고 삭제를 선택합니다. 프로젝트를 삭제하면 Cloud SDK에서 프로젝트를 변경해야 합니다. gcloud projects list를 실행하여 사용 가능한 모든 프로젝트의 목록을 볼 수 있습니다.