最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring AI整合Ollama實現(xiàn)工具調(diào)用的實戰(zhàn)全解

 更新時間:2026年05月13日 09:33:27   作者:霸道流氓氣質(zhì)  
在大模型應(yīng)用開發(fā)中,工具調(diào)用(Tool Calling / Function Calling)是實現(xiàn)智能 Agent 的核心能力,本文將基于 Spring AI + Ollama,從基礎(chǔ)環(huán)境搭建、工具的定義與注冊、完整項目實現(xiàn)到常見問題排查,系統(tǒng)性地講解如何實現(xiàn)本地大模型的工具調(diào)用,需要的朋友可以參考下

場景

在大模型應(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事件處理機制和適配器全面解析

    Java事件處理機制和適配器全面解析

    這篇文章主要介紹了Java事件處理機制和適配器全面解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java敏感詞過濾的實現(xiàn)方式

    java敏感詞過濾的實現(xiàn)方式

    文章描述了如何搭建敏感詞過濾系統(tǒng)來防御用戶生成內(nèi)容中的違規(guī)、廣告或惡意言論,包括引入依賴、定義敏感詞類、非敏感詞類、替換詞類和工具類等步驟,并指出資源文件應(yīng)放在src/main/resources目錄下
    2025-12-12
  • Java8中Function接口的使用方法詳解

    Java8中Function接口的使用方法詳解

    在 Java 8 中,Function 接口是 java.util.function 包中的一個函數(shù)式接口,函數(shù)式接口是僅包含一個抽象方法的接口,適用于 Lambda 表達式或方法引用,本文給大家介紹了Java8的Function接口的使用方法,需要的朋友可以參考下
    2024-09-09
  • 解決Spring?MVC中文亂碼的編碼配置

    解決Spring?MVC中文亂碼的編碼配置

    這篇文章主要為大家介紹了解決SpringMVC中文亂碼的編碼配置示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Java利用轉(zhuǎn)義字符過濾HTML中的標簽

    Java利用轉(zhuǎn)義字符過濾HTML中的標簽

    通過本文介紹的Java方法,我們可以輕松利用轉(zhuǎn)義字符來過濾HTML文本中的標簽,確保輸出內(nèi)容的純文本展示,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Maven?依賴沖突調(diào)解與版本控制問題記錄

    Maven?依賴沖突調(diào)解與版本控制問題記錄

    這篇文章主要介紹了Maven?依賴沖突調(diào)解與版本控制問題記錄,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-04-04
  • Java并發(fā)工具之CyclicBarrier使用詳解

    Java并發(fā)工具之CyclicBarrier使用詳解

    這篇文章主要介紹了Java并發(fā)工具之CyclicBarrier使用詳解,CyclicBarrier是一個同步器,允許一組線程相互之間等待,直到到達某個公共屏障點(common barrier point),再繼續(xù)執(zhí)行,需要的朋友可以參考下
    2023-12-12
  • java對接webservice接口的4種方式總結(jié)

    java對接webservice接口的4種方式總結(jié)

    因工作需要和一個Sap相關(guān)系統(tǒng)以WebService的方式進行接口聯(lián)調(diào),之前僅聽過這種技術(shù),但并沒有實操過,所以將本次開發(fā)進行記錄,這篇文章主要給大家介紹了關(guān)于java對接webservice接口的4種方式,需要的朋友可以參考下
    2023-10-10
  • 圖文詳解Java中的字節(jié)輸入與輸出流

    圖文詳解Java中的字節(jié)輸入與輸出流

    在Java中所有數(shù)據(jù)都是使用流讀寫的,流是一組有序的數(shù)據(jù)序列,將數(shù)據(jù)從一個地方帶到另一個地方,這篇文章主要給大家介紹了關(guān)于Java中字節(jié)輸入與輸出流的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • MyBatis一級緩存避坑完全指南

    MyBatis一級緩存避坑完全指南

    這篇文章主要給大家介紹了關(guān)于MyBatis一級緩存避坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-11-11

最新評論

屯昌县| 太康县| 连云港市| 大新县| 泾源县| 左权县| 南安市| 大石桥市| 新巴尔虎左旗| 洛隆县| 金塔县| 营山县| 蒙阴县| 藁城市| 富川| 桂平市| 通河县| 五台县| 乐山市| 晋城| 大竹县| 都安| 阳东县| 五峰| 敖汉旗| 黎川县| 育儿| 乐亭县| 杨浦区| 睢宁县| 浙江省| 延寿县| 大庆市| 海盐县| 磴口县| 无极县| 博湖县| 昌吉市| 绵竹市| 嵊州市| 新晃|