核心摘要
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。
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 路径。
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)
}
}
预期输出:
accepted: inspect incident
只有在补齐 Credential、Timeout、Rate Limit、Retry、Usage 与 Model Version 测试后,才应把 fixedModel 替换为固定版本的 EinoExt Provider。
添加 Tool,但不扩大权限
Tool 应放进 adk.ToolsConfig,通常通过 compose.ToolsNodeConfig 配置。每次请求可见的 Tool Set 应由 Policy 推导:
- 在模型之外认证 Caller。
- 解析 Tenant、Object Scope 与 Data Classification。
- 为任务选择最小 Tool Set。
- 将 Tool Description 提供给模型。
- 严格解析生成参数。
- 执行前再次授权准确 Action。
- 应用 Idempotency、Quota、Egress Policy 与 Result Size Limit。
- 记录 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。
一手资料
- Eino
v0.9.21Package 文档 - Eino ChatModelAgent 指南
- Eino ADK Quickstart
- Eino Human-in-the-Loop 指南
- Eino DeepAgents 指南
- Eino Examples Cookbook
- OWASP LLM06:2025 Excessive Agency