mcpField
L
langchain4j-tool-function-calling-patterns

langchain4j-tool-function-calling-patterns

github.com/giuseppe-trisciuoglioエージェントワークフロー3653.7k 回インストール7 週間前に更新
リポジトリ

langchain4j-tool-function-calling-patterns について

LangChain4j で AI エージェントを構築する Java 開発者向けのパターンガイドです。メソッドを LLM が呼び出せるツールとして公開する方法に加え、パラメーター説明、実行管理、エラー処理、タイムアウト、動的なツール提供を扱います。

主な機能

  1. 01@Tool と @P によるツールとパラメーターの定義
  2. 02AiServices を使ったツール登録
  3. 03実行エラーと不明なツール名への対応
  4. 04並行実行とタイムアウトの設定
  5. 05コンテキストに応じたツールの提供

活用シーン

  1. 01AI エージェントからデータベースや外部 API を呼び出す
  2. 02ツールのパラメーター形式と制約を説明する
  3. 03安全なメッセージでツール失敗に対応する
  4. 04ユーザーのコンテキストに応じてツール群を切り替える

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill langchain4j-tool-function-calling-patterns

インストール後、Claude Code で/langchain4j-tool-function-calling-patternsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
advanced-features.md
core-patterns.md
error-handling.md
examples.md
implementation-patterns.md
integration-examples.md
references.md
setup-configuration.md

詳細

LangChain4j ツールと関数呼び出しのパターン

LangChain4j アプリケーションで、メソッドをツールとしてアノテーションする方法、ツール実行機能を設定する方法、AI サービスにツールを登録する方法、パラメーターを検証する方法、ツール実行エラーに対処する方法のパターンを紹介します。

概要

LangChain4j では、@Tool アノテーションを使用して、Java メソッドを AI エージェントが呼び出せる関数として公開します。AiServices ビルダーにツールを登録すると、チャットモデルを通じて LLM がテキスト生成以外のアクション(データベースクエリ、API 呼び出し、計算、業務システムとの連携など)を実行できるようになります。パラメーターには、LLM を導く説明を指定するために @P を使用します。

使用する場面

  • 外部ツール(天気、株価、データベースクエリなど)を呼び出す AI エージェントの構築
  • LLM のツール使用に向けた関数仕様の定義(@Tool、@P アノテーション)
  • AiServices.builder().tools() を使用したツールセットの登録と管理
  • ツール実行エラー、タイムアウト、幻覚によるツール名への対処
  • @ToolMemoryId を介してユーザー状態を注入する、コンテキスト対応ツールの実装
  • 大規模または条件付きのツールセット向けの動的ツールプロバイダーの設定

手順

1. メソッドに @Tool を付ける

@Tool アノテーションを付けたメソッドを持つツールクラスを定義します。最初のパラメーターに説明を指定します。各パラメーターの説明には @P を使用します。

public class WeatherTools {
    private final WeatherService weatherService;

    public WeatherTools(WeatherService weatherService) {
        this.weatherService = weatherService;
    }

    @Tool("Get current weather for a city")
    public String getWeather(
            @P("City name") String city,
            @P("Temperature unit: celsius or fahrenheit") String unit) {
        return weatherService.getWeather(city, unit);
    }
}

検証:インスタンスを作成し、エラーなくクラスが読み込まれることを確認します。

2. AiServices にツールを登録する

AiServices.builder() を使用して、チャットモデルにツールインスタンスを登録します。

MathAssistant assistant = AiServices.builder(MathAssistant.class)
    .chatModel(chatModel)
    .tools(new Calculator(), new WeatherTools(weatherService))
    .build();

検証:assistant.chat("What is 2 + 2?") を呼び出し、LLM が例外をスローせずに応答することを確認します。

3. ツール呼び出しをエンドツーエンドでテストする

ツールの使用を促すプロンプトを送り、ツールが実行され、その結果が応答に反映されることを確認します。

String response = assistant.chat("What is the weather in Rome?");
System.out.println(response);

検証:ログでツールの呼び出しを確認し、応答にツールの出力が使われていることを確認します。

4. ツール実行エラーに対処する

スタックトレースを公開せずに失敗を適切に処理できるよう、エラーハンドラーを追加します。

AiServices.builder(Assistant.class)
    .chatModel(chatModel)
    .tools(new ExternalServiceTools())
    .toolExecutionErrorHandler((request, exception) -> {
        logger.error("Tool '{}' failed: {}", request.name(), exception.getMessage());
        return "An error occurred while processing your request";
    })
    .hallucinatedToolNameStrategy(request ->
        ToolExecutionResultMessage.from(request,
            "Error: tool '" + request.name() + "' does not exist"))
    .toolArgumentsErrorHandler((error, context) ->
        ToolErrorHandlerResult.text("Invalid arguments: " + error.getMessage()))
    .build();

検証:エラー条件を発生させ、LLM が安全なエラーメッセージを受け取ることを確認します。

5. パフォーマンスとスケーラビリティを最適化する

ツールの並行実行を有効にし、実行時間の長いツールにはタイムアウトを設定します。

AiServices.builder(Assistant.class)
    .chatModel(chatModel)
    .tools(new DbTools(), new HttpTools())
    .executeToolsConcurrently(Executors.newFixedThreadPool(5))
    .toolExecutionTimeout(Duration.ofSeconds(30))
    .build();

検証:リクエストを並行して実行し、スレッドの競合やデッドロックが発生しないことを確認します。

例

完全なクラスを使った計算ツール
public class Calculator {
    @Tool("Perform basic arithmetic")
    public double calculate(
            @P("Expression like 2+2 or 10*5") String expression) {
        // Parse and evaluate expression
        return eval(expression);
    }
}

Assistant assistant = AiServices.builder(Assistant.class)
    .chatModel(ChatModel.builder()
        .apiKey(System.getenv("API_KEY"))
        .model("gpt-4o")
        .build())
    .tools(new Calculator())
    .build();
即時戻り値を返すツール(LLM の応答なし)
@Tool(value = "Send email notification", returnBehavior = ReturnBehavior.IMMEDIATELY)
public void sendEmail(@P("Recipient email address") String to,
                     @P("Email subject") String subject,
                     @P("Email body") String body) {
    emailService.send(to, subject, body);
}
動的ツールプロバイダー
ToolProvider provider = request -> {
    if (request.userContext().contains("admin")) {
        return List.of(new AdminTools());
    }
    return List.of(new UserTools());
};

AiServices.builder(Assistant.class)
    .chatModel(chatModel)
    .toolProvider(provider)
    .build();

ベストプラクティス

  • 分かりやすい @Tool 名:「Get」「Send」「Calculate」などの命令形の動詞を使い、対象範囲を明確にします
  • 正確な @P の説明:形式、制約、有効な値を含めます。曖昧な説明は、不正確な LLM 呼び出しの原因になります
  • 安全なエラー処理:スタックトレースを決して公開せず、ユーザーに分かりやすいエラー文字列を返します
  • タイムアウトの設定:外部サービスを呼び出す場合は、必ず .toolExecutionTimeout() を設定します
  • 並行実行:ツールが独立している場合は、.executeToolsConcurrently() を有効にします
  • 入力検証:ツールメソッド内でパラメーターを検証し、説明的なエラーを返します
  • 権限チェック:AI サービスのレベルではなく、ツール内で認可を行います
  • 監査ログ:デバッグとコンプライアンス対応のため、ツール名、パラメーター、実行結果を記録します

よくある問題と解決策

問題解決策
LLM が存在しないツールを呼び出す.hallucinatedToolNameStrategy() を追加し、安全なエラーメッセージを返します
ツールが誤ったパラメーターを受け取る@P の説明を改善し、.toolArgumentsErrorHandler() を追加します
ツールの実行が停止する.toolExecutionTimeout(Duration.ofSeconds(N)) を設定します
外部 API でレート制限エラーが発生するツールメソッド内に再試行ロジックまたはレートリミッターを追加します
LLM がツールの出力を無視するLLM が解釈できる文字列をツールが返すようにします

回復性のパターンについては references/error-handling.md を、パラメーターと戻り値の型の詳細については references/core-patterns.md を参照してください。

クイックリファレンス

アノテーション/API目的
@Toolメソッドを呼び出し可能なツールとして指定します
@PLLM 向けにツールのパラメーターを説明します
@ToolMemoryId会話 ID/ユーザー ID をツールに注入します
AiServices.builder()登録済みツールを備えた AI サービスを作成します
ReturnBehavior.IMMEDIATELYLLM の応答を待たずにツールを実行します
ToolProviderコンテキストに基づいてツールを動的に提供します
executeToolsConcurrently()独立したツール呼び出しを並列実行します
toolExecutionTimeout()個々のツール呼び出しのタイムアウトを設定します

制約と警告

  • 機密データ:@Tool や @P の説明に API キー、パスワード、認証情報を含めないでください
  • 副作用:データを変更するツールは、その説明に警告を記載してください。AI モデルが複数回呼び出す場合があります
  • 大量のツール:ツールが多すぎると LLM モデルが混乱します。条件に応じて登録するには ToolProvider を使用してください
  • ブロッキング処理:ツールでは、タイムアウトを設定せずに長時間の同期 I/O を実行しないでください
  • スタックトレースの漏えい:例外は必ずエラーハンドラーを介し、安全な文字列を返すようにしてください
  • パラメーターの具体性:曖昧な @P の説明は、不適切なツール呼び出しに直結します。形式と制約を具体的に記述してください
  • 並行処理の安全性:executeToolsConcurrently() を使用する場合は、ツールクラスがステートレスまたはスレッドセーフであることを確認してください

関連スキル

  • langchain4j-ai-services-patterns — AI サービスの高水準な設定
  • langchain4j-rag-implementation-patterns — ツール統合による RAG 検索
  • langchain4j-spring-boot-integration — Spring Boot アプリケーションでのツール登録

参考資料

コメント