
译者按:本文是难得一见的 ADK 实战佳作。作者没有止步于 Hello World 级别的演示,而是从工程化视角完整展示了一个多 Agent 协作系统的构建流程:从本地开发调试到云端部署,从单体应用到分布式架构。文中关于 A2A 协议在无服务器环境下的实践、Agent 间的状态同步机制,以及流式输出的去重处理,都是实际项目中会遇到的痛点问题。建议配合源码阅读效果更佳。
市面上已经有不少 Python ADK 的入门教程,但大多停留在「如何创建一个 Agent」层面。本文的目标更进一步——搭建一个多 Agent 协作的测试平台,覆盖开发、调试、部署的全流程。
与常见示例不同,本文是首批深入探索如何借助 Gemini CLI 的高级工具链来构建多 Agent 应用的实践教程。教程的起点是 Google 官方的 Codelab,经过重新设计和工程化改造,适配到了真实的生产开发场景。
原始 Codelab 地址:Building a Multi-Agent System
Python 版本碎片化是老大难问题。本文使用 pyenv 来统一管理 Python 版本:
当前主流 Python 版本为 3.13。验证本地版本:
python --version
Python 3.13.13
Gemini CLI 对 Node 版本有要求,需要使用 nvm 来管理:
AWS Lambda (Amazon Web Services Lambda) 是亚马逊提供的无服务器、事件驱动计算服务。开发者只需关注业务代码(函数逻辑),底层的基础设施管理——包括容量配置、自动扩缩容、操作系统维护——全部由 AWS 代劳。
(在国内,阿里有函数计算 FC 对标,腾讯云也有 SCF,本质都是 FaaS 形态。)
这是 Google 推出的命令行 AI 助手,可以直接与源码交互、提供实时帮助。如果未安装:
npm install -g @google/gemini-cli
安装完成后需要进行身份认证:
▝▜▄ Gemini CLI v0.33.1
▝▜▄
▗▟▀ Logged in with Google /auth
▝▀ Gemini Code Assist Standard /upgrade no sandbox (see /docs) /model Auto (Gemini 3) | 239.8 MB
Google Agent Development Kit (ADK) 是一个开源的、基于 Python 的框架,用于简化复杂多 Agent AI 系统的创建、部署和编排。它将 Agent 开发视为软件工程,提供模块化架构、状态管理和内置工具(如 Google Search)来构建自主 Agent。
Gemini CLI 可以与 ADK agents 深度集成,支持 Agent Development MCP server 和专门的 Agent skills。
查看可用的 Agent Skills:
> /skills list
Available Agent Skills:
查看 MCP 服务器配置:
> /mcp list
Configured MCP servers:
🟢 adk-docs-mcp (from adk-docs-ext) - Ready (2 tools)
Tools:
- mcp_adk-docs-mcp_fetch_docs
- mcp_adk-docs-mcp_list_doc_sources
所有代码示例和文档都在 GitHub 上。第一步把仓库拉到本地:
cd ~
git clone https://github.com/xbill9/gemini-cli-aws
cd multi-lambda
运行初始化脚本:
source init2.sh
脚本会自动检测你的 shell 环境并配置相应变量。如果会话超时或需要重新认证,运行:
source set_env.sh
登录云控制台:
aws login --remote
安装依赖包:
make install
用 researcher agent 在本地验证 ADK 是否正常工作:
xbill@penguin:~/gemini-cli-aws/multi-lambda/agents$ adk run researcher
/home/xbill/.pyenv/versions/3.13.13/lib/python3.13/site-packages/authlib/_joserfc_helpers.py:8: AuthlibDeprecationWarning: authlib.jose module is deprecated, please use joserfc instead.
It will be compatible before version 2.0.0.
from authlib.jose import ECKey
/home/xbill/.pyenv/versions/3.13.13/lib/python3.13/site-packages/google/adk/features/_feature_decorator.py:72: UserWarning: [EXPERIMENTAL] feature FeatureName.PLUGGABLE_AUTH is enabled.
check_feature_enabled()
Log setup complete: /tmp/agents_log/agent.20260422_134822.log
To access latest log: tail -F /tmp/agents_log/agent.latest.log
{"asctime": "2026-04-22 13:48:23,011", "name": "root", "levelname": "INFO", "message": "Logging initialized for researcher", "filename": "logging_config.py", "lineno": 54, "service": "researcher", "log_level": "INFO"}
{"asctime": "2026-04-22 13:48:23,013", "name": "researcher.agent", "levelname": "INFO", "message": "Initialized researcher agent with model: gemini-2.5-flash", "filename": "agent.py", "lineno": 85}
{"asctime": "2026-04-22 13:48:23,015", "name": "google_adk.google.adk.cli.utils.envs", "levelname": "INFO", "message": "Loaded .env file for researcher at /home/xbill/gemini-cli-aws/multi-lambda/.env", "filename": "envs.py", "lineno": 83}
{"asctime": "2026-04-22 13:48:23,016", "name": "google_adk.google.adk.cli.utils.local_storage", "levelname": "INFO", "message": "Using per-agent session storage rooted at /home/xbill/gemini-cli-aws/multi-lambda/agents", "filename": "local_storage.py", "lineno": 84}
{"asctime": "2026-04-22 13:48:23,016", "name": "google_adk.google.adk.cli.utils.local_storage", "levelname": "INFO", "message": "Using file artifact service at /home/xbill/gemini-cli-aws/multi-lambda/agents/researcher/.adk/artifacts", "filename": "local_storage.py", "lineno": 110}
{"asctime": "2026-04-22 13:48:23,017", "name": "google_adk.google.adk.cli.utils.service_factory", "levelname": "INFO", "message": "Using in-memory memory service", "filename": "service_factory.py", "lineno": 266}
{"asctime": "2026-04-22 13:48:23,047", "name": "google_adk.google.adk.cli.utils.local_storage", "levelname": "INFO", "message": "Creating local session service at /home/xbill/gemini-cli-aws/multi-lambda/agents/researcher/.adk/session.db", "filename": "local_storage.py", "lineno": 60}
Running agent researcher, type exit to exit.
[user]:
启动 ADK agent 的 Web 界面:
xbill@penguin:~/gemini-cli-aws/multi-lambda/agents$ adk web --host 0.0.0.0
通过本地地址 127.0.0.1 或全网地址 0.0.0.0 访问 Web 界面:

如果在云端环境部署(如 Google Cloud Shell),需要添加 CORS 配置以允许跨域访问:
adk web --host 0.0.0.0 --allow_origins 'regex:.*'
整个系统由 5 个核心 Agent 组成:
关于多 Agent 架构的详细设计思路,可以参考这篇文章:Multi-Agent A2A with the Agent Development Kit (ADK), Cloud Run, and Gemini CLI
查看当前运行状态:
xbill@penguin:~/gemini-cli-aws/multi-lambda$ make status
Checking status of locally running agents and servers...
--- Network Status ---
No services listening on expected ports (8000-8004, 5173).
--- Process Status ---
No matching processes found.
一键启动所有服务:
✦ The frontend has been built and all local services (Researcher, Judge, Content Builder, Orchestrator, App Backend, and Frontend dev server) have
been started in the background.
- Frontend: http://localhost:5173
- Backend: http://localhost:8000
Logs for each service are available in the project root: researcher.log, judge.log, content_builder.log, orchestrator.log, backend.log, and
frontend.log.
连接本地前端:

整个 Agent 系统在本地环境运行:

Gemini CLI 可以直接访问本地 Agent 日志用于调试:
> review the local logs for the multi-agent run
✦ I will check run_local.sh and the project structure to determine where logs are stored or how they are generated.
验证本地运行情况:
✦ The local logs confirm a successful multi-agent run for the topic "the history of the internet." Here is a summary of the execution flow:
* Orchestrator (orchestrator.log): Successfully managed the pipeline. It captured the topic, coordinated the Research-Judge loop, and escalated to
content generation after the first iteration.
* Researcher (researcher.log): Gathered approximately 9.2KB of research data using the google_search tool. It completed its task with a 200 OK
response.
* Judge (judge.log): Evaluated the findings and gave a "pass" status. The judge noted that the research was "comprehensive, accurate, and
well-structured," making it an "excellent foundation for educational content."
* Content Builder (content_builder.log): Successfully transformed the validated research into a structured Markdown course module and finished
execution.
* Backend & Frontend (backend.log, frontend.log): The FastAPI backend (port 8000) and Vite frontend (port 5173) are running and communicating with
the orchestrator as expected.
Notable Observation:
* A minor warning appeared in researcher.log: Researcher callback: 'response' not found or has no parts. However, this did not impact the
successful completion of the research or the overall pipeline.
All services are currently active and logged at the DEBUG level as specified in run_local.sh.
使用 Makefile 部署到 AWS Lambda:
xbill@penguin:~/gemini-cli-aws/multi-lambda$ make deploy
chmod +x lambda/deploy-lambda.sh
./lambda/deploy-lambda.sh
Ensuring IAM role McpLambdaExecutionRole exists...
Logging in to Amazon ECR...
部署完成后获取各服务的 URL:
xbill@penguin:~/gemini-cli-aws/multi-lambda$ make endpoint
https://wqv5reqmno6skv3xsqb64kgrsm0hletn.lambda-url.us-east-1.on.aws/
查看所有 Lambda 函数状态:
xbill@penguin:~/gemini-cli-aws/multi-lambda$ make status
Course Creator Lambda Status:
-----------------------------------------------------
---------------------------------------------
| GetFunction |
+---------------------------------+---------+
| Name | Status |
+---------------------------------+---------+
| course-creator-course-builder | Active |
+---------------------------------+---------+
URL: https://wqv5reqmno6skv3xsqb64kgrsm0hletn.lambda-url.us-east-1.on.aws/
-----------------------------------------------------
-------------------------------------------
| GetFunction |
+-------------------------------+---------+
| Name | Status |
+-------------------------------+---------+
| course-creator-orchestrator | Active |
+-------------------------------+---------+
URL: https://q5bciiujjktr6wris6tple6fra0yyrqc.lambda-url.us-east-1.on.aws/
-----------------------------------------------------
-----------------------------------------
| GetFunction |
+----------------------------+----------+
| Name | Status |
+----------------------------+----------+
| course-creator-researcher | Active |
+----------------------------+----------+
URL: https://gfhdoxhiiznflcz2cdhc65z2eq0cwimd.lambda-url.us-east-1.on.aws/
-----------------------------------------------------
------------------------------------
| GetFunction |
+-----------------------+----------+
| Name | Status |
+-----------------------+----------+
| course-creator-judge | Active |
+-----------------------+----------+
URL: https://kaen6rupkl5ph5kde2g6h7wgr40sirch.lambda-url.us-east-1.on.aws/
-----------------------------------------------------
----------------------------------------------
| GetFunction |
+----------------------------------+---------+
| Name | Status |
+----------------------------------+---------+
| course-creator-content-builder | Active |
+----------------------------------+---------+
URL: https://k5wt4o6vrdao3w4zjiabszdeue0kauxp.lambda-url.us-east-1.on.aws/
在 AWS 控制台查看服务:

运行完整测试:
xbill@penguin:~/gemini-cli-aws/multi-lambda$ make e2e-test-lambda
Fetching Lambda endpoint...
make[1]: Entering directory '/home/xbill/gemini-cli-aws/multi-lambda'
Running end-to-end test against https://wqv5reqmno6skv3xsqb64kgrsm0hletn.lambda-url.us-east-1.on.aws/...
Temporary JSON file content: {"message": "Create a short course about the history of the internet", "user_id": "e2e_test_user"}
Executing: curl -s -X POST https://wqv5reqmno6skv3xsqb64kgrsm0hletn.lambda-url.us-east-1.on.aws/api/chat_stream -H "Content-Type: application/json" -d @/tmp/tmp.vmxl0Dsf88 --no-buffer
{"type": "progress", "text": "🚀 Connected to backend, starting research..."}
{"type": "progress", "text": "🚀 Starting the course creation pipeline..."}
{"type": "progress", "text": "🔍 Research is starting..."}
{"type": "progress", "text": "🔍 Researcher is gathering information..."}
{"type": "progress", "text": "⚖️ Judge is evaluating findings..."}
{"type": "progress", "text": "⚖️ Judge is evaluating findings..."}
{"type": "progress", "text": "📝 Building the final course content..."}
通过 Lambda URL 访问部署后的应用:
https://wqv5reqmno6skv3xsqb64kgrsm0hletn.lambda-url.us-east-1.on.aws/

使用在线课程生成器:

最后一步,用 Gemini CLI 对整个项目进行代码审查:
✦ The multi-lambda project is a well-engineered, distributed multi-agent system that effectively leverages the
Google Agent Development Kit (ADK) and the A2A protocol within an AWS Lambda environment. The architecture is
modular, resilient, and optimized for streaming AI interactions.
Key Strengths
* Robust Orchestration: The use of SequentialAgent and LoopAgent in agents/orchestrator/agent.py creates a
sophisticated Research-Judge pipeline. Custom components like StateCapturer and EscalationChecker provide
fine-grained control over the agent loop and state persistence.
* Infrastructure-Aware A2A: The middleware in shared/a2a_utils.py dynamically rewrites agent card URLs based on
x-forwarded-* headers, a critical feature for services running behind proxies or as Lambda Function URLs.
* Intelligent Agent Callbacks: Each sub-agent (researcher, judge, content_builder) utilizes
before_agent_callback to sanitize inputs and recover topics/findings from session history. This makes the
agents highly resilient to the "noise" of accumulated conversation history.
* Unified Deployment: The project employs a single Docker image (using the aws-lambda-adapter) for all
services. The deploy-lambda.sh script automates the complex task of deploying five distinct services,
managing their Function URLs, and wiring them together via environment variables.
* Modern Python Stack: The use of Python 3.13 and uvicorn ensures high performance, while the gateway's
merge_strings logic gracefully handles the complexities of streaming deduplication.
Observations & Recommendations
* Session Persistence: Currently, the system appears to use ADK's default in-memory session storage. In a
Lambda environment, sessions may be lost across cold starts or scaling events. For production use,
integrating a persistent session store (e.g., DynamoDB or Redis) via the session_service_uri option is
recommended.
* Security: Inter-agent communication currently bypasses IAM authentication (using NONE auth type) and relies
on the authenticated_httpx.py bypass logic. While acceptable for a demo, production environments should
leverage AWS IAM or Google Identity Tokens for service-to-service authorization.
* State Management: The orchestrator's StateCapturer effectively "syncs" findings from the event stream into
the session state. This is a clever approach to distributed state management, ensuring the Orchestrator
remains the source of truth even when sub-agents are remote.
Overall, this is a sophisticated implementation that successfully bridges Google's AI agent framework with AWS's
serverless infrastructure.
本文完整展示了如何使用 Agent Development Kit (ADK) 结合 Gemini Flash LLM 模型构建支持 A2A 协议的多 Agent 系统。开发流程从本地调试到云端部署,整个链路一气呵成。
几个值得关注的工程亮点:
如果要在生产环境使用,建议补充:会话持久化(DynamoDB 或 Redis)、服务间认证(IAM 或 JWT Token)以及更完善的监控告警体系。