从0到1:Google ADK企业级多智能体开发终极指南
AI Agent(智能体)的概念火爆全网,它就像是给大模型装上了“手”和“脚”,能自主理解任务、调用工具、与外部世界交互。但对于很多刚入门的开发者来说,构建一个真正可用、可扩展的智能体系统似乎遥不可及。
今天,将用最浅显易懂的方式,一步步走完从单个智能体到企业级 Web 服务,再到多智能体系统的全过程。
这里将使用 Google 的 Agent Development Kit (ADK),并结合一个非常实用的案例——深度研究智能体,来进行学习。
学习内容
- 构建基础 ADK 智能体:如何使用 ADK 创建一个具备工具(Tools)使用能力的智能体。
- 变身企业级 Web 服务:如何使用 FastAPI 将你的智能体封装成一个高性能的 API 服务。
- 融入多智能体生态:如何使用最新的 FastMCP 协议,将你的智能体工具暴露出去,让其他 AI(如 Claude、Gemini 或你自己的其他智能体)可以发现并调用它们。
- 企业级开发最佳实践:贯穿全文的代码组织、环境管理和问题排查技巧。
准备工作
- Python 3.10+ 环境。
- 一个 Google Gemini API 密钥。你可以在 Google AI for Developers 免费获取。
- 基础的 Python 和 API 概念知识。
Part 1: 构建你的第一个“深度研究智能体”
想象一下,你需要一个能帮你做深度研究的助手。它至少需要两个核心能力:上网搜索和读取本地文件。这就是我们要构建的智能体的雏形。
Google ADK 正是为此而生的框架,它能帮你轻松地为大模型(如 Gemini)插上工具的翅膀。
步骤 1: 安装必要的库
首先,需要安装 ADK 核心库。为了方便管理 API 密钥,同时安装 python-dotenv
。
pip install google-adk python-dotenv
步骤 2: 创建项目结构
一个良好的项目结构是成功的开始。在你的工作区创建一个新文件夹,并按如下结构组织:
adk-researcher/
├── .env # 存放你的 API 密钥
├── research_agent/
│ ├── __init__.py # 包初始化文件
│ └── agent.py # 智能体核心定义
└── __init__.py # 根目录包初始化文件
在 .env
文件中,写入你的 Gemini API 密钥:
# .env 文件
GOOGLE_API_KEY="YOUR_GEMINI_API_KEY"
步骤 3: 编写智能体核心代码
现在,来编写智能体的核心逻辑。这里将定义两个工具函数:一个模拟的网页搜索工具和一个本地文件读取工具。
打开 research_agent/agent.py
文件,输入以下代码:
# research_agent/agent.py
import os
import requests # 实际开发中会用到,先做个模拟
from google.adk.agents import Agent
# --- 定义工具 (Tools) ---
def search_web(query: str) -> dict:
"""
根据给定的查询词在网上搜索信息。
在实际应用中,这里会调用真正的搜索引擎API,如Google Search API。
"""
print(f"--- 正在执行工具: search_web, 查询: {query} ---")
# 为了演示,我们返回一个模拟的搜索结果
if "mcp" in query.lower():
return {
"status": "success",
"results": [
{"title": "Model Context Protocol (MCP) Official Site", "snippet": "MCP是一种开放标准,用于AI模型与外部工具和服务进行通信..."},
{"title": "FastMCP: The Pythonic way to build MCP servers", "snippet": "FastMCP 是一个用于构建 MCP 服务器的现代 Python 框架..."},
]
}
return {
"status": "success",
"results": f"关于 '{query}' 的搜索结果为空。"
}
def read_local_file(file_path: str) -> dict:
"""
读取指定本地文件的内容。
"""
print(f"--- 正在执行工具: read_local_file, 路径: {file_path} ---")
try:
# 为了安全,我们只允许读取项目根目录下的文件
# 在真实项目中,需要更严格的路径校验!
base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
safe_path = os.path.join(base_dir, file_path)
if not os.path.exists(safe_path):
return {"status": "error", "error_message": f"文件 '{file_path}' 不存在。"}
with open(safe_path, 'r', encoding='utf-8') as f:
content = f.read()
return {"status": "success", "content": content}
except Exception as e:
return {"status": "error", "error_message": str(e)}
# --- 定义智能体 (Agent) ---
# 注意:根据 ADK 的规范,智能体实例必须命名为 root_agent
root_agent = Agent(
name="research_assistant",
model="gemini-2.5-flash", # 你可以选择其他 Gemini 模型
description="一个可以进行网络搜索和文件阅读的深度研究助手。",
instruction="""
你是一个能干的研究助理。
你的任务是根据用户的请求,利用你的工具(网页搜索、文件读取)来收集信息,并给出全面、有条理的回答。
在调用工具前,请先思考你需要什么信息。
""",
tools=[search_web, read_local_file], # 将我们定义的工具注册到智能体
)
专家提示:函数的 docstring
(文档字符串)和 type hints
(类型提示,如 query: str
)至关重要!ADK 会自动解析它们,生成给大模型看的工具说明,这直接影响大模型调用工具的准确性。
接着,编辑 research_agent/__init__.py
,将智能体导出,以便 ADK 的命令行工具可以找到它。
# research_agent/__init__.py
from .agent import root_agent
__all__ = ["root_agent"]
步骤 4: 测试你的智能体
ADK 提供了超方便的命令行和网页工具来测试你的成果。
命令行聊天测试:
# 确保你在 adk-researcher 目录下
adk chat -a research_agent
现在,你可以和它对话了!试试问它:“帮我搜索一下什么是MCP?”
网页界面测试:
# 同样在 adk-researcher 目录下
adk web -a research_agent
访问浏览器中提示的地址(通常是 http://127.0.0.1:8080
),你将看到一个功能完善的聊天界面。
至此,你已经成功构建了一个本地运行的、拥有基础工具的智能体。但这还只是第一步。
Part 2: 变身 Web 服务:集成 FastAPI
为了让智能体能被其他应用调用,或者部署到服务器上,我们需要将它变成一个 Web 服务。FastAPI 是我们的不二之选,它高性能、易于使用,并且与 ADK 配合得天衣无缝。
步骤 1: 安装 FastAPI 相关库
pip install fastapi "uvicorn[standard]" sqlalchemy
步骤 2: 创建 FastAPI 包装器
在项目根目录 adk-researcher/
下创建 api.py
文件。
# api.py
import os
import uvicorn
from fastapi import FastAPI
from google.adk.cli.fast_api import get_fast_api_app # ADK 提供的便捷函数
from dotenv import load_dotenv
# 加载 .env 文件中的环境变量
load_dotenv()
# --- FastAPI 应用设置 ---
# 设置路径,确保ADK能找到agent包
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
AGENT_DIR = BASE_DIR
# 为会话管理设置一个SQLite数据库路径
SESSION_DB_URL = f"sqlite:///{os.path.join(BASE_DIR, 'sessions.db')}"
# 使用ADK的帮助函数快速创建一个集成了ADK功能的FastAPI应用
app: FastAPI = get_fast_api_app(
agent_dir=AGENT_DIR,
session_db_url=SESSION_DB_URL,
allow_origins=["*"], # 在生产环境中,请务必限制为你的前端域名
web=True, # 启用ADK自带的Web UI
)
# --- 添加自定义 API 端点 ---
# 这展示了你可以在ADK的基础上自由扩展你的API
@app.get("/health")
async def health_check():
"""健康检查端点"""
return {"status": "healthy"}
@app.get("/agent-info")
async def agent_info():
"""获取智能体基本信息"""
# 动态导入,避免循环引用
from research_agent import root_agent
return {
"agent_name": root_agent.name,
"description": root_agent.description,
"model": root_agent.model,
"tools": [t.__name__ for t in root_agent.tools]
}
# --- 运行服务器 ---
if __name__ == "__main__":
print("启动 FastAPI Web 服务器...")
uvicorn.run(
app,
host="0.0.0.0",
port=9999,
reload=False # 生产环境建议关闭reload
)
步骤 3: 运行 FastAPI 服务器
python api.py
现在,你的智能体已经是一个标准的 Web 服务了!
- 访问
http://localhost:9999/dev-ui
可以看到和adk web
一样的聊天界面。 - 访问
http://localhost:9999/docs
可以看到 FastAPI 自动生成的 API 文档。 - 访问
http://localhost:9999/health
可以看到我们自定义的健康检查端点返回结果。
这已经是一个可以部署到云服务器上的企业级应用雏形了。但要实现真正的“多智能体”,还需要最后一步。
Part 3: 迈向多智能体:构建 FastMCP 服务器
模型上下文协议 (Model Context Protocol, MCP) 是一个开放标准,被誉为“AI 的 USB-C 接口”。它允许不同的 AI 模型、智能体和工具提供方以一种标准化的方式互相发现和通信。
我们将使用最新的 fastmcp
库,因为它更现代、更简洁,能用极少的代码将我们的工具暴露为 MCP 服务。
步骤 1: 安装 FastMCP
pip install fastmcp
步骤 2: 在 api.py
中添加 MCP 服务逻辑
我们将改造 api.py
,让它可以通过一个命令行参数,选择启动 FastAPI 模式,还是 MCP 模式。
# api.py (完整版)
import os
import uvicorn
import argparse
import asyncio
from fastapi import FastAPI
from google.adk.cli.fast_api import get_fast_api_app
from dotenv import load_dotenv
# --- 新增:FastMCP 相关导入 ---
from fastmcp import FastMCP
# 加载 .env 文件
load_dotenv()
# --- 导入我们的工具函数 ---
from research_agent.agent import search_web, read_local_file
# ==========================================================
# FastAPI 部分 (与之前相同)
# ==========================================================
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
AGENT_DIR = BASE_DIR
SESSION_DB_URL = f"sqlite:///{os.path.join(BASE_DIR, 'sessions.db')}"
app: FastAPI = get_fast_api_app(
agent_dir=AGENT_DIR,
session_db_url=SESSION_DB_URL,
allow_origins=["*"],
web=True,
)
@app.get("/health")
async def health_check():
return {"status": "healthy"}
@app.get("/agent-info")
async def agent_info():
from research_agent import root_agent
return {
"agent_name": root_agent.name,
"description": root_agent.description,
"model": root_agent.model,
"tools": [t.__name__ for t in root_agent.tools]
}
# ==========================================================
# FastMCP 部分 (全新)
# ==========================================================
def create_mcp_app() -> FastMCP:
"""创建并配置 FastMCP 应用"""
mcp_app = FastMCP("ResearcherMCP_Server")
# 使用装饰器,非常优雅地将现有函数注册为 MCP 工具
# FastMCP 会自动处理函数的签名和文档,生成符合协议的工具定义
mcp_app.tool(search_web)
mcp_app.tool(read_local_file)
return mcp_app
# ==========================================================
# 主程序入口 (改造后)
# ==========================================================
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="ADK 研究智能体服务器")
parser.add_argument(
"--mode",
choices=["web", "mcp"],
default="web",
help="选择运行模式: 'web' (FastAPI) 或 'mcp' (FastMCP)"
)
args = parser.parse_args()
if args.mode == "mcp":
print("启动 FastMCP 服务器模式...")
mcp_server = create_mcp_app()
# FastMCP 的 run() 方法会处理所有底层通信协议 (默认为stdio)
asyncio.run(mcp_server.run())
else:
print("启动 FastAPI Web 服务器模式...")
uvicorn.run(
app,
host="0.0.0.0",
port=9999,
reload=False
)
看到 create_mcp_app
函数了吗?使用 @mcp_app.tool()
装饰器,几乎不费吹灰之力就将已有的工具函数转换成了标准的 MCP 工具。
步骤 3: 测试 MCP 服务器
FastMCP 同样提供了强大的客户端工具用于测试。我们创建一个 test_mcp.py
文件。
# test_mcp.py
import asyncio
from fastmcp import Client
async def main():
print("正在连接到 MCP 服务器...")
# FastMCP 客户端可以直接连接到一个启动脚本
# 它会自动管理子进程和stdio通信,非常方便
async with Client(f"python api.py --mode mcp") as client:
try:
# 1. 列出所有可用的工具
tools = await client.list_tools()
tool_names = [tool.name for tool in tools]
print(f"\n✅ 成功发现 {len(tool_names)} 个工具: {', '.join(tool_names)}")
assert "search_web" in tool_names
assert "read_local_file" in tool_names
print("✅ 工具列表验证通过!")
# 2. 调用一个工具
print("\n正在调用 'search_web' 工具...")
query_args = {"query": "什么是 FastMCP"}
result = await client.call_tool("search_web", query_args)
print(f"✅ 工具调用成功,返回结果: \n{result.text}")
except Exception as e:
print(f"\n❌ 测试失败: {e}")
finally:
print("\n测试完成。")
if __name__ == "__main__":
asyncio.run(main())
现在,运行这个测试脚本:
python test_mcp.py
如果一切顺利,你将看到它成功连接到你的 MCP 服务器,列出了 search_web
和 read_local_file
两个工具,并成功调用了其中一个。
这意味着,你的“研究智能体”现在已经是一个标准的、可被发现、可被调用的多智能体系统节点了!任何支持 MCP 协议的客户端(比如 Claude Desktop 或其他高级 AI 框架)现在都可以配置使用你的这个工具集。
总结
恭喜你!从一个简单的 Python 脚本开始,你已经成功构建了一个功能强大、架构灵活的智能体系统。回顾一下你的成果:
- 一个基于 ADK、拥有核心工具集的“研究智能体”。
- 一个基于 FastAPI 的企业级 Web 服务,提供了标准的 HTTP 接口和漂亮的 Web UI。
- 一个基于 FastMCP 的多智能体节点,使你的工具可以被整个 AI 生态系统发现和利用。
最关键的是,这一切都源自同一套核心代码,通过不同的启动模式对外提供服务,这极大地提高了代码的复用性和可维护性。