langchain4j-tool-function-calling-patterns
langchain4j-tool-function-calling-patterns について
LangChain4j で AI エージェントを構築する Java 開発者向けのパターンガイドです。メソッドを LLM が呼び出せるツールとして公開する方法に加え、パラメーター説明、実行管理、エラー処理、タイムアウト、動的なツール提供を扱います。
主な機能
- 01@Tool と @P によるツールとパラメーターの定義
- 02AiServices を使ったツール登録
- 03実行エラーと不明なツール名への対応
- 04並行実行とタイムアウトの設定
- 05コンテキストに応じたツールの提供
活用シーン
- 01AI エージェントからデータベースや外部 API を呼び出す
- 02ツールのパラメーター形式と制約を説明する
- 03安全なメッセージでツール失敗に対応する
- 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.mdcore-patterns.mderror-handling.mdexamples.mdimplementation-patterns.mdintegration-examples.mdreferences.mdsetup-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 | メソッドを呼び出し可能なツールとして指定します |
@P | LLM 向けにツールのパラメーターを説明します |
@ToolMemoryId | 会話 ID/ユーザー ID をツールに注入します |
AiServices.builder() | 登録済みツールを備えた AI サービスを作成します |
ReturnBehavior.IMMEDIATELY | LLM の応答を待たずにツールを実行します |
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 アプリケーションでのツール登録
参考資料
- references/setup-configuration.md — Maven のセットアップ、チャットモデルの設定、最初のツール登録
- references/core-patterns.md — 基本的なツール定義、複雑なパラメーター、戻り値の型
- references/advanced-features.md — メモリコンテキスト、動的なツールプロバイダー、ストリーミング、即時リターン
- references/error-handling.md — エラーハンドラー、再試行ロジック、監視
- references/integration-examples.md — データベース、REST API、コンテキスト対応ツールの例