07 · Google ADK:最像「企业软件」的 Agent 框架
前置:会调大模型 API。做过需要交付、需要过审的企业项目会更有共鸣。
别的框架文档第一页是「20 行代码跑通一个 Agent」。这个框架的文档第一页是目录结构、配置、评测集和部署目标。
第一眼会觉得啰嗦。但如果你的处境是:这个 Agent 要交付给客户、要过合规审查、要有人接手维护、要能证明它这版比上版强 —— 那这套啰嗦就是它在替你先想好的事。
图片来源:google/adk-python
| 仓库 | google/adk-python |
| Star | 21.2k(Go 版 8.7k、Java 版 1.7k) |
| 版本 | 2.7.1(相对 1.x 有破坏性变更) |
| 语言 | Python / TypeScript / Go / Java / Kotlin 五种 |
| 许可证 | Apache 2.0 |
| 层级 | Framework,自带 Runtime 能力 |
| 一句话 | 把软件工程规范(分层 、测试、评测、部署、协议)套到 Agent 开发上,Gemini 优化但不锁定 |
一、定位:它是本专题里「最不像玩具」的一个
这种取向具体落在这几个地方:
- 五种语言官方实现 —— Python / TypeScript / Go / Java / Kotlin。Java 和 Go 版的存在直接说明它想进的是什么样的公司
- 自带评测:
adk eval跑 evalset,是本专题里少数把评测做进核心的框架 - 自带 Web 调试 UI:
adk web,不用连第三方 SaaS - Agent Config:YAML 定义 Agent,不写代码
- A2A 协议:跨框架、跨组织的 Agent 互通
二、两个主类:Agent 和 Workflow
官方给新手的定位很清楚:Agent 定义「一个 AI 怎么想」,Workflow 定义「多个步骤怎么走」。
2.1 Agent
from google.adk import Agent
# ADK 约定:模块里名为 root_agent 的变量就是入口,
# `adk run` / `adk web` 会自动找它,不用你写启动代码
root_agent = Agent(
name="greeting_agent", # 名字要唯一,多 Agent 时用来互相引用
model="gemini-2.5-flash", # 也可以换成其他厂商的模型
instruction="You are a helpful assistant. Greet the user warmly.", # 系统提示词
)
2.2 Workflow:ADK 2.0 的核心新东西
from google.adk import Agent, Workflow
# 两个各司其职的小 Agent
generate_fruit_agent = Agent(
name="generate_fruit_agent",
instruction="Return the name of a random fruit. Return only the name.",
)
generate_benefit_agent = Agent(
name="generate_benefit_agent",
instruction="Tell me a health benefit about the specified fruit.",
)
# Workflow 负责编排:谁先跑、谁后跑、怎么分支
root_agent = Workflow(
name="root_agent",
# 一个元组就是一条链:START → 先出水果名 → 再讲这个水果的好处。
# 上一个节点的输出会自动成为下一个节点的输入
edges=[("START", generate_fruit_agent, generate_benefit_agent)],
)
三、Workflow 图:和 LangGraph 的同与不同
ADK 2.0 把工作流做成有向图,节点(NodeLike)可以是:
@node装饰的 Python 函数(同步 / 异步 / 生成器)LlmAgent实例BaseTool实例- 另一个
Workflow(可嵌套) START哨兵节点
3.1 边的三种写法:链式元组是亮点
from google.adk.workflow import DEFAULT_ROUTE, START
# ① 顺序:元组里从左到右依次执行,START -> a -> b -> c
edges = [(START, step_a, step_b, step_c)]
# ② 并行 fan-out:位置上放一个「元组」,里面的节点同时开跑
# 含义是 START -> a,然后 a -> b 和 a -> c 并发
edges = [(START, step_a, (step_b, step_c))]
# ③ 条件路由:位置上放一个「字典」,键是路由标签,值是去向节点。
# step_a 内部通过 yield Event(route="success") 发出标签,框架据此选边
edges = [
(START, step_a, {
"success": step_b, # a 发出 "success" 就走 b
"failure": step_c, # 发出 "failure" 就走 c
DEFAULT_ROUTE: fallback_step, # 发出别的标签一律走兜底分支
}),
]
节点通过 yield Event(route="success") 发出路由信号。也支持显式的 Edge 对象写法:
from google.adk.workflow import Edge, START
# 和上面的链式元组等价,只是把每条边显式写出来。
# 图很复杂时这种写法更好读,也更容易在代码里动态拼装
edges = [
Edge(from_node=START, to_node=step_a), # 无条件边
Edge(from_node=step_a, to_node=step_b, route="success"), # 带路由标签的条件边
Edge(from_node=step_a, to_node=step_c, route="failure"),
]
3.2 编译期校验 —— 这是它比 LangGraph 强的地方
Workflow 初始化时会跑 validate_graph(),把结构性错误在启动时就报出来:节点名必须唯一、必须有且只有一个 START、START 不能有入边等等。
| ADK 2.0 Workflow | LangGraph StateGraph | |
|---|---|---|
| 边的写法 | 链式元组,一行表达顺序 / 并行 / 条件 | add_edge / add_conditional_edges 逐条加 |
| 状态 | Session State(带作用域前缀) | TypedDict + Reducer |
| 并行合并 | Join node | Reducer 自动归并 |
| 图校验 | 实例化时强校验 | 编译时校验较弱 |
| 持久化 | SessionService(含 Vertex 托管) | Checkpointer(含 Postgres) |
| 心智负担 | 中等 | 高(reducer 语义要理解) |
ADK 的链式元组语法确实比 LangGraph 逐条 add_edge 更紧凑可读,代价是灵活度略低。
其他内置节点能力:retry_config 重试、join_node 汇合、parallel_worker 并行工人、dynamic_nodes 运行时动态生成节点。
四、Session / State / Memory:三层上下文
这是 ADK 设计里我认为最值得学的部分 —— 它把「状态该存多久、给谁看」做成了 key 前缀:
| 前缀 | 作用域 | 举例 |
|---|---|---|
| 无前缀 | 仅当前会话 | draft(这次对话的草稿) |
user: | 该用户的所有会话 | user:display_name |
app: | 整个应用所有用户 | app:model_tier |
temp: | 仅当前一次调用,不落盘 | temp:intermediate_calc |
from google.adk.sessions import InMemorySessionService
session = await session_service.create_session(
app_name="notes", # 应用名,app: 前缀的数据以它为作用域
user_id="ada", # 用户 ID,user: 前缀的数据以它为作用域
session_id="monday", # 这次会话的 ID,无前缀的数据只在这次会话里可见
state={
"app:model_tier": "pro", # 全应用共享:所有用户、所有会话都读得到
"user:display_name": "Ada", # 该用户的所有会话共享:明天新开会话还在
# 还可以写 "draft": "..."(只在本次会话)
# 或 "temp:calc": 1(只在本次调用内,根本不落盘)
},
)
4.1 一个必须理解的机制:写入是 delta,靠 Event 落盘
代码不直接改 Session.state 那个 dict,而是写 ctx.state(工具里就是 ToolContext)。每次写会记录两遍:一遍进当前值(下一行代码能读到),一遍进 delta(挂在即将发出的 Event 上)。只有 event 被 append 时,delta 才真正持久化。
这个设计让「状态变更」和「执行事件」天然对齐 —— 事件流就是完整的状态变更审计日志。对要过合规的系统很友好。
三种 SessionService:InMemorySessionService(开发)、DatabaseSessionService(自托管)、VertexAiSessionService(GCP 托管)。另有独立的 MemoryService 管跨会话长期记忆。
官方明确:2.0 对 agent API、event model、session schema 都有破坏性变更。ADK 2.0 生成的 session 能被 1.28+ 读(多余字段忽略),但和更老的 1.x 不兼容。 老项目升级前先看迁移文档。
五、工具与人工确认
工 具来源:自定义函数、OpenAPI spec 自动生成、MCP tools、内置工具(google_search 等)、以及跨框架工具适配。
Tool Confirmation 是它的 HITL 机制 —— 在工具执行前要求显式确认,还能带自定义输入表单。对照 01 D6 维度,这属于第 3 档(工具级审批协议)。
六、开发体验:adk 命令行
adk run path/to/my_agent # 在终端里和 Agent 对话,最快的调试方式
adk web path/to/agents_dir # 起本地 Web UI,能看每一步的事件、状态、工具调用
# 跑评测集做回归:第一个参数是 Agent 目录,第二个是评测用例文件。
# 改完提示词跑一遍,就知道有没有把原来对的场景改坏
adk eval samples/hello_world samples/hello_world/hello_world_eval_set_001.evalset.json
图片来源:google/adk-python
adk eval 值得单独说:它把「评测集」做成一等公民,你可以把回归用例存成 .evalset.json,改完提示词跑一遍看有没有退化。本专题里绝大多数框架都没有这个 —— 大家默认你自己搭评测(比如 EvalHub 那种)。
还有 Agent Config:用 YAML 定义 Agent 不写代码,给非工程角色用。
七、A2A:跨组织的 Agent 互通
MCP 解决的是「Agent 怎么用工具」,A2A(Agent-to-Agent)解决的是「Agent 怎么用另一个 Agent」 —— 尤其是当那个 Agent 属于另一个团队、另一家公司,用的还是别的框架。
ADK 提供 RemoteA2aAgent:远端 Agent 在本地看起来就是个普通 sub-agent。
这是 Google 在 Agent 领域的协议布局:MCP 管纵向(Agent → 工具),A2A 管横向(Agent → Agent)。ADK 2.0 的 Task API 则是同一个进程内的结构化委派(多轮任务模式、单轮受控输出、HITL、任务 Agent 作为 workflow 节点)。
八、部署
| 目标 | 说明 |
|---|---|
| Vertex AI Agent Engine / Agent Runtime | GCP 全托管,会话、记忆、伸缩都不用管 |
| Cloud Run | 容器化,最常见 |
| GKE | 需要 K8s 级控制时 |
| 自建 | 打成容器随便跑 |
adk api_server | 本地起 HTTP 服务,前端可直接联调 |
九、供应商中立性:说清楚
官方说 model-agnostic、deployment-agnostic,这话基本成立,但有梯度:
| 部分 | 换出 GCP 的成本 |
|---|---|
| Agent / Workflow / Tools / Session 抽象 | 低,纯代码 |
| 模型 | 低(LiteLLM 接其他家) |
内置 google_search 等 Google 工具 | 高,得换实现 |
| Vertex AI Agent Engine 托管 | 高,这是它最省事的部署路径 |
VertexAiSessionService | 中,换 DatabaseSessionService 即可 |
结论:不在 GCP 上,ADK 依然是个设计良好的框架(多语言 + 图校验 + 评测是真优势);但它最省心的那条路在 GCP 上。这和 OpenAI Agents SDK 与 OpenAI 的关系是同构的。
十、什么时候用 / 什么时候别用
10.1 用它,如果
- 主力在 GCP / Gemini —— Agent Engine 部署是本专题里最省事的托管路径之一
- 团队不是纯 Python —— 五语言官方实现,Java / Go 后端团队几乎没有第二选择
- 需要评测和回归 ——
adk eval是内建的 - 要跨组织对接别人的 Agent —— A2A 目前最完整的实现
- 要过合规审计 —— 事件驱动的状态 delta 天然是审计日志
10.2 别用它,如果
- 只想快速验证一个想法 —— 目录结构、配置、Session 概念的前置成本高于 OpenAI Agents SDK
- 深度绑另一家云 —— 在 AWS 上用 ADK 会一直有「用错工具」的别扭感,那边有 Strands Agents
- 社区规模是硬指标 —— 21.2k 对比 LangChain 144.5k,遇到冷门问题时 Stack Overflow 上的答案密度差很多
- 不能接受破坏性升级 —— 1.x → 2.0 的经历说明它还在快速演进期
- 官方仓库:https://github.com/google/adk-python
- 文档:https://adk.dev/ (原 https://google.github.io/adk-docs/ )
- Workflow 图指 南:https://github.com/google/adk-python/blob/main/docs/guides/workflow/graph/index.md
- State 指南:https://github.com/google/adk-python/blob/main/docs/guides/sessions/state/index.md
- 样例:https://github.com/google/adk-samples
- 其他语言:ADK Go · ADK Java · ADK Kotlin
