This commit is contained in:
Nelson
2026-04-06 12:36:04 +08:00
commit 514723dbe7
23 changed files with 7529 additions and 0 deletions

View File

@@ -0,0 +1,293 @@
"""
Google ADK 高级主题完整示例
展示安全、自定义 Agent、多模型等高级功能
对应教程第10章 - 高级主题
"""
# 导入 ADK 核心模块
from google.adk.agents import ( # 导入所有 Agent 类型
Agent, # LLM Agent
LlmAgent, # LLM Agent完整名
BaseAgent, # 基础 Agent
)
from google.adk.events import Event, EventActions # 导入事件类型
from google.adk.agents.invocation_context import InvocationContext # 导入上下文
from google.adk.models.lite_llm import LiteLlm # LiteLLM 适配器
# 导入辅助模块
from typing import AsyncGenerator # 异步生成器
import re # 正则表达式
import random # 随机数
import asyncio # 异步编程
# ========================================
# 示例一:输入安全过滤
# ========================================
async def input_security_filter(cb_ctx, inv_ctx):
"""
输入安全过滤回调
检测注入攻击和敏感信息
Args:
cb_ctx: 回调上下文
inv_ctx: 调用上下文
"""
# 获取用户消息
events = inv_ctx.session.events # 获取会话事件
user_msgs = [ # 筛选用户消息
e for e in events
if hasattr(e, 'content') and e.content.role == 'user'
]
if not user_msgs: # 如果没有用户消息
return # 直接返回
text = user_msgs[-1].content.parts[0].text # 提取文本
# 检测注入攻击
injection_patterns = [ # 注入模式
r"忽略.*指令", # 中文注入
r"ignore.*instruction", # 英文注入
r"你现在是", # 角色切换
r"system\s*:", # 系统提示伪造
]
for pattern in injection_patterns: # 遍历模式
if re.search(pattern, text, re.IGNORECASE): # 如果匹配
print(f"[安全] ⚠️ 检测到可能的注入攻击") # 记录警告
break # 跳出循环
# 检测敏感信息
sensitive_patterns = [ # 敏感信息模式
r"\b\d{3}-\d{2}-\d{4}\b", # SSN
r"\b\d{16}\b", # 信用卡号
]
for pattern in sensitive_patterns: # 遍历模式
if re.search(pattern, text): # 如果匹配
print(f"[安全] ⚠️ 检测到可能的敏感信息") # 记录警告
break # 跳出循环
# 检查输入长度
if len(text) > 5000: # 如果过长
print(f"[安全] ⚠️ 输入过长: {len(text)} 字符") # 记录警告
# ========================================
# 示例二:自定义 Agent — 规则引擎
# ========================================
class RuleEngineAgent(BaseAgent):
"""
规则引擎 Agent
基于预定义规则处理请求,不使用 LLM
"""
def __init__(self, rules: dict, **kwargs):
"""
初始化规则引擎
Args:
rules: 规则字典 {匹配模式: 响应}
"""
super().__init__(**kwargs) # 调用父类初始化
self.rules = rules # 保存规则
async def _run_async_impl(
self,
ctx: InvocationContext, # 调用上下文
) -> AsyncGenerator[Event, None]: # 返回事件生成器
"""执行规则匹配"""
# 获取用户消息
events = ctx.session.events # 获取事件
user_events = [ # 筛选用户消息
e for e in events
if hasattr(e, 'content') and e.content.role == 'user'
]
if not user_events: # 如果没有消息
yield Event( # 生成提示
author=self.name,
content="请输入您的问题。",
)
return # 退出
text = user_events[-1].content.parts[0].text # 提取文本
# 匹配规则
for pattern, response in self.rules.items(): # 遍历规则
if pattern.lower() in text.lower(): # 如果匹配
yield Event( # 生成响应
author=self.name,
content=response,
)
return # 退出
# 没有匹配的规则
yield Event( # 生成默认响应
author=self.name,
content="抱歉,我无法处理您的请求。请尝试其他问题。",
)
# ========================================
# 示例三:自定义 Agent — 随机路由
# ========================================
class RandomRouter(BaseAgent):
"""
随机路由 Agent
随机选择一个子 Agent 处理请求
"""
async def _run_async_impl(
self,
ctx: InvocationContext, # 调用上下文
) -> AsyncGenerator[Event, None]: # 返回事件生成器
"""随机选择子 Agent"""
sub_agents = self.sub_agents # 获取子 Agent
if not sub_agents: # 如果没有子 Agent
yield Event( # 生成错误
author=self.name,
content="没有可用的子 Agent。",
)
return # 退出
chosen = random.choice(sub_agents) # 随机选择
print(f"[随机路由] 选择了 {chosen.name}") # 打印选择
yield Event( # 生成委派事件
author=self.name,
actions=EventActions(
transfer_to_agent=chosen.name, # 委派
),
)
# ========================================
# 示例四:多模型混合策略
# ========================================
# 简单任务:使用快速模型
simple_agent = LlmAgent(
name="SimpleAgent", # 简单任务 Agent
model="gemini-2.0-flash", # 快速模型
description="处理简单的问答和翻译。", # 描述
instruction="快速准确地回答简单问题。", # 指令
)
# 复杂推理:使用强力模型
reasoning_agent = LlmAgent(
name="ReasoningAgent", # 推理 Agent
model="gemini-2.5-pro-preview-05-06", # 强力模型
description="处理需要深度推理的复杂任务。", # 描述
instruction="仔细分析,给出深入的推理过程。", # 指令
)
# 代码生成:使用 DeepSeek
code_agent = LlmAgent(
name="CodeAgent", # 代码 Agent
model=LiteLlm( # 使用 LiteLLM
model="deepseek/deepseek-coder", # DeepSeek Coder
api_key="your_api_key", # API Key
),
description="处理代码生成和调试。", # 描述
instruction="编写高质量的代码。", # 指令
)
# 协调器:使用快速模型
multi_model_coordinator = LlmAgent(
name="MultiModelCoordinator", # 多模型协调器
model="gemini-2.0-flash", # 快速模型
instruction=( # 指令
"根据任务类型分配给合适的 Agent\n"
"- 简单问答 → SimpleAgent\n"
"- 复杂推理 → ReasoningAgent\n"
"- 代码相关 → CodeAgent"
),
sub_agents=[simple_agent, reasoning_agent, code_agent], # 子 Agent
)
# ========================================
# 示例五:完整实战 — 智能客服系统
# ========================================
def search_faq(query: str) -> dict:
"""搜索 FAQ"""
faq_db = { # FAQ 数据库
"退款": "退款将在3-5个工作日内处理完成。",
"配送": "标准配送3-5天加急配送1-2天。",
"退换货": "7天无理由退换货请保持商品完好。",
}
for key, value in faq_db.items(): # 遍历 FAQ
if key in query: # 如果匹配
return {"status": "success", "answer": value}
return {"status": "not_found"}
def create_ticket(category: str, description: str) -> dict:
"""创建工单"""
ticket_id = f"TK{hash(description) % 10000:04d}" # 生成工单号
return { # 返回结果
"status": "success",
"ticket_id": ticket_id,
"message": f"工单 {ticket_id} 已创建。",
}
# FAQ Agent
faq_agent = LlmAgent(
name="FAQBot", # FAQ 机器人
model="gemini-2.0-flash", # 模型
description="处理常见问题。", # 描述
instruction="使用 search_faq 工具查找答案。", # 指令
tools=[search_faq], # FAQ 工具
)
# 工单 Agent
ticket_agent = LlmAgent(
name="TicketBot", # 工单机器人
model="gemini-2.0-flash", # 模型
description="创建客户工单。", # 描述
instruction="使用 create_ticket 创建工单。", # 指令
tools=[create_ticket], # 工单工具
)
# 客服协调器
customer_service = LlmAgent(
name="CustomerService", # 客服系统
model="gemini-2.0-flash", # 模型
description="智能客服主协调器。", # 描述
instruction=( # 指令
"你是智能客服协调器。\n"
"常见问题 → FAQBot\n"
"无法解决 → TicketBot\n"
"使用 transfer_to_agent 委派任务。"
),
sub_agents=[faq_agent, ticket_agent], # 子 Agent
before_model_callback=input_security_filter, # 安全过滤
)
# ========================================
# 打印信息
# ========================================
if __name__ == "__main__":
print("=" * 60) # 分隔线
print("Google ADK 高级主题示例") # 标题
print("=" * 60) # 分隔线
print("\n🔒 安全过滤回调: input_security_filter") # 安全
print("🤖 自定义 Agent: RuleEngineAgent, RandomRouter") # 自定义
print("🔀 多模型策略: SimpleAgent + ReasoningAgent + CodeAgent") # 多模型
print("🏢 实战项目: 智能客服系统 (CustomerService)") # 实战
print("\n✅ 所有高级功能定义完成!") # 成功信息

View File

@@ -0,0 +1,255 @@
"""
Google ADK 回调机制完整示例
展示四种回调函数的使用方法
对应教程第07章 - 回调机制与事件系统
"""
# 导入 ADK 核心模块
from google.adk.agents import Agent # Agent 类
from google.adk.agents.invocation_context import InvocationContext # 调用上下文
from google.adk.runners import Runner # 运行器
from google.adk.sessions import InMemorySessionService # 会话服务
from google.genai import types # 类型定义
# 导入异步和时间模块
import asyncio # 异步编程库
import time # 时间模块
# ========================================
# 示例一:日志回调(记录所有操作)
# ========================================
async def log_before_model(cb_ctx, inv_ctx):
"""
模型调用前回调
Args:
cb_ctx: 回调上下文
inv_ctx: 调用上下文
"""
# 记录开始时间
inv_ctx.session.state["temp:model_start_time"] = time.time() # 保存时间戳
# 获取调用计数
count = inv_ctx.session.state.get("model_call_count", 0) # 读取计数
inv_ctx.session.state["model_call_count"] = count + 1 # 递增
print(f"🔍 [模型前] Agent '{inv_ctx.agent.name}' 即将调用 LLM (第{count+1}次)") # 打印日志
async def log_after_model(cb_ctx, inv_ctx):
"""
模型调用后回调
Args:
cb_ctx: 回调上下文
inv_ctx: 调用上下文
"""
# 计算耗时
start = inv_ctx.session.state.get("temp:model_start_time", time.time()) # 开始时间
elapsed = time.time() - start # 计算耗时
response = cb_ctx.response # 获取模型响应
if response and response.function_calls: # 如果有工具调用
tools = [fc.name for fc in response.function_calls] # 工具名列表
print(f"✅ [模型后] LLM 调用完成 ({elapsed:.2f}s),决定调用工具: {tools}") # 打印
else: # 如果直接响应
print(f"✅ [模型后] LLM 调用完成 ({elapsed:.2f}s),直接响应") # 打印
async def log_before_tool(cb_ctx, inv_ctx):
"""
工具调用前回调
Args:
cb_ctx: 回调上下文
inv_ctx: 调用上下文
"""
fc = cb_ctx.function_call # 获取函数调用
print(f"🔧 [工具前] 调用工具: {fc.name}({fc.args})") # 打印工具信息
async def log_after_tool(cb_ctx, inv_ctx):
"""
工具调用后回调
Args:
cb_ctx: 回调上下文
inv_ctx: 调用上下文
"""
fc = cb_ctx.function_call # 获取函数调用
result = cb_ctx.tool_result # 获取工具结果
status = "成功" # 默认成功
if result and result.get("status") == "error": # 如果错误
status = "失败" # 标记失败
print(f"📊 [工具后] {fc.name} 执行{status}") # 打印结果
# ========================================
# 示例二:人工确认回调
# ========================================
async def human_confirmation(cb_ctx, inv_ctx):
"""
人工确认回调
在敏感操作前暂停
Args:
cb_ctx: 回调上下文
inv_ctx: 调用上下文
"""
tool_name = cb_ctx.function_call.name # 获取工具名
tool_args = cb_ctx.function_call.args # 获取工具参数
# 定义敏感操作
sensitive_ops = { # 敏感操作映射
"delete_file": "删除文件", # 删除文件
"send_email": "发送邮件", # 发送邮件
"make_payment": "发起支付", # 发起支付
}
if tool_name in sensitive_ops: # 如果是敏感操作
op = sensitive_ops[tool_name] # 获取操作描述
print(f"\n⚠️ [人工确认] 需要人工确认!") # 打印警告
print(f" 操作: {op}") # 打印操作
print(f" 参数: {tool_args}") # 打印参数
print(f" 状态: 已记录(模拟自动通过)") # 模拟通过
# ========================================
# 示例三:参数验证回调
# ========================================
async def validate_params(cb_ctx, inv_ctx):
"""
参数验证回调
在工具调用前验证参数
Args:
cb_ctx: 回调上下文
inv_ctx: 调用上下文
"""
tool_name = cb_ctx.function_call.name # 工具名
tool_args = cb_ctx.function_call.args # 工具参数
# 验证搜索查询长度
if tool_name == "search": # 如果是搜索工具
query = tool_args.get("query", "") # 获取查询
if len(query) < 2: # 如果太短
print(f"⚠️ [验证] 搜索查询过短: '{query}'") # 打印警告
# 验证数值范围
if tool_name == "calculate": # 如果是计算工具
value = tool_args.get("value", 0) # 获取数值
if value < 0: # 如果为负数
print(f"⚠️ [验证] 数值不能为负: {value}") # 打印警告
# ========================================
# 定义工具函数
# ========================================
def get_weather(city: str) -> dict:
"""获取天气信息"""
weather_data = { # 天气数据
"北京": {"temp": "25°C", "condition": "晴天"},
"上海": {"temp": "28°C", "condition": "多云"},
}
data = weather_data.get(city) # 查找数据
if not data: # 如果找不到
return {"status": "error", "error_message": f"未找到'{city}'的天气信息"}
return {"status": "success", "city": city, **data} # 返回天气
def delete_file(filename: str) -> dict:
"""删除文件(模拟)"""
print(f"🗑️ 执行删除: {filename}") # 模拟删除
return {"status": "success", "message": f"文件 '{filename}' 已删除"}
# ========================================
# 创建带回调的 Agent
# ========================================
monitored_agent = Agent(
name="monitored_agent", # Agent 名称
model="gemini-2.0-flash", # 模型
instruction=( # 系统指令
"你是一个天气助手。\n"
"使用 get_weather 工具查询天气。\n"
"使用 delete_file 工具删除文件(需要确认)。"
),
tools=[get_weather, delete_file], # 注册工具
before_model_callback=log_before_model, # 模型前回调
after_model_callback=log_after_model, # 模型后回调
before_tool_callback=log_before_tool, # 工具前回调
after_tool_callback=log_after_tool, # 工具后回调
)
# ========================================
# 运行演示
# ========================================
APP_NAME = "callback_demo" # 应用名称
USER_ID = "user_001" # 用户 ID
SESSION_ID = "session_001" # 会话 ID
async def main():
"""主函数"""
print("=" * 60) # 分隔线
print("Google ADK 回调机制演示") # 标题
print("=" * 60) # 分隔线
# 初始化
session_service = InMemorySessionService() # 会话服务
await session_service.create_session( # 创建会话
app_name=APP_NAME, # 应用名称
user_id=USER_ID, # 用户 ID
session_id=SESSION_ID, # 会话 ID
)
# 创建 Runner
runner = Runner(
agent=monitored_agent, # Agent
app_name=APP_NAME, # 应用名称
session_service=session_service, # 会话服务
)
# 测试问题
queries = [ # 测试列表
"北京天气怎么样?", # 天气查询
]
for query in queries: # 遍历测试
print(f"\n{'='*60}") # 分隔线
print(f"[用户]: {query}") # 打印用户输入
# 构造消息
content = types.Content(
role='user', # 角色
parts=[types.Part(text=query)], # 内容
)
# 运行 Agent
events = runner.run_async(
user_id=USER_ID, # 用户 ID
session_id=SESSION_ID, # 会话 ID
new_message=content, # 消息
)
# 处理事件
async for event in events: # 遍历事件
if event.is_final_response(): # 最终响应
print(f"[Agent]: {event.content.parts[0].text}") # 打印回复
if __name__ == "__main__": # 直接运行
asyncio.run(main()) # 执行主函数

View File

@@ -0,0 +1,338 @@
"""
Google ADK 自定义工具开发完整示例
展示各种工具开发技巧和最佳实践
对应教程第04章 - 自定义工具开发
"""
# 导入 ADK 核心模块
from google.adk.agents import Agent # Agent 类
from google.adk.tools import AgentTool # AgentToolAgent 作为工具)
# 导入类型提示
from typing import Optional, List # 可选类型和列表类型
# 导入运行相关模块
from google.adk.runners import Runner # 运行器
from google.adk.sessions import InMemorySessionService # 会话服务
from google.genai import types # 类型定义
# 导入异步库
import asyncio # 异步编程库
# ========================================
# 示例一:基础函数工具
# ========================================
def get_weather(city: str) -> dict:
"""
获取指定城市的天气信息
Args:
city (str): 城市名称,例如"北京""上海"
Returns:
dict: 包含天气状态的字典
- status: "success""error"
- city: 城市名称
- temperature: 温度
- condition: 天气状况
"""
# 模拟天气数据
weather_data = { # 天气数据库
"北京": {"temp": "25°C", "condition": "晴天"}, # 北京
"上海": {"temp": "28°C", "condition": "多云"}, # 上海
"广州": {"temp": "32°C", "condition": "雷阵雨"}, # 广州
}
# 查找城市天气
data = weather_data.get(city) # 获取天气数据
if not data: # 如果找不到
return { # 返回错误
"status": "error",
"error_message": f"未找到'{city}'的天气信息"
}
return { # 返回成功结果
"status": "success",
"city": city,
"temperature": data["temp"],
"condition": data["condition"],
}
# ========================================
# 示例二:带可选参数的工具
# ========================================
def search_restaurant(
city: str, # 必选参数
cuisine: str = "中餐", # 可选参数,默认中餐
price_range: str = "中等", # 可选参数,默认中等
) -> dict:
"""
搜索指定城市的餐厅
Args:
city (str): 城市名称
cuisine (str, optional): 菜系类型,默认"中餐"
price_range (str, optional): 价格范围,默认"中等"
Returns:
dict: 搜索结果
"""
return { # 返回搜索结果
"status": "success",
"city": city,
"cuisine": cuisine,
"price_range": price_range,
"results": [ # 餐厅列表
{"name": "美味餐厅", "rating": 4.5, "price": "人均100元"},
{"name": "佳肴轩", "rating": 4.2, "price": "人均80元"},
],
}
# ========================================
# 示例三:使用 Optional 类型
# ========================================
def create_user_profile(
username: str, # 必选参数
bio: Optional[str] = None, # 可选参数
avatar_url: Optional[str] = None, # 可选参数
) -> dict:
"""
创建用户档案
Args:
username (str): 用户名
bio (str, optional): 个人简介
avatar_url (str, optional): 头像 URL
Returns:
dict: 创建结果
"""
profile = { # 创建档案
"username": username, # 用户名
"bio": bio or "这个人很懒,什么都没写。", # 简介
"avatar_url": avatar_url or "", # 头像
}
return { # 返回结果
"status": "success",
"profile": profile,
}
# ========================================
# 示例四List 类型参数
# ========================================
def compare_cities(cities: List[str]) -> dict:
"""
比较多个城市的信息
Args:
cities (List[str]): 城市名称列表
Returns:
dict: 比较结果
"""
city_info = { # 城市信息
"北京": {"population": "2189万", "area": "16410km²"},
"上海": {"population": "2487万", "area": "6341km²"},
"广州": {"population": "1881万", "area": "7434km²"},
}
results = [] # 结果列表
for city in cities: # 遍历城市
info = city_info.get(city) # 获取信息
if info: # 如果存在
results.append({"city": city, **info}) # 添加到结果
return { # 返回结果
"status": "success" if results else "error",
"results": results,
}
# ========================================
# 示例五:健壮的工具(完善的错误处理)
# ========================================
def calculate_loan(
principal: float, # 贷款本金
annual_rate: float, # 年利率
years: int, # 贷款年限
) -> dict:
"""
计算贷款月供和总利息
Args:
principal (float): 贷款本金(元)
annual_rate (float): 年利率(百分比,如 4.5
years (int): 贷款年限
Returns:
dict: 计算结果
"""
# 参数验证
if principal <= 0: # 本金必须大于0
return { # 返回错误
"status": "error",
"error_code": "INVALID_PRINCIPAL",
"error_message": "贷款本金必须大于0。"
}
if annual_rate <= 0 or annual_rate > 30: # 利率范围检查
return { # 返回错误
"status": "error",
"error_code": "INVALID_RATE",
"error_message": "年利率必须在 0-30% 之间。"
}
if years <= 0 or years > 30: # 年限范围检查
return { # 返回错误
"status": "error",
"error_code": "INVALID_YEARS",
"error_message": "贷款年限必须在 1-30 年之间。"
}
try: # 尝试计算
monthly_rate = annual_rate / 100 / 12 # 月利率
total_months = years * 12 # 总月数
# 等额本息月供公式
if monthly_rate == 0: # 如果利率为0
monthly_payment = principal / total_months # 直接除
else: # 正常计算
monthly_payment = ( # 月供计算
principal * monthly_rate * (1 + monthly_rate) ** total_months
/ ((1 + monthly_rate) ** total_months - 1)
)
total_amount = monthly_payment * total_months # 总还款额
total_interest = total_amount - principal # 总利息
return { # 返回计算结果
"status": "success",
"monthly_payment": round(monthly_payment, 2), # 月供
"total_interest": round(total_interest, 2), # 总利息
"total_amount": round(total_amount, 2), # 总还款额
}
except Exception as e: # 捕获计算异常
return { # 返回错误
"status": "error",
"error_code": "CALCULATION_ERROR",
"error_message": f"计算出错:{str(e)}"
}
# ========================================
# 示例六Agent-as-a-Tool
# ========================================
# 定义一个翻译 Agent
translator_agent = Agent(
name="translator", # 翻译 Agent
model="gemini-2.0-flash", # 模型
instruction="你是翻译专家,将文本翻译成目标语言。只输出翻译结果。", # 指令
)
# 将翻译 Agent 包装为工具
translation_tool = AgentTool(
agent=translator_agent, # 传入翻译 Agent
)
# ========================================
# 创建综合 Agent
# ========================================
comprehensive_agent = Agent(
name="comprehensive_agent", # Agent 名称
model="gemini-2.0-flash", # 模型
instruction=( # 系统指令
"你是一个多功能助手。\n"
"你可以:\n"
"1. 查询天气get_weather\n"
"2. 搜索餐厅search_restaurant\n"
"3. 创建用户档案create_user_profile\n"
"4. 比较城市compare_cities\n"
"5. 计算贷款calculate_loan\n"
"6. 翻译文本translation_tool\n"
"根据用户需求选择合适的工具。"
),
tools=[ # 注册所有工具
get_weather, # 天气查询
search_restaurant, # 餐厅搜索
create_user_profile, # 用户档案
compare_cities, # 城市比较
calculate_loan, # 贷款计算
translation_tool, # 翻译工具
],
)
# ========================================
# 运行示例
# ========================================
APP_NAME = "tools_demo" # 应用名称
USER_ID = "user_001" # 用户 ID
SESSION_ID = "session_001" # 会话 ID
async def main():
"""运行工具演示"""
# 创建会话服务
session_service = InMemorySessionService() # 会话服务
await session_service.create_session( # 创建会话
app_name=APP_NAME, # 应用名称
user_id=USER_ID, # 用户 ID
session_id=SESSION_ID, # 会话 ID
)
# 创建运行器
runner = Runner(
agent=comprehensive_agent, # Agent
app_name=APP_NAME, # 应用名称
session_service=session_service, # 会话服务
)
# 测试查询
queries = [ # 测试问题列表
"北京天气怎么样?", # 天气查询
"帮我搜索上海的意大利餐厅", # 餐厅搜索
"贷款100万利率4.5%30年月供多少", # 贷款计算
]
for query in queries: # 遍历测试问题
print(f"\n[用户]: {query}") # 打印用户输入
# 构造消息
content = types.Content(
role='user', # 角色
parts=[types.Part(text=query)], # 内容
)
# 运行 Agent
events = runner.run_async(
user_id=USER_ID, # 用户 ID
session_id=SESSION_ID, # 会话 ID
new_message=content, # 消息
)
# 获取响应
async for event in events: # 遍历事件
if event.is_final_response(): # 最终响应
print(f"[Agent]: {event.content.parts[0].text}") # 打印回复
if __name__ == "__main__": # 直接运行
asyncio.run(main()) # 执行主函数

View File

@@ -0,0 +1,201 @@
"""
Google ADK 部署配置完整示例
展示各种部署方式的配置
对应教程第09章 - 部署指南
"""
# 导入 ADK 核心模块
from google.adk.agents import Agent # Agent 类
from google.adk.tools import google_search # Google 搜索工具
# ========================================
# 定义 Agent部署入口
# ========================================
def get_weather(city: str) -> dict:
"""
获取天气信息
Args:
city (str): 城市名称
Returns:
dict: 天气信息
"""
weather_data = { # 天气数据
"北京": {"temp": "25°C", "condition": "晴天"},
"上海": {"temp": "28°C", "condition": "多云"},
}
data = weather_data.get(city) # 查找数据
if not data: # 如果找不到
return {"status": "error", "error_message": f"未找到'{city}'的天气信息"}
return {"status": "success", "city": city, **data} # 返回天气
# root_agent 是 ADK 的入口点
# 部署时 ADK 会自动查找这个变量
root_agent = Agent(
name="deploy_agent", # Agent 名称
model="gemini-2.0-flash", # 模型
description="部署演示 Agent。", # 描述
instruction=( # 系统指令
"你是一个多功能助手。\n"
"可以查询天气和搜索信息。\n"
"使用中文回答。"
),
tools=[get_weather, google_search], # 注册工具
)
# ========================================
# 以下为部署配置参考
# ========================================
# ----------------------------------------
# Dockerfile 内容(保存为 Dockerfile
# ----------------------------------------
"""
# 使用 Python 3.11 作为基础镜像
FROM python:3.11-slim
# 设置工作目录
WORKDIR /app
# 设置环境变量
ENV PYTHONUNBUFFERED=1
# 复制依赖文件
COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 复制 Agent 代码
COPY deploy_demo.py .
# 暴露端口
EXPOSE 8080
# 启动 API Server
CMD ["adk", "api_server", "--port", "8080", "--host", "0.0.0.0"]
"""
# ----------------------------------------
# requirements.txt 内容
# ----------------------------------------
"""
google-adk>=1.0.0
"""
# ----------------------------------------
# start.sh 启动脚本
# ----------------------------------------
"""
#!/bin/bash
# ADK Agent 启动脚本
# 从环境变量读取 API Key
export GOOGLE_API_KEY="${GOOGLE_API_KEY}"
# 启动 API Server
adk api_server \\
--port 8080 \\
--host 0.0.0.0
"""
# ----------------------------------------
# docker-compose.yml 内容
# ----------------------------------------
"""
version: '3.8'
services:
adk-agent:
build: .
ports:
- "8080:8080"
environment:
- GOOGLE_API_KEY=${GOOGLE_API_KEY}
restart: unless-stopped
"""
# ----------------------------------------
# 部署命令参考
# ----------------------------------------
"""
# 构建镜像
docker build -t my-adk-agent .
# 运行容器
docker run -d \\
--name my-agent \\
-p 8080:8080 \\
-e GOOGLE_API_KEY="your_api_key" \\
my-adk-agent
# 使用 adk deploy 部署到 Cloud Run
adk deploy . --platform cloud-run
# 使用 adk deploy 部署到 Vertex AI
adk deploy . --platform vertex-ai
"""
# ========================================
# API 调用示例
# ========================================
def api_call_example():
"""
调用 ADK API Server 的示例代码
需要先启动 API Server: adk api_server --port 8080
"""
import requests # HTTP 请求库
import json # JSON 处理
API_BASE = "http://localhost:8080" # API 地址
APP_NAME = "deploy_agent" # 应用名称
USER_ID = "user_001" # 用户 ID
SESSION_ID = "session_001" # 会话 ID
# 创建会话
session_url = f"{API_BASE}/apps/{APP_NAME}/users/{USER_ID}/sessions"
response = requests.post( # 发送请求
session_url, # URL
json={"session_id": SESSION_ID}, # 请求体
)
print(f"会话创建: {response.json()}") # 打印结果
# 发送消息
run_url = f"{session_url}/{SESSION_ID}:run"
payload = { # 请求体
"user_id": USER_ID, # 用户 ID
"session_id": SESSION_ID, # 会话 ID
"new_message": { # 新消息
"role": "user", # 角色
"parts": [{"text": "北京天气怎么样?"}], # 内容
},
}
response = requests.post( # 发送请求
run_url, # URL
json=payload, # 请求体
stream=True, # 流式响应
)
for line in response.iter_lines(): # 逐行读取
if line: # 如果有内容
data = json.loads(line) # 解析 JSON
print(f"事件: {data}") # 打印事件
if __name__ == "__main__":
print("✅ 部署配置示例") # 打印信息
print("请参考文件中的注释配置部署。") # 提示
print("\n快速启动命令:") # 打印命令
print(" adk api_server --port 8080 # 启动 API Server")
print(" adk web --port 8000 # 启动 Web UI")
print(" adk deploy . --platform cloud-run # 部署到 Cloud Run")

View File

@@ -0,0 +1,272 @@
"""
Google ADK 智能体评估完整示例
展示评估集创建和评估运行方法
对应教程第08章 - 智能体评估
"""
# 导入 ADK 核心模块
from google.adk.agents import Agent # Agent 类
from google.adk.runners import Runner # 运行器
from google.adk.sessions import InMemorySessionService # 会话服务
from google.genai import types # 类型定义
# 导入辅助模块
import asyncio # 异步编程库
import json # JSON 处理
# ========================================
# 定义被评估的 Agent
# ========================================
def get_weather(city: str) -> dict:
"""
获取天气信息
Args:
city (str): 城市名称
Returns:
dict: 天气信息
"""
weather_data = { # 天气数据
"北京": {"temp": "25°C", "condition": "晴天"},
"上海": {"temp": "28°C", "condition": "多云"},
"广州": {"temp": "32°C", "condition": "雷阵雨"},
}
data = weather_data.get(city) # 查找数据
if not data: # 如果找不到
return {"status": "error", "error_message": f"未找到'{city}'的天气信息"}
return {"status": "success", "city": city, **data} # 返回天气
agent = Agent(
name="weather_agent", # Agent 名称
model="gemini-2.0-flash", # 模型
instruction="你是天气助手,使用 get_weather 工具查询天气。用中文回答。", # 指令
tools=[get_weather], # 工具
)
# ========================================
# 示例一:创建评估集
# ========================================
def create_eval_set():
"""
创建评估集文件
生成 .evalset.json 文件供 adk eval 使用
"""
# 定义评估用例
eval_cases = [ # 用例列表
{
"case_id": "weather_beijing", # 用例 ID
"description": "测试北京天气查询", # 描述
"user_input": "北京今天天气怎么样?", # 用户输入
"expected_keywords": ["北京", "天气"], # 期望关键词
},
{
"case_id": "weather_shanghai", # 用例 ID
"description": "测试上海天气查询", # 描述
"user_input": "帮我查一下上海的天气", # 用户输入
"expected_keywords": ["上海"], # 期望关键词
},
{
"case_id": "greeting", # 用例 ID
"description": "测试问候功能", # 描述
"user_input": "你好!", # 用户输入
"expected_keywords": ["你好"], # 期望关键词
},
{
"case_id": "unknown_city", # 用例 ID
"description": "测试未知城市处理", # 描述
"user_input": "查询月球基地的天气", # 用户输入
"expected_keywords": ["找不到", "无法", "不支持"], # 期望关键词
},
{
"case_id": "multiple_cities", # 用例 ID
"description": "测试多城市查询", # 描述
"user_input": "北京和上海的天气对比", # 用户输入
"expected_keywords": ["北京", "上海"], # 期望关键词
},
]
# 构建评估集
eval_set = { # 评估集对象
"eval_cases": eval_cases, # 用例列表
}
# 写入文件
filepath = "weather_agent_eval_set.evalset.json" # 文件路径
with open(filepath, "w", encoding="utf-8") as f: # 打开文件
json.dump( # 写入 JSON
eval_set, # 数据
f, # 文件对象
ensure_ascii=False, # 允许中文
indent=2, # 格式化
)
print(f"✅ 评估集已创建: {filepath}") # 打印成功信息
print(f" 用例数量: {len(eval_cases)}") # 打印用例数
return filepath # 返回文件路径
# ========================================
# 示例二:代码方式运行评估
# ========================================
async def evaluate_agent(test_cases: list) -> dict:
"""
评估 Agent
Args:
test_cases: 测试用例列表
Returns:
dict: 评估结果汇总
"""
# 初始化服务
session_service = InMemorySessionService() # 会话服务
runner = Runner( # 运行器
agent=agent, # Agent
app_name="eval_app", # 应用名称
session_service=session_service, # 会话服务
)
results = [] # 结果列表
passed = 0 # 通过计数
for i, case in enumerate(test_cases): # 遍历用例
case_id = case.get("case_id", f"case_{i}") # 用例 ID
print(f"\n📋 测试用例: {case_id}") # 打印用例 ID
print(f" 输入: {case['user_input']}") # 打印输入
# 创建独立会话
session_id = f"eval_session_{i}" # 会话 ID
await session_service.create_session( # 创建会话
app_name="eval_app", # 应用名称
user_id="eval_user", # 用户 ID
session_id=session_id, # 会话 ID
)
# 构造消息
content = types.Content(
role='user', # 角色
parts=[types.Part(text=case["user_input"])], # 内容
)
# 运行 Agent
events = runner.run_async(
user_id="eval_user", # 用户 ID
session_id=session_id, # 会话 ID
new_message=content, # 消息
)
# 收集响应
response_text = "" # 初始化响应
async for event in events: # 遍历事件
if event.is_final_response(): # 最终响应
response_text = event.content.parts[0].text # 提取文本
# 检查期望关键词
case_passed = True # 默认通过
failure_reason = "" # 失败原因
if "expected_keywords" in case: # 如果有关键词要求
missing = [] # 缺失的关键词
for kw in case["expected_keywords"]: # 遍历关键词
if kw not in response_text: # 如果缺失
missing.append(kw) # 记录缺失
if missing: # 如果有缺失
case_passed = False # 标记失败
failure_reason = f"缺少关键词: {missing}" # 失败原因
# 检查不应出现的关键词
if "not_expected_keywords" in case: # 如果有排除关键词
for kw in case["not_expected_keywords"]: # 遍历
if kw in response_text: # 如果出现
case_passed = False # 标记失败
failure_reason = f"不应包含关键词: '{kw}'" # 失败原因
if case_passed: # 如果通过
passed += 1 # 递增通过数
print(f" ✅ 通过") # 打印通过
else: # 如果失败
print(f" ❌ 失败: {failure_reason}") # 打印失败原因
# 记录结果
results.append({ # 添加结果
"case_id": case_id, # 用例 ID
"status": "passed" if case_passed else "failed", # 状态
"response": response_text[:200], # 响应(截断)
"reason": failure_reason, # 失败原因
})
# 返回汇总
return { # 返回结果
"total": len(test_cases), # 总数
"passed": passed, # 通过数
"failed": len(test_cases) - passed, # 失败数
"pass_rate": passed / len(test_cases) if test_cases else 0, # 通过率
"results": results, # 详细结果
}
# ========================================
# 示例三:打印评估报告
# ========================================
def print_report(result: dict):
"""
打印评估报告
Args:
result: 评估结果
"""
print("\n" + "=" * 60) # 分隔线
print("📊 评估报告") # 标题
print("=" * 60) # 分隔线
print(f"总用例数: {result['total']}") # 总数
print(f"通过: {result['passed']}") # 通过数
print(f"失败: {result['failed']}") # 失败数
print(f"通过率: {result['pass_rate']:.1%}") # 通过率
print("-" * 60) # 分隔线
for r in result["results"]: # 遍历详细结果
icon = "" if r["status"] == "passed" else "" # 状态图标
print(f" {icon} {r['case_id']}: {r['status']}") # 打印结果
if r["reason"]: # 如果有失败原因
print(f" 原因: {r['reason']}") # 打印原因
if r["status"] == "passed": # 如果通过
print(f" 响应: {r['response'][:100]}...") # 打印响应片段
print("=" * 60) # 分隔线
# ========================================
# 主函数
# ========================================
async def main():
"""主函数"""
# 第一步:创建评估集
filepath = create_eval_set() # 创建评估集文件
# 第二步:加载评估用例
with open(filepath, "r", encoding="utf-8") as f: # 读取文件
eval_set = json.load(f) # 解析 JSON
test_cases = eval_set["eval_cases"] # 获取用例列表
# 第三步:运行评估
result = await evaluate_agent(test_cases) # 执行评估
# 第四步:打印报告
print_report(result) # 打印评估报告
if __name__ == "__main__": # 直接运行
asyncio.run(main()) # 执行主函数

View File

@@ -0,0 +1,137 @@
"""
Google ADK Hello World 示例
一个带有自定义工具的完整 Agent 示例
对应教程第02章 - 快速开始Hello World
运行方式adk run hello_world将此文件放在 hello_world/agent.py 中)
"""
# 导入 ADK 的 Agent 类
from google.adk.agents import Agent # Agent 是 LlmAgent 的别名
# 导入标准库:日期时间处理
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/Shanghai", # 广州使用上海时区
"深圳": "Asia/Shanghai", # 深圳使用上海时区
"东京": "Asia/Tokyo", # 东京时区
"首尔": "Asia/Seoul", # 首尔时区
"纽约": "America/New_York", # 纽约时区
"伦敦": "Europe/London", # 伦敦时区
"巴黎": "Europe/Paris", # 巴黎时区
"洛杉矶": "America/Los_Angeles", # 洛杉矶时区
}
# 查找城市对应的时区标识符
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 # 格式化后的时间字符串
}
def get_weather(city: str) -> dict:
"""
获取指定城市的天气信息(模拟数据)
Args:
city (str): 城市名称
Returns:
dict: 包含天气信息的字典
"""
# 模拟天气数据(实际应用中应调用真实天气 API
weather_data = { # 模拟天气数据库
"北京": {"temp": "25°C", "condition": "晴天", "humidity": "45%"}, # 北京
"上海": {"temp": "28°C", "condition": "多云", "humidity": "65%"}, # 上海
"广州": {"temp": "32°C", "condition": "雷阵雨", "humidity": "80%"}, # 广州
}
# 查找城市天气数据
data = weather_data.get(city) # 从字典中获取天气数据
# 如果找不到该城市的天气
if not data: # 检查数据是否存在
return { # 返回错误信息
"status": "error", # 状态:错误
"error_message": f"未找到'{city}'的天气信息" # 错误描述
}
# 返回成功结果
return { # 返回天气信息
"status": "success", # 状态:成功
"city": city, # 城市名称
"temperature": data["temp"], # 温度
"condition": data["condition"], # 天气状况
"humidity": data["humidity"], # 湿度
}
# ========================================
# 定义 AgentADK 入口点)
# ========================================
# root_agent 是 ADK 自动识别的入口变量
# 变量名必须是 root_agent不能修改
root_agent = Agent(
name="hello_agent", # Agent 的唯一标识名称
model="gemini-2.0-flash", # 使用 Gemini 2.0 Flash 模型
description="一个能查询城市时间和天气的友好助手。", # Agent 的描述
instruction=( # 系统指令(多行字符串)
"你是一个友好的助手,可以帮助用户查询世界各城市的当前时间和天气。\n"
"当用户询问某个城市的时间时,使用 get_current_time 工具来获取。\n"
"当用户询问某个城市的天气时,使用 get_weather 工具来获取。\n"
"如果工具返回错误,请友好地告知用户并建议尝试其他城市。\n"
"回复时请使用中文,语气亲切友好。"
),
tools=[ # 将自定义函数注册为 Agent 的工具
get_current_time, # 时间查询工具
get_weather, # 天气查询工具
],
)

View File

@@ -0,0 +1,210 @@
"""
Google ADK LLM 智能体完整示例
展示 LlmAgent 的各种配置和用法
对应教程第03章 - LLM 智能体详解
"""
# 导入 ADK 核心模块
from google.adk.agents import Agent, LlmAgent # Agent 和 LlmAgent
from google.adk.agents import SequentialAgent # 顺序工作流
from google.adk.models.lite_llm import LiteLlm # LiteLLM 适配器
from google.adk.tools import google_search # Google 搜索工具
from google.adk.tools import code_execution # 代码执行工具
# 导入运行相关模块
from google.adk.runners import Runner # 运行器
from google.adk.sessions import InMemorySessionService # 内存会话服务
from google.genai import types # Google GenAI 类型定义
# 导入异步库
import asyncio # 异步编程库
# ========================================
# 示例一:基础 LlmAgent 配置
# ========================================
# 使用 Gemini 模型(默认)
gemini_agent = Agent(
name="gemini_agent", # Agent 名称
model="gemini-2.0-flash", # 使用 Gemini 2.0 Flash
instruction="你是一个专业的编程助手。", # 系统指令
description="擅长编程和代码审查。", # 描述(用于多 Agent 路由)
)
# 使用 LiteLLM 适配 DeepSeek 模型
deepseek_agent = Agent(
name="deepseek_agent", # Agent 名称
model=LiteLlm( # 使用 LiteLLM 适配器
model="deepseek/deepseek-chat", # 格式provider/model_name
api_key="你的_DEEPSEEK_API_KEY", # API Key
),
instruction="你是一个中文写作助手。", # 系统指令
)
# 使用 LiteLLM 适配 OpenAI 模型
openai_agent = Agent(
name="openai_agent", # Agent 名称
model=LiteLlm( # 使用 LiteLLM 适配器
model="openai/gpt-4o", # OpenAI GPT-4o
api_key="你的_OPENAI_API_KEY", # API Key
),
instruction="你是一个数据分析助手。", # 系统指令
)
# ========================================
# 示例二:使用 Google 内置工具
# ========================================
# 带搜索能力的 Agent
search_agent = Agent(
name="search_agent", # Agent 名称
model="gemini-2.0-flash", # 使用 Gemini 模型
instruction=( # 系统指令
"你是一个信息查询助手。\n"
"使用 Google Search 工具搜索最新信息。\n"
"根据搜索结果提供准确、全面的回答。"
),
tools=[google_search], # 注册 Google 搜索工具
)
# 带代码执行能力的 Agent
code_agent = Agent(
name="code_agent", # Agent 名称
model="gemini-2.0-flash", # 使用 Gemini 模型
instruction=( # 系统指令
"你是一个数据分析助手。\n"
"使用 Code Execution 工具执行 Python 代码。\n"
"确保代码正确且高效。"
),
tools=[code_execution], # 注册代码执行工具
)
# 多功能 Agent搜索 + 代码执行)
super_agent = Agent(
name="super_agent", # Agent 名称
model="gemini-2.0-flash", # 使用 Gemini 模型
instruction="你是一个全能助手,可以搜索信息和执行代码。", # 指令
tools=[google_search, code_execution], # 注册多个工具
)
# ========================================
# 示例三output_key 用法
# ========================================
# 第一步:提取信息的 Agent
extractor = Agent(
name="Extractor", # 信息提取 Agent
model="gemini-2.0-flash", # 模型
instruction="从用户输入中提取关键信息。只输出提取的信息。", # 指令
output_key="extracted_info", # 将输出保存到 state['extracted_info']
)
# 第二步:分析信息的 Agent引用第一步的输出
analyzer = Agent(
name="Analyzer", # 信息分析 Agent
model="gemini-2.0-flash", # 模型
instruction=( # 指令:通过 {key} 引用 state 中的值
"分析以下提取的信息,给出深度分析。\n"
"提取的信息:{extracted_info}"
),
output_key="analysis_result", # 将分析结果保存到 state
)
# 创建顺序流水线
pipeline = SequentialAgent(
name="InfoPipeline", # 流水线名称
sub_agents=[extractor, analyzer], # 按顺序执行
)
# ========================================
# 示例四Agent Transfer动态委派
# ========================================
# 定义专门的子 Agent
booking_agent = LlmAgent(
name="BookingAgent", # 预订 Agent
model="gemini-2.0-flash", # 模型
description="负责处理航班和酒店的预订请求。", # 描述
instruction="你是一个预订助手,帮助用户预订航班和酒店。", # 指令
)
info_agent = LlmAgent(
name="InfoAgent", # 信息查询 Agent
model="gemini-2.0-flash", # 模型
description="负责回答一般性问题和提供信息。", # 描述
instruction="你是一个信息助手,回答用户的各种问题。", # 指令
)
# 定义协调器 Agent
coordinator = LlmAgent(
name="Coordinator", # 协调器
model="gemini-2.0-flash", # 模型
description="主协调器,负责分配任务。", # 描述
instruction=( # 指令
"你是一个协调器。\n"
"预订任务交给 BookingAgent。\n"
"信息查询交给 InfoAgent。\n"
"使用 transfer_to_agent 工具委派任务。"
),
sub_agents=[booking_agent, info_agent], # 注册子 Agent
)
# ========================================
# 示例五:通过代码运行 Agent
# ========================================
# 定义应用信息
APP_NAME = "llm_demo_app" # 应用名称
USER_ID = "user_001" # 用户 ID
SESSION_ID = "session_001" # 会话 ID
async def run_demo():
"""运行 LlmAgent 演示"""
# 创建会话服务
session_service = InMemorySessionService() # 内存会话服务
# 创建会话
session = await session_service.create_session(
app_name=APP_NAME, # 应用名称
user_id=USER_ID, # 用户 ID
session_id=SESSION_ID, # 会话 ID
)
# 创建运行器
runner = Runner(
agent=gemini_agent, # 使用 Gemini Agent
app_name=APP_NAME, # 应用名称
session_service=session_service, # 会话服务
)
# 构造用户消息
content = types.Content(
role='user', # 角色:用户
parts=[types.Part(text='用 Python 写一个冒泡排序算法')], # 消息
)
# 运行 Agent
events = runner.run_async(
user_id=USER_ID, # 用户 ID
session_id=SESSION_ID, # 会话 ID
new_message=content, # 用户消息
)
# 处理事件流
async for event in events: # 遍历所有事件
if event.is_final_response(): # 如果是最终响应
response = event.content.parts[0].text # 提取文本
print(f"Agent 回复:\n{response}") # 打印回复
# 运行演示
if __name__ == "__main__": # 当脚本被直接运行时
asyncio.run(run_demo()) # 执行异步函数

View File

@@ -0,0 +1,275 @@
"""
Google ADK 多智能体系统完整示例
展示各种多 Agent 协作模式
对应教程第05章 - 多智能体系统
"""
# 导入 ADK 核心模块
from google.adk.agents import ( # 导入所有 Agent 类型
Agent, # LLM Agent别名
LlmAgent, # LLM Agent完整名
SequentialAgent, # 顺序工作流
ParallelAgent, # 并行工作流
LoopAgent, # 循环工作流
BaseAgent, # 基础 Agent自定义用
)
from google.adk.events import Event, EventActions # 导入事件类型
from google.adk.agents.invocation_context import InvocationContext # 导入上下文
from typing import AsyncGenerator # 导入异步生成器
# ========================================
# 模式一:协调器/调度器模式
# ========================================
# 定义专门的子 Agent
math_agent = LlmAgent(
name="MathExpert", # 数学专家
model="gemini-2.0-flash", # 模型
description="擅长数学计算和统计分析。", # 描述
instruction="你是数学专家,解决数学问题。给出详细的计算过程。", # 指令
)
writing_agent = LlmAgent(
name="WritingExpert", # 写作专家
model="gemini-2.0-flash", # 模型
description="擅长文案撰写和内容创作。", # 描述
instruction="你是写作专家,帮助用户撰写高质量的内容。", # 指令
)
coding_agent = LlmAgent(
name="CodingExpert", # 编程专家
model="gemini-2.0-flash", # 模型
description="擅长编程和代码调试。", # 描述
instruction="你是编程专家,帮助用户解决编程问题。提供带注释的代码。", # 指令
)
# 定义协调器
coordinator = LlmAgent(
name="Coordinator", # 协调器
model="gemini-2.0-flash", # 模型
description="根据问题类型分配给合适的专家。", # 描述
instruction=( # 指令
"你是一个任务协调器。\n"
"根据用户的问题类型,将任务分配给合适的专家:\n"
"- 数学相关 → MathExpert\n"
"- 写作相关 → WritingExpert\n"
"- 编程相关 → CodingExpert\n"
"使用 transfer_to_agent 工具进行任务分配。"
),
sub_agents=[math_agent, writing_agent, coding_agent], # 注册子 Agent
)
# ========================================
# 模式二:顺序流水线模式
# ========================================
# 步骤一:信息提取
extractor = LlmAgent(
name="Extractor", # 信息提取 Agent
model="gemini-2.0-flash", # 模型
instruction="从用户输入中提取关键信息。只输出提取的关键信息。", # 指令
output_key="extracted_info", # 输出保存到 state
)
# 步骤二:信息分析
analyzer = LlmAgent(
name="Analyzer", # 信息分析 Agent
model="gemini-2.0-flash", # 模型
instruction=( # 指令:引用上一步输出
"分析以下提取的信息,给出深度分析报告。\n"
"提取的信息:{extracted_info}"
),
output_key="analysis_result", # 输出保存到 state
)
# 步骤三:报告生成
reporter = LlmAgent(
name="Reporter", # 报告生成 Agent
model="gemini-2.0-flash", # 模型
instruction=( # 指令:引用前两步输出
"根据分析结果生成一份简洁的报告。\n"
"原始信息:{extracted_info}\n"
"分析结果:{analysis_result}"
),
)
# 创建顺序流水线
pipeline = SequentialAgent(
name="InfoPipeline", # 流水线名称
sub_agents=[extractor, analyzer, reporter], # 按顺序执行
)
# ========================================
# 模式三:并行扇出模式
# ========================================
# 并行任务一:天气查询
weather_agent = LlmAgent(
name="WeatherFetcher", # 天气查询
model="gemini-2.0-flash", # 模型
instruction="查询并返回天气信息。只返回天气数据。", # 指令
output_key="weather_data", # 输出保存到 state
)
# 并行任务二:新闻查询
news_agent = LlmAgent(
name="NewsFetcher", # 新闻查询
model="gemini-2.0-flash", # 模型
instruction="查询并返回最新新闻。只返回新闻摘要。", # 指令
output_key="news_data", # 输出保存到 state
)
# 并行任务三:交通查询
traffic_agent = LlmAgent(
name="TrafficFetcher", # 交通查询
model="gemini-2.0-flash", # 模型
instruction="查询并返回交通状况。只返回交通信息。", # 指令
output_key="traffic_data", # 输出保存到 state
)
# 创建并行执行器
gatherer = ParallelAgent(
name="InfoGatherer", # 并行执行器名称
sub_agents=[weather_agent, news_agent, traffic_agent], # 并行执行
)
# ========================================
# 模式四循环优化模式Generator-Critic
# ========================================
# 生成器 Agent
generator = LlmAgent(
name="Generator", # 生成器
model="gemini-2.0-flash", # 模型
instruction=( # 指令
"你是一个创意写手。\n"
"根据用户需求创作内容。\n"
"将创作的内容保存到 state['draft']。"
),
output_key="draft", # 输出保存到 state
)
# 评审器 Agent
critic = LlmAgent(
name="Critic", # 评审器
model="gemini-2.0-flash", # 模型
instruction=( # 指令
"你是一个严格的内容评审。\n"
"评审以下内容给出评分1-10和改进建议。\n"
"当前草稿:{draft}\n"
"如果评分 >= 8将 state['approved'] 设为 True。\n"
"否则,将改进建议保存到 state['feedback']。"
),
)
# 条件检查 Agent
class ApprovalChecker(BaseAgent):
"""检查内容是否通过审批"""
async def _run_async_impl(
self,
ctx: InvocationContext, # 调用上下文
) -> AsyncGenerator[Event, None]: # 返回事件生成器
"""执行检查"""
approved = ctx.session.state.get("approved", False) # 获取审批状态
yield Event( # 生成事件
author=self.name, # 事件作者
actions=EventActions(
escalate=approved, # 通过则退出循环
),
)
# 创建迭代优化循环
review_loop = LoopAgent(
name="ReviewLoop", # 循环名称
max_iterations=3, # 最多迭代3次
sub_agents=[critic, ApprovalChecker(name="Checker"), generator], # 循环体
)
# ========================================
# 模式五:多层级嵌套
# ========================================
# 第三层:具体执行 Agent
code_reviewer = LlmAgent(
name="CodeReviewer", # 代码审查
model="gemini-2.0-flash", # 模型
description="审查代码质量。", # 描述
instruction="审查代码并给出改进建议。", # 指令
)
test_writer = LlmAgent(
name="TestWriter", # 测试编写
model="gemini-2.0-flash", # 模型
description="编写单元测试。", # 描述
instruction="为代码编写单元测试。", # 指令
)
# 第二层:开发流水线
dev_pipeline = SequentialAgent(
name="DevPipeline", # 流水线
sub_agents=[code_reviewer, test_writer], # 顺序执行
)
# 第二层:其他 Agent
doc_writer = LlmAgent(
name="DocWriter", # 文档编写
model="gemini-2.0-flash", # 模型
description="编写技术文档。", # 描述
instruction="编写清晰的技术文档。", # 指令
)
# 第一层:根协调器
root_agent = LlmAgent(
name="RootCoordinator", # 根协调器
model="gemini-2.0-flash", # 模型
description="开发团队协调器。", # 描述
instruction=( # 指令
"你是一个开发团队协调器。\n"
"代码审查和测试交给 DevPipeline。\n"
"文档编写交给 DocWriter。"
),
sub_agents=[dev_pipeline, doc_writer], # 子 Agent
)
# ========================================
# 打印结构信息
# ========================================
if __name__ == "__main__":
print("=" * 60) # 分隔线
print("Google ADK 多智能体系统示例") # 标题
print("=" * 60) # 分隔线
print("\n📦 模式一:协调器/调度器") # 模式一
print(f" 根 Agent: {coordinator.name}") # 根 Agent
print(f" 子 Agent: {[a.name for a in coordinator.sub_agents]}") # 子 Agent
print("\n📦 模式二:顺序流水线") # 模式二
print(f" 流水线: {pipeline.name}") # 流水线
print(f" 步骤: {[a.name for a in pipeline.sub_agents]}") # 步骤
print("\n📦 模式三:并行扇出") # 模式三
print(f" 并行器: {gatherer.name}") # 并行器
print(f" 任务: {[a.name for a in gatherer.sub_agents]}") # 任务
print("\n📦 模式四:循环优化") # 模式四
print(f" 循环: {review_loop.name}") # 循环
print(f" 最大迭代: {review_loop.max_iterations}") # 最大迭代
print("\n📦 模式五:多层级嵌套") # 模式五
print(f" 根: {root_agent.name}") # 根
print(f" 第二层: {[a.name for a in root_agent.sub_agents]}") # 第二层
print(f" 第三层: {[a.name for a in dev_pipeline.sub_agents]}") # 第三层
print("\n✅ 所有模式定义完成!") # 成功信息
print("使用 'adk web''adk run' 运行。") # 运行提示

View File

@@ -0,0 +1,318 @@
"""
Google ADK 会话与状态管理完整示例
展示 Session、State、Memory 的使用方法
对应教程第06章 - 会话与状态管理
"""
# 导入 ADK 核心模块
from google.adk.agents import Agent # Agent 类
from google.adk.runners import Runner # 运行器
from google.adk.sessions import InMemorySessionService # 内存会话服务
from google.adk.memory import InMemoryMemoryService # 内存记忆服务
from google.genai import types # 类型定义
# 导入异步库
import asyncio # 异步编程库
# ========================================
# 示例一State 管理(购物车)
# ========================================
def add_to_cart(item: str, price: float, ctx) -> dict:
"""
将商品添加到购物车
Args:
item (str): 商品名称
price (float): 商品价格
ctx: 工具上下文(自动注入)
Returns:
dict: 操作结果
"""
# 获取当前购物车
cart = ctx.state.get("cart", []) # 从 state 读取购物车
# 添加新商品
cart.append({ # 追加商品
"item": item, # 商品名
"price": price, # 价格
})
# 更新 state
ctx.state["cart"] = cart # 写回 state
# 计算总价
total = sum(item["price"] for item in cart) # 求和
return { # 返回结果
"status": "success",
"message": f"已将 {item} 添加到购物车",
"cart_items": len(cart),
"total": total,
}
def get_cart(ctx) -> dict:
"""
获取购物车内容
Args:
ctx: 工具上下文
Returns:
dict: 购物车内容
"""
cart = ctx.state.get("cart", []) # 读取购物车
if not cart: # 如果为空
return { # 返回空信息
"status": "success",
"message": "购物车是空的",
"items": [],
"total": 0,
}
total = sum(item["price"] for item in cart) # 计算总价
return { # 返回购物车
"status": "success",
"items": cart,
"total": total,
}
def clear_cart(ctx) -> dict:
"""
清空购物车
Args:
ctx: 工具上下文
Returns:
dict: 操作结果
"""
ctx.state["cart"] = [] # 清空购物车
return { # 返回结果
"status": "success",
"message": "购物车已清空",
}
# ========================================
# 示例二temp: 临时状态
# ========================================
def step1_process(query: str, ctx) -> dict:
"""
处理步骤一:预处理数据
Args:
query (str): 用户查询
ctx: 工具上下文
Returns:
dict: 预处理结果
"""
processed = query.strip().lower() # 预处理
# 保存到临时状态(当前调用结束后自动清除)
ctx.state["temp:processed_query"] = processed # 临时存储
return { # 返回结果
"status": "success",
"processed_query": processed,
}
def step2_enhance(ctx) -> dict:
"""
处理步骤二:增强数据
Args:
ctx: 工具上下文
Returns:
dict: 增强结果
"""
# 从临时状态读取
processed = ctx.state.get("temp:processed_query") # 读取临时状态
if not processed: # 如果没有数据
return { # 返回错误
"status": "error",
"error_message": "请先执行预处理步骤。"
}
enhanced = f"[增强] {processed}" # 增强处理
return { # 返回结果
"status": "success",
"enhanced_query": enhanced,
}
# ========================================
# 创建 Agent
# ========================================
shopping_agent = Agent(
name="shopping_assistant", # Agent 名称
model="gemini-2.0-flash", # 模型
instruction=( # 指令
"你是一个购物助手。\n"
"帮助用户管理购物车:\n"
"- 添加商品:使用 add_to_cart\n"
"- 查看购物车:使用 get_cart\n"
"- 清空购物车:使用 clear_cart"
),
tools=[add_to_cart, get_cart, clear_cart], # 注册工具
)
# ========================================
# 示例三Session 管理
# ========================================
async def session_management_demo():
"""演示 Session 管理功能"""
print("=" * 50) # 分隔线
print("Session 管理演示") # 标题
print("=" * 50) # 分隔线
# 创建会话服务
session_service = InMemorySessionService() # 内存会话服务
# 创建会话
session = await session_service.create_session(
app_name="shopping_app", # 应用名称
user_id="user_001", # 用户 ID
session_id="session_001", # 会话 ID
state={"cart": []}, # 初始化状态
)
print(f"✅ 会话创建成功: {session.id}") # 打印会话 ID
# 获取会话
existing = await session_service.get_session(
app_name="shopping_app",
user_id="user_001",
session_id="session_001",
)
print(f"✅ 获取会话: {existing.id}") # 打印会话信息
# 删除会话
await session_service.delete_session(
app_name="shopping_app",
user_id="user_001",
session_id="session_001",
)
print("✅ 会话已删除") # 确认删除
# ========================================
# 示例四:多轮对话
# ========================================
async def multi_turn_demo():
"""演示多轮对话"""
print("\n" + "=" * 50) # 分隔线
print("多轮对话演示") # 标题
print("=" * 50) # 分隔线
# 初始化
session_service = InMemorySessionService() # 会话服务
await session_service.create_session( # 创建会话
app_name="chat_app", # 应用名称
user_id="user_001", # 用户 ID
session_id="chat_001", # 会话 ID
)
# 创建 Runner
runner = Runner(
agent=shopping_agent, # Agent
app_name="chat_app", # 应用名称
session_service=session_service, # 会话服务
)
# 模拟多轮对话
conversations = [ # 对话列表
"帮我添加一个苹果价格5元", # 第一轮
"再添加一个香蕉价格3元", # 第二轮
"查看我的购物车", # 第三轮
"清空购物车", # 第四轮
]
for msg in conversations: # 遍历对话
print(f"\n[用户]: {msg}") # 打印用户消息
# 构造消息
content = types.Content(
role='user', # 角色
parts=[types.Part(text=msg)], # 内容
)
# 运行 Agent
events = runner.run_async(
user_id="user_001", # 用户 ID
session_id="chat_001", # 同一会话
new_message=content, # 消息
)
# 获取响应
async for event in events: # 遍历事件
if event.is_final_response(): # 最终响应
print(f"[Agent]: {event.content.parts[0].text}") # 打印回复
# ========================================
# 示例五Memory 管理
# ========================================
async def memory_demo():
"""演示 Memory 管理功能"""
print("\n" + "=" * 50) # 分隔线
print("Memory 管理演示") # 标题
print("=" * 50) # 分隔线
# 创建记忆服务
memory_service = InMemoryMemoryService() # 内存记忆服务
# 添加记忆(从会话事件中提取)
await memory_service.add_session_events_to_memory(
app_name="my_app", # 应用名称
user_id="user_001", # 用户 ID
session_id="session_001", # 会话 ID
)
print("✅ 记忆已添加") # 确认添加
# 搜索记忆
results = await memory_service.search(
query="用户偏好", # 搜索查询
app_name="my_app", # 应用名称
user_id="user_001", # 用户 ID
)
print(f"✅ 搜索完成,结果数: {len(results)}") # 打印结果数
# ========================================
# 主函数
# ========================================
async def main():
"""主函数"""
# 运行所有演示
await session_management_demo() # Session 管理
await multi_turn_demo() # 多轮对话
await memory_demo() # Memory 管理
if __name__ == "__main__": # 直接运行
asyncio.run(main()) # 执行主函数

View File

@@ -0,0 +1,69 @@
"""
Google ADK 环境搭建验证脚本
验证 ADK 是否正确安装,并打印版本信息
对应教程第01章 - ADK 简介与环境搭建
"""
# 导入 ADK 核心模块,验证安装是否成功
from google.adk.agents import Agent # 智能体模块
from google.adk.runners import Runner # 运行器模块
from google.adk.sessions import InMemorySessionService # 内存会话服务
def verify_installation():
"""验证 ADK 安装是否成功"""
# 打印分隔线
print("=" * 50) # 打印分隔线
print("Google ADK 环境验证") # 打印标题
print("=" * 50) # 打印分隔线
# 验证 Agent 类是否可用
try: # 尝试导入
agent = Agent( # 创建一个简单的测试 Agent
name="test_agent", # 设置 Agent 名称
model="gemini-2.0-flash", # 使用 Gemini 模型
instruction="你是一个测试助手。", # 设置系统指令
)
print(f"✅ Agent 模块可用") # 确认 Agent 可用
print(f" Agent 名称: {agent.name}") # 打印 Agent 名称
except ImportError as e: # 如果导入失败
print(f"❌ Agent 模块导入失败: {e}") # 打印错误信息
return False # 返回失败
# 验证 Runner 类是否可用
try: # 尝试导入
print(f"✅ Runner 模块可用") # 确认 Runner 可用
except ImportError as e: # 如果导入失败
print(f"❌ Runner 模块导入失败: {e}") # 打印错误信息
return False # 返回失败
# 验证 SessionService 是否可用
try: # 尝试创建
session_service = InMemorySessionService() # 创建内存会话服务
print(f"✅ SessionService 可用") # 确认会话服务可用
except Exception as e: # 如果创建失败
print(f"❌ SessionService 创建失败: {e}") # 打印错误信息
return False # 返回失败
# 验证 ADK 版本
try: # 尝试获取版本
import importlib.metadata # 导入元数据模块
version = importlib.metadata.version("google-adk") # 获取版本号
print(f"✅ ADK 版本: {version}") # 打印版本号
except Exception: # 如果获取失败
print("⚠️ 无法获取 ADK 版本") # 打印警告
# 打印成功信息
print("=" * 50) # 打印分隔线
print("🎉 所有模块验证通过!") # 打印成功信息
print("可以开始使用 Google ADK 了!") # 提示用户
print("=" * 50) # 打印分隔线
return True # 返回成功
# 当脚本被直接运行时执行验证
if __name__ == "__main__": # 判断是否直接运行
verify_installation() # 执行验证函数