上一篇我們已經介紹了工具型與子代理型 Agent 的定義、差異以及子代理型寫法為什麼更好 等了,那這篇就來實際做做看吧。不過這一篇篇幅會比較長,我會先放上程式碼再逐步解析其中的重點。
工具型 Agent 是把函數綁到 tools
參數上來提供功能。下面是示範如何定義一個處理數學與文字的代理:把函式寫好後直接放到 tools
裡,讓 root agent 根據輸入選擇要用哪個工具(以 Day 13 為例):
root_agent = Agent(
name="math_text_agent",
model="gemini-2.0-flash",
description=prompt.ROOT_AGENT_DESCRIPTION,
instruction=prompt.ROOT_AGENT_INSTRUCTION,
tools=[add_numbers, reverse_text],
)
程式碼解析:
add_numbers
和 reverse_text
是兩個獨立的 Python 函數,分別封裝加法與文字反轉功能,並符合 ADK 的工具規範(明確輸入/輸出型別)。name
:代理名稱,用來識別。model
:指定的語言模型(例如 gemini-2.0-flash
)。description
、instruction
:從外部 prompt
引入,用來定義代理的行為與任務範圍。tools
:綁定工具函數清單,代理會根據使用者輸入挑選適合的工具。'hello'
反轉時,代理會呼叫 reverse_text
;若輸入「2 加 3」,則會選擇 add_numbers
。優點:
限制:
子代理是把多個獨立 Agent 綁到主代理的 sub_agents
,達成多代理協作。下面示範一個有兩個子代理(問候與天氣)的結構。
__init__.py
from .RootAgent import root_agent
HelloAgent.py
將 Day 06 的問候 API 改為工具函式,讓 sub agent 可呼叫:
from fastapi import FastAPI, HTTPException
from google.adk.agents import Agent
from . import prompt
# 將 API 改為函式
def greet_user(request: dict) -> dict:
"""
呼叫問候 Agent,根據提供的名字回傳客製化問候語。
"""
try:
# 從 request dict 取出名字
user_name = request.get("name", "")
# 生成問候語
greeting_message = generate_greeting(user_name)
# 回傳結果
return {"greeting": greeting_message}
except Exception as e:
raise HTTPException(status_code=500, detail=f"An error occurred: {e}")
def generate_greeting(name: str) -> str:
"""
根據輸入的名字生成一個問候語。
"""
if not name:
return "Hello there! What's your name?"
else:
return f"Hello, {name}! Nice to meet you."
hello_agent = Agent(
name="hello_agent",
model="gemini-2.5-flash",
description=prompt.HELLO_AGENT_DESCRIPTION,
instruction=prompt.HELLO_AGENT_INSTRUCTION,
tools=[greet_user],
)
WeatherAgent.py
把 Day 07 的天氣 API 改為工具函式,供 sub agent 使用:
import datetime
from zoneinfo import ZoneInfo
from google.adk.agents import Agent
import httpx
import os
from dotenv import load_dotenv
from . import prompt
load_dotenv()
# 將 API 改為函式
def get_weather(city: str) -> dict:
"""從中央氣象局 API 獲取指定城市的 36 小時天氣資訊(同步)"""
try:
url = "https://opendata.cwa.gov.tw/api/v1/rest/datastore/F-C0032-001"
params = {
"Authorization": os.getenv("CWA_API_KEY"),
"locationName": city,
"format": "JSON"
}
with httpx.Client() as client:
response = client.get(url, params=params)
response.raise_for_status()
data = response.json()
locations = data["records"]["location"]
for loc in locations:
if loc["locationName"] == city:
wx = _get_first_param(loc, "Wx")
pop = _get_first_param(loc, "PoP")
min_t = _get_first_param(loc, "MinT")
max_t = _get_first_param(loc, "MaxT")
ci = _get_first_param(loc, "CI")
return {
"status": "success",
"report": (
f"{city} 天氣預報:{wx},降雨機率 {pop}%,"
f"氣溫 {min_t}°C ~ {max_t}°C,體感 {ci}。"
)
}
return {"status": "error", "error_message": f"找不到 {city} 的天氣資料"}
except Exception as e:
return {"status": "error", "error_message": str(e)}
def _get_first_param(location: dict, element_name: str) -> str:
"""從 weatherElement 擷取指定 element 的第一筆資料"""
for element in location["weatherElement"]:
if element["elementName"] == element_name:
return element["time"][0]["parameter"]["parameterName"]
return "無資料"
weather_agent = Agent(
name="weather_agent",
model="gemini-2.5-flash",
description=prompt.WEATHER_AGENT_DESCRIPTION,
instruction=prompt.WEATHER_AGENT_INSTRUCTION,
tools=[get_weather],
)
RootAgent.py
把兩個子代理加入 sub_agents
:
from google.adk.agents import Agent
import os
from dotenv import load_dotenv
from .HelloAgent import hello_agent
from .WeatherAgent import weather_agent
from . import prompt
load_dotenv()
root_agent = Agent(
name="root_agent",
model="gemini-2.5-flash",
description=prompt.ROOT_AGENT_DESCRIPTION,
instruction=prompt.ROOT_AGENT_INSTRUCTION,
sub_agents=[
hello_agent,
weather_agent
],
)
prompt.py
為每個 Agent 撰寫對應的 prompt:
ROOT_AGENT_DESCRIPTION = """
This is a coordination agent (root agent) capable of handling greetings ("hello world") and weather queries. It delegates user requests to the appropriate sub-agents.
"""
ROOT_AGENT_INSTRUCTION = """
You are a root agent responsible for coordinating different sub-agents, handling user greetings and weather-related questions. You can use the following sub-agents:
1. **Hello Agent**: Handles greetings and casual conversation, and can provide personalized greetings based on the user's name.
2. **Weather Agent**: Handles weather queries related to specific cities or locations.
Your responsibilities:
- Analyze user input and determine which sub-agent should handle it.
- If the input is a greeting, casual chat, or small talk, delegate it to the Hello Agent.
- If the input is about weather, temperature, climate, or weather conditions, delegate it to the Weather Agent.
- If the input involves both categories, you may use both agents.
- Integrate the sub-agent outputs into a clear, friendly, and helpful response.
Dispatch guidelines:
- Weather-related keywords: weather, temperature, rain, sunny, cloudy, forecast, climate, hot, cold, etc.
- Greeting-related keywords: hello, hi, hey, good morning, how are you, etc.
- Understand the context and the user's actual intent to make the best dispatch decision.
Respond naturally and friendly, ensuring the user receives the most relevant and helpful information.
"""
WEATHER_AGENT_DESCRIPTION = """
Provides real-time weather information and conditions for specific cities or locations, delivering accurate and referenceable meteorological data.
"""
WEATHER_AGENT_INSTRUCTION = """
You are a weather query agent responsible for providing users with weather information for specified locations.
Your responsibilities:
- Retrieve the latest weather conditions based on the city or location provided by the user.
- Provide temperature, precipitation probability, weather description, and feels-like information.
- Respond in a clear and friendly format.
- Handle all weather-related queries concerning geographic locations.
Focus on weather-related questions and provide as complete information as possible, including current conditions, temperature range, precipitation probability, and any weather alerts.
"""
HELLO_AGENT_DESCRIPTION = """
Handles user greetings and opening remarks, generating personalized greetings when the user provides their name.
"""
HELLO_AGENT_INSTRUCTION = """
You are a greeting agent. Your task is to handle greetings and opening conversation, providing personalized responses if the user provides their name.
Your responsibilities:
- Respond to user greetings (e.g., hello, hi, hey, good morning, etc.).
- If the user provides their name, generate a personalized greeting including the name.
- If the user does not provide a name, respond with a generic greeting.
Maintain a friendly, natural, and relaxed tone.
"""
記得要在
.env
裡加入會使用到的 API Key,否則執行會失敗。
程式碼解析重點:
RootAgent.py
):透過 sub_agents
綁定 hello_agent
與 weather_agent
,由主代理負責任務分配(例如把「問候」派給 hello_agent,把「天氣」派給 weather_agent)。使用較高階模型(如 gemini-2.5-flash
)有助於任務協調與理解複雜指令。helloAgent.py
, weatherAgent.py
):每個子代理都是獨立的 Agent
實例,擁有自己的模型、指令、描述與工具,專注特定任務。優點:
限制: