AgenticModel - ARK
An implementation of the Volcengine Ark model based on Eino, implementing the AgenticModel component interface. This enables the model to seamlessly integrate into Eino’s Agent capabilities, providing enhanced natural language processing and generation features.
💡 This component was introduced in version alpha/09
Features
- Implements the
github.com/cloudwego/eino/components/model.AgenticModelinterface - Easy integration into Eino’s agent system
- Configurable model parameters
- Supports Responses API
- Supports streaming responses
- Supports tool calling, including Function Tools, MCP Tools, and Server Tools
- Supports Prefix Cache and Session Cache
Installation
go get github.com/cloudwego/eino-ext/components/model/agenticark@latest
Quick Start
Here’s a quick example of how to use AgenticModel:
package main
import (
"context"
"log"
"os"
"github.com/bytedance/sonic"
"github.com/cloudwego/eino-ext/components/model/agenticark"
"github.com/cloudwego/eino/schema"
)
func main() {
ctx := context.Background()
// Get ARK_API_KEY and ARK_MODEL_ID: https://www.volcengine.com/docs/82379/1399008
am, err := agenticark.New(ctx, &agenticark.Config{
Model: os.Getenv("ARK_MODEL_ID"),
APIKey: os.Getenv("ARK_API_KEY"),
})
if err != nil {
log.Fatalf("failed to create agentic model, err: %v", err)
}
input := []*schema.AgenticMessage{
schema.UserAgenticMessage("what is the weather like in Beijing"),
}
msg, err := am.Generate(ctx, input)
if err != nil {
log.Fatalf("failed to generate, err: %v", err)
}
meta := msg.ResponseMeta.Extension.(*agenticark.ResponseMetaExtension)
log.Printf("request_id: %s
", meta.ID)
respBody, _ := sonic.MarshalIndent(msg, " ", " ")
log.Printf(" body: %s
", string(respBody))
}
Configuration
The AgenticModel can be configured using the agenticark.Config struct:
type Config struct {
// Timeout specifies the maximum duration to wait for API responses
// If HTTPClient is set, Timeout will not be used.
// Optional. Default: 10 minutes
Timeout *time.Duration
// HTTPClient specifies the client to use for sending HTTP requests.
// If HTTPClient is set, Timeout will not be used.
// Optional. Default: &http.Client{Timeout: Timeout}
HTTPClient *http.Client
// RetryTimes specifies the number of retries for failed API calls
// Optional. Default: 2
RetryTimes *int
// BaseURL specifies the base URL of the Ark service
// Optional. Default: "https://agenticark.cn-beijing.volces.com/api/v3"
BaseURL string
// Region specifies the region where the Ark service is located
// Optional. Default: "cn-beijing"
Region string
// The following three fields are authentication related - either APIKey or AccessKey/SecretKey pair is required
// For authentication details, see: https://www.volcengine.com/docs/82379/1298459
// If both are provided, APIKey takes precedence
APIKey string
AccessKey string
SecretKey string
// The following fields correspond to Ark's responses API parameters
// Reference: https://www.volcengine.com/docs/82379/1298454
// Model specifies the endpoint ID on the ark platform
// Required
Model string
// MaxTokens specifies the maximum number of tokens to generate in the response.
// Optional.
MaxTokens *int
// Temperature specifies the sampling temperature to use
// It's generally recommended to modify this or TopP, but not both
// Range: 0.0 to 1.0. Higher values make the output more random
// Optional. Default: 1.0
Temperature *float64
// TopP controls diversity through nucleus sampling
// It's generally recommended to modify this or Temperature, but not both
// Range: 0.0 to 1.0. Lower values make the output more focused
// Optional. Default: 0.7
TopP *float64
// Stop sequences where the API will stop generating more tokens
// Optional. Example: []string{"
", "User:"}
Stop []string
// FrequencyPenalty penalizes tokens based on frequency to prevent repetition
// Range: -2.0 to 2.0. Positive values reduce the likelihood of repetition
// Optional. Default: 0
FrequencyPenalty *float64
// LogitBias modifies the likelihood of specific tokens appearing in completions
// Optional. Maps token IDs to bias values from -100 to 100
LogitBias map[string]int32
// PresencePenalty penalizes tokens based on presence to prevent repetition
// Range: -2.0 to 2.0. Positive values increase the likelihood of new topics
// Optional. Default: 0
PresencePenalty *float64
// LogProbs specifies whether to return log probabilities of the output tokens.
LogProbs *bool
// TopLogProbs specifies the number of most likely tokens to return at each token position, each with an associated log probability.
TopLogProbs *int
// RepetitionPenalty penalizes tokens based on their existing frequency in the text so far.
// Range: 0.0 to 2.0. 1.0 means no penalty.
RepetitionPenalty *float64
// Thinking controls whether the model is set to activate deep thinking mode.
// Enabled by default.
Thinking *responses.ResponsesThinking
// Reasoning specifies the reasoning effort for the model.
// Optional.
// EnablePassBackReasoning controls whether the model passes back reasoning items in the next request.
// Note that doubao 1.6 does not support passing back reasoning items.
// Optional. Default: true
EnablePassBackReasoning *bool
// MaxToolCalls limits the maximum number of tool calls generated in chat completions.
// Optional.
MaxToolCalls *int64
// ParallelToolCalls controls whether the model is set to perform parallel tool calls.
// Optional.
ParallelToolCalls *bool
// ServerTools specifies server-side tools available to the model.
// Optional.
ServerTools []*ServerToolConfig
// MCPTools specifies MCP tools available to the model.
// Optional.
MCPTools []*responses.ToolMcp
// Cache specifies the cache configuration for the model.
// Optional.
Cache *CacheConfig
// CustomHeader HTTP headers to pass when requesting the model
CustomHeader map[string]string
}
Advanced Usage
Tool Calling
AgenticModel supports tool calling, including Function Tools, MCP Tools, and Server Tools.
Function Tool Example
package main
import (
"context"
"errors"
"io"
"log"
"os"
"github.com/bytedance/sonic"
"github.com/cloudwego/eino-ext/components/model/agenticark"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/schema"
"github.com/eino-contrib/jsonschema"
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model/responses"
"github.com/wk8/go-ordered-map/v2"
)
func main() {
ctx := context.Background()
// Get ARK_API_KEY and ARK_MODEL_ID: https://www.volcengine.com/docs/82379/1399008
am, err := agenticark.New(ctx, &agenticark.Config{
Model: os.Getenv("ARK_MODEL_ID"),
APIKey: os.Getenv("ARK_API_KEY"),
Thinking: &responses.ResponsesThinking{
Type: responses.ThinkingType_disabled.Enum(),
},
})
if err != nil {
log.Fatalf("failed to create agentic model, err=%v", err)
}
functionTools := []*schema.ToolInfo{
{
Name: "get_weather",
Desc: "get the weather in a city",
ParamsOneOf: schema.NewParamsOneOfByJSONSchema(&jsonschema.Schema{
Type: "object",
Properties: orderedmap.New[string, *jsonschema.Schema](
orderedmap.WithInitialData(
orderedmap.Pair[string, *jsonschema.Schema]{
Key: "city",
Value: &jsonschema.Schema{
Type: "string",
Description: "the city to get the weather",
},
},
),
),
Required: []string{"city"},
}),
},
}
allowedTools := []*schema.AllowedTool{
{
FunctionName: "get_weather",
},
}
opts := []model.Option{
model.WithAgenticToolChoice(&schema.AgenticToolChoice{
Type: schema.ToolChoiceForced,
Forced: &schema.AgenticForcedToolChoice{
Tools: allowedTools,
},
}),
model.WithTools(functionTools),
}
firstInput := []*schema.AgenticMessage{
schema.UserAgenticMessage("what's the weather like in Beijing today"),
}
sResp, err := am.Stream(ctx, firstInput, opts...)
if err != nil {
log.Fatalf("failed to stream, err: %v", err)
}
var msgs []*schema.AgenticMessage
for {
msg, err := sResp.Recv()
if err != nil {
if errors.Is(err, io.EOF) {
break
}
log.Fatalf("failed to receive stream response, err: %v", err)
}
msgs = append(msgs, msg)
}
concatenated, err := schema.ConcatAgenticMessages(msgs)
if err != nil {
log.Fatalf("failed to concat agentic messages, err: %v", err)
}
lastBlock := concatenated.ContentBlocks[len(concatenated.ContentBlocks)-1]
toolCall := lastBlock.FunctionToolCall
toolResultMsg := schema.FunctionToolResultAgenticMessage(toolCall.CallID, toolCall.Name, "20 degrees")
secondInput := append(firstInput, concatenated, toolResultMsg)
gResp, err := am.Generate(ctx, secondInput)
if err != nil {
log.Fatalf("failed to generate, err: %v", err)
}
meta := concatenated.ResponseMeta.Extension.(*agenticark.ResponseMetaExtension)
log.Printf("request_id: %s
", meta.ID)
respBody, _ := sonic.MarshalIndent(gResp, " ", " ")
log.Printf(" body: %s
", string(respBody))
}
Server Tool Example
package main
import (
"context"
"errors"
"io"
"log"
"os"
"github.com/bytedance/sonic"
"github.com/cloudwego/eino-ext/components/model/agenticark"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/schema"
"github.com/volcengine/volcengine-go-sdk/service/arkruntime/model/responses"
)
func main() {
ctx := context.Background()
// Get ARK_API_KEY and ARK_MODEL_ID: https://www.volcengine.com/docs/82379/1399008
am, err := agenticark.New(ctx, &agenticark.Config{
Model: os.Getenv("ARK_MODEL_ID"),
APIKey: os.Getenv("ARK_API_KEY"),
})
if err != nil {
log.Fatalf("failed to create agentic model, err=%v", err)
}
serverTools := []*agenticark.ServerToolConfig{
{
WebSearch: &responses.ToolWebSearch{
Type: responses.ToolType_web_search,
},
},
}
allowedTools := []*schema.AllowedTool{
{
ServerTool: &schema.AllowedServerTool{
Name: string(agenticark.ServerToolNameWebSearch),
},
},
}
opts := []model.Option{
agenticark.WithServerTools(serverTools),
model.WithAgenticToolChoice(&schema.AgenticToolChoice{
Type: schema.ToolChoiceForced,
Forced: &schema.AgenticForcedToolChoice{
Tools: allowedTools,
},
}),
agenticark.WithThinking(&responses.ResponsesThinking{
Type: responses.ThinkingType_disabled.Enum(),
}),
}
input := []*schema.AgenticMessage{
schema.UserAgenticMessage("what's the weather like in Beijing today"),
}
resp, err := am.Stream(ctx, input, opts...)
if err != nil {
log.Fatalf("failed to stream, err: %v", err)
}
var msgs []*schema.AgenticMessage
for {
msg, err := resp.Recv()
if err != nil {
if errors.Is(err, io.EOF) {
break
}
log.Fatalf("failed to receive stream response, err: %v", err)
}
msgs = append(msgs, msg)
}
concatenated, err := schema.ConcatAgenticMessages(msgs)
if err != nil {
log.Fatalf("failed to concat agentic messages, err: %v", err)
}
meta := concatenated.ResponseMeta.Extension.(*agenticark.ResponseMetaExtension)
for _, block := range concatenated.ContentBlocks {
if block.ServerToolCall == nil {
continue
}
serverToolArgs := block.ServerToolCall.Arguments.(*agenticark.ServerToolCallArguments)
args, _ := sonic.MarshalIndent(serverToolArgs, " ", " ")
log.Printf("server_tool_args: %s
", string(args))
}
log.Printf("request_id: %s
", meta.ID)
respBody, _ := sonic.MarshalIndent(concatenated, " ", " ")
log.Printf(" body: %s
", string(respBody))
}
For more examples, please refer to the examples directory.