Spring AI整合Ollama實現(xiàn)工具調(diào)用的實戰(zhàn)全解
場景
在大模型應(yīng)用開發(fā)中,工具調(diào)用(Tool Calling / Function Calling)是實現(xiàn)智能 Agent 的核心能力。
通過工具調(diào)用,大模型可以自主決定何時調(diào)用外部工具來獲取實時信息、執(zhí)行計算或操作外部系統(tǒng)。
Spring AI 作為 Java 生態(tài)中的 AI 集成框架,提供了一套優(yōu)雅的 API 來定義和管理工具,而 Ollama 則讓開發(fā)者可以在本地運行強大的開源大模型。
本文將基于 Spring AI + Ollama,從基礎(chǔ)環(huán)境搭建、工具的定義與注冊、完整項目實現(xiàn)到常見問題排查,系統(tǒng)性地講解如何實現(xiàn)本地大模型的工具調(diào)用,并提供可直接運行的完整代碼示例。
工具調(diào)用的工作流程
在 Ollama + Spring AI 的場景下,工具調(diào)用的完整流程如下:
定義工具:通過 @Tool 注解或編程式 API 將 Java 方法標記為可調(diào)用的工具。
注冊工具:在 ChatClient 構(gòu)建時將工具注入,Spring AI 會自動生成符合 OpenAI 規(guī)范的 JSON Schema。
模型決策:當用戶提問時,Ollama 模型評估是否需要調(diào)用工具,如果需要,則返回工具名稱和參數(shù)。
執(zhí)行與反饋:Spring AI 自動執(zhí)行對應(yīng)的 Java 方法,并將結(jié)果回傳給模型。
生成回答:模型根據(jù)工具執(zhí)行結(jié)果生成最終的自然語言回答。
模型兼容性要求
并非所有 Ollama 模型都支持工具調(diào)用。必須使用原生支持 Function Calling 的模型,否則 LLM 將直接忽略工具列表,
只返回純文本回答。
可以通過 ollama list 查看已下載的模型,通過 ollama pull <模型名> 下載新模型。
兩種工具定義方式
Spring AI 提供了兩種工具定義方式,可根據(jù)場景靈活選擇。
使用 @Tool 注解(推薦)
在 Spring 管理的 Bean 方法上添加 @Tool 注解,Spring AI 會自動將其包裝為 ToolCallback。
編程式 API(無需注解)
使用 MethodToolCallback 構(gòu)建工具回調(diào),適合動態(tài)創(chuàng)建或無法修改已有類的場景。
import org.springframework.ai.tool.MethodToolCallback;
import org.springframework.ai.tool.ToolCallback;
public ToolCallback dynamicTool(Object target) {
return MethodToolCallback.builder()
.method("methodName", target)
.description("工具描述")
.build();
}實現(xiàn)
pom.xml 依賴配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version> <!-- 降級為穩(wěn)定版,解決沖突 -->
</parent>
<groupId>com.example</groupId>
<artifactId>spring-ai-ollama-tool</artifactId>
<version>1.0</version>
<properties>
<java.version>17</java.version>
<spring-ai.version>1.1.2</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring AI Ollama 核心 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-ollama</artifactId>
<version>${spring-ai.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-milestones</id>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>application.yml 配置
?
server:
port: 886
spring:
ai:
ollama:
base-url: http://localhost:11434
chat:
model: qwen2.5:7b-instruct
options:
temperature: 0.7
num-ctx: 4096 # 上下文窗口大小
logging:
level:
org.springframework.ai.chat.client: DEBUG # 查看工具調(diào)用詳情
?工具服務(wù)類(含 @Tool 注解)
package com.badao.ai.service;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Service
public class ToolService {
/**
* 獲取當前日期和時間
*/
@Tool(description = "獲取當前系統(tǒng)的日期和時間,返回格式化后的時間字符串")
public String getCurrentDateTime() {
System.out.println("獲取當前日期和時間工具被調(diào)用");
return LocalDateTime.now()
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
/**
* 查詢指定城市的天氣(模擬)
*/
@Tool(description = "查詢指定城市的天氣信息")
public String getWeather(@ToolParam(description = "城市名稱") String city) {
System.out.println("查詢指定城市的天氣信息工具被調(diào)用");
return String.format("城市:%s,天氣:晴,溫度:22°C ~ 28°C,濕度:45%%,風力:3級", city);
}
/**
* 計算兩個數(shù)的和
*/
@Tool(description = "計算兩個數(shù)字的和")
public double add(@ToolParam(description = "第一個加數(shù)") double a,
@ToolParam(description = "第二個加數(shù)") double b) {
System.out.println("計算兩個數(shù)字的和工具被調(diào)用");
return a + b;
}
}ChatClient 配置類
注意:在 Spring AI 1.1.2 中,@Tool 標注的方法不會自動生成 ToolCallbackProvider,我們需要手動注入工具服務(wù)類。
package com.badao.ai.config;
import com.badao.ai.service.ToolService;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ChatConfig {
@Bean
public ChatClient chatClient(ChatClient.Builder chatClientBuilder,
ToolService toolService) { // ? 直接注入工具類
return chatClientBuilder
.defaultTools(toolService) // ? 使用 defaultTools
.build();
}
}控制器
package com.badao.ai.controller;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class ToolChatController {
private final ChatClient chatClient;
public ToolChatController(ChatClient chatClient) {
this.chatClient = chatClient;
}
/**
* 通用對話接口,AI 會自動判斷是否需要調(diào)用工具
*/
@PostMapping("/chat")
public ChatResponse chat(@RequestBody ChatRequest request) {
String result = chatClient.prompt()
.user(request.getMessage())
.call()
.content();
return new ChatResponse(200, "success", result);
}
/**
* 流式輸出對話(支持打字機效果)
*/
@GetMapping(value = "/stream", produces = org.springframework.http.MediaType.TEXT_EVENT_STREAM_VALUE)
public reactor.core.publisher.Flux<String> streamChat(@RequestParam String msg) {
return chatClient.prompt()
.user(msg)
.stream()
.content();
}
// 請求體
public record ChatRequest(String message) {
public String getMessage() {
return message;
}
}
// 響應(yīng)體
public record ChatResponse(int code, String msg, String data) {}
}測試驗證
測試天氣工具調(diào)用

調(diào)用計算器

常見問題與解決方案
1、找不到 ToolCallbackProvider Bean
報錯信息:
Could not autowire. No beans of 'ToolCallbackProvider' type found.
原因:僅使用 @Tool 注解時,Spring AI 不會自動創(chuàng)建 ToolCallbackProvider Bean。
解決:直接注入工具服務(wù)類 ToolService,使用 .defaultTools(toolService) 注冊工具(參考上文中 ChatConfig 的寫法)。
2、找不到 spring-ai-starter-model-ollama 依賴
報錯信息:
Could not find artifact org.springframework.ai:spring-ai-ollama-spring-boot-starter:pom:1.1.2
原因:錯誤的 artifactId。
解決:在 Spring AI 1.1.2 中,正確的依賴名為 spring-ai-starter-model-ollama。
3、模型從不調(diào)用工具,只返回文字回答
原因:當前模型不支持 Function Calling(如 llama2、早期 qwen 等)。
解決:更換為原生支持工具調(diào)用的模型,如 qwen2.5:7b、llama3.1:8b、mistral:7b。
關(guān)鍵知識點總結(jié)
@Tool 注解 將方法標記為工具,description 用于告知 LLM 何時調(diào)用
@ToolParam 注解 描述工具方法參數(shù)的含義,幫助 LLM 準確填充參數(shù)
ChatClient.defaultTools() 將包含 @Tool 方法的類注入 ChatClient,使其具備工具調(diào)用能力
模型兼容性 必須使用原生支持 Function Calling 的模型
JSON Schema 自動生成 Spring AI 會根據(jù) Java 方法簽名和注解自動生成符合 OpenAI 規(guī)范的 Schema
日志調(diào)試 開啟 org.springframework.ai.chat.client 的 DEBUG 日志可觀察工具調(diào)用過程
以上就是Spring AI整合Ollama實現(xiàn)工具調(diào)用的實戰(zhàn)全解的詳細內(nèi)容,更多關(guān)于Spring AI Ollama工具調(diào)用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java并發(fā)工具之CyclicBarrier使用詳解
這篇文章主要介紹了Java并發(fā)工具之CyclicBarrier使用詳解,CyclicBarrier是一個同步器,允許一組線程相互之間等待,直到到達某個公共屏障點(common barrier point),再繼續(xù)執(zhí)行,需要的朋友可以參考下2023-12-12
java對接webservice接口的4種方式總結(jié)
因工作需要和一個Sap相關(guān)系統(tǒng)以WebService的方式進行接口聯(lián)調(diào),之前僅聽過這種技術(shù),但并沒有實操過,所以將本次開發(fā)進行記錄,這篇文章主要給大家介紹了關(guān)于java對接webservice接口的4種方式,需要的朋友可以參考下2023-10-10

