Google ADK 的安装与使用

我们首先安装必要的包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
uv venv # 创建一个虚拟环境
uv pip install google-adk # google-adk 主要依赖
uv pip install litellm # 如果想调用第三方的 LLM API,需要安装 LiteLLM 作为接口

# 创建一个名为 my_agent 的 agent,当前目录下会创建一个 my_agent 文件夹
adk create my_agent

# 运行这个 agent,终端会出现一个简易的对话
adk run my_agent

# 运行 Dev UI
adk web

# 运行 API Server
adk api_server

Multi-Tool Single Agent

创建完的文件夹结构如下:

1
2
3
4
my_agent
├── agent.py
├── .env
└── __init__.py

其中 agent.py 是 agent 的定义文件,包含一个 Agent Class,定义了这个 agent 可以使用的 tools 和这个 agent 所使用的模型.

首先我们定义一些 agent 可以使用的工具.

Tools Definition

注意!Tools 必须要写完整详细的 docstring,包括函数用途和参数意义,不然 LLM 可能读不懂.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import datetime
from zoneinfo import ZoneInfo


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}

然后我们定义 agent. 这里,我们使用 OpenRouter 作为第三方 API Provider,使用 meta-llama/llama-4-scout:free 模型,且这个 agent 可以使用我们刚刚定义的两个 tools

Agent Definition

注意,agent.py 的变量必须命名为 root_agent,这样才能让 Googlr ADK 自动查找到.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
import os


root_agent = Agent(
name="weather_time_agent",
model=LiteLlm(
model="openrouter/meta-llama/llama-4-scout:free",
api_key=os.getenv("OpenRouter_API"),
api_base=os.getenv("OpenRouter_URL"),
),
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],
)

这些参数分别是什么意思呢?

  • name 这个 agent 的专属编号
  • model 这个 agent 使用的模型
  • description 主要用于多 agent 协作。当其他 agent 希望转发任务时,会阅读 desciption 判断这个 agent 是不是负责这一部分的.
  • instruction 用于提示 LLM 其 behaviour, persona, goals 以及告诉他 how and when to utilize its assigned tools.

构建并运行

要让我们写的 Agent 真正运行起来,我们还需要两件东西:

  1. 我们需要让 Agent 有自己的一个 Session. 这个 Session 包含所有 Agent 运行时需要的信息(如聊天记录等等)
  2. 如果我们不是用 adk run 启动 Agent 的话,我们需要一个 Runner. 这个 Runner 就包含了自动调用 API 进行对话、自动进行 task delegation
Session

我们写一个 InMemorySession,当程序在运行时,数据会记录在内存里,当程序结束之后,这些在内存里的数据就丢弃了。

一个 Session 的构建需要 InMemorySessionService,再通过 create_session() API 进行建构。

1
2
3
4
5
6
7
8
9
10
USER_ID = "user_123"
SESSION_ID = "session_abc"
APP_NAME = "weather_agent_team_app"

session_service = InMemorySessionService()
session = await session_service.create_session(
app_name=APP_NAME,
user_id=USER_ID,
session_id=SESSION_ID,
)
Runner 对象与通过 Standalone File 运行

接下来来写 Runner. Runner 需要的信息包括 app_namesession_serviceagent.

1
2
3
4
5
runner_agent_team = Runner(
app_name=APP_NAME,
agent=weather_agent_team,
session_service=session_service,
)

OK, 所以接下来,我们就需要通过 Runner 对象提供的接口来与 Agent 进行交互、对话. 和 LangChain API 类似,我们需要先用特殊的数据结构 (types.Content) 包裹我们的问题,再发送给 Agent.

1
2
3
4
from google.genai import types

# 假设我们问的问题是 query
content = types.Content(role="user", parts=[types.Part(text=query)])

为了提升速度,我们接下来用 Runner.run_async() 方法处理 LLM Agent 的输出. Agent 通常有两种输出,一个种是 Final Answer,就是最终输出的答案;另一种类似于中间产物,比如说执行一个 tool、把任务转发到其他 agent 之类的。在 ADK 中,这两个种类都被打包成 Event class,并且可以用 .is_final_response() 判断消息是不是 Agent 最终输出的结果. Runner 生产一系列的 Event、然后异步执行直到得出 Final Response,完成一次 Agentic Run.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 由于方法是 async 的,所以我们得等到所有 events 执行完毕.
# 所以需要在 for 前加上 await 关键词
async for event in runner.run_async(
user_id=user_id,
session_id=session_id,
new_message=content,
):
# 输出所有中间产物,各种各样的 events
print(f" [Event]")
print(f"\tAuthor: {event.author}")
print(f"\tType: {type(event).__name__}")
print(f"\tFinal: {event.is_final_response()}")
print(f"\tContent: {event.content}")

# is_final_response() marks the concluding message for the turn.
if event.is_final_response():
if event.content and event.content.parts:
# Assuming text response in the first part
final_response_text = event.content.parts[0].text
elif (
event.actions and event.actions.escalate
): # Handle potential errors/escalations
final_response_text = (
f"Agent escalated: {event.error_message or 'No specific message.'}"
)
# Add more checks here if needed (e.g., specific error codes)
break # Stop processing events once the final response is found

print(f"<<< Agent Response: {final_response_text}")