Skip to content

Commit 399f3b7

Browse files
authored
ADK-vLLM code migration (#1792)
* Code migration Migrating code from the AI on GKE (tutorials-and-examples) repo -> https://github.com/ai-on-gke/tutorials-and-examples/tree/main/adk/llama/vllm * Add changes to Terraform * Adding licenses * Remove ToDo from oicenses
1 parent 69fb037 commit 399f3b7

File tree

17 files changed

+1176
-0
lines changed

17 files changed

+1176
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
name: ai-ml-adk-vertex
16+
on:
17+
push:
18+
branches:
19+
- main
20+
paths:
21+
- '.github/workflows/ai-ml-adk-vllm.yml'
22+
- 'ai-ml/adk-vllm/**'
23+
pull_request:
24+
paths:
25+
- '.github/workflows/ai-ml-adk-vllm.yml'
26+
- 'ai-ml/adk-vllm/**'
27+
jobs:
28+
job:
29+
runs-on: ubuntu-22.04
30+
steps:
31+
- uses: actions/checkout@v4
32+
- name: Build container image
33+
run: |
34+
cd ai-ml/adk-vllm/deploy-agent
35+
docker build --tag adk-vllm-weather-agent .
36+
- name: Validate Terraform config
37+
run: |
38+
cd ai-ml/adk-vllm/terraform
39+
terraform init
40+
terraform validate

ai-ml/adk-vllm/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Deploy an agentic AI application on GKE with the Agent Development Kit (ADK) and a self-hosted LLM
2+
3+
Deploy and manage containerized agentic AI/ML applications on GKE using the Google Agent Development Kit (ADK) and a self-hosted LLM like Llama 3.1 served by vLLM.
4+
5+
Visit https://cloud.google.com/kubernetes-engine/docs/tutorials/agentic-adk-vllm to follow the tutorial.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
FROM python:3.13-alpine
16+
WORKDIR /app
17+
18+
COPY requirements.txt .
19+
RUN pip install --no-cache-dir -r requirements.txt
20+
21+
RUN adduser --disabled-password --gecos "" myuser && \
22+
chown -R myuser:myuser /app
23+
24+
COPY --chown=myuser:myuser . .
25+
26+
USER myuser
27+
28+
ENV PATH="/home/myuser/.local/bin:$PATH"
29+
30+
CMD ["sh", "-c", "uvicorn main:app --host 0.0.0.0 --port $PORT"]
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
apiVersion: apps/v1
16+
kind: Deployment
17+
metadata:
18+
name: adk-agent
19+
spec:
20+
replicas: 1
21+
selector:
22+
matchLabels:
23+
app: adk-agent
24+
template:
25+
metadata:
26+
labels:
27+
app: adk-agent
28+
spec:
29+
containers:
30+
- name: adk-agent
31+
imagePullPolicy: Always
32+
image: us-central1-docker.pkg.dev/<PROJECT_ID>/adk-repo/adk-agent:latest
33+
resources:
34+
limits:
35+
memory: "2048Mi"
36+
cpu: "1000m"
37+
ephemeral-storage: "2048Mi"
38+
requests:
39+
memory: "2048Mi"
40+
cpu: "1000m"
41+
ephemeral-storage: "2048Mi"
42+
ports:
43+
- containerPort: 8080
44+
env:
45+
- name: PORT
46+
value: "8080"
47+
- name: LLM_BASE_URL
48+
value: http://vllm-llama3-service:8000/v1
49+
- name: MODEL_NAME
50+
value: hosted_vllm/meta-llama/Llama-3.1-8B-Instruct
51+
readinessProbe:
52+
httpGet:
53+
path: /dev-ui/
54+
port: 8080
55+
initialDelaySeconds: 30
56+
periodSeconds: 10
57+
timeoutSeconds: 5
58+
failureThreshold: 5
59+
successThreshold: 1
60+
---
61+
apiVersion: v1
62+
kind: Service
63+
metadata:
64+
name: adk-agent
65+
spec:
66+
type: NodePort
67+
ports:
68+
- port: 80
69+
targetPort: 8080
70+
selector:
71+
app: adk-agent
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
17+
import uvicorn
18+
from fastapi import FastAPI
19+
from google.adk.cli.fast_api import get_fast_api_app
20+
21+
# Get the directory where main.py is located
22+
AGENT_DIR = os.path.dirname(os.path.abspath(__file__))
23+
# Example session DB URL (e.g., SQLite)
24+
SESSION_DB_URL = ""
25+
# Example allowed origins for CORS
26+
ALLOWED_ORIGINS = ["http://localhost", "http://localhost:8080", "*"]
27+
# Set web=True if you intend to serve a web interface, False otherwise
28+
SERVE_WEB_INTERFACE = True
29+
30+
# Call the function to get the FastAPI app instance
31+
# Ensure the agent directory name ('capital_agent') matches your agent folder
32+
app: FastAPI = get_fast_api_app(
33+
agents_dir=AGENT_DIR,
34+
session_db_url=SESSION_DB_URL,
35+
allow_origins=ALLOWED_ORIGINS,
36+
web=SERVE_WEB_INTERFACE,
37+
)
38+
39+
# You can add more FastAPI routes or configurations below if needed
40+
# Example:
41+
# @app.get("/hello")
42+
# async def read_root():
43+
# return {"Hello": "World"}
44+
45+
if __name__ == "__main__":
46+
# Use the PORT environment variable provided by Cloud Run, defaulting to 8080
47+
uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
google_adk==1.2.1
16+
fastapi==0.115.0
17+
litellm==1.68.0
18+
uvicorn==0.34.0
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from . import agent
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Full example code for the basic weather agent
16+
# --- Full example code demonstrating LlmAgent with Tools ---
17+
import os
18+
19+
from google.adk.agents import LlmAgent
20+
from google.adk.runners import Runner
21+
from google.adk.sessions import InMemorySessionService
22+
from google.adk.models.lite_llm import LiteLlm
23+
from google.genai import types
24+
from litellm.rerank_api.main import httpx
25+
from pydantic import BaseModel, Field
26+
27+
# --- 1. Define Schemas ---
28+
29+
# Input schema used by both agents
30+
class CityInput(BaseModel):
31+
city: str = Field(description="The city to get information about.")
32+
33+
# --- 2. Define the Tool (Only for the first agent) ---
34+
def get_weather(city: str) -> str:
35+
"""Retrieves the weather condition of a given city."""
36+
print(f"\n-- Tool Call: get_weather(city='{city}') --")
37+
city_weather = {
38+
"paris": "The weather in Paris is sunny with a temperature of 25 degrees Celsius (77 degrees Fahrenheit).",
39+
"ottawa": "In Ottawa, it's currently cloudy with a temperature of 18 degrees Celsius (64 degrees Fahrenheit) and a chance of rain.",
40+
"tokyo": "Tokyo sees humid conditions with a high of 28 degrees Celsius (82 degrees Fahrenheit) and possible rainfall."
41+
}
42+
result = city_weather.get(city.strip().lower(), f"Sorry, I don't have weather information in {city}.")
43+
print(f"-- Tool Result: '{result}' --")
44+
return result
45+
46+
# --- 3. Configure Agent ---
47+
# Connect to the deployed model by using LiteLlm
48+
api_base_url = os.getenv("LLM_BASE_URL", "http://vllm-llama3-service:8000/v1")
49+
model_name_at_endpoint = os.getenv("MODEL_NAME", "hosted_vllm/meta-llama/Llama-3.1-8B-Instruct")
50+
model = LiteLlm(
51+
model=model_name_at_endpoint,
52+
api_base=api_base_url,
53+
)
54+
55+
# Uses a tool and output_key
56+
weather_agent = LlmAgent(
57+
model=model,
58+
name="weather_agent_tool",
59+
description="Retrieves weather in a city using a specific tool.",
60+
instruction="""You are a helpful agent that provides weather report in a city using a tool.
61+
The user will provide a city name in a JSON format like {"city": "city_name"}.
62+
1. Extract the city name.
63+
2. Use the `get_weather` tool to find the weather. Don't use other tools!
64+
3. Answer on user request based on the weather
65+
""",
66+
tools=[get_weather],
67+
input_schema=CityInput,
68+
output_key="city_weather_tool_result", # Store final text response
69+
)
70+
71+
root_agent = weather_agent
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.

0 commit comments

Comments
 (0)