13 KiB
13 KiB
第02章:快速开始 — Hello World
📌 本章目标
- 使用
adk create创建第一个 Agent 项目 - 理解 Agent 项目结构
- 编写一个带有自定义工具的 Agent
- 通过 CLI 和 Web UI 两种方式运行 Agent
2.1 创建 Agent 项目
2.1.1 使用 CLI 创建项目
# 在工作目录下创建一个新的 Agent 项目
adk create hello_world
# 创建完成后,会生成以下目录结构:
# hello_world/
# ├── agent.py # Agent 主代码文件(核心)
# ├── .env # 环境变量配置文件(API Key 等)
# └── __init__.py # Python 包初始化文件
2.1.2 项目结构说明
hello_world/
│
├── agent.py # 🔑 核心文件:定义 Agent 的行为和工具
│ # - root_agent 变量是 ADK 的入口点
│ # - 可以定义自定义工具函数
│
├── .env # 🔑 配置文件:存储 API Key 等敏感信息
│ # - GOOGLE_API_KEY="your_key_here"
│ # - 不会被提交到版本控制
│
└── __init__.py # Python 包标识文件
# - 使目录成为 Python 包
# - 通常为空文件
⚠️ 重要:
agent.py中的root_agent是 ADK 识别 Agent 的入口点,这个变量名不能修改。
2.2 编写第一个 Agent
2.2.1 最简单的 Agent
打开 agent.py,编写最基础的 Agent:
"""
第一个 Google ADK Agent 示例
这是一个最简单的 Agent,不包含任何自定义工具
"""
# 从 ADK 的 agents 模块导入 Agent 类
# Agent 是 LlmAgent 的别名,是最常用的智能体类型
from google.adk.agents import Agent
# 定义 root_agent —— 这是 ADK 的入口点
# ADK 会自动查找名为 root_agent 的变量
root_agent = Agent(
name="hello_agent", # Agent 的名称,用于标识和日志
model="gemini-2.0-flash", # 使用的 LLM 模型
instruction="你是一个友好的助手。", # 系统指令,定义 Agent 的角色和行为
)
2.2.2 带工具的 Agent
让我们给 Agent 添加一个获取当前时间的工具:
"""
带自定义工具的 Hello World Agent
演示如何为 Agent 添加自定义函数工具
"""
# 导入 ADK 的 Agent 类
from google.adk.agents import Agent
# 导入标准库:日期时间处理
import datetime # 用于获取当前时间
from zoneinfo import ZoneInfo # 用于处理时区信息
# ========================================
# 定义自定义工具函数
# ========================================
def get_current_time(city: str) -> dict:
"""
获取指定城市的当前时间
这个函数会被 ADK 自动转换为工具(FunctionTool),
Agent 可以在对话中调用这个工具来获取时间信息。
Args:
city (str): 需要查询时间的城市名称,例如"北京"、"东京"、"纽约"
Returns:
dict: 包含状态和结果的字典
- status: "success" 或 "error"
- report: 时间信息或错误消息
"""
# 定义城市到时区的映射字典
city_timezone_map = { # 常见城市对应的时区
"北京": "Asia/Shanghai", # 北京使用上海时区
"上海": "Asia/Shanghai", # 上海使用上海时区
"东京": "Asia/Tokyo", # 东京时区
"纽约": "America/New_York", # 纽约时区
"伦敦": "Europe/London", # 伦敦时区
"巴黎": "Europe/Paris", # 巴黎时区
}
# 查找城市对应的时区标识符
tz_identifier = city_timezone_map.get(city) # 从字典中获取时区
# 如果找不到该城市的时区信息
if not tz_identifier:
return { # 返回错误信息
"status": "error", # 状态标记为错误
"error_message": f"未找到'{city}'的时区信息,请尝试其他城市。" # 错误描述
}
# 根据时区标识符创建时区对象
tz = ZoneInfo(tz_identifier) # 创建 ZoneInfo 时区对象
# 获取该时区的当前时间
now = datetime.datetime.now(tz) # 获取指定时区的当前时间
# 格式化时间字符串
time_str = now.strftime( # 将时间格式化为字符串
"%Y-%m-%d %H:%M:%S %Z%z" # 格式:年-月-日 时:分:秒 时区
)
# 返回成功结果
return { # 返回包含时间信息的字典
"status": "success", # 状态标记为成功
"city": city, # 城市名称
"time": time_str # 格式化后的时间字符串
}
# ========================================
# 定义 Agent
# ========================================
root_agent = Agent(
name="hello_agent", # Agent 的唯一标识名称
model="gemini-2.0-flash", # 使用 Gemini 2.0 Flash 模型
description="一个能查询城市时间的友好助手。", # Agent 的描述,用于多 Agent 场景
instruction=( # 系统指令(多行字符串)
"你是一个友好的助手,可以帮助用户查询世界各城市的当前时间。\n"
"当用户询问某个城市的时间时,使用 get_current_time 工具来获取。\n"
"如果工具返回错误,请友好地告知用户并建议尝试其他城市。\n"
"回复时请使用中文。"
),
tools=[get_current_time], # 将自定义函数注册为 Agent 的工具
)
2.3 配置 API Key
在运行 Agent 之前,需要配置 API Key:
# 方法一:在 .env 文件中配置(推荐)
echo 'GOOGLE_API_KEY="你的_GEMINI_API_KEY"' > hello_world/.env
# 方法二:通过环境变量设置
export GOOGLE_API_KEY="你的_GEMINI_API_KEY"
# 方法三:直接在代码中设置(不推荐,有安全风险)
💡 获取 API Key:访问 Google AI Studio,点击 "Create API Key" 即可免费获取。
2.4 运行 Agent
2.4.1 命令行交互模式(CLI)
# 在项目父目录下运行(不是在 hello_world 目录内)
adk run hello_world
# 运行后进入交互式对话界面:
# Running agent hello_agent, type exit to exit.
# [user]: 北京现在几点?
# [hello_agent]: 北京当前时间是 2025-04-05 14:30:00 CST+0800。
# [user]: exit
2.4.2 Web UI 模式
# 启动 Web 服务器(默认端口 8000)
adk web --port 8000
# 浏览器打开 http://localhost:8000
# 在左上角选择 Agent,然后输入问题进行对话
Web UI 提供以下功能:
- 💬 对话界面:与 Agent 进行交互式对话
- 📊 Event 面板:查看工具调用和事件流
- 📋 Request/Response:查看原始请求和响应数据
- 🔍 调试信息:帮助排查问题
2.4.3 代码方式运行
除了 CLI 和 Web UI,还可以通过 Python 代码直接运行 Agent:
"""
通过 Python 代码直接运行 Agent
适用于集成到自己的应用中
"""
# 导入必要的模块
from google.adk.agents import Agent # Agent 类
from google.adk.runners import Runner # 运行器,负责执行 Agent
from google.adk.sessions import InMemorySessionService # 内存会话服务
from google.genai import types # Google GenAI 类型定义
# 导入异步运行支持
import asyncio # 异步编程库
# ========================================
# 定义工具函数
# ========================================
def get_current_time(city: str) -> dict:
"""获取指定城市的当前时间"""
import datetime # 导入日期时间模块
from zoneinfo import ZoneInfo # 导入时区模块
city_timezone_map = { # 城市时区映射
"北京": "Asia/Shanghai",
"上海": "Asia/Shanghai",
"东京": "Asia/Tokyo",
"纽约": "America/New_York",
"伦敦": "Europe/London",
}
tz_identifier = city_timezone_map.get(city) # 查找时区
if not tz_identifier: # 如果找不到时区
return { # 返回错误
"status": "error",
"error_message": f"未找到'{city}'的时区信息"
}
tz = ZoneInfo(tz_identifier) # 创建时区对象
now = datetime.datetime.now(tz) # 获取当前时间
time_str = now.strftime("%Y-%m-%d %H:%M:%S %Z%z") # 格式化时间
return { # 返回结果
"status": "success",
"city": city,
"time": time_str
}
# ========================================
# 定义 Agent
# ========================================
root_agent = Agent(
name="hello_agent", # Agent 名称
model="gemini-2.0-flash", # 使用 Gemini 模型
instruction="你是一个友好的时间查询助手。使用工具获取城市时间。", # 系统指令
tools=[get_current_time], # 注册工具
)
# ========================================
# 定义运行逻辑
# ========================================
# 定义应用名称、用户ID和会话ID
APP_NAME = "hello_world_app" # 应用名称,用于标识
USER_ID = "user_001" # 用户唯一标识
SESSION_ID = "session_001" # 会话唯一标识
async def main():
"""主函数:异步运行 Agent"""
# 第一步:创建会话服务
# InMemorySessionService 将会话数据存储在内存中
# 适用于开发和测试,数据在程序重启后会丢失
session_service = InMemorySessionService()
# 第二步:创建会话
# 会话(Session)代表一次对话交互
# 包含消息历史、状态数据等
session = await session_service.create_session(
app_name=APP_NAME, # 关联的应用名称
user_id=USER_ID, # 用户标识
session_id=SESSION_ID, # 会话标识
)
# 第三步:创建运行器
# Runner 是 ADK 的核心执行引擎
# 负责协调 Agent、会话服务和工具调用
runner = Runner(
agent=root_agent, # 要运行的 Agent
app_name=APP_NAME, # 应用名称
session_service=session_service, # 会话服务
)
# 第四步:构造用户消息
# Content 对象表示一条消息
# role='user' 表示这是用户发送的消息
content = types.Content(
role='user', # 消息角色:用户
parts=[types.Part(text='北京现在几点?')] # 消息内容
)
# 第五步:运行 Agent 并获取响应
# run_async 返回一个异步事件流
# 我们需要遍历所有事件来获取最终响应
events = runner.run_async(
user_id=USER_ID, # 用户标识
session_id=SESSION_ID, # 会话标识
new_message=content, # 用户消息
)
# 第六步:处理事件流
async for event in events: # 遍历所有事件
if event.is_final_response(): # 如果是最终响应事件
# 从事件中提取文本内容
final_response = event.content.parts[0].text
print(f"Agent 回复: {final_response}") # 打印 Agent 的回复
# 运行主函数
if __name__ == "__main__": # 当脚本被直接运行时
asyncio.run(main()) # 使用 asyncio 运行异步主函数
2.5 理解 Agent 的核心参数
Agent 构造函数接受以下关键参数:
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
name |
str | ✅ | Agent 的唯一标识名称 |
model |
str | ✅ | 使用的 LLM 模型名称 |
instruction |
str | ❌ | 系统指令,定义 Agent 的角色和行为 |
description |
str | ❌ | Agent 描述,用于多 Agent 场景中的路由 |
tools |
list | ❌ | Agent 可用的工具列表 |
sub_agents |
list | ❌ | 子 Agent 列表,用于多 Agent 系统 |
output_key |
str | ❌ | 输出保存到 State 的键名 |
before_model_callback |
func | ❌ | 模型调用前的回调函数 |
after_model_callback |
func | ❌ | 模型调用后的回调函数 |
before_tool_callback |
func | ❌ | 工具调用前的回调函数 |
after_tool_callback |
func | ❌ | 工具调用后的回调函数 |
2.6 完整代码示例
详见 code/hello_world.py — 包含完整的带工具的 Hello World Agent 示例。
📌 本章小结
- 使用
adk create快速创建 Agent 项目 agent.py中的root_agent是 ADK 的入口点- 自定义工具就是普通的 Python 函数,ADK 会自动转换为 FunctionTool
- 三种运行方式:CLI(
adk run)、Web UI(adk web)、代码调用 - Runner 是 ADK 的核心执行引擎,负责协调 Agent 和会话
下一章:第03章 - LLM 智能体详解 → 深入了解 LlmAgent 的配置和高级用法。