SpringBoot 4.1講座 LLM に自作 Java メソッドを呼び出させる!Spring AI の Tool Calling(@Tool)完全ガイド
ChatGPT などの LLM(大容量言語モデル)は、非常に高い言語理解能力を持っていますが、「リアルタイムのデータ」や「自社のデータベース/業務ロジック」には直接アクセスできないという根本的な限界があります。
例えば、「現在の最新の書籍価格は?」や「現在のシステム時刻は?」と質問しても、学習データに含まれていないか、あるいは「正確な答えは分かりません」と返ってきてしまいます。Web検索機能を補助的に使用して回答はできていますが、AIの知識にはありません。
この限界を突破するのが Tool Calling(Function Calling) です!
今回は、Spring AI が提供する @Tool アノテーションを使い、LLM に自作 Java メソッドを自動認識・呼び出しさせる実装手法を解説します。
1. Tool Calling の仕組み(フロー)
Tool Calling は、AI が回答を作るプロセスの一部を アプリケーション側の Java コードに委譲(Delegation)する 仕組みです。
Plaintext
[ユーザー] ──(1) 質問送信 ──► [Spring Boot (Spring AI)]
│
├─(2) 質問 + 利用可能なTool定義を送る ─► [LLM]
│ │
│ (3) AIがToolの
│ 必要性を判断
│ │
├─(4) Tool呼び出し要求(関数名・引数)◄──┘
│
(5) 指定された Java メソッド(@Tool)を実行
│
├─(6) 実行結果(データ)を送信 ─────────► [LLM]
│ │
│ (7) データを組み込んで
│ 最終回答を作成
│ │
[ユーザー] ◄─(8) 自然言語の回答 ─┴─(8) クライアントへ返却 ───────────────┘
重要なのは、「いつどの Tool をどの引数で呼び出すか」は LLM が自発的に判断し、実際のメソッド実行と AI へのデータ受け渡しは Spring AI が裏で全自動処理してくれる という点です。
2. @Tool アノテーションで Java メソッドを公開する
Spring AI では、コンポーネントクラスのメソッドに @Tool を付与するだけで、LLM が利用できる「道具(Tool)」として公開できます。
① 日時取得ツール(DateTimeTools.java)
LLM 単体では知り得ない「現在のシステム時刻」を返すツールです。
Java
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class DateTimeTools {
@Tool(description = "現在の日時を ISO-8601 形式で返します。")
public String getCurrentDateTime() {
return LocalDateTime.now().toString();
}
}
description プロパティが最重要!: LLM はこの説明文を読んで「ユーザーの質問に回答するためにこのツールを使うべきか」を判定します。具体的かつ明確に目的を記述します。
② 書籍価格検索ツール(BookTools.java)
自社の在庫・価格データ(DB や InMemory マップなど)を参照するツールです。
Java
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
public class BookTools {
private static final Map<String, Double> PRICES = Map.of(
"spring-boot-4", 49.99,
"java-25-guide", 39.99,
"docker-manual", 29.99
);
@Tool(description = "指定された ISBN や識別子(SKU)に基づいて書籍の最新価格を取得します。")
public String getBookPrice(String sku) {
Double price = PRICES.get(sku.toLowerCase());
return price == null ? "指定された書籍は見つかりませんでした。" : "価格: $" + price;
}
}
3. ChatClient への Tool 登録とコントローラー実装
作成した Tool を ChatClient にセットするには、リクエスト構築時に .tools(...) メソッドに Spring Bean を渡すだけです。複数指定も可能です!
BookAssistantController.java
Java
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/ai")
public class BookAssistantController {
private final ChatClient chatClient;
private final DateTimeTools dateTimeTools;
private final BookTools bookTools;
public BookAssistantController(ChatClient chatClient,
DateTimeTools dateTimeTools,
BookTools bookTools) {
this.chatClient = chatClient;
this.dateTimeTools = dateTimeTools;
this.bookTools = bookTools;
}
public record AssistantAnswer(String reply) {}
@GetMapping("/assistant")
public AssistantAnswer assist(@RequestParam String question) {
String reply = chatClient.prompt()
.user(question)
.tools(dateTimeTools, bookTools) // 複数 Tool を登録!
.call()
.content();
return new AssistantAnswer(reply);
}
}
4. 動作確認(複合クエリのテスト)
1 つの質問の中で 「書籍の価格」と「現在の時刻」の両方を尋ねる高度なリクエスト を送信してみます。
リクエスト (curl)
Bash
curl -s "http://localhost:8080/api/ai/assistant?question=spring-boot-4%20%E3%81%AE%E4%BE%A1%E6%A0%BC%E3%81%A8%E3%80%81%E4%BB%8A%E3%81%AE%E6%97%A5%E6%99%82%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84"
レスポンス
JSON
{
"reply": "spring-boot-4 の価格は $49.99 です。また、現在のシステム日時は 2026-07-26T21:00:00 です。"
}
何が起きているのか?
LLM はユーザーの質問を解析し、1 回のやり取りの中で getBookPrice("spring-boot-4") と getCurrentDateTime() の 2 つの Tool を連続して呼び出すリクエストを自発的に発行しました。
Spring AI が両方の Java メソッドを実行して結果を統合し、自然な 1 つの文章として整形して返却してくれたのです!開発者がオーケストレーション(複雑な呼び出し制御)のコードを書く必要は全くありません。
補足:旧バージョン(Spring AI 1.x)からの変更点
以前のバージョンで提供されていた FunctionCallback や .functions(...) API は非推奨/廃止され、よりシンプルな ToolCallback / .tools(...) API および @Tool アノテーション へ一元化されました。旧コードを移行する場合は注意してください。
まとめ
@Tool で Java メソッドを公開: description を明確に書くことで、LLM が呼び出すタイミングを正しく判断できる。
.tools(...) で簡単にバインド: ChatClient に渡すだけで、マルチツール呼び出しやパラメータ抽出を Spring AI が全自動で処理する。
静的知識から動的システムへ: DB 検索や外部 API 連携、ドメインロジックを組み込むことで、LLM を真に実用的な業務アシスタントへと進化させられる。
次回は、「自社ドキュメントやPDFをベクトルDBに格納して検索・回答させる RAG(Retrieval-Augmented Generation)パイプライン」 の構築方法を解説します!
ここから先は
¥ 100
この記事が気に入ったらチップで応援してみませんか?
