Skip to content

Tools - Agent機能を拡張

ツールでAgentに外部機能へのアクセスを提供します。


ツールとは?

ツールは、Agentが外部システムとやり取りしたり、計算を実行したり、データを取得したりするために呼び出すことができる関数です。Agno-Goは、Agent機能を拡張するための柔軟なツールキットシステムを提供しています。

組み込みツール

  • Calculator: 基本的な数学演算
  • HTTP: Webリクエストを実行
  • File: 安全制御付きのファイル読み書き

ツールの使用

基本的な例

go
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/rexleimo/agno-go/pkg/agno/agent"
    "github.com/rexleimo/agno-go/pkg/agno/models/openai"
    "github.com/rexleimo/agno-go/pkg/agno/tools/calculator"
    "github.com/rexleimo/agno-go/pkg/agno/tools/toolkit"
)

func main() {
    model, _ := openai.New("gpt-4o-mini", openai.Config{
        APIKey: os.Getenv("OPENAI_API_KEY"),
    })

    agent, _ := agent.New(agent.Config{
        Name:     "Math Assistant",
        Model:    model,
        Toolkits: []toolkit.Toolkit{calculator.New()},
    })

    output, _ := agent.Run(context.Background(), "What is 23 * 47?")
    fmt.Println(output.Content) // Agentは自動的に計算機を使用
}

Calculator Tool

数学演算を実行します。

演算

  • add(a, b) - 加算
  • subtract(a, b) - 減算
  • multiply(a, b) - 乗算
  • divide(a, b) - 除算

go
import "github.com/rexleimo/agno-go/pkg/agno/tools/calculator"

agent, _ := agent.New(agent.Config{
    Model:    model,
    Toolkits: []toolkit.Toolkit{calculator.New()},
})

// Agentは自動的に計算機を使用
output, _ := agent.Run(ctx, "Calculate 15% tip on $85")

HTTP Tool

外部APIへのHTTPリクエストを実行します。

メソッド

  • get(url) - HTTP GETリクエスト
  • post(url, body) - HTTP POSTリクエスト

go
import "github.com/rexleimo/agno-go/pkg/agno/tools/http"

agent, _ := agent.New(agent.Config{
    Model:    model,
    Toolkits: []toolkit.Toolkit{http.New()},
})

// AgentはAPIからデータを取得可能
output, _ := agent.Run(ctx, "Get the latest GitHub status from https://www.githubstatus.com/api/v2/status.json")

設定

セキュリティのために許可ドメインを制御:

go
httpTool := http.New(http.Config{
    AllowedDomains: []string{"api.github.com", "api.weather.com"},
    Timeout:        10 * time.Second,
})

File Tool

組み込みの安全制御でファイルを読み書きします。

操作

  • read_file(path) - ファイル内容を読み取り
  • write_file(path, content) - ファイルに内容を書き込み
  • list_directory(path) - ディレクトリ内容をリスト
  • delete_file(path) - ファイルを削除

go
import "github.com/rexleimo/agno-go/pkg/agno/tools/file"

fileTool := file.New(file.Config{
    AllowedPaths: []string{"/tmp", "./data"},  // アクセスを制限
    MaxFileSize:  1024 * 1024,                 // 1MB制限
})

agent, _ := agent.New(agent.Config{
    Model:    model,
    Toolkits: []toolkit.Toolkit{fileTool},
})

output, _ := agent.Run(ctx, "Read the contents of ./data/report.txt")

安全機能

  • パス制限(ホワイトリスト)
  • ファイルサイズ制限
  • 読み取り専用モードオプション
  • 自動パスサニタイゼーション

複数のツール

Agentは複数のツールを使用できます:

go
agent, _ := agent.New(agent.Config{
    Name:  "Multi-Tool Agent",
    Model: model,
    Toolkits: []toolkit.Toolkit{
        calculator.New(),
        http.New(),
        file.New(file.Config{
            AllowedPaths: []string{"./data"},
        }),
    },
})

// Agentは計算、データ取得、ファイル読み取りが可能
output, _ := agent.Run(ctx,
    "Fetch weather data, calculate average temperature, and save to file")

カスタムツールの作成

Toolkitインターフェースを実装して独自のツールを構築します。

ステップ1: Toolkit構造体を作成

go
package mytool

import "github.com/rexleimo/agno-go/pkg/agno/tools/toolkit"

type MyToolkit struct {
    *toolkit.BaseToolkit
}

func New() *MyToolkit {
    t := &MyToolkit{
        BaseToolkit: toolkit.NewBaseToolkit("my_tools"),
    }

    // 関数を登録
    t.RegisterFunction(&toolkit.Function{
        Name:        "greet",
        Description: "Greet a person by name",
        Parameters: map[string]toolkit.Parameter{
            "name": {
                Type:        "string",
                Description: "Person's name",
                Required:    true,
            },
        },
        Handler: t.greet,
    })

    return t
}

ステップ2: ハンドラーを実装

go
func (t *MyToolkit) greet(args map[string]interface{}) (interface{}, error) {
    name, ok := args["name"].(string)
    if !ok {
        return nil, fmt.Errorf("name must be a string")
    }

    return fmt.Sprintf("Hello, %s!", name), nil
}

ステップ3: ツールを使用

go
agent, _ := agent.New(agent.Config{
    Model:    model,
    Toolkits: []toolkit.Toolkit{mytool.New()},
})

output, _ := agent.Run(ctx, "Greet Alice")
// Agentはgreet("Alice")を呼び出し、"Hello, Alice!"で応答

高度なカスタムツールの例

データベースクエリツール:

go
type DatabaseToolkit struct {
    *toolkit.BaseToolkit
    db *sql.DB
}

func NewDatabaseToolkit(db *sql.DB) *DatabaseToolkit {
    t := &DatabaseToolkit{
        BaseToolkit: toolkit.NewBaseToolkit("database"),
        db:          db,
    }

    t.RegisterFunction(&toolkit.Function{
        Name:        "query_users",
        Description: "Query users from database",
        Parameters: map[string]toolkit.Parameter{
            "limit": {
                Type:        "integer",
                Description: "Maximum number of results",
                Required:    false,
            },
        },
        Handler: t.queryUsers,
    })

    return t
}

func (t *DatabaseToolkit) queryUsers(args map[string]interface{}) (interface{}, error) {
    limit := 10
    if l, ok := args["limit"].(float64); ok {
        limit = int(l)
    }

    rows, err := t.db.Query("SELECT id, name FROM users LIMIT ?", limit)
    if err != nil {
        return nil, err
    }
    defer rows.Close()

    var users []map[string]interface{}
    for rows.Next() {
        var id int
        var name string
        rows.Scan(&id, &name)
        users = append(users, map[string]interface{}{
            "id":   id,
            "name": name,
        })
    }

    return users, nil
}

ツールのベストプラクティス

1. 明確な説明

Agentがいつツールを使用するかを理解できるように:

go
// 良い例 ✅
Description: "Calculate the square root of a number. Use when user asks for square roots."

// 悪い例 ❌
Description: "Math function"

2. 入力を検証

常にツールパラメータを検証:

go
func (t *MyToolkit) divide(args map[string]interface{}) (interface{}, error) {
    b, ok := args["divisor"].(float64)
    if !ok || b == 0 {
        return nil, fmt.Errorf("divisor must be a non-zero number")
    }
    // ... 除算を実行
}

3. エラー処理

意味のあるエラーを返す:

go
func (t *MyToolkit) fetchData(args map[string]interface{}) (interface{}, error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, fmt.Errorf("failed to fetch data: %w", err)
    }
    // ... 応答を処理
}

4. セキュリティ

ツール機能を制限:

go
// 許可された操作をホワイトリスト化
fileTool := file.New(file.Config{
    AllowedPaths: []string{"/safe/path"},
    ReadOnly:     true,  // 書き込みを防止
})

// ドメインを検証
httpTool := http.New(http.Config{
    AllowedDomains: []string{"api.trusted.com"},
})

ツール実行フロー

  1. ユーザーがAgentにリクエストを送信
  2. Agent(LLM)がツールが必要かどうかを判断
  3. LLMがパラメータ付きのツール呼び出しを生成
  4. Agno-Goがツール関数を実行
  5. ツール結果がLLMに返される
  6. LLMが最終応答を生成

例のフロー

ユーザー: "25 * 17は何ですか?"

LLM: "計算機を使う必要があります"

ツール呼び出し: multiply(25, 17)

ツール結果: 425

LLM: "答えは425です"

ユーザーが受け取る: "答えは425です"

トラブルシューティング

Agentがツールを使用しない

明確な指示を確認:

go
agent, _ := agent.New(agent.Config{
    Model:        model,
    Toolkits:     []toolkit.Toolkit{calculator.New()},
    Instructions: "Use the calculator tool for any math operations.",
})

ツールエラー

ツールの登録とパラメータの型を確認:

go
// ツールは数値にfloat64を期待
args := map[string]interface{}{
    "value": 42.0,  // ✅ 正しい
    // "value": "42"  // ❌ 誤った型
}

次のステップ

  • 会話状態についてはMemoryを参照
  • 専門的なツールAgentでTeamsを構築
  • ツールオーケストレーションのためにWorkflowを探索
  • 詳細なドキュメントはAPIリファレンスを確認

関連例

Released under the MIT License.