智脑的诞生:从代码到对话的奇幻旅程

人工智能(AI)的浪潮正席卷全球,它不再是科幻电影中的遥远梦想,而是我们日常生活中触手可及的伙伴。从天气预报到语音助手,AI正以惊人的速度改变着世界。而这一切的背后,有一个不起眼的英雄——Agent Development Kit(ADK)。这个由谷歌打造的Python框架,让开发者能轻松构建智能代理,让机器不仅能计算,还能“思考”和“对话”。这篇文章将带你走进ADK的世界,从一行简单的代码开始,逐步解锁它的魔法,打造一个能查天气、打招呼、甚至懂得安全的智能团队。准备好了吗?让我们一起踏上这场从代码到智慧的奇幻旅程!


🌱 从零开始:一个简单的天气探秘者

想象一下,你坐在电脑前,想让机器告诉你纽约的天气。以前,这可能需要复杂的API调用和冗长的代码。但有了ADK,一切变得像搭积木一样简单。我们先从最基础的开始,搭建一个能查天气的代理。

第一步是安装ADK。打开终端,输入几行命令,虚拟环境就搭建好了:

python -m venv .venv
source .venv/bin/activate  # macOS/Linux
pip install google-adk

接下来,我们创建一个名叫“multi_tool_agent”的项目文件夹,里面放上几个关键文件:__init__.pyagent.py.env。这些文件就像一个新生的智能代理的“骨架”。在agent.py中,我们定义了两个工具函数:get_weatherget_current_time,它们就像代理的“双手”,能抓取天气和时间信息:

def get_weather(city: str) -> dict:
    if city.lower() == "new york":
        return {"status": "success", "report": "The weather in New York is sunny with a temperature of 25 degrees Celsius."}
    else:
        return {"status": "error", "error_message": f"Weather information for '{city}' is not available."}

def get_current_time(city: str) -> dict:
    if city.lower() == "new york":
        tz = ZoneInfo("America/New_York")
        now = datetime.datetime.now(tz)
        return {"status": "success", "report": f'The current time in {city} is {now.strftime("%Y-%m-%d %H. %M:%S %Z%z")}'}
    else:
        return {"status": "error", "error_message": f"Sorry, I don’t have timezone information for {city}."}

然后,我们用ADK的Agent类把这些工具整合成一个代理:

root_agent = Agent(
    name="weather_time_agent",
    model="gemini-2.0-flash-exp",
    description="Agent to answer questions about the time and weather in a city.",
    instruction="I can answer your questions about the time and weather in a city.",
    tools=[get_weather, get_current_time],
)

简单几行代码,一个能回答“纽约天气如何?”或“现在纽约几点?”的代理就诞生了。运行它也很简单,在终端输入adk web,浏览器里就会弹出一个交互界面。你可以输入问题,看到代理的回答,甚至用语音和它对话——就像一个会说话的小助手。这就是ADK的魔力:它把复杂的底层逻辑藏起来,让你专注于创造。


🎙️ 让代理开口:流媒体的魔法

如果说基础代理是“哑巴助手”,那ADK的流媒体功能就像给它装上了“声带”。在“Quickstart (Streaming)”文档中,我们学会了如何让代理不仅能听懂文字,还能处理语音和视频。

这次我们打造一个“谷歌搜索代理”。项目结构稍有不同:

adk-streaming/app/
    ├── .env
    └── google_search_agent/
        ├── __init__.py
        └── agent.py

agent.py中,我们定义了一个简单的搜索代理:

from google.adk.agents import Agent
from google.adk.tools import google_search

root_agent = Agent(
    name="basic_search_agent",
    model="gemini-2.0-flash-exp",
    description="Agent to answer questions using Google Search.",
    instruction="You are an expert researcher. You always stick to the facts.",
    tools=[google_search]
)

配置好API密钥后,运行adk web,你就可以对着麦克风问:“纽约的天气如何?”代理会通过谷歌搜索实时回答,甚至能“边想边说”,答案像流水一样呈现在屏幕上。更酷的是,打开摄像头,问“这是什么?”,它还能描述镜头里的景象。这种实时双向交互,让代理从静态的工具变成了活生生的对话伙伴。

但这只是开始。文档还展示了如何用FastAPI打造一个自定义流媒体应用。main.pyindex.html的组合,让你可以用WebSocket实现双向通信。试着问“Gemini是什么?”,你会看到答案逐字显现,就像和朋友聊天一样自然。这种流媒体技术,不仅让交互更流畅,还为未来的多模态应用(语音、图像、视频)打开了大门。


🤝 团队合作:从独奏到交响乐

单个代理虽然强大,但真正的智慧往往来自协作。在“Tutorial”文档中,我们从一个简单的天气代理开始,逐步构建了一个多代理团队,就像从独奏小提琴升级到交响乐团。

🛠️ 工具与代理:分工明确

首先,我们定义了一个基础的天气工具:

def get_weather(city: str) -> dict:
    mock_weather_db = {
        "newyork": {"status": "success", "report": "The weather in New York is sunny with a temperature of 25°C. "},
        "london": {"status": "success", "report": "It’s cloudy in London with a temperature of 15°C. "}
    }
    city_normalized = city.lower().replace(" ", "")
    return mock_weather_db.get(city_normalized, {"status": "error", "error_message": f"No weather data for '{city}'."})

然后,创建一个天气代理:

weather_agent = Agent(
    name="weather_agent_v1",
    model="gemini-2.5-pro",
    description="Provides weather information for specific cities.",
    instruction="Use the 'get_weather' tool to answer weather queries.",
    tools=[get_weather]
)

🌐 多模型切换:智慧的选择

ADK通过LiteLLM支持多种大模型。我们可以用GPT-4o或Claude Sonnet替换Gemini:

from google.adk.models.lite_llm import LiteLlm

weather_agent_gpt = Agent(
    name="weather_agent_gpt",
    model=LiteLlm(model="gpt-4o"),
    description="Weather info with GPT-4o.",
    instruction="Use 'get_weather' for weather queries.",
    tools=[get_weather]
)

不同模型的回答风格可能略有差异,就像请教不同的气象学家,但核心逻辑保持一致。这种灵活性让开发者能根据任务需求选择最优模型。

👥 代理团队:各司其职

接下来,我们加入了打招呼和告别的子代理:

def say_hello(name: str = "there") -> str:
    return f"Hello, {name}!"

def say_goodbye() -> str:
    return "Goodbye! Have a great day."

greeting_agent = Agent(
    name="greeting_agent",
    model=LiteLlm(model="gpt-4o"),
    description="Handles simple greetings using 'say_hello'.",
    instruction="Use 'say_hello' to greet users.",
    tools=[say_hello]
)

farewell_agent = Agent(
    name="farewell_agent",
    model=LiteLlm(model="gpt-4o"),
    description="Handles farewells using 'say_goodbye'.",
    instruction="Use 'say_goodbye' for farewell messages.",
    tools=[say_goodbye]
)

根代理负责协调:

root_agent = Agent(
    name="weather_agent_v2",
    model="gemini-2.5-pro",
    description="Coordinates weather requests and delegates greetings/farewells.",
    instruction="Handle weather with 'get_weather', delegate greetings to 'greeting_agent', farewells to 'farewell_agent'.",
    tools=[get_weather],
    sub_agents=[greeting_agent, farewell_agent]
)

试着问“Hi!”、“New York weather?”和“Bye!”,你会看到根代理聪明地把任务分派给合适的子代理,就像一个高效的团队主管。


🧠 记忆的力量:从健忘到长情

没有记忆的代理就像一个失忆的朋友,每次对话都像初次见面。ADK的Session State让代理有了“记忆力”。我们升级天气工具,让它根据用户的温度单位偏好(摄氏度或华氏度)调整输出:

from google.adk.tools.tool_context import ToolContext

def get_weather_stateful(city: str, tool_context: ToolContext) -> dict:
    preferred_unit = tool_context.state.get("user_preference_temperature_unit", "Celsius")
    mock_weather_db = {"newyork": {"temp_c": 25, "condition": "sunny"}}
    city_normalized = city.lower().replace(" ", "")
    data = mock_weather_db.get(city_normalized)
    if data:
        temp_c = data["temp_c"]
        temp = (temp_c * 9/5) +енту

        if preferred_unit == "Fahrenheit":
            temp_value = (temp_c * 9/5) + 32
            temp_unit = "°F"
        else:
            temp_value = temp_c
            temp_unit = "°C"
        report = f"The weather in {city.capitalize()} is {data['condition']} with a temperature of {temp_value:.0f}{temp_unit}."
        tool_context.state["last_city_checked"] = city
        return {"status": "success", "report": report}
    return {"status": "error", "error_message": f"No weather data for '{city}'."}

根代理更新为:

root_agent_stateful = Agent(
    name="weather_agent_v4",
    model="gemini-2.5-pro",
    instruction="Use 'get_weather_stateful' for weather queries.",
    tools=[get_weather_stateful],
    sub_agents=[greeting_agent, farewell_agent],
    output_key="last_weather_report"
)

初始化会话时设置偏好:

session_service = InMemorySessionService()
session = session_service.create_session(
    app_name="weather_app",
    user_id="user1",
    session_id="session1",
    state={"user_preference_temperature_unit": "Celsius"}
)

试着查天气,然后切换偏好为“Fahrenheit”,再次查询,你会发现温度单位随之改变。更妙的是,通过output_key,代理的回答会自动保存到状态中,随时可查。这种记忆能力让交互更自然,像和老朋友聊天。


🛡️ 安全的守护:智慧与责任并存

智能固然强大,但无约束的代理可能像脱缰野马。ADK提供了回调机制,确保安全。我们先用before_model_callback拦截输入:

def block_keyword_guardrail(callback_context: CallbackContext, llm_request: LlmRequest) -> Optional[LlmResponse]:
    last_message = next((c.parts[0].text for c in reversed(llm_request.contents) if c.role == 'user' and c.parts), "")
    if "BLOCK" in last_message.upper():
        return LlmResponse(content=types.Content(role="model", parts=[types.Part(text="Blocked due to keyword 'BLOCK'.")]))
    return None

再用before_tool_callback限制工具参数:

def block_paris_tool_guardrail(tool: BaseTool, args: Dict[str, Any], tool_context: ToolContext) -> Optional[Dict]:
    if tool.name == "get_weather_stateful" and args.get("city", "").lower() == "paris":
        return {"status": "error", "error_message": "Weather checks for 'Paris' are disabled."}
    return None

更新根代理:

root_agent_safe = Agent(
    name="weather_agent_v6",
    model="gemini-2.5-pro",
    instruction="Handle weather, greetings, and farewells safely.",
    tools=[get_weather_stateful],
    sub_agents=[greeting_agent, farewell_agent],
    before_model_callback=block_keyword_guardrail,
    before_tool_callback=block_paris_tool_guardrail
)

试着输入“BLOCK weather”或查“Paris”的天气,你会发现代理立刻被拦下,就像有了一个尽职的保安。这种安全机制,确保了智慧不会失控。


🌟 未来已来:从天气到宇宙

从一个简单的天气查询,到一个能打招呼、记忆偏好、懂得安全的代理团队,ADK展示了一个从代码到智慧的完整进化过程。它的模块化设计(代理与工具分离)、灵活性(多模型支持)、状态管理(会话记忆)和安全保障(回调机制),为开发者提供了一把万能钥匙。

想更进一步?可以用真实天气API替换模拟数据,或者加入更多子代理,比如预测未来天气的“预言家”。甚至可以用流媒体技术,打造一个能实时语音聊天的天气助手。ADK就像一块未雕琢的宝石,等着你赋予它无限可能。

就像图灵曾问:“机器能思考吗?”今天的ADK回答:不仅能思考,还能对话、协作,甚至守护安全。从算盘到AI的旅程,已然抵达一个新起点——而你,就是下一个探路者。


参考文献

  1. Google Agent Development Kit. Quickstart Guide. https://google.github.io/adk-docs/get-started/quickstart/
  2. Google Agent Development Kit. Streaming Quickstart Guide. https://google.github.io/adk-docs/get-started/quickstart-streaming/
  3. Google Agent Development Kit. Tutorial: Build Your First Intelligent Agent Team. https://google.github.io/adk-docs/get-started/tutorial/
  4. Turing, A. M. (1950). “Computing Machinery and Intelligence.” Mind.
  5. Goodfellow, I. , et al. (2016). Deep Learning. MIT Press.

评论

发表回复

人生梦想 - 关注前沿的计算机技术 acejoy.com 🐾 步子哥の博客 🐾 背多分论坛 🐾 知差(chai)网