Skip to content

アノテーションベースのツール

アノテーションベースのツールは、大規模言語モデル(LLM)に機能をツールとして公開するための宣言的な方法を提供します。アノテーションを使用することで、任意の関数をLLMが理解し、利用できるツールに変換できます。

このアプローチは、ツール記述を手動で実装することなく、既存の機能をLLMに公開する必要がある場合に役立ちます。

NOTE

アノテーションベースのツールはJVM専用であり、他のプラットフォームでは利用できません。マルチプラットフォームサポートについては、クラスベースのツールAPIを使用してください。

主要なアノテーション

プロジェクトでアノテーションベースのツールを使い始めるには、以下の主要なアノテーションを理解する必要があります。

アノテーション説明
@ToolLLMにツールとして公開すべき関数をマークします。
@LLMDescriptionツールとそのコンポーネントに関する記述情報を提供します。

@Toolアノテーション

@Toolアノテーションは、LLMにツールとして公開すべき関数をマークするために使用されます。 @Toolでアノテーションされた関数は、ToolSetインターフェースを実装するオブジェクトからリフレクションによって収集されます。詳細については、「ToolSetインターフェースの実装」を参照してください。

定義

kotlin
@Target(AnnotationTarget.FUNCTION)
public annotation class Tool(val customName: String = "")

パラメーター

名前
必須説明
customNameいいえツールにカスタム名を指定します。指定しない場合、関数の名前が使用されます。

使用法

関数をツールとしてマークするには、ToolSetインターフェースを実装するクラスでその関数に@Toolアノテーションを適用します。

kotlin
class MyToolSet : ToolSet {
    @Tool
    fun myTool(): String {
        // Tool implementation
        return "Result"
    }

    @Tool(customName = "customToolName")
    fun anotherTool(): String {
        // Tool implementation
        return "Result"
    }
}

@LLMDescriptionアノテーション

@LLMDescriptionアノテーションは、コード要素(クラス、関数、パラメーターなど)に関する記述情報をLLMに提供します。 これにより、LLMはこれらの要素の目的と使用法を理解するのに役立ちます。

定義

kotlin
@Target(
    AnnotationTarget.PROPERTY,
    AnnotationTarget.CLASS,
    AnnotationTarget.PROPERTY,
    AnnotationTarget.TYPE,
    AnnotationTarget.VALUE_PARAMETER,
    AnnotationTarget.FUNCTION
)
public annotation class LLMDescription(val description: String)

パラメーター

名前必須説明
descriptionはいアノテーションされた要素を記述する文字列。

使用法

@LLMDescriptionアノテーションは、さまざまなレベルで適用できます。例:

  • 関数レベル:
kotlin
@Tool
@LLMDescription("Performs a specific operation and returns the result")
fun myTool(): String {
    // Function implementation
    return "Result"
}
  • パラメーターレベル:
kotlin
@Tool
@LLMDescription("Processes input data")
fun processTool(
    @LLMDescription("The input data to process")
    input: String,

    @LLMDescription("Optional configuration parameters")
    config: String = ""
): String {
    // Function implementation
    return "Processed: $input with config: $config"
}

ツールの作成

1. ToolSetインターフェースを実装する

ToolSetインターフェースを実装するクラスを作成します。 このインターフェースは、クラスがツールのコンテナーであることを示します。

kotlin
class MyFirstToolSet : ToolSet {
    // Tools will go here
}

2. ツール関数を追加する

クラスに関数を追加し、@Toolでアノテーションを付けてツールとして公開します。

kotlin
class MyFirstToolSet : ToolSet {
    @Tool
    fun getWeather(location: String): String {
        // In a real implementation, you would call a weather API
        return "The weather in $location is sunny and 72°F"
    }
}

3. 説明を追加する

LLMにコンテキストを提供するために、@LLMDescriptionアノテーションを追加します。

kotlin
@LLMDescription("Tools for getting weather information")
class MyFirstToolSet : ToolSet {
    @Tool
    @LLMDescription("Get the current weather for a location")
    fun getWeather(
        @LLMDescription("The city and state/country")
        location: String
    ): String {
        // In a real implementation, you would call a weather API
        return "The weather in $location is sunny and 72°F"
    }
}

4. エージェントでツールを使用する

これで、エージェントでツールを使用できるようになります。

kotlin
fun main() {
    runBlocking {
        // Create your tool set
        val weatherTools = MyFirstToolSet()

        // Create an agent with your tools

        val agent = AIAgent(
            executor = simpleOpenAIExecutor(apiToken),
            systemPrompt = "Provide weather information for a given location.",
            llmModel = OpenAIModels.Chat.GPT4o,
            toolRegistry = ToolRegistry {
                tools(weatherTools)
            }
        )

        // The agent can now use your weather tools
        agent.run("What's the weather like in New York?")
    }
}

使用例

ここでは、ツールアノテーションの実際の使用例をいくつか紹介します。

基本的な例: スイッチコントローラー

この例は、スイッチを制御するためのシンプルなツールセットを示しています。

kotlin
@LLMDescription("Tools for controlling a switch")
class SwitchTools(val switch: Switch) : ToolSet {
    @Tool
    @LLMDescription("Switches the state of the switch")
    fun switch(
        @LLMDescription("The state to set (true for on, false for off)")
        state: Boolean
    ): String {
        switch.switch(state)
        return "Switched to ${if (state) "on" else "off"}"
    }

    @Tool
    @LLMDescription("Returns the current state of the switch")
    fun switchState(): String {
        return "Switch is ${if (switch.isOn()) "on" else "off"}"
    }
}

LLMがスイッチを制御する必要がある場合、提供された記述から以下の情報を理解できます。

  • ツールの目的と機能。
  • ツールを使用するために必要なパラメーター。
  • 各パラメーターに許容される値。
  • 実行時に期待される戻り値。

高度な例: 診断ツール

この例は、デバイスの診断のためのより複雑なツールセットを示しています。

kotlin
@LLMDescription("Tools for performing diagnostics and troubleshooting on devices")
class DiagnosticToolSet : ToolSet {
    @Tool
    @LLMDescription("Run diagnostic on a device to check its status and identify any issues")
    fun runDiagnostic(
        @LLMDescription("The ID of the device to diagnose")
        deviceId: String,

        @LLMDescription("Additional information for the diagnostic (optional)")
        additionalInfo: String = ""
    ): String {
        // Implementation
        return "Diagnostic results for device $deviceId"
    }

    @Tool
    @LLMDescription("Analyze an error code to determine its meaning and possible solutions")
    fun analyzeError(
        @LLMDescription("The error code to analyze (e.g., 'E1001')")
        errorCode: String
    ): String {
        // Implementation
        return "Analysis of error code $errorCode"
    }
}

ベストプラクティス

  • 明確な説明を提供する: ツール、パラメーター、および戻り値の目的と動作を説明する、明確で簡潔な説明を記述します。
  • すべてのパラメーターを記述する: LLMが各パラメーターの目的を理解できるよう、すべてのパラメーターに@LLMDescriptionを追加します。
  • 一貫した命名を使用する: ツールとパラメーターに一貫した命名規則を使用し、より直感的にします。
  • 関連ツールをグループ化する: 関連するツールを同じToolSet実装にグループ化し、クラスレベルの記述を提供します。
  • 情報量の多い結果を返す: ツールの戻り値が操作の結果に関する明確な情報を提供するようにします。
  • エラーを適切に処理する: ツールにエラー処理を含め、情報量の多いエラーメッセージを返します。
  • デフォルト値を文書化する: パラメーターにデフォルト値がある場合は、記述にそれを文書化します。
  • ツールを集中させる: 各ツールは、多くのことを一度に行うのではなく、特定の明確に定義されたタスクを実行するようにします。

よくある問題のトラブルシューティング

ツールアノテーションを使用する際、いくつかのよくある問題に遭遇する可能性があります。

ツールが認識されない

エージェントがツールを認識しない場合は、以下を確認してください。

  • クラスがToolSetインターフェースを実装していること。
  • すべてのツール関数が@Toolでアノテーションされていること。
  • ツール関数が適切な戻り値の型を持っていること(簡潔さのためにStringが推奨されます)。
  • ツールがエージェントに正しく登録されていること。

不明瞭なツール記述

LLMがツールを正しく使用しない、または目的を誤解している場合は、以下を試してください。

  • @LLMDescriptionアノテーションをより具体的かつ明確にするように改善します。
  • 適切な場合は、記述に例を含めます。
  • 記述にパラメーターの制約(例:「"正の数である必要があります"」)を指定します。
  • 記述全体で一貫した用語を使用します。

パラメーターの型に関する問題

LLMが誤ったパラメーターの型を提供する場合、以下を試してください。

  • 可能な場合は、シンプルなパラメーターの型(StringBooleanInt)を使用します。
  • パラメーター記述で期待される形式を明確に記述します。
  • 複雑な型の場合は、特定の形式を持つStringパラメーターを使用し、ツール内でそれらを解析することを検討します。
  • パラメーター記述に有効な入力例を含めます。

パフォーマンスの問題

ツールがパフォーマンスの問題を引き起こす場合は、以下を試してください。

  • ツールの実装を軽量に保ちます。
  • リソースを大量に消費する操作の場合は、非同期処理の実装を検討します。
  • 適切な場合は結果をキャッシュします。
  • ボトルネックを特定するためにツールの使用状況をログに記録します。