核心摘要

Eino ADK 应用由 Runner 驱动,不能把它当成一个返回单条 Message 的模型接口直接调用。在 v0.9.21 中,ChatModelAgentConfig 使用 Instruction、ToolsConfig 与 MaxIterations;Runner.Query 或 Runner.Run 返回 AgentEvent 的 AsyncIterator。可恢复中断需要 CheckPointStore 与稳定 Checkpoint ID。框架负责组织执行,应用仍负责授权、预算、幂等和结果核验。

核心要点

  • ChatModelAgent 提供常见 ReAct Model-Tool Loop;没有 Tool 时只执行一次 Model Call。
  • Runner 管理执行、Event Delivery、Streaming Mode、Checkpoint 与 Resume 入口。
  • MaxIterations 只是循环保护,不是完整 Token、Time、Cost 或 Side-effect Budget。
  • DeepAgent 位于 adk/prebuilt/deep,高权限能力必须放进 Sandbox。
  • Human Approval 必须绑定准确 Principal、Action、Argument、Policy Revision 与 Expiry。

当前 ADK 契约

固定版本的 v0.9.21 Package 文档与 ChatModelAgent 指南定义了这些核心类型:

类型 职责
adk.Agent 统一 Agent 接口
adk.ChatModelAgent ReAct 式 Model 与 Tool 循环
adk.Runner 发起 Run、输出 Event、Checkpoint 与 Resume
adk.AgentEvent Message 或 Control Output 加 Error
adk.ToolsConfig ToolsNode 配置与返回行为
adk.CheckPointStore 保存可恢复框架状态

使用 SystemPrompt、顶层 Tools、MaxSteps、StreamRun、adk.NewDeepAgent 或自行定义可序列化 AgentCheckpoint 的旧示例,都不符合当前 API。

sequenceDiagram participant C as Client participant R as Runner participant A as ChatModelAgent participant M as Model participant T as ToolsNode C->>R: Query 或 Run R->>A: AgentInput A->>M: Messages 加 ToolInfo alt 模型提议 Tool Call M-->>A: Assistant ToolCall A->>T: 执行已配置 Tool T-->>A: Tool Result A->>M: 更新后的 Messages else 最终回答 M-->>A: Assistant Message end A-->>R: AgentEvent Stream R-->>C: Message 与 Control Event

ChatModelAgent 配置

v0.9.21 的关键字段包括:

字段 用途 边界
Name / Description Agent 身份和委派 Metadata 不是 Authentication
Instruction System Instruction 不是 Authorization
Model model.BaseModel 实现 使用 Tool 时须支持相应 Tool Option
ToolsConfig Tool Set 与执行行为 Tool 仍需服务端 Policy
MaxIterations Model Generation 上限 默认 20,不是 Cost SLA
Handlers 当前 Interface-based Middleware 顺序与数据暴露需审阅
ModelRetryConfig Model Call Retry Policy Policy Denial 不应重试
ModelFailoverConfig 合格失败后切换模型 跨模型重新评测行为

当 Agent 暴露给另一个 Agent 时,Name 与 Description 会成为上游输入。它们是不可信 Metadata,不是权限声明。

无 Provider 凭据的可运行 Agent

下面完整示例以 Eino Core v0.9.21 为目标。确定性 Mock 实现 BaseChatModel,因此无需网络或 API Key 也能编译并运行 ChatModelAgent 与 Runner 路径。

go
package main

import (
	"context"
	"fmt"

	"github.com/cloudwego/eino/adk"
	"github.com/cloudwego/eino/components/model"
	"github.com/cloudwego/eino/schema"
)

type fixedModel struct{}

func (fixedModel) Generate(
	ctx context.Context,
	input []*schema.Message,
	_ ...model.Option,
) (*schema.Message, error) {
	if err := ctx.Err(); err != nil {
		return nil, err
	}
	return schema.AssistantMessage("accepted: "+input[len(input)-1].Content, nil), nil
}

func (fixedModel) Stream(
	ctx context.Context,
	input []*schema.Message,
	_ ...model.Option,
) (*schema.StreamReader[*schema.Message], error) {
	message, err := (fixedModel{}).Generate(ctx, input)
	if err != nil {
		return nil, err
	}
	return schema.StreamReaderFromArray([]*schema.Message{message}), nil
}

func main() {
	ctx := context.Background()
	agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
		Name:          "bounded-assistant",
		Description:   "Returns one deterministic response.",
		Instruction:   "Answer once.",
		Model:         fixedModel{},
		MaxIterations: 2,
	})
	if err != nil {
		panic(err)
	}

	runner := adk.NewRunner(ctx, adk.RunnerConfig{Agent: agent})
	events := runner.Query(ctx, "inspect incident")
	for {
		event, ok := events.Next()
		if !ok {
			break
		}
		if event.Err != nil {
			panic(event.Err)
		}
		if event.Output == nil || event.Output.MessageOutput == nil {
			continue
		}
		message, err := event.Output.MessageOutput.GetMessage()
		if err != nil {
			panic(err)
		}
		fmt.Println(message.Content)
	}
}

预期输出:

text
accepted: inspect incident

只有在补齐 Credential、Timeout、Rate Limit、Retry、Usage 与 Model Version 测试后,才应把 fixedModel 替换为固定版本的 EinoExt Provider。

添加 Tool,但不扩大权限

Tool 应放进 adk.ToolsConfig,通常通过 compose.ToolsNodeConfig 配置。每次请求可见的 Tool Set 应由 Policy 推导:

  1. 在模型之外认证 Caller。
  2. 解析 Tenant、Object Scope 与 Data Classification。
  3. 为任务选择最小 Tool Set。
  4. 将 Tool Description 提供给模型。
  5. 严格解析生成参数。
  6. 执行前再次授权准确 Action。
  7. 应用 Idempotency、Quota、Egress Policy 与 Result Size Limit。
  8. 记录 Effect ID 与权威 Outcome。

ReturnDirectly 只控制 Agent 的响应流程,不会让 Tool Result 自动可信或获得授权。

中断与恢复

HITL 官方文档把 Interrupt 建模为可恢复执行状态。生产流程需要:

  • 在 Runner 配置 CheckPointStore;
  • 发起运行时使用稳定 WithCheckPointID;
  • 将 Approval Record 绑定已认证 Reviewer;
  • 绑定准确 Tool Name、Normalized Argument、Object Version、Policy Revision 与 Expiry;
  • 简单恢复使用 Runner.Resume,定向传递数据使用 ResumeWithParams。

不要序列化博客中想象出来的 Checkpoint Struct。应使用固定版本的框架 Store Contract,把它当敏感状态保护,并测试 Schema Migration 与 Expiry。

审批不等于执行成功。恢复后,下游 Operation 仍需 Idempotency 与 Reconciliation。

什么时候值得使用 DeepAgent

当前 DeepAgents 文档将构造函数放在 github.com/cloudwego/eino/adk/prebuilt/deep 下,通过 deep.New 创建。它可以加入 Planning、File Operation、Shell Execution 与 Sub-agent Delegation。

只有满足以下条件时,扩大能力面才合理:

  • 代表性任务确实需要分解或隔离委派;
  • 结果显著优于简单 ChatModelAgent 或确定性 Workflow;
  • File 与 Shell Backend 位于窄 Mount、窄 Egress 的 Sandbox;
  • 生成的 Plan 与 TODO 只作为工作状态,不作为 Authority;
  • Output、Fan-out、Iteration、Time 与 Spend 全部有界。

Planning 不保证计划正确,Reflection 不证明结果正确,父 Agent 能描述任务也不代表子 Agent 自动继承权限。

State、Memory 与 Checkpoint 的区别

概念 用途 常见误区
Input Messages 一次 Run 的 Context 假设 Agent 永久保存
Session Values Request 或 Workflow State 把它当 Authorization Source
Long-term Memory 产品管理的持久事实 把模型推断当用户事实
Checkpoint 恢复框架执行 假设外部副作用会回滚
Trace 可观察证据 记录 Secret 或隐藏推理

Agent Memory 指南解释持久记忆,状态持久化指南解释 Checkpoint 与恢复。

发布门禁

  • 使用准确 Eino 与 EinoExt 依赖图编译。
  • 测试 Direct Answer、一次 Tool Call、重复 Tool Call、Malformed Argument 与 Unknown Tool。
  • 分别执行 MaxIterations、Wall Time、Tool、Token、Byte 与 Spend Budget。
  • 测试 Tool 执行前、中、后的 Cancellation。
  • 注入 Transient、Permanent、Unauthorized 与 Ambiguous Failure。
  • 验证 Checkpoint Expiry、Resume Ownership、重复恢复与版本迁移。
  • 用确定性 Baseline 比较 ChatModelAgent 与 DeepAgent。
  • 将每次权限扩大与 Model 或 Prompt 修改分开评审。

常见问题

ChatModelAgent 会跨请求自动保存对话历史吗?

不能这样假设。一次 Run 会接收 Messages,并在该次执行内累积状态;跨请求历史需要显式 Session 或应用 Store,同时定义 Retention、Deletion 与 Authorization Policy。

MaxIterations 设置多少合适?

没有通用数字。先观察代表性评测集中最短成功 Trace,再选择能够限制最坏风险与成本的上限,并独立设置 Wall-time、Tool、Token 与 Byte Limit。

开启 Runner Streaming 后会直接输出模型 Token 吗?

Runner 输出类型化 AgentEvent。Consumer 必须同时处理 Streaming 与非 Streaming Message Variant、Tool Event、Action、Error、Cancellation 与 Redaction,不能把每个 Event 都当作可展示文本。

Tool Error 应原样返回给模型吗?

只返回能帮助选择安全下一步的有界、脱敏、类型化错误。不要暴露 Stack Trace、Credential、内部 Topology 或授权细节。

弹出审批框就足以保护敏感操作吗?

不足。Approval 必须绑定 Reviewer Identity、准确 Action 与 Argument、Object Revision、Policy Revision 和 Expiry;执行时重新授权,并保证 Effect Idempotent。

一手资料

相关阅读