Spring AI整合Ollama实现工具调用的实战全解
作者:霸道流氓气质
场景
在大模型应用开发中,工具调用(Tool Calling / Function Calling)是实现智能 Agent 的核心能力。
通过工具调用,大模型可以自主决定何时调用外部工具来获取实时信息、执行计算或操作外部系统。
Spring AI 作为 Java 生态中的 AI 集成框架,提供了一套优雅的 API 来定义和管理工具,而 Ollama 则让开发者可以在本地运行强大的开源大模型。
本文将基于 Spring AI + Ollama,从基础环境搭建、工具的定义与注册、完整项目实现到常见问题排查,系统性地讲解如何实现本地大模型的工具调用,并提供可直接运行的完整代码示例。
工具调用的工作流程
在 Ollama + Spring AI 的场景下,工具调用的完整流程如下:
定义工具:通过 @Tool 注解或编程式 API 将 Java 方法标记为可调用的工具。
注册工具:在 ChatClient 构建时将工具注入,Spring AI 会自动生成符合 OpenAI 规范的 JSON Schema。
模型决策:当用户提问时,Ollama 模型评估是否需要调用工具,如果需要,则返回工具名称和参数。
执行与反馈:Spring AI 自动执行对应的 Java 方法,并将结果回传给模型。
生成回答:模型根据工具执行结果生成最终的自然语言回答。
模型兼容性要求
并非所有 Ollama 模型都支持工具调用。必须使用原生支持 Function Calling 的模型,否则 LLM 将直接忽略工具列表,
只返回纯文本回答。
可以通过 ollama list 查看已下载的模型,通过 ollama pull <模型名> 下载新模型。
两种工具定义方式
Spring AI 提供了两种工具定义方式,可根据场景灵活选择。
使用 @Tool 注解(推荐)
在 Spring 管理的 Bean 方法上添加 @Tool 注解,Spring AI 会自动将其包装为 ToolCallback。
编程式 API(无需注解)
使用 MethodToolCallback 构建工具回调,适合动态创建或无法修改已有类的场景。
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();
}实现
pom.xml 依赖配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version> <!-- 降级为稳定版,解决冲突 -->
</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 # 查看工具调用详情
工具服务类(含 @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 = "获取当前系统的日期和时间,返回格式化后的时间字符串")
public String getCurrentDateTime() {
System.out.println("获取当前日期和时间工具被调用");
return LocalDateTime.now()
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
/**
* 查询指定城市的天气(模拟)
*/
@Tool(description = "查询指定城市的天气信息")
public String getWeather(@ToolParam(description = "城市名称") String city) {
System.out.println("查询指定城市的天气信息工具被调用");
return String.format("城市:%s,天气:晴,温度:22°C ~ 28°C,湿度:45%%,风力:3级", city);
}
/**
* 计算两个数的和
*/
@Tool(description = "计算两个数字的和")
public double add(@ToolParam(description = "第一个加数") double a,
@ToolParam(description = "第二个加数") double b) {
System.out.println("计算两个数字的和工具被调用");
return a + b;
}
}ChatClient 配置类
注意:在 Spring AI 1.1.2 中,@Tool 标注的方法不会自动生成 ToolCallbackProvider,我们需要手动注入工具服务类。
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 会自动判断是否需要调用工具
*/
@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;
}
}
// 响应体
public record ChatResponse(int code, String msg, String data) {}
}测试验证
测试天气工具调用

调用计算器

常见问题与解决方案
1、找不到 ToolCallbackProvider Bean
报错信息:
Could not autowire. No beans of 'ToolCallbackProvider' type found.
原因:仅使用 @Tool 注解时,Spring AI 不会自动创建 ToolCallbackProvider Bean。
解决:直接注入工具服务类 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、模型从不调用工具,只返回文字回答
原因:当前模型不支持 Function Calling(如 llama2、早期 qwen 等)。
解决:更换为原生支持工具调用的模型,如 qwen2.5:7b、llama3.1:8b、mistral:7b。
关键知识点总结
@Tool 注解 将方法标记为工具,description 用于告知 LLM 何时调用
@ToolParam 注解 描述工具方法参数的含义,帮助 LLM 准确填充参数
ChatClient.defaultTools() 将包含 @Tool 方法的类注入 ChatClient,使其具备工具调用能力
模型兼容性 必须使用原生支持 Function Calling 的模型
JSON Schema 自动生成 Spring AI 会根据 Java 方法签名和注解自动生成符合 OpenAI 规范的 Schema
日志调试 开启 org.springframework.ai.chat.client 的 DEBUG 日志可观察工具调用过程
以上就是Spring AI整合Ollama实现工具调用的实战全解的详细内容,更多关于Spring AI Ollama工具调用的资料请关注脚本之家其它相关文章!
