/eino-agent
Eino ADK agent construction, middleware, and runner. Use when a user needs to build an AI Agent, configure ChatModelAgent with ReAct pattern, use middleware (filesystem, tool search, tool reduction, summarization, plan-task, skill, agents.md), set up the Runner for event-driven
$ npx -y skills add cloudwego/eino-ext --skill eino-agent --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/eino-agent
Context preview
The summary Claude sees to decide when to auto-load this skill.
Eino ADK agent construction, middleware, and runner. Use when a user needs to build an AI Agent, configure ChatModelAgent with ReAct pattern, use middleware (filesystem, tool search, tool reduction, summarization, plan-task, skill, agents.md), set up the Runner for event-driven
SKILL.md
eino-agent.SKILL.mdname: eino-agent
description: Eino ADK agent construction, middleware, and runner. Use when a user needs to build an AI Agent, configure ChatModelAgent with ReAct pattern, use middleware (filesystem, tool search, tool reduction, summarization, plan-task, skill, agents.md), set up the Runner for event-driven execution, implement human-in-the-loop with interrupt/resume, use Cancel/Retry/Failover for model resilience, build push-based multi-turn loops with TurnLoop, or wrap agents as tools. Covers ChatModelAgent, DeepAgents, and TurnLoop.
Eino ADK Overview
Import: `github.com/cloudwego/eino/adk`
The Agent Development Kit (ADK) provides a framework for building agents in Go. The ADK is generically parameterized by `MessageType` to support both classic `*schema.Message` and the new `*schema.AgenticMessage`. Prefer `*schema.AgenticMessage` for new usage.
type MessageType interface {
*schema.Message | *schema.AgenticMessage
}
type TypedAgent[M MessageType] interface {
Name(ctx context.Context) string
Description(ctx context.Context) string
Run(ctx context.Context, input *TypedAgentInput[M], options ...AgentRunOption) *AsyncIterator[*TypedAgentEvent[M]]
}
// Convenience aliases for classic message type
type Agent = TypedAgent[*schema.Message]Agent Types
| Type | Description | Decision | |------|-------------|----------| | ChatModelAgent | ReAct pattern: LLM reasons, calls tools, loops until done | Dynamic (LLM) | | DeepAgent | Pre-built agent with planning, filesystem, sub-agents | Dynamic (LLM) | | TurnLoop | Push-based event loop for multi-turn execution with preemption and lifecycle management | Runtime | | Custom Agent | Implement the TypedAgent interface directly | Custom |
ChatModelAgent Quick Start
import (
"context"
"fmt"
"log"
"github.com/cloudwego/eino-ext/components/model/openai"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/components/tool/utils"
"github.com/cloudwego/eino/compose"
)
func main() {
ctx := context.Background()
// 1. Create a tool
searchTool, _ := utils.InferTool("search_book", "Search books by genre",
func(ctx context.Context, input *struct {
Genre string `json:"genre" jsonschema_description:"Book genre"`
}) (string, error) {
return `{"books": ["The Great Gatsby"]}`, nil
})
// 2. Create model (BaseModel[M], not ToolCallingChatModel)
cm, _ := openai.NewChatModel(ctx, &openai.ChatModelConfig{
APIKey: "your-key", Model: "gpt-4o",
})
// 3. Create agent
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Name: "BookRecommender",
Description: "Recommends books",
Instruction: "You recommend books using the search_book tool.",
Model: cm,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{searchTool},
},
},
})
// 4. Run with Runner
runner := adk.NewRunner(ctx, adk.RunnerConfig{Agent: agent})
iter := runner.Query(ctx, "recommend a fiction book")
for {
event, ok := iter.Next()
if !ok {
break
}
if event.Err != nil {
log.Fatal(event.Err)
}
if event.Output != nil && event.Output.MessageOutput != nil {
msg, _ := event.Output.MessageOutput.GetMessage()
fmt.Printf("Agent[%s]: %v\n", event.AgentName, msg)
}
}
}Cancel Mechanism
Cancel provides safe, controllable termination of agent execution.
// Create a cancel function alongside the run
cancelOpt, cancelFn := adk.WithCancel()
iter := runner.Query(ctx, "do something", cancelOpt)
// ... iterate events ...
// Cancel at a safe point (cancelFn is non-blocking, Wait blocks until complete)
handle, ok := cancelFn(adk.WithAgentCancelMode(adk.CancelAfterChatModel))
if ok {
handle.Wait()
}**CancelMode** (bitmask):
| Mode | Behavior | |------|----------| | `CancelImmediate` (0) | Abort immediately, stream terminated | | `CancelAfterChatModel` | Wait for current model call to finish | | `CancelAfterToolCalls` | Wait for current tool calls to finish |
**Cancel options:**
- `WithAgentCancelMode(mode)` -- set safe point
- `WithAgentCancelTimeout(d)` -- escalate to immediate if safe point not reached in time
- `WithRecursive()` -- propagate cancel into nested AgentTool agents
Cancel produces a `CancelError` on the event stream with checkpoint data for later resumption.
Model Retry
Output-based retry with full control over retry decisions.
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
// ...
ModelRetryConfig: &adk.ModelRetryConfig{
MaxRetries: 3,
ShouldRetry: func(ctx context.Context, retryCtx *adk.RetryContext) *adk.RetryDecision {
// Retry based on output content (e.g., empty response, bad finish reason)
if retryCtx.Err != nil {
return &adk.RetryDecision{Retry: true, Backoff: time.Second}
}
if retryCtx.OutputMessage == nil || retryCtx.OutputMessage.Content == "" {
return &adk.RetryDecision{Retry: true, Backoff: time.Second}
}
return &adk.RetryDecision{Retry: false}
},
},
})**RetryContext** provides: `RetryAttempt`, `InputMessages`, `OutputMessage` (full concatenated response), `Err`.
**RetryDecision** controls: `Retry`, `ModifiedInputMessages`, `AdditionalOptions`, `Backoff`, `RejectReason`.
When streaming, a `WillRetryError` is emitted on the stream to signal retry is occurring.
Model Failover
Dynamic model switching when primary model fails or produces unsatisfactory output.
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
// ...
ModelFailoverConfig: &adk.ModelFailoverConfig[*schema.Message]Read more
name: eino-agent description: Eino ADK agent construction, middleware, and runner. Use when a user needs to build an AI Agent, configure ChatModelAgent with ReAct pattern, use middleware (filesystem, tool search, tool reduction, summarization, plan-task, skill, agents.md), set up the Runner for event-driven execution, implement human-in-the-loop with interrupt/resume, use Cancel/Retry/Failover for model resilience, build push-based multi-turn loops with TurnLoop, or wrap agents as tools. Covers ChatModelAgent, DeepAgents, and TurnLoop.
Eino ADK Overview
Import: `github.com/cloudwego/eino/adk`
The Agent Development Kit (ADK) provides a framework for building agents in Go. The ADK is generically parameterized by `MessageType` to support both classic `*schema.Message` and the new `*schema.AgenticMessage`. Prefer `*schema.AgenticMessage` for new usage.
type MessageType interface {
*schema.Message | *schema.AgenticMessage
}
type TypedAgent[M MessageType] interface {
Name(ctx context.Context) string
Description(ctx context.Context) string
Run(ctx context.Context, input *TypedAgentInput[M], options ...AgentRunOption) *AsyncIterator[*TypedAgentEvent[M]]
}
// Convenience aliases for classic message type
type Agent = TypedAgent[*schema.Message]Agent Types
| Type | Description | Decision | |------|-------------|----------| | ChatModelAgent | ReAct pattern: LLM reasons, calls tools, loops until done | Dynamic (LLM) | | DeepAgent | Pre-built agent with planning, filesystem, sub-agents | Dynamic (LLM) | | TurnLoop | Push-based event loop for multi-turn execution with preemption and lifecycle management | Runtime | | Custom Agent | Implement the TypedAgent interface directly | Custom |
ChatModelAgent Quick Start
import (
"context"
"fmt"
"log"
"github.com/cloudwego/eino-ext/components/model/openai"
"github.com/cloudwego/eino/adk"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/components/tool/utils"
"github.com/cloudwego/eino/compose"
)
func main() {
ctx := context.Background()
// 1. Create a tool
searchTool, _ := utils.InferTool("search_book", "Search books by genre",
func(ctx context.Context, input *struct {
Genre string `json:"genre" jsonschema_description:"Book genre"`
}) (string, error) {
return `{"books": ["The Great Gatsby"]}`, nil
})
// 2. Create model (BaseModel[M], not ToolCallingChatModel)
cm, _ := openai.NewChatModel(ctx, &openai.ChatModelConfig{
APIKey: "your-key", Model: "gpt-4o",
})
// 3. Create agent
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
Name: "BookRecommender",
Description: "Recommends books",
Instruction: "You recommend books using the search_book tool.",
Model: cm,
ToolsConfig: adk.ToolsConfig{
ToolsNodeConfig: compose.ToolsNodeConfig{
Tools: []tool.BaseTool{searchTool},
},
},
})
// 4. Run with Runner
runner := adk.NewRunner(ctx, adk.RunnerConfig{Agent: agent})
iter := runner.Query(ctx, "recommend a fiction book")
for {
event, ok := iter.Next()
if !ok {
break
}
if event.Err != nil {
log.Fatal(event.Err)
}
if event.Output != nil && event.Output.MessageOutput != nil {
msg, _ := event.Output.MessageOutput.GetMessage()
fmt.Printf("Agent[%s]: %v\n", event.AgentName, msg)
}
}
}Cancel Mechanism
Cancel provides safe, controllable termination of agent execution.
// Create a cancel function alongside the run
cancelOpt, cancelFn := adk.WithCancel()
iter := runner.Query(ctx, "do something", cancelOpt)
// ... iterate events ...
// Cancel at a safe point (cancelFn is non-blocking, Wait blocks until complete)
handle, ok := cancelFn(adk.WithAgentCancelMode(adk.CancelAfterChatModel))
if ok {
handle.Wait()
}**CancelMode** (bitmask):
| Mode | Behavior | |------|----------| | `CancelImmediate` (0) | Abort immediately, stream terminated | | `CancelAfterChatModel` | Wait for current model call to finish | | `CancelAfterToolCalls` | Wait for current tool calls to finish |
**Cancel options:**
- `WithAgentCancelMode(mode)` -- set safe point
- `WithAgentCancelTimeout(d)` -- escalate to immediate if safe point not reached in time
- `WithRecursive()` -- propagate cancel into nested AgentTool agents
Cancel produces a `CancelError` on the event stream with checkpoint data for later resumption.
Model Retry
Output-based retry with full control over retry decisions.
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
// ...
ModelRetryConfig: &adk.ModelRetryConfig{
MaxRetries: 3,
ShouldRetry: func(ctx context.Context, retryCtx *adk.RetryContext) *adk.RetryDecision {
// Retry based on output content (e.g., empty response, bad finish reason)
if retryCtx.Err != nil {
return &adk.RetryDecision{Retry: true, Backoff: time.Second}
}
if retryCtx.OutputMessage == nil || retryCtx.OutputMessage.Content == "" {
return &adk.RetryDecision{Retry: true, Backoff: time.Second}
}
return &adk.RetryDecision{Retry: false}
},
},
})**RetryContext** provides: `RetryAttempt`, `InputMessages`, `OutputMessage` (full concatenated response), `Err`.
**RetryDecision** controls: `Retry`, `ModifiedInputMessages`, `AdditionalOptions`, `Backoff`, `RejectReason`.
When streaming, a `WillRetryError` is emitted on the stream to signal retry is occurring.
Model Failover
Dynamic model switching when primary model fails or produces unsatisfactory output.
agent, _ := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
// ...
ModelFailoverConfig: &adk.ModelFailoverConfig[*schema.Message]Various extensions for the Eino framework: https://github.com/cloudwego/eino
Other skills on eino-ext.
- /eino-component
Eino component selection, configuration, and usage. Use when a user needs to choose or configure a ChatModel, AgenticModel, Embedding, Retriever, Indexer, Tool, Document loader/parser/transformer, Prompt template, or Callback handler. Covers all component interfaces and their
Open skill - /eino-compose
Eino orchestration with Graph, Chain, and Workflow. Use when a user needs to build multi-step pipelines, compose components into executable graphs, handle streaming between nodes, use branching or parallel execution, manage state with checkpoints, or understand the Runnable
Open skill - /eino-guide
Eino framework overview, concepts, and navigation. Use when a user asks general questions about Eino, needs help getting started, wants to understand the architecture, or is unsure which Eino skill to use. Eino is a Go framework for building LLM applications with components,
Open skill

