Agent Abstraction

Agent Interface

All ADK functionality revolves around the Agent interface:

// github.com/cloudwego/eino/adk

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]]
}

// Default type alias (uses *schema.Message)
type Agent = TypedAgent[*schema.Message]
MethodDescription
Name
Agent name identifier
Description
Capability description, for other Agents or the framework to understand its capabilities
Run
Core execution method, asynchronously returns an event stream (Future pattern)

MessageType Constraint

type MessageType interface {
    *schema.Message | *schema.AgenticMessage
}

All ADK generic types are parameterized with [M MessageType]. *schema.Message supports full ADK features; *schema.AgenticMessage is used for the structured content block mode added in v0.9.

Type Alias Quick Reference

Generic TypeDefault Alias
TypedAgent[*schema.Message]
Agent
TypedAgentInput[*schema.Message]
AgentInput
TypedAgentEvent[*schema.Message]
AgentEvent
TypedAgentOutput[*schema.Message]
AgentOutput
TypedMessageVariant[*schema.Message]
MessageVariant

AgentInput

type TypedAgentInput[M MessageType] struct {
    Messages       []M
    EnableStreaming bool
}
  • Messages: User instructions, conversation history, background knowledge, etc., same format as ChatModel input
  • EnableStreaming: Suggests the Agent use streaming output. Components that support streaming (such as ChatModel) will return progressively; components that don’t are unaffected

AgentEvent

Events produced during Agent execution:

type TypedAgentEvent[M MessageType] struct {
    AgentName string
    RunPath   []RunStep
    Output    *TypedAgentOutput[M]
    Action    *AgentAction
    Err       error
}

AgentOutput

type TypedAgentOutput[M MessageType] struct {
    MessageOutput    *TypedMessageVariant[M]
    CustomizedOutput any
}

MessageVariant provides unified handling for streaming and non-streaming messages:

type TypedMessageVariant[M MessageType] struct {
    IsStreaming   bool
    Message       M
    MessageStream *schema.StreamReader[M]
    Role          schema.RoleType       // *schema.Message path
    AgenticRole   schema.AgenticRoleType // *schema.AgenticMessage path
    ToolName      string
}
  • IsStreaming=true → Read frame-by-frame from MessageStream
  • IsStreaming=false → Get all at once from Message
  • Role/ToolName: Only effective for the *schema.Message path (Assistant or Tool)
  • AgenticRole: Only effective for the *schema.AgenticMessage path

AgentAction

Behavioral signals for controlling multi-Agent collaboration:

type AgentAction struct {
    Exit            bool
    Interrupted     *InterruptInfo
    TransferToAgent *TransferToAgentAction  // NOT RECOMMENDED
    BreakLoop       *BreakLoopAction
    CustomizedAction any
}
  • Interrupted: Interrupts Runner execution, carries custom data, supports subsequent Resume
  • BreakLoop: Terminates the LoopAgent’s loop
  • Exit: Immediately exits the multi-Agent system
  • TransferToAgent: (Not recommended) Task transfer, AgentAsTool is recommended instead

AgentRunOption

Request-level Agent configuration. ADK built-ins:

  • WithSessionValues(map[string]any): Inject cross-Agent shared KV data
  • WithCallbacks(...callbacks.Handler): Add callback handlers
  • WithCancel(): Enable Agent Cancel capability (see Cancel and TurnLoop)

Custom Option:

type myOptions struct {
    modelName string
}

func WithModelName(name string) adk.AgentRunOption {
    return adk.WrapImplSpecificOptFn(func(t *myOptions) {
        t.modelName = name
    })
}

// Read in Run
func (m *MyAgent) Run(ctx context.Context, input *adk.AgentInput, opts ...adk.AgentRunOption) *adk.AsyncIterator[*adk.AgentEvent] {
    o := adk.GetImplSpecificOptions(&myOptions{}, opts...)
    // Use o.modelName ...
}

DesignateAgent can restrict an Option to a specified Agent:

opt := adk.WithSessionValues(map[string]any{"key": "val"}).DesignateAgent("agent_1")

AsyncIterator

The asynchronous event iterator returned by Run:

iter := agent.Run(ctx, input)
for {
    event, ok := iter.Next()
    if !ok {
        break
    }
    // Handle event
}

Next() blocks until a new event is available or iteration ends. Agent implementations typically write to a Generator in a goroutine and return the Iterator immediately:

func (m *MyAgent) Run(ctx context.Context, input *adk.AgentInput, opts ...adk.AgentRunOption) *adk.AsyncIterator[*adk.AgentEvent] {
    iter, gen := adk.NewAsyncIteratorPair[*adk.AgentEvent]()
    go func() {
        defer gen.Close()
        // Execute logic, produce events via gen.Send(event)
    }()
    return iter
}

Language Settings

adk.SetLanguage(adk.LanguageChinese) // Or adk.LanguageEnglish (default)

Affects ADK built-in prompts (FileSystem, Reduction, Skill, ChatModelAgent and other components). It is recommended to set this during program initialization.

💡 Language settings only affect ADK built-in prompts. Custom Instructions need to handle internationalization on their own.