site logo

Marico's space

多 Agent A2A:ADK、AWS Lambda 与 Gemini CLI

AI技术与应用 2026-04-26 11:48:25 13

译者按:本文是难得一见的 ADK 实战佳作。作者没有止步于 Hello World 级别的演示,而是从工程化视角完整展示了一个多 Agent 协作系统的构建流程:从本地开发调试到云端部署,从单体应用到分布式架构。文中关于 A2A 协议在无服务器环境下的实践、Agent 间的状态同步机制,以及流式输出的去重处理,都是实际项目中会遇到的痛点问题。建议配合源码阅读效果更佳。

市面上已经有不少 Python ADK 的入门教程,但大多停留在「如何创建一个 Agent」层面。本文的目标更进一步——搭建一个多 Agent 协作的测试平台,覆盖开发、调试、部署的全流程。

这有什么不一样?

与常见示例不同,本文是首批深入探索如何借助 Gemini CLI 的高级工具链来构建多 Agent 应用的实践教程。教程的起点是 Google 官方的 Codelab,经过重新设计和工程化改造,适配到了真实的生产开发场景。

原始 Codelab 地址:Building a Multi-Agent System

环境准备

Python 版本管理

Python 版本碎片化是老大难问题。本文使用 pyenv 来统一管理 Python 版本:

  • GitHub 地址:pyenv/pyenv

当前主流 Python 版本为 3.13。验证本地版本:

python --version
Python 3.13.13

Node 版本管理

Gemini CLI 对 Node 版本有要求,需要使用 nvm 来管理:

  • GitHub 地址:nvm-sh/nvm

核心组件介绍

Amazon Lambda

AWS Lambda (Amazon Web Services Lambda) 是亚马逊提供的无服务器、事件驱动计算服务。开发者只需关注业务代码(函数逻辑),底层的基础设施管理——包括容量配置、自动扩缩容、操作系统维护——全部由 AWS 代劳。

(在国内,阿里有函数计算 FC 对标,腾讯云也有 SCF,本质都是 FaaS 形态。)

Gemini CLI

这是 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

Agent Development Kit (ADK)

Google Agent Development Kit (ADK) 是一个开源的、基于 Python 的框架,用于简化复杂多 Agent AI 系统的创建、部署和编排。它将 Agent 开发视为软件工程,提供模块化架构、状态管理和内置工具(如 Google Search)来构建自主 Agent。

Agent Skills

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

验证 ADK 安装

用 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 Web 界面

启动 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 界面:

ADK Web界面截图

如果在云端环境部署(如 Google Cloud Shell),需要添加 CORS 配置以允许跨域访问:

adk web --host 0.0.0.0 --allow_origins 'regex:.*'

多 Agent 系统设计

整个系统由 5 个核心 Agent 组成:

  • Researcher:负责信息检索和资料收集
  • Judge:对研究结果进行评估和审核
  • Orchestrator:编排整个工作流程
  • Content Builder:将研究成果转化为结构化内容
  • Course Builder:构建最终的课程结构

关于多 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 控制台查看服务:

AWS Lambda控制台

端到端测试

运行完整测试:

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..."}

访问 Web 界面

通过 Lambda URL 访问部署后的应用:

https://wqv5reqmno6skv3xsqb64kgrsm0hletn.lambda-url.us-east-1.on.aws/

部署后应用界面

使用在线课程生成器:

课程生成器使用

Gemini CLI 代码审查

最后一步,用 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 系统。开发流程从本地调试到云端部署,整个链路一气呵成。

几个值得关注的工程亮点:

  1. A2A 协议在无服务器环境的适配:通过中间件动态重写 Agent Card URL,解决了 Lambda Function URL 在代理场景下的寻址问题
  2. 流式输出的去重处理:gateway 中的 merge_strings 逻辑优雅地解决了 SSE 流在网关层的合并问题
  3. 分布式状态管理:通过 StateCapturer 将事件流中的状态同步到 session 中,确保 Orchestrator 始终是权威数据源

如果要在生产环境使用,建议补充:会话持久化(DynamoDB 或 Redis)、服务间认证(IAM 或 JWT Token)以及更完善的监控告警体系。