441 lines
14 KiB
Markdown
441 lines
14 KiB
Markdown
|
|
---
|
|||
|
|
Description: ""
|
|||
|
|
date: "2026-03-02"
|
|||
|
|
lastmod: ""
|
|||
|
|
tags: []
|
|||
|
|
title: ARK
|
|||
|
|
weight: 2
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
基于 [Eino](https://github.com/cloudwego/eino) 的火山引擎 Ark 模型实现,实现了 `AgenticModel` 组件接口。这使得该模型能够无缝集成到 Eino 的 Agent 能力中,提供增强的自然语言处理和生成功能。
|
|||
|
|
|
|||
|
|
> 💡
|
|||
|
|
> 本组件在 alpha/09 版本引入
|
|||
|
|
|
|||
|
|
## 功能特性
|
|||
|
|
|
|||
|
|
- 实现了 `github.com/cloudwego/eino/components/model.AgenticModel` 接口
|
|||
|
|
- 易于集成到 Eino 的 agent 系统中
|
|||
|
|
- 可配置的模型参数
|
|||
|
|
- 支持 Responses API
|
|||
|
|
- 支持流式响应 (Streaming)
|
|||
|
|
- 支持工具调用 (Tools),包括函数工具 (Function Tools)、MCP 工具 (MCP Tools) 和服务器工具 (Server Tools)
|
|||
|
|
- 支持前缀缓存 (Prefix Cache) 和会话缓存 (Session Cache)
|
|||
|
|
|
|||
|
|
## 安装
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
go get github.com/cloudwego/eino-ext/components/model/agenticark@latest
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 快速开始
|
|||
|
|
|
|||
|
|
以下是如何使用 `AgenticModel` 的一个快速示例:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
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()
|
|||
|
|
|
|||
|
|
// 获取 ARK_API_KEY 和 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))
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 配置
|
|||
|
|
|
|||
|
|
可以使用 `agenticark.Config` 结构体配置 `AgenticModel`:
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
type Config struct {
|
|||
|
|
// Timeout 指定等待 API 响应的最大持续时间
|
|||
|
|
// 如果设置了 HTTPClient,则不会使用 Timeout。
|
|||
|
|
// 可选。默认值:10 分钟
|
|||
|
|
Timeout *time.Duration
|
|||
|
|
|
|||
|
|
// HTTPClient 指定用于发送 HTTP 请求的客户端。
|
|||
|
|
// 如果设置了 HTTPClient,则不会使用 Timeout。
|
|||
|
|
// 可选。默认值 &http.Client{Timeout: Timeout}
|
|||
|
|
HTTPClient *http.Client
|
|||
|
|
|
|||
|
|
// RetryTimes 指定失败 API 调用的重试次数
|
|||
|
|
// 可选。默认值:2
|
|||
|
|
RetryTimes *int
|
|||
|
|
|
|||
|
|
// BaseURL 指定 Ark 服务的基准 URL
|
|||
|
|
// 可选。默认值:"https://agenticark.cn-beijing.volces.com/api/v3"
|
|||
|
|
BaseURL string
|
|||
|
|
|
|||
|
|
// Region 指定 Ark 服务所在的区域
|
|||
|
|
// 可选。默认值:"cn-beijing"
|
|||
|
|
Region string
|
|||
|
|
|
|||
|
|
// 以下三个字段与认证有关 - 需要 APIKey 或 AccessKey/SecretKey 对之一
|
|||
|
|
// 有关认证的详细信息,请参阅:https://www.volcengine.com/docs/82379/1298459
|
|||
|
|
// 如果同时提供,APIKey 优先
|
|||
|
|
APIKey string
|
|||
|
|
|
|||
|
|
AccessKey string
|
|||
|
|
|
|||
|
|
SecretKey string
|
|||
|
|
|
|||
|
|
// 以下字段对应于 Ark 的 responses API 参数
|
|||
|
|
// 参考:https://www.volcengine.com/docs/82379/1298454
|
|||
|
|
|
|||
|
|
// Model 指定 ark 平台上的端点 ID
|
|||
|
|
// 必填
|
|||
|
|
Model string
|
|||
|
|
|
|||
|
|
// MaxTokens 指定响应中要生成的最大令牌数。
|
|||
|
|
// 可选。
|
|||
|
|
MaxTokens *int
|
|||
|
|
|
|||
|
|
// Temperature 指定要使用的采样温度
|
|||
|
|
// 通常建议修改此项或 TopP,但不能同时修改
|
|||
|
|
// 范围:0.0 到 1.0。值越高,输出越随机
|
|||
|
|
// 可选。默认值:1.0
|
|||
|
|
Temperature *float64
|
|||
|
|
|
|||
|
|
// TopP 通过核心采样控制多样性
|
|||
|
|
// 通常建议修改此项或 Temperature,但不能同时修改
|
|||
|
|
// 范围:0.0 到 1.0。值越低,输出越集中
|
|||
|
|
// 可选。默认值:0.7
|
|||
|
|
TopP *float64
|
|||
|
|
|
|||
|
|
// Stop 序列,API 将在这些序列处停止生成更多 token
|
|||
|
|
// 可选。示例:[]string{"
|
|||
|
|
", "User:"}
|
|||
|
|
Stop []string
|
|||
|
|
|
|||
|
|
// FrequencyPenalty 根据频率惩罚 token 以防止重复
|
|||
|
|
// 范围:-2.0 到 2.0。正值降低重复的可能性
|
|||
|
|
// 可选。默认值:0
|
|||
|
|
FrequencyPenalty *float64
|
|||
|
|
|
|||
|
|
// LogitBias 修改特定 token 在补全中出现的可能性
|
|||
|
|
// 可选。将 token ID 映射到 -100 到 100 的偏置值
|
|||
|
|
LogitBias map[string]int32
|
|||
|
|
|
|||
|
|
// PresencePenalty 根据存在与否惩罚 token 以防止重复
|
|||
|
|
// 范围:-2.0 到 2.0。正值增加新主题的可能性
|
|||
|
|
// 可选。默认值:0
|
|||
|
|
PresencePenalty *float64
|
|||
|
|
|
|||
|
|
// LogProbs 指定是否返回输出 token 的对数概率。
|
|||
|
|
LogProbs *bool
|
|||
|
|
|
|||
|
|
// TopLogProbs 指定每个 token 位置返回的最可能 token 的数量,每个都带有相关的对数概率。
|
|||
|
|
TopLogProbs *int
|
|||
|
|
|
|||
|
|
// RepetitionPenalty 基于 token 在目前为止的文本中的现有频率对其进行惩罚。
|
|||
|
|
// 范围:0.0 到 2.0。1.0 表示无惩罚。
|
|||
|
|
RepetitionPenalty *float64
|
|||
|
|
|
|||
|
|
// Thinking 控制模型是否设置为激活深度思考模式。
|
|||
|
|
// 默认设置为启用。
|
|||
|
|
Thinking *responses.ResponsesThinking
|
|||
|
|
|
|||
|
|
// Reasoning 指定模型的推理力度。
|
|||
|
|
// 可选。
|
|||
|
|
|
|||
|
|
// EnablePassBackReasoning 控制模型是否在下一次请求中传回推理项。
|
|||
|
|
// 注意 doubao 1.6 不支持传回推理项。
|
|||
|
|
// 可选. 默认值:true
|
|||
|
|
EnablePassBackReasoning *bool
|
|||
|
|
|
|||
|
|
// MaxToolCalls 限制聊天补全中生成的最大工具调用数。
|
|||
|
|
// 可选。
|
|||
|
|
MaxToolCalls *int64
|
|||
|
|
|
|||
|
|
// ParallelToolCalls 控制模型是否设置为执行并行工具调用。
|
|||
|
|
// 可选。
|
|||
|
|
ParallelToolCalls *bool
|
|||
|
|
|
|||
|
|
// ServerTools 指定模型可用的服务器端工具。
|
|||
|
|
// 可选。
|
|||
|
|
ServerTools []*ServerToolConfig
|
|||
|
|
|
|||
|
|
// MCPTools 指定模型可用的 MCP 工具。
|
|||
|
|
// 可选。
|
|||
|
|
MCPTools []*responses.ToolMcp
|
|||
|
|
|
|||
|
|
// Cache 指定模型的缓存配置。
|
|||
|
|
// 可选。
|
|||
|
|
Cache *CacheConfig
|
|||
|
|
|
|||
|
|
// CustomHeader 请求模型时传递的 http 标头
|
|||
|
|
CustomHeader map[string]string
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 高级用法
|
|||
|
|
|
|||
|
|
### 工具调用 (Tool Calling)
|
|||
|
|
|
|||
|
|
`AgenticModel` 支持工具调用,包括函数工具、MCP 工具和服务器工具。
|
|||
|
|
|
|||
|
|
#### 函数工具示例
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
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()
|
|||
|
|
|
|||
|
|
// 获取 ARK_API_KEY 和 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))
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 服务器工具示例
|
|||
|
|
|
|||
|
|
```go
|
|||
|
|
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))
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
更多示例请参考 `examples` 目录。
|