Tools 示例

HTTP 请求工具

使用 HTTP 工具调用 REST API

HTTP 请求工具示例

展示如何使用内置的 HTTP 工具调用 REST API。

完整代码

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{"http"},  // 启用 HTTP 工具
    }, deps)
    if err != nil {
        log.Fatal(err)
    }
    defer ag.Close()

    // 测试 HTTP 请求
    tasks := []string{
        "获取 https://api.github.com/users/golang 的信息",
        "获取 https://api.github.com/repos/golang/go 的 star 数量",
        "请求 https://httpbin.org/get 并显示返回的 headers",
    }

    for i, task := range tasks {
        fmt.Printf("\n========== 请求 %d ==========\n", i+1)
        fmt.Printf("任务: %s\n\n", task)

        result, err := ag.Chat(ctx, task)
        if err != nil {
            log.Printf("错误: %v", err)
            continue
        }

        fmt.Printf("结果: %s\n", result.Message.Content)
    }
}

可用的 HTTP 工具

1. http_get

发送 GET 请求。

// Agent 调用示例
{
    "url": "https://api.github.com/users/golang",
    "headers": {
        "Accept": "application/json"
    }
}

2. http_post

发送 POST 请求。

// Agent 调用示例
{
    "url": "https://api.example.com/data",
    "headers": {
        "Content-Type": "application/json"
    },
    "body": {
        "name": "test",
        "value": 123
    }
}

3. http_put

发送 PUT 请求。

4. http_delete

发送 DELETE 请求。

运行示例

export ANTHROPIC_API_KEY="sk-ant-xxx"
go run main.go

输出示例

========== 请求 1 ==========
任务: 获取 https://api.github.com/users/golang 的信息

结果: 获取到 golang 用户的信息:
- 名称: Go
- 公开仓库: 32
- 关注者: 79.5K
- 创建时间: 2009-11-10
- 简介: The Go programming language

========== 请求 2 ==========
任务: 获取 https://api.github.com/repos/golang/go 的 star 数量

结果: golang/go 仓库目前有 125,847 个 stars

========== 请求 3 ==========
任务: 请求 https://httpbin.org/get 并显示返回的 headers

结果: httpbin.org 返回的 headers:
- Content-Type: application/json
- Server: gunicorn/19.9.0
- Access-Control-Allow-Origin: *

实用场景

API 数据聚合

result, _ := ag.Chat(ctx, `
查询以下 API 并汇总结果:
1. GitHub: golang/go 仓库的 star 数
2. GitHub: golang/go 仓库的 issue 数
3. 总结整体活跃度
`)
// Agent 会依次调用多个 API 并汇总

Webhook 触发

result, _ := ag.Chat(ctx, `
发送 POST 请求到 https://hooks.slack.com/xxx
内容:部署完成,版本 v1.2.3
`)

天气查询

result, _ := ag.Chat(ctx, "查询北京今天的天气(使用 wttr.in API)")
// Agent 会:
// 1. 调用 wttr.in API
// 2. 解析天气数据
// 3. 格式化输出

带认证的 API 调用

自定义 HTTP 工具添加认证:

import "github.com/astercloud/aster/pkg/tools"

// 创建带认证的 HTTP 工具
func AuthenticatedHTTPTool(apiKey string) tools.Tool {
    return tools.Tool{
        Name:        "api_call",
        Description: "调用需要认证的 API",
        InputSchema: map[string]interface{}{
            "type": "object",
            "properties": map[string]interface{}{
                "endpoint": map[string]interface{}{
                    "type": "string",
                },
            },
            "required": []string{"endpoint"},
        },
        Handler: func(ctx context.Context, tc *tools.ToolContext) (interface{}, error) {
            endpoint := tc.Input["endpoint"].(string)
            url := "https://api.example.com" + endpoint

            req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
            req.Header.Set("Authorization", "Bearer "+apiKey)

            client := &http.Client{Timeout: 30 * time.Second}
            resp, err := client.Do(req)
            if err != nil {
                return nil, err
            }
            defer resp.Body.Close()

            var result interface{}
            json.NewDecoder(resp.Body).Decode(&result)
            return result, nil
        },
    }
}

// 注册工具
toolRegistry.Register(AuthenticatedHTTPTool(os.Getenv("API_KEY")))

速率限制

控制 HTTP 请求频率:

import "golang.org/x/time/rate"

type RateLimitedHTTPTool struct {
    limiter *rate.Limiter
}

func (t *RateLimitedHTTPTool) Handler(ctx context.Context, tc *tools.ToolContext) (interface{}, error) {
    // 等待速率限制
    if err := t.limiter.Wait(ctx); err != nil {
        return nil, err
    }

    // 执行 HTTP 请求
    // ...
}

错误处理

处理 HTTP 错误:

result, _ := ag.Chat(ctx, "调用 API,如果失败请重试 3 次")
// Agent 会自动处理错误和重试

相关资源