哈哈,这个标题确实有点夸张了呢!不过本文的重点是介绍如何使用 Google 的 Agent 开发工具包(ADK)和模型上下文协议(MCP)来构建智能 AI 代理,并且结合了 Google 的 Gemini LLM(大型语言模型)作为 MCP 客户端。文章详细讲解了从环境搭建到代码实现的全过程,还涉及了如何通过 MCP 与外部工具交互,以及如何处理一些常见的问题和注意事项。整体来说,是一篇技术性很强的教程,适合对 AI 代理开发感兴趣的朋友哦!
文章来自Arjun Prabhulal,大佬的源码在https://github.com/arjunprabhulal/adk-python-mcp-client
什么是 ADK — Agent 开发工具包?
Agent 开发工具包(ADK) 是一个开源的、以代码为中心的 Python 工具包,用于构建、评估和部署智能 AI 代理。
ADK 使开发人员能够创建代理工作流 — 从简单的单代理任务到复杂的多代理编排 — 全部在一个模块化且可扩展的框架内完成。
ADK 中的代理是什么?
代理 是一个自主的、自包含的执行单元,旨在实现特定目标。代理可以:
- 执行任务,
- 与用户交互,
- 利用外部工具,以及
- 与其他代理协作以完成复杂的工作流。
https://google.github.io/adk-docs/agents/
核心代理类别
ADK 提供三种主要的代理类型,以支持:
- LLM 代理(例如 LlmAgent、Agent):使用 LLM 进行理解、推理、规划和行动 — 非常适合动态的、以语言驱动的任务。
- 工作流代理(例如 SequentialAgent、ParallelAgent、LoopAgent):以可预测的模式协调其他代理,而不依赖于 LLM 进行流程控制 — 最适合结构化、可重复的过程。
- 自定义代理:通过扩展 BaseAgent 来实现自定义逻辑、专业工作流或独特的工具集成 — 非常适合高级的、量身定制的解决方案。
在本文中,我们将使用 LLM 代理类型,并结合 MCPTools。
在 ADK 的上下文中,工具是什么?
工具 表示授予 AI 代理的特定能力,允许它执行动作并与外部世界进行交互,而不仅仅是基本的文本生成和推理。
工具通常是模块化的代码组件 — 例如 Python 函数、类方法,甚至是另一个代理 — 设计用于执行定义的任务。
代理如何使用工具?
代理通过 函数调用机制 动态利用工具,其中 LLM 会对上下文进行推理,选择并调用适当的工具,生成输入,观察结果,并将输出整合到其下一步操作或响应中。
ADK 中的工具类型
ADK 支持几种类型的工具:
-
函数工具:为我们的应用程序的独特逻辑和工作流专门构建的自定义工具。
- 函数/方法:作为工具注册的标准同步 Python 函数(def)或类方法。
- 代理作为工具:在父代理中将专业代理用作可调用工具,以实现模块化行为。
- 长运行函数工具:为异步或耗时操作设计的工具。
-
内置工具:框架中预定义的工具,用于执行网络搜索、代码执行或 RAG 等任务。
-
第三方工具:轻松集成来自流行生态系统(如 LangChain 或 CrewAI)的工具。
架构
图由作者提供
实现
让我们通过分解关键实现步骤,使用 ADK + MCP + Gemini AI 构建这个管道。
准备工作
-
安装 Python 3.8+
-
通过 API 密钥获取 Google Gemini 生成式 AI 访问权限
-
获取有效的 SerpAPI 密钥(用于获取实时航班数据)
第一步:设置虚拟环境
安装依赖项
# 设置虚拟环境(mac 或 Unix)
python -m venv venv && source venv/bin/activate
# 安装代理开发工具包
pip install google-adk
# 安装 MCP 服务器
pip install mcp-flight-search
# 安装 GenAI Python SDK
pip install google-genai
google-sdk:Google 的代理开发工具包,用于构建代理。
google-genai:Google 的库,用于与生成式 AI 模型(如 Gemini)交互。
mcp-flight-search:使用 MCP 库的 MCP 服务器,通过 SerpAPI 搜索航班。
设置环境变量:
注意这里的变化:在 ADK 中,它将是 GOOGLE_API_KEY,而不是 GEMINI_API_KEY
export GOOGLE_API_KEY="your-google-api-key"
export SERP_API_KEY="your-serpapi-key"
第二步:安装 MCP 服务器 — mcp-flight-search
为了让 Gemini 能够与现实世界的 API 进行交互,我们将使用符合 MCP 标准的服务器。
在本文中,我们将使用 mcp-flight-search — 这是一个使用 FastMCP 构建的轻量级 MCP 服务器,它通过 SerpAPI 暴露一个工具,用于搜索实时航班数据。
验证安装的 MCP 服务器包 https://pypi.org/project/mcp-flight-search/
# 从 PyPI 安装(已在第一步安装)
pip install mcp-flight-search
第三步:理解 ADK 作为 MCP 客户端
from google.adk.agents.llm_agent import LlmAgent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters
LlmAgent — 是 ADK 中的核心组件,作为我们应用程序的“思考”部分,它利用大型语言模型(LLM)的力量进行推理、理解自然语言、做决策、生成响应以及与工具进行交互。
Runner 负责协调代理生命周期中各个组件之间的交互。Runner 使用内存中的实现来提供工件、会话和内存服务,为代理执行提供一个轻量级且自包含的环境。
InMemorySessionService 是 ADK 的 SessionService 接口的一个实现,它直接将所有会话数据 — 例如对话历史记录、状态和元数据 — 存储在应用程序的内存中。这意味着当应用程序停止或重新启动时,所有会话信息都会丢失。
当用户与 AI 代理交互时,会创建一个会话对象来跟踪对话。
MCPToolSet — 是 ADK 中的一个类,它使我们的 AI 代理能够连接到外部 MCP 服务器。这些服务器暴露工具 — 例如 API 或服务 — 代理可以利用这些工具来执行特定任务。通过使用 MCPToolset,代理可以无缝地发现、调用和管理这些外部工具。
StdioServerParameters 是一个配置类,用于指定代理应如何通过标准输入/输出流连接到 MCP 服务器。当 MCP 服务器是一个通过控制台通信的本地进程时,这特别有用。
MCPToolSet 和 StdioServerParameters 是如何协同工作的?
当组合使用时,MCPToolSet 和 StdioServerParameters 允许 ADK 代理:
- 建立连接:使用 StdioServerParameters,定义启动 MCP 服务器进程所需的命令和参数。
- 发现可用工具:MCPToolSet 连接到 MCP 服务器并检索代理可以使用的工具列表。
- 将工具集成到代理中:发现的工具被适配成与 ADK 代理兼容的格式,允许在代理执行期间无缝调用。
- 管理连接生命周期:MCPToolSet 处理与 MCP 服务器连接的设置和拆除,确保资源得到适当管理。
第四步:连接到 MCP 服务器
StdioServerParameters 定义了 MCP 配置,通过 MCPToolSet 以异步方式列出和监听。
# --- 第一步:从 MCP 服务器获取工具 ---
async def get_tools_async():
"""从飞行搜索 MCP 服务器获取工具。"""
print("尝试连接到 MCP 飞行搜索服务器...")
server_params = StdioServerParameters(
command="mcp-flight-search",
args=["--connection_type", "stdio"],
env={"SERP_API_KEY": os.getenv("SERP_API_KEY")},
)
tools, exit_stack = await MCPToolset.from_server(
connection_params=server_params
)
print("MCP 工具集创建成功。")
return tools, exit_stack
第五步:从 ADK 创建代理
如上所述,我们将使用 Llm 代理,这是应用程序的思考部分。
# --- 第二步:定义 ADK 代理创建 ---
async def get_agent_async():
"""创建一个配备了来自 MCP 服务器工具的 ADK 代理。"""
tools, exit_stack = await get_tools_async()
print(f"从 MCP 服务器获取了 {len(tools)} 个工具。")
# 创建 LlmAgent,匹配示例结构
root_agent = LlmAgent(
model=os.getenv("GEMINI_MODEL", "gemini-2.5-pro-preview-03-25"),
name='flight_search_assistant',
instruction='帮助用户使用可用工具根据提示搜索航班。如果未指定返回日期,则使用空字符串表示单程旅行。',
tools=tools,
)
return root_agent, exit_stack
第六步:将代理创建、会话管理和编排与 Runner 整合
async def async_main():
# 创建服务
session_service = InMemorySessionService()
# 创建会话
session = session_service.create_session(
state={}, app_name='flight_search_app', user_id='user_flights'
)
# 定义用户提示
query = "Find flights from Atlanta to Las Vegas 2025-05-05"
print(f"用户查询:'{query}'")
# 将输入格式化为 types.Content
content = types.Content(role='user', parts=[types.Part(text=query)])
# 获取代理和 exit_stack
root_agent, exit_stack = await get_agent_async()
# 创建 Runner
runner = Runner(
app_name='flight_search_app',
agent=root_agent,
session_service=session_service,
)
print("运行代理...")
events_async = runner.run_async(
session_id=session.id,
user_id=session.user_id,
new_message=content
)
# 处理事件
final_content = None
async for event in events_async:
print(f"收到事件:{event}")
# 始终清理资源
print("关闭 MCP 服务器连接...")
await exit_stack.aclose()
print("清理完成。")
第七步:演示
用户在 MCP 客户端中的查询:
query = "Find flights from Atlanta to Las Vegas 2025-05-05"
标准日志记录的演示
调试日志记录的演示
将 MCP 与 ADK 集成的关键注意事项
-
MCP 与 ADK
- MCP 是一种 开放协议,用于标准化 AI 模型与外部工具和数据源的交互。
- ADK 是一个 基于 Python 的框架,用于构建和部署 AI 代理。
- MCPToolset:作为桥梁,使 ADK 代理能够使用 MCP 服务器暴露的工具。
要在 Python 中构建 MCP 服务器,请使用 model-context-protocol 库。
-
工具类型和集成
- ADK 工具:设计用于直接在 ADK 代理中使用的 Python 对象(例如 BaseTool、FunctionTool)。
- MCP 工具:由 MCP 服务器暴露的能力,MCPToolset 将其适配为可在 ADK 代理中使用的工具。
- 第三方工具:像 LangChain 和 CrewAI 这样的库提供了可以使用 LangchainTool 和 CrewaiTool 等包装器集成到 ADK 中的工具。
-
异步架构
- ADK 和 MCP Python 库都基于 Python 的 asyncio 框架构建。
- 工具实现和服务器处理程序应为异步(async def),以确保操作不会阻塞。
-
MCP 中的状态化会话
- 与典型的无状态 REST API 不同,MCP 在客户端和服务器之间建立了持久的、有状态的连接。
- 这种有状态性允许在交互之间保留上下文,但需要谨慎管理会话。
-
部署注意事项
- MCP 连接的持久性可能会给远程服务器处理多个用户时的扩展和部署带来挑战。
- 基础设施考虑因素包括负载均衡和会话亲和性,以保持连接稳定性。
-
在 ADK 中管理 MCP 连接
- MCPToolset 在 ADK 中管理 MCP 连接的生命周期。
- 使用 exit_stack 确保在代理执行完成后正确终止连接。
故障排除:
-
默认情况下,adk 库期望使用 GCP 项目 Vertex AI、位置和 VertexAI 配置。请确保使用 GOOGLE_API_KEY,而不是 GEMINI_API_KEY,因为错误消息可能不会清楚地表明缺少环境值。
解决方案:确保将变量设置为 GOOGLE_API_KEY
ValueError: Missing key inputs argument! To use the Google AI API, provide (`api_key`) arguments. To use the Google Cloud API, provide (`vertexai`, `project` & `location`) arguments.
-
频繁出现 429 速率限制错误和 500 内部服务器错误。
解决方案:切换到 Gemini 2 Flash,因为 "Gemini API 的免费层级通过 API 服务提供,具有较低的速率限制,仅用于测试目的"
google.genai.errors.ClientError: 429 RESOURCE_EXHAUSTED. {'error': {'code': 429, 'message': 'You exceeded your current quota, please check your plan and billing details. For more information on this error, head to: https://ai.google.dev/gemini-api/docs/rate-limits.', 'status': 'RESOURCE_EXHAUSTED', 'details': [{'@type': 'type.googleapis.com/google.rpc.QuotaFailure', 'violations': [{'quotaMetric': 'generativelanguage.googleapis.com/generate_content_free_tier_requests', 'quotaId': 'GenerateRequestsPerDayPerProjectPerModel-FreeTier', 'quotaDimensions': {'model': 'gemini-2.0-pro-exp', 'location': 'global'}, 'quotaValue': '25'}]}, {'@type': 'type.googleapis.com/google.rpc.Help', 'links': [{'description': 'Learn more about Gemini API quotas', 'url': 'https://ai.google.dev/gemini-api/docs/rate-limits'}]}, {'@type': 'type.googleapis.com/google.rpc.RetryInfo', 'retryDelay': '27s'}]}} An error occurred during execution: 500 INTERNAL. {'error': {'code': 500, 'message': 'An internal error has occurred. Please retry or report in https://developers.generativeai.google/guide/troubleshooting', 'status': 'INTERNAL'}}
Gemini API 成本计费
Gemini 2.5 Pro 预览版 — 根据 Google 文档,Gemini API 的“免费层级”通过 API 服务提供,具有较低的速率限制,仅用于测试目的。Gemini API 的“付费层级”提供更高的速率限制、额外功能以及不同的数据处理方式。
官方文档参考
- Agent 开发工具包(ADK)文档 — 完整的指南,介绍与 Gemini 和 Google 集成的开源 AI 代理框架。
- ADK 中的 LLM 代理 — 关于实现 LLM 代理的详细文档,包括定义身份、指令、工具和高级配置。
- 使用 ADK 作为 MCP 客户端的 MCP 工具 — 关于使用 ADK 作为 MCP 客户端连接到 MCP 服务器的具体指导。