# ADK Go 2.0 发布：构建可靠的多智能体应用，新增基于图的工作流引擎、人工参与循环与动态编排

- 来源：Google Developers Blog（RSS）
- 发布时间：2026-07-01 01:17
- AIHOT 分数：67
- AIHOT 标记：精选
- AIHOT 链接：https://aihot.virxact.com/items/cmr0wupt4007gsl403t7s6dbn
- 原文链接：https://developers.googleblog.com/announcing-adk-go-20

## 精选理由

Google 给 Go 生态补上了多智能体编排的关键一环，图工作流引擎和人机协同直接内置，比之前拼积木的方式可靠很多，做 Agent 的 Go 开发者值得跟进。

## AI 摘要

Agent Development Kit (ADK) for Go 2.0 发布，引入了一类基于图的工作流引擎，用于组合复杂多智能体应用。新版本内置人工参与循环（HITL）编排、使用纯 Go 代码的动态执行、以及指数退避重试等自动弹性特性。统一执行模型后，单智能体应用与复杂图均运行在同一运行时上，简化了遥测与状态持久化。

## 正文

ADK for Go 2.0：以图结构构建智能体工作流

构建真实世界的智能体应用很少像发送单条提示词那么简单。生产环境中的智能体必须进行分类、分支、扇出、请求人工审批、失败重试，并循环执行直至完成。将这种复杂编排表达为临时控制流会很快变得脆弱。

自 1.0 版本发布以来，Go 语言的智能体开发工具包（ADK）帮助 Go 开发者以简洁、地道的 API 构建生产级智能体——强类型、iter.Seq2 事件流，以及能自然融入现有 Go 服务的运行时。这一基础取得了真正的成功，也正因如此，下一步的演进才成为可能。

今天，我们很高兴地分享 ADK for Go 2.0。其核心亮点是一种全新的、一等公民式的多智能体应用组合方式：基于图的 workflow 引擎。与之相伴的还有作为内置原语的人机协同（HITL）、用纯 Go 编写的动态编排、LLM 智能体模式，以及一个将所有功能统一起来的节点运行时——单个智能体和完整图结构现在运行在相同的执行模型上。

如果你关注过 Python ADK 2.0，那么对此会感到熟悉：这是相同的以图优先的方向，但从零开始设计，使其具有 Go 语言的感觉。

为什么采用图结构？

真实的智能体应用很少是单条提示词。它们需要进行分类、分支、扇出到专业智能体、收集结果、请求人工审批、失败重试，并循环执行直至完成。将这种逻辑表达为临时控制流会很快变得脆弱。

ADK 2.0 让你能够将应用的形态描述为由边连接的节点图，并将执行交给一个调度器，该调度器知道如何并发运行、持久化状态、暂停等待人工介入，以及稍后恢复执行——即使在进程重启后也能做到。以下是将节点串联在一起的简单方式：

import "google.golang.org/adk/v2/workflow"

upper := workflow.NewFunctionNode("upper", upperFn, cfg) suffix := workflow.NewFunctionNode("suffix", suffixFn, cfg)

edges := workflow.Chain(workflow.Start, upper, suffix)

wf, _ := workflowagent.New(workflowagent.Config{ Name: "simple_sequence_workflow", Edges: edges, })

Go

那个 wf 就是一个 agent.Agent。它在你已经使用的同一个 runner、launcher 和 console 中运行——无需特殊框架，无需新服务器。图结构本身就是一个智能体。

构建模块

适用于一切的节点

节点是任何实现了 Node 接口的工作单元。你很少需要手动编写该接口——ADK 为常见场景提供了类型化的节点构造函数：

函数节点封装了一个普通的带类型 Go 函数。泛型会自动为你推断输入/输出模式：

workflow.NewFunctionNode("classify", func(ctx agent.Context, in string) (Category, error) { ... }, cfg)

Go

发射型函数节点是那些额外获得一个 emit 回调的函数节点，因此单个函数可以流式传输事件或暂停等待人工介入，而无需降级为动态节点：

workflow.NewEmittingFunctionNode("progress", func(ctx agent.Context, in Job, emit func(*session.Event) error) (Result, error) { ... }, cfg)

Go

智能体节点可以将任意 `agent.Agent`（例如 `LlmAgent`）放入图中。

工具节点将 `tool.Tool` 转换为图中的一个步骤。

汇合节点是扇入屏障：它们等待所有前驱节点，然后将它们的输出以一个映射（map）的形式交给你。

动态节点让你在代码中进行编排（下文将详细介绍）。

工作流节点将整个子工作流嵌入为单个节点——图是可以组合的。

并行工作器会针对列表中的每一项并发运行一个节点，并汇总结果。

状态绑定节点（`NewFunctionNodeFromState`）通过 `state:"<key>"` 标签，将选定的会话状态值直接拉取到一个带类型的 Params 结构体中——无需手动进行状态传递。

边、路由以及你需要的形状

边连接节点，并且可以携带路由条件。一个节点会发射一个路由值；匹配的边会触发。仅这一个概念就能提供你所需的所有控制流形状：

b := workflow.NewEdgeBuilder() b.AddRoutes(router, map[string]workflow.Node{ "question": answerNode, "statement": commentNode, "exclamation": reactNode, }) b.AddFanOut(planner, researchA, researchB, researchC) // parallel branches b.AddFanIn(join, researchA, researchB, researchC) // gather results

Go

顺序链、条件路由器、扇出/扇入、嵌套子图，甚至循环（已完成的节点可以被重新触发，因此循环是一等公民）——全部通过边和路由实现。标准路由包括 StringRoute、IntRoute、BoolRoute、MultiRoute，以及在没有其他匹配项时触发的 Default 路由。如需更深入的配置，请利用 Route 接口。

让大语言模型来引导图

最有用的模式之一是将模型用作路由器的“大脑”。LlmAgent 对用户消息进行分类；一个简单的函数发射匹配的路由；图将任务分派给正确的处理器：

User -> What time is it? Agent -> question answering question... User -> Hello world! Agent -> exclamation reacting to exclamation... User -> The sky is blue. Agent -> statement commenting on statement...

纯文本

模型做出决策；图使其变得可靠、可观测且可恢复。（参见 examples/workflow/routing/llm/。）

动态编排——用纯 Go 实现

有时执行顺序直到运行时才能确定：它取决于数据、循环次数，或者模型刚刚说了什么。为此，ADK 2.0 提供了动态节点，其中的编排主体是普通的 Go 代码，通过调用 `RunNode(...)` 来运行每个子节点：

greeter := workflow.NewDynamicNode("greeter_workflow", func(nc agent.Context, in string, emit func(*session.Event) error) (string, error) { return workflow.RunNode[string](nc, greeterNode, in) }, workflow.NodeConfig{}, )

Go

循环、条件判断、累加、动态列表的扇出——所有这些都用你熟悉的 Go 语言来表达。诸如 `WithRunID`、`WithUseSubBranch`、`WithUseAsOutput` 和 `WithIsolationScope` 等选项，让你能够精确控制子节点身份、历史隔离和输出委派。这是 Python ADK 动态图在 Go 语言中的对应实现。

内置人工介入机制

生产环境中的智能体通常需要人类在运行过程中批准、纠正或提供某些信息。在 ADK 2.0 中，任何节点都可以暂停图执行并向人类提问——工作流会持久等待答案：

event := workflow.NewRequestInputEvent(ctx, session.RequestInput{ InterruptID: "approve_refund", Message: "Approve a $200 refund? (yes/no)", ResponseSchema: schema, }) // yield the event; the node moves to "waiting"

Go

当人类在后续轮次中回复时，工作流恢复执行。你可以选择恢复方式：

交接——答案直接流向下一个节点。

重新进入——暂停的节点重新运行，通过 `ctx.ResumedInput(...)` 获取人类的响应。

恢复过程是持久的。运行状态保存在会话中，ADK 甚至可以通过扫描会话历史来重建暂停的工作流——因此工作流可以在进程重启后恢复，甚至跨不同运行时恢复，因为中断格式与 Python ADK 共享。响应会按照模式进行验证，恢复操作是幂等的，当出现问题时你会收到明确的错误信息（`ErrInvalidResumeResponse`、`ErrNothingToResume`）。

控制台启动器和 Web UI 都原生支持人工介入机制，能够展示工具确认提示和工作流输入请求。

无需样板代码的弹性

每个节点都可以携带带有指数退避和抖动的重试策略——无需外部依赖：

cfg := workflow.NodeConfig{ RetryConfig: workflow.DefaultRetryConfig() } // 5 attempts, 1s initial delay, 60s cap, 2x backoff, full jitter

Go

为每个节点添加超时设置，使用 `WithMaxConcurrency(n)` 限制图级别的并发数，并隔离并行分支，使一个分支的交互不会泄漏到另一个分支的 LLM 提示词历史中。调度器会为你处理 goroutine、通道、背压和取消操作。

智能体模式与统一运行时

ADK 2.0 为 LLM 智能体引入了多种模式——聊天模式、任务模式和单轮模式——因此协调器可以与用户聊天，同时子智能体静默完成任务或执行单次操作。根据每个智能体的角色，会自动安装相应的辅助工具（`finish_task`、`single_turn`、`task`）。

在底层，运行器现在通过驱动工作流的同一节点运行时，驱动一个纯粹的 LlmAgent。其回报是：单智能体应用和完整图共享同一个执行模型，并且人机交互现在也能用于纯粹的 LLM 智能体——而不仅限于工作流内部。

我们还简化了编程模型：ToolContext 和 CallbackContext 现在统一为单一的 agent.Context——无论你是在编写工具、回调还是图节点，只需学习这一种类型——并且节点/智能体的执行会显示在一条一致的遥测跨度树中，这样你就能准确看到你的图执行了哪些操作。

从 1.0 升级

ADK 2.0 是高度增量的——整个工作流引擎都是你可以选择接入的新包。在统一运行时的过程中，有一些新的且不兼容的变更；每个变更都有简单、机械式的修复方法：

节点和节点函数的签名现在接收 `agent.Context`。如果你编写节点或节点函数，请将第一个参数从 `agent.InvocationContext` 改为 `agent.Context`（它内嵌了 InvocationContext，因此你使用的所有方法仍然有效）：

// before: func(ctx agent.InvocationContext, in string) (string, error) // after: func(ctx agent.Context, in string) (string, error)

Go

统一的上下文。ToolContext、CallbackContext 已不复存在——工具、回调和工作流节点都直接接收 agent.Context。如果你在测试中模拟过上下文，`agent/context_mock.go` 仍然保留；请使用该文件中的 `StrictContextMock` 作为你的测试替身。

自定义的 `InvocationContext` 实现需要两个方法：`IsolationScope()` 和 `ResumedInput(id string)`。大多数代码会内嵌提供的实现，并免费获得这些方法。

事件流更加丰富。事件现在携带节点字段（IsolationScope、Output、Routes、RequestedInput）和一个元数据字段（NodeInfo）。如果你在测试中断言确切的 `session.Event` 相等性，请预期这些新字段；自定义会话存储应持久化它们。

`llmagent.New` 可能会安装特定模式的工具。如果你设置了子智能体模式，有效的工具集会反映这些模式；任务模式下的智能体不能用作静态图节点。

`session.NewEvent` 接收一个上下文。其签名现在是 `NewEvent(ctx context.Context, invocationID string)`。通过将已在作用域内的 `context.Context` 作为第一个参数传入，来迁移调用点。

以上就是全部列表。`runner.Run/RunLive`、`agenttool` 以及 LLM 智能体回调的公开签名保持不变。如需查看分步的修改前后对比说明，请参阅 ADK Go 2.0 迁移指南。

立即体验

快速上手 ADK 2.0 的最佳方式是查看新的工作流示例：

go run ./examples/workflow/basic/ go run ./examples/workflow/routing/llm/ # LLM-as-router go run ./examples/workflow/dynamic/hitl/ # dynamic + human-in-the-loop go run ./examples/workflow/hitl_rerun/ # HITL with re-entry resume go run ./examples/workflow/complex/ # a larger, multi-shape graph

Shell

ADK 1.0 已经证明，用 Go 语言构建严肃的智能体可以既简洁又高效。ADK 2.0 则更进一步：将这些智能体组合成可靠、可观测、可恢复的工作流——以图结构的形式，用地道的 Go 语言实现，并在关键时刻让人参与其中。

我们迫不及待想看到你的作品。

—— ADK for Go 团队
