ADK 的核心是一个简洁而强大的 Agent 接口:

type Agent interface {
    Name(ctx context.Context) string
    Description(ctx context.Context) string
    Run(ctx context.Context, input *AgentInput, options ...AgentRunOption) *AsyncIterator[*AgentEvent]
}

每个 Agent 都有明确的身份(Name)、清晰的职责(Description)和标准化的执行方式(Run),为 Agent 之间的发现与调用提供了基础。无论是简单的问答机器人,还是复杂的多步骤任务处理系统,都可以通过这个统一的接口加以实现。

⚡ 异步事件驱动架构

ADK 采用了异步事件流设计,通过 AsyncIterator[*AgentEvent] 实现非阻塞的事件处理,并通过 Runner 框架运行 Agent:

  • 实时响应AgentEvent 包含 Agent 执行过程中特定节点输出(Agent 回复、工具处理结果等等),用户可以立即看到 Agent 的思考过程和中间结果。
  • 追踪执行过程AgentEvent 额外携带状态修改动作与运行轨迹,便于开发调试和理解 Agent 行为。
  • 自动流程控制:框架通过 Runner 自动处理中断、跳转、退出行为,无需用户额外干预。

🤝 灵活的协作机制

Eino ADK 支持处于同一个系统内的 Agent 之间以多种方式进行协作(交换数据或触发运行):

  • 共享 Session:单次运行过程中持续存在的 KV 存储,用于支持跨 Agent 的状态管理和数据共享。
// 获取全部 SessionValues
func GetSessionValues(ctx context.Context) map[string]any

// 指定 key 获取 SessionValues 中的一个值,key 不存在时第二个返回值为 false,否则为 true
func GetSessionValue(ctx context.Context, key string) (any, bool)

// 添加 SessionValues
func AddSessionValue(ctx context.Context, key string, value any)

// 批量添加 SessionValues
func AddSessionValues(ctx context.Context, kvs map[string]any)


  • 移交运行(Transfer):携带本 Agent 输出结果上下文,将任务移交至子 Agent 继续处理。适用于智能体功能可以清晰的划分边界与层级的场景,常结合 ChatModelAgent 使用,通过 LLM 的生成结果进行动态路由。结构上,以此方式进行协作的两个 Agent 称为父子 Agent:

Transfer

// 设置父子 Agent 关系
func SetSubAgents(ctx context.Context, agent Agent, subAgents []Agent) (Agent, error)

// 指定目标 Agent 名称,构造 Transfer Event
func NewTransferToAgentAction(destAgentName string) *AgentAction


  • 显式调用(ToolCall):将 Agent 视为工具进行调用。适用于 Agent 运行仅需要明确清晰的参数而非完整运行上下文的场景,常结合 ChatModelAgent,作为工具运行后将结果返回给 ChatModel 继续处理。除此之外,ToolCall 同样支持调用符合工具接口构造的、不含 Agent 的普通工具。

ToolCall

// 将 Agent 转换为 Tool
func NewAgentTool(_ context.Context, agent Agent, options ...AgentToolOption) tool.BaseTool


🔄 中断与恢复机制

Eino ADK 提供运行时中断与恢复的功能,允许正在运行中的 Agent 主动中断并保存其当前状态,并在未来从中断点恢复执行。该功能为长时间等待、可暂停或需要外部输入(Human in the loop)等场景下的开发提供协助。

  • Agent 内部运行过程中,通过抛出含 Interrupt Action 的 Event 主动通知 Runner 中断运行,并允许携带额外信息供调用方阅读与使用。
  • Runner 通过初始化时注册的 CheckPointStore 记录当前运行状态
  • 重新准备好运行后,通过 Resume 方法携带恢复运行所需要的新信息,从断点处重新启动该 Agent 运行
// 1. 创建支持断点恢复的 Runner
runner := adk.NewRunner(ctx, adk.RunnerConfig{
    Agent:           complexAgent,
    CheckPointStore: memoryStore, // 内存状态存储
})

// 2. 开始执行
iter := runner.Query(ctx, "recommend a book to me", adk.WithCheckPointID("1"))
for {
    event, ok := iter.Next()
    if !ok {
       break
    }
    if event.Err != nil {
       log.Fatal(event.Err)
    }
    if event.Action != nil {
        // 3. 由 Agent 内部抛出 Interrupt 事件
        if event.Action.Interrupted != nil {
           ii, _ := json.MarshalIndent(event.Action.Interrupted.Data, "", "\t")
           fmt.Printf("action: interrupted\n")
           fmt.Printf("interrupt snapshot: %v", string(ii))
        }
    }
}

// 4. 从 stdin 接收用户输入
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("\nyour input here: ")
scanner.Scan()
fmt.Println()
nInput := scanner.Text()

// 5. 携带用户输入信息,从断点恢复执行
iter, err := runner.Resume(ctx, "1", adk.WithToolOptions([]tool.Option{subagents.WithNewInput(nInput)}))


快速开始

安装

go get github.com/cloudwego/eino@latest


项目开发经理智能体

下面的示例使用 Eino ADK 构建了一个项目开发经理智能体,面向多方面管理协同的场景:

  • Project Manager Agent:项目经理智能体,整体使用 Supervisor 模式,各 Agent 的功能如下:
    • ResearchAgent:调研 Agent,负责调研并生成可行方案,支持中断后从用户处接收额外的上下文信息来提高调研方案生成的准确性。
    • CodeAgent:编码 Agent,使用知识库工具,召回相关知识作为参考,生成高质量的代码。
    • ReviewAgent:评论 Agent,使用顺序工作流编排问题分析、评价生成、评价验证三个步骤,对调研结果 / 编码结果进行评审,给出合理的评价,供项目经理进行决策。
    • ProjectManagerAgent:项目经理 Agent,根据动态的用户输入,路由并协调多个负责不同维度工作的子智能体开展工作。
  • 该 Agent 可能的工作场景为:
    • 从零开始实现项目:项目经理从需求入手,经由调研、编码、评论三个 Agent 工作,最终完成项目交付。
    • 对已有项目的完善:项目经理从评论 Agent 获得项目仍旧需要完善的功能点,交由编码 Agent 进行实现,再交由评论 Agent 对修改后的代码进行评审。
    • 开展技术调研:项目经理要求调研 Agent 生成技术调研报告,然后由评论 Agent 给出评审意见。调用方结合返回的技术调研报告和评审意见,决定后续动作。

ProjetctManager

设计点 传统开发模式 基于 Eino ADK 开发
Agent 抽象 没有统一定义,团队协作开发效率差,后期维护成本高 统一定义,职责独立,代码整洁,便于各 Agent 分头开发
输入输出 没有统一定义,输入输出混乱;<br> 运行过程只能手动加日志,不利于调试 有统一定义,全部基于事件驱动;<br> 运行过程通过 iterator 透出,所见即所得
Agent 协作 通过代码手动传递上下文 框架自动传递上下文
中断恢复能力 需要从零开始实现,解决序列化与反序列化、状态存储与恢复等问题 仅需在 Runner 中注册 CheckPointStore,提供断点数据存储介质
Agent 模式 需要从零开始实现 多种成熟模式开箱即用

核心代码如下,完整代码详见 Eino-Examples 项目中提供的源码

func main() {
    ctx := context.Background()

    // Init chat model for agents
    tcm, err := openai.NewChatModel(ctx, &openai.ChatModelConfig{
       APIKey:  os.Getenv("OPENAI_API_KEY"),
       Model:   os.Getenv("OPENAI_MODEL"),
       BaseURL: os.Getenv("OPENAI_BASE_URL"),
       ByAzure: func() bool {
          return os.Getenv("OPENAI_BY_AZURE") == "true"
       }(),
    })
    if err != nil {
       log.Fatal(err)
    }

    // Init research agent
    researchAgent, err := agents.NewResearchAgent(ctx, tcm)
    if err != nil {
       log.Fatal(err)
    }

    // Init code agent
    codeAgent, err := agents.NewCodeAgent(ctx, tcm)
    if err != nil {
       log.Fatal(err)
    }

    // Init technical agent
    reviewAgent, err := agents.NewReviewAgent(ctx, tcm)
    if err != nil {
       log.Fatal(err)
    }

    // Init project manager agent
    s, err := agents.NewProjectManagerAgent(ctx, tcm)
    if err != nil {
       log.Fatal(err)
    }

    // Combine agents into ADK supervisor pattern
    // Supervisor: project manager
    // Sub-agents: researcher / coder / reviewer
    supervisorAgent, err := supervisor.New(ctx, &supervisor.Config{
       Supervisor: s,
       SubAgents:  []adk.Agent{researchAgent, codeAgent, reviewAgent},
    })
    if err != nil {
       log.Fatal(err)
    }

    // Init Agent runner
    runner := adk.NewRunner(ctx, adk.RunnerConfig{
       Agent:           supervisorAgent,
       EnableStreaming: true,                // enable stream output
       CheckPointStore: newInMemoryStore(),  // enable checkpoint for interrupt & resume
    })

    // Replace it with your own query
    query := "please generate a simple ai chat project with python."
    checkpointID := "1"

    // Start runner with a new checkpoint id
    iter := runner.Query(ctx, query, adk.WithCheckPointID(checkpointID))
    interrupted := false
    for {
       event, ok := iter.Next()
       if !ok {
          break
       }
       if event.Err != nil {
          log.Fatal(event.Err)
       }
       if event.Action != nil && event.Action.Interrupted != nil {
          interrupted = true
       }
       prints.Event(event)
    }

    if !interrupted {
       return
    }
    
    // interrupt and ask for additional user context
    scanner := bufio.NewScanner(os.Stdin)
    fmt.Print("\ninput additional context for web search: ")
    scanner.Scan()
    fmt.Println()
    nInput := scanner.Text()

    // Resume by checkpoint id, with additional user context injection
    iter, err = runner.Resume(ctx, checkpointID, adk.WithToolOptions([]tool.Option{agents.WithNewInput(nInput)}))
    if err != nil {
       log.Fatal(err)
    }
    for {
       event, ok := iter.Next()
       if !ok {
          break
       }
       if event.Err != nil {
          log.Fatal(event.Err)
       }
       prints.Event(event)
    }
}




结尾

Eino ADK 不仅仅是一个开发框架,更是一个完整的智能体开发生态。它通过统一的抽象、灵活的组合和强大的协作机制,让 Go 开发者能够轻松构建从简单对话机器人到复杂多智能体系统的各种 AI 应用。

💡 立即开始你的智能体开发之旅

Eino ADK,让智能体开发变得简单而强大!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐