展示如何让 Agent 使用内置工具(文件系统、Bash 等)。
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/astercloud/aster/pkg/agent"
"github.com/astercloud/aster/pkg/provider"
"github.com/astercloud/aster/pkg/sandbox"
"github.com/astercloud/aster/pkg/store"
"github.com/astercloud/aster/pkg/tools"
"github.com/astercloud/aster/pkg/tools/builtin"
"github.com/astercloud/aster/pkg/types"
)
func main() {
ctx := context.Background()
// 创建工具注册表并注册内置工具
toolRegistry := tools.NewRegistry()
builtin.RegisterAll(toolRegistry)
// 创建依赖
deps := &agent.Dependencies{
ToolRegistry: toolRegistry,
SandboxFactory: sandbox.NewFactory(),
ProviderFactory: provider.NewMultiProviderFactory(),
Store: store.NewMemoryStore(),
TemplateRegistry: agent.NewTemplateRegistry(),
}
// 创建 Agent,启用工具
ag, err := agent.Create(ctx, &types.AgentConfig{
TemplateID: "assistant",
ModelConfig: &types.ModelConfig{
Provider: "anthropic",
Model: "claude-sonnet-4-5",
APIKey: os.Getenv("ANTHROPIC_API_KEY"),
},
Tools: []string{"filesystem", "bash"}, // 启用工具
}, deps)
if err != nil {
log.Fatal(err)
}
defer ag.Close()
// 订阅进度和控制事件
eventCh := ag.Subscribe([]types.AgentChannel{
types.ChannelProgress,
types.ChannelControl,
}, nil)
// 处理事件
go func() {
for envelope := range eventCh {
switch envelope.Event.Type {
case types.EventTypeTextDelta:
fmt.Print(envelope.Event.TextDelta)
case types.EventTypeToolCallRequest:
tool := envelope.Event.ToolCall
fmt.Printf("\n[工具调用] %s\n", tool.Name)
fmt.Printf("[参数] %v\n", tool.Arguments)
case types.EventTypeToolCallResult:
result := envelope.Event.ToolResult
fmt.Printf("[结果] %s\n\n", result.Content)
}
}
}()
// 发送需要使用工具的请求
err = ag.Send(ctx, "创建一个 hello.txt 文件,内容为 'Hello, aster!'")
if err != nil {
log.Fatal(err)
}
// 等待完成
select {}
}
export ANTHROPIC_API_KEY="sk-ant-xxx"
go run main.go
我来为您创建这个文件。
[工具调用] filesystem_write
[参数] map[content:Hello, aster! path:hello.txt]
[结果] 文件已创建: hello.txt
文件已成功创建!您可以在当前目录找到 hello.txt 文件。
Tools: []string{
"filesystem", // 文件系统操作
"bash", // Shell 命令
"http", // HTTP 请求
"websearch", // 网页搜索
}
Agent 可以自动链式调用多个工具:
// 请求需要多步操作
ag.Send(ctx, "列出当前目录的 .go 文件,然后统计总行数")
// Agent 会自动:
// 1. 调用 bash: ls *.go
// 2. 调用 bash: wc -l file1.go file2.go
// 3. 返回统计结果
详细监控每个工具调用:
go func() {
for envelope := range eventCh {
switch envelope.Event.Type {
case types.EventTypeToolCallRequest:
tool := envelope.Event.ToolCall
log.Printf("🔧 调用工具: %s", tool.Name)
log.Printf("📥 输入: %+v", tool.Arguments)
case types.EventTypeToolCallResult:
result := envelope.Event.ToolResult
if result.IsError {
log.Printf("❌ 错误: %s", result.Content)
} else {
log.Printf("✅ 成功: %s", result.Content)
}
}
}
}()
如果不需要实时监控,可以使用同步 Chat():
result, err := ag.Chat(ctx, "创建 hello.txt 文件")
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Message.Content)
// Agent 会自动调用工具并返回最终结果