Hem Cloud Run'da çalışan bir arka uç ADK aracısını çağıran bir Gradio ön uç uygulamasını dağıtma

1. Giriş

Genel Bakış

Bu codelab'de, ADK aracısını arka uç hizmeti olarak Cloud Run'a dağıtacak, ardından ADK aracısı için bir Gradio ön ucu ikinci bir Cloud Run hizmeti olarak dağıtacaksınız. Bu codelab'de, ADK aracısı hizmetinizde kimlik doğrulama gerektirme ve gradio ön uç hizmetinden kimliği doğrulanmış çağrılar yapma işlemleri gösterilmektedir.

Neler öğreneceksiniz?

  • Cloud Run'a ADK aracısı dağıtma
  • Cloud Run'a Gradio uygulaması dağıtma
  • Cloud Run'da hizmetten hizmete kimliği doğrulanmış çağrı yapma

2. API'leri etkinleştir

Öncelikle Google Cloud projenizi ayarlayın.

gcloud config set project <YOUR_PROJECT_ID>

Aşağıdaki komutu çalıştırarak Google Cloud projenizi onaylayabilirsiniz:

gcloud config get-value project

Bu codelab için aşağıdaki API'lerin etkinleştirilmesi gerekir:

gcloud services enable run.googleapis.com \
    compute.googleapis.com \
    run.googleapis.com \
    cloudbuild.googleapis.com \
    artifactregistry.googleapis.com \
    aiplatform.googleapis.com

3. Kurulum ve Gereksinimler

Bu bölümde, birkaç hizmet hesabı oluşturacak ve bunlara uygun IAM rollerini vereceksiniz. Her Cloud Run hizmetinin kendi hizmet hesabı olur.

Öncelikle, bu codelab boyunca kullanılacak ortam değişkenlerini ayarlayın.

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"

Ardından, ADK aracısı için hizmet hesabını oluşturun.

gcloud iam service-accounts create $SERVICE_ACCOUNT_ADK \
--display-name="Service account for adk agent on cloud run"

Ayrıca ADK hizmet hesabına "Vertex AI Kullanıcısı" rolünü verin.

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

Şimdi Gradio ön ucu için hizmet hesabını oluşturun.

gcloud iam service-accounts create $SERVICE_ACCOUNT_GRADIO \
  --display-name="Service account for gradio frontend cloud run"

Ayrıca Gradio ön ucuna Cloud Run çağırıcısı rolünü verin. Bu rol, ön ucun Cloud Run'da barındırılan ADK aracısını çağırmasına olanak tanır.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SERVICE_ACCOUNT_ADDRESS_GRADIO" \
  --role="roles/run.invoker"

4. ADK uygulaması oluşturma

Bir sonraki adımda, ADK hızlı başlangıç uygulaması için kodu oluşturacaksınız.

Not: Laboratuvarın sonunda dosya yapınız aşağıdaki gibi görünmelidir:

- 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

Öncelikle, genel codelab için bir dizin oluşturun.

mkdir codelab-gradio-adk
cd codelab-gradio-adk

Şimdi ADK aracısı hizmeti için bir dizin oluşturun.

mkdir multi_tool_agent && cd multi_tool_agent

Aşağıdaki içeriklerle bir __init__.py dosyası oluşturun:

from . import agent

requirements.txt dosyası oluşturma:

google-adk

agent.py adlı bir dosya oluşturun.

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 aracısını dağıtma

Bu bölümde, ADK aracısını Cloud Run'a dağıtacaksınız. Ardından, ADK tarafından sağlanan geliştirici web kullanıcı arayüzünü kullanarak dağıtımın çalıştığını doğrulayacaksınız. Son olarak, bu hizmete kimliği doğrulanmış çağrılar yapmanız gerekir.

Üst klasöre gidin.

NOT: ADK aracı kodu, kök klasör olarak multi_tool_agent klasörünü içermelidir.

cd ..

Öncelikle Cloud Run hizmetini oluşturun:

NOT: --with_ui, bir sonraki adımda gösterildiği gibi, geliştirici kullanıcı arayüzüyle test etmek için isteğe bağlıdır:

NOT: -- komutu, komut satırı işaretlerini temel alınan gcloud run deploy komutuna iletmenize olanak tanır.

NOT: uvx --from, google-adk paketinden bir komut yürütür. uvx, geçici bir sanal ortam oluşturur, google-adk'yı bu ortama yükler, belirtilen komutu çalıştırır ve ardından ortamı kapatır.

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

Ardından, URL'yi bu codelab'in ikinci bölümünde kullanacağınız bir ortam değişkeni olarak kaydedin.

AGENT_SERVICE_URL=$(gcloud run services describe adk-agent-cr --region $REGION --format 'value(status.url)')

Şimdi temsilciyi deneyin

Web tarayıcınızda hizmet URL'sini açın ve tell me about the weather in new york diye sorun. "New York'ta hava güneşli ve sıcaklık 25 santigrat derece (77 Fahrenheit) olacak." gibi bir yanıt görürsünüz.

Son olarak, aracının güvenliğini sağlayın.

Şimdi temsilciye erişimi güvenli hale getirelim. Sonraki bölümde, bu arka uç hizmetine kimliği doğrulanmış bir çağrı yapan bir Cloud Run hizmeti dağıtacaksınız.

gcloud run services remove-iam-policy-binding adk-agent-cr \
  --member="allUsers" \
  --role="roles/run.invoker" \
  --region=$REGION

6. Bir Gradio ön ucu dağıtma

Bu adımda, ADK temsilciniz için bir Gradio ön ucu oluşturacaksınız.

Not: Gradio uygulamasını ADK aracısıyla aynı hizmette kullanabilirsiniz. Bu codelab, Cloud Run'da hizmetten hizmete kimliği doğrulanmış çağrıların nasıl yapılacağını göstermek için 2 ayrı hizmet sunar.

Öncelikle multi_tool_agent klasörünün yanında bir uygulama oluşturun.

mkdir gradio-frontend && cd gradio-frontend

Ardından, aşağıdakileri içeren bir requirements.txt dosyası oluşturun:

gradio
requests
google-auth

Şimdi app.py dosyası oluşturun

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 uygulamanızı dağıtma ve test etme

Bu adımda, ön uç Gradio uygulamasını Cloud Run'a dağıtacaksınız.

gradiodaki uygulama dizininde olduğunuzdan emin olun.

pwd

codelab-gradio-adk/gradio-frontend ifadesini görmeniz gerekir.

Şimdi Gradio uygulamanızı dağıtın.

Not: Bu Gradio ön uç hizmeti herkese açık bir web sitesi olsa da arka uç hizmeti için kimlik doğrulama gerekir. Bunu neden yapmak isteyebileceğinizi göstermek için bu ön uç hizmetine kullanıcı kimlik doğrulaması (ör. Firebase Auth) ekleyebilir ve ardından yalnızca oturum açmış kullanıcıların arka uç hizmetine çağrı yapmasına izin verebilirsiniz.

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

Dağıtım tamamlandıktan sonra what's the weather in new york? sorusunu sorun. The weather in New York is sunny with a temperature of 25 degrees Celsius (77 degrees Fahrenheit). sorusuna benzer bir yanıt alırsınız.

8. Tebrikler!

Codelab'i tamamladığınız için tebrikler.

Yapay zeka uygulamalarını ve aracılarını barındırma ile ilgili dokümanları incelemenizi öneririz.

İşlediğimiz konular

  • Cloud Run'a ADK aracısı dağıtma
  • Cloud Run'a Gradio uygulaması dağıtma
  • Cloud Run'da hizmetten hizmete kimliği doğrulanmış çağrı yapma

9. Temizleme

Örneğin, Cloud Run hizmetlerinin ücretsiz katmandaki aylık Cloud Run çağırma tahsisinizden daha fazla sayıda çağrılması gibi yanlışlıkla ücretlendirmeleri önlemek için 6. adımda oluşturduğunuz Cloud Run hizmetini silebilirsiniz.

Cloud Run hizmetlerini silmek için https://console.cloud.google.com/run adresinden Cloud Run Cloud Console'a gidin ve my-adk-gradio-frontend ile adk-agent-cr hizmetlerini silin.

Projenin tamamını silmek için Kaynakları Yönet'e gidin, 2. adımda oluşturduğunuz projeyi seçin ve Sil'i tıklayın. Projeyi silerseniz Cloud SDK'nızda projeleri değiştirmeniz gerekir. gcloud projects list komutunu çalıştırarak kullanılabilir tüm projelerin listesini görüntüleyebilirsiniz.