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 (using *schema.Message)
type Agent = TypedAgent[*schema.Message]
MethodDescription
Name
Agent name identifier
Description
Capability description, for other Agents or the framework to understand 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 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., consistent with ChatModel input format
  • EnableStreaming: Suggests the Agent use streaming output. Components that support streaming (e.g., ChatModel) will return progressively; components that don’t support it 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 unifies handling of 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 at once from Message
  • Role/ToolName: Only valid for *schema.Message path (Assistant or Tool)
  • AgenticRole: Only valid for *schema.AgenticMessage path

AgentAction

Behavior signals that control 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, use AgentAsTool instead

AgentRunOption

Request-level Agent configuration. ADK built-in options:

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

Custom Options:

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 restricts an Option to a specific 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 arrives or iteration ends. Agent implementations typically write to a Generator in a goroutine and immediately return the Iterator:

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). Recommended to set during program initialization.

💡 The language setting only affects ADK built-in prompts. Custom Instructions need to handle internationalization on their own.