知識庫 / Spring / Spring AI RSS 訂閱

使用 Spring AI 構建 AI 助手

Artificial Intelligence,Spring AI
HongKong
8
10:53 AM · Dec 06 ,2025

1. 概述

本教程將探討 Spring AI 的概念,這些概念可以幫助您使用像 ChatGPT、Ollama、Mistral 等 LLM 創建 AI 助手。

企業正越來越多地採用 AI 助手來增強跨各種現有業務功能的用户體驗:

  • 回答用户查詢
  • 根據用户輸入執行交易
  • 總結冗長的句子和文檔

雖然這些只是 LLM 的幾個基本能力,但其潛力遠不止於此。

2. Spring AI 功能

Spring AI 框架提供一系列令人興奮的功能,以實現人工智能驅動的功能:

  1. 能夠無縫集成底層 LLM 服務和向量數據庫的接口
  2. 利用 RAG 和 Function Calling API 實現情境感知響應生成和動作執行
  3. 結構化輸出轉換器,將 LLM 響應轉換為 POJO 或 JSON 等可讀格式
  4. 通過 Advisor API 提供的攔截器豐富提示並應用安全措施
  5. 通過維護對話狀態提升用户參與度

我們可以將其可視化:

為了説明這些功能,我們將在一個遺留訂單管理系統 (OMS) 中構建一個聊天機器人:

典型的 OMS 功能包括:

  1. 創建訂單
  2. 獲取用户訂單

3. 先決條件

首先,我們需要一個 OpenAI 訂閲才能使用其 LLM 服務。然後,在 Spring Boot 應用程序中,我們將添加 Spring AI 庫的 Maven 依賴項。我們之前在其他文章中對這些先決條件進行了詳細的説明,因此我們不會在此贅述。

此外,我們將使用內存中的 HSQLDB 數據庫以快速啓動。讓我們為其創建所需的表並插入一些數據:

CREATE TABLE User_Order (
    order_id BIGINT NOT NULL PRIMARY KEY,
    user_id VARCHAR(20) NOT NULL,
    quantity INT
);

INSERT INTO User_Order (order_id, user_id, quantity) VALUES (1, 'Jenny', 2);
INSERT INTO User_Order (order_id, user_id, quantity) VALUES (2, 'Mary', 5);
INSERT INTO User_Order (order_id, user_id, quantity) VALUES (3, 'Alex', 1);
INSERT INTO User_Order (order_id, user_id, quantity) VALUES (4, 'John', 3);
INSERT INTO User_Order (order_id, user_id, quantity) VALUES (5, 'Sophia', 4);
--and so on..

我們將在 Spring 的 application.properties文件中使用一些標準配置屬性,用於初始化 HSQLDB 和 OpenAI 客户端:

spring.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
spring.datasource.url=jdbc:hsqldb:mem:testdb;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.hibernate.ddl-auto=none

spring.ai.openai.chat.options.model=gpt-4o-mini
spring.ai.openai.api-key=xxxxxxx

選擇合適的模型以適應特定用例是一個複雜且迭代的過程,需要大量的嘗試和錯誤。 儘管如此,為了本文章的簡單演示應用程序,成本效益高的 GPT-4o mini 模型已經足夠。

4. Function Calling API

此功能是基於LLM應用中流行的“代理式”概念的基石之一。它使應用程序能夠執行復雜的一系列精確任務並獨立做出決策。

例如,它可以極大地幫助構建在遺留訂單管理應用程序中的聊天機器人。聊天機器人可以通過自然語言幫助用户提出訂單請求、檢索訂單歷史記錄以及執行更多操作。

這些技能是由一個或多個應用程序函數提供的專業技能。我們通過向LLM發送包含支持函數模式的提示來定義算法。LLM接收到該模式並識別出要執行的正確函數,然後將決策發送給應用程序。

最後,應用程序執行該函數並向LLM返回更多信息:

首先,讓我們來看看遺留應用程序的主要組件:

OrderManagementService類有兩個重要的函數:創建訂單和檢索用户訂單歷史記錄。這兩個函數使用OrderRepository Bean 與 DB 集成:

@Service
public class OrderManagementService {
    @Autowired
    private OrderRepository orderRepository;

    public Long createOrder(OrderInfo orderInfo) {
        return orderRepository.save(orderInfo).getOrderID();
    }

    public Optional<List<OrderInfo>> getAllUserOrders(String userID) {
       return orderRepository.findByUserID(userID);
    }
}

現在,讓我們看看 Spring AI 如何幫助在遺留應用程序中實現聊天機器人:

在類圖中,<em>OmAiAssistantConfiguration</em> 類是一個 Spring 配置 Bean。它註冊了函數回調 Bean,<em>createOrderFn</em><em>getUserOrderFn</em>

@Configuration
public class OmAiAssistantConfiguration {
    @Bean
    @Description("Create an order. The Order ID is identified with orderID. "
      + The order quantity is identified by orderQuantity."
      + "The user is identified by userID. "
      + "The order quantity should be a positive whole number."
      + "If any of the parameters like user id and the order quantity is missing"
      + "then ask the user to provide the missing information.")
    public Function<CreateOrderRequest, Long> createOrderFn(OrderManagementService orderManagementService) {
        return createOrderRequest -> orderManagementService.createOrder(createOrderRequest.orderInfo());
    }
    @Bean
    @Description("get all the orders of an user. The user ID is identified with userID.")
    public Function<GetOrderRequest, List<OrderInfo>> getUserOrdersFn(OrderManagementService orderManagementService) {
        return getOrderRequest -> orderManagementService.getAllUserOrders(getOrderRequest.userID()).get();
    }
}

@Description 註解有助於生成函數方案。隨後,應用程序將該方案作為提示的一部分發送給 LLM。由於函數使用OrderManagementService類中的現有方法,從而促進了可重用性。

此外,CreateOrderRequestGetOrderRequests 是 Record 類,Spring AI 利用它們生成下游服務調用的 POJO:

record GetOrderRequest(String userID) {}

record CreateOrderRequest(OrderInfo orderInfo) {}

最後,讓我們來查看一下新的 OrderManagementAIAssistant 類,它會將用户查詢發送到 LLM 服務:

@Service
public class OrderManagementAIAssistant {
    @Autowired
    private ChatModel chatClient;

    public ChatResponse callChatClient(Set<String> functionNames, String promptString) {
        Prompt prompt  = new Prompt(promptString, OpenAiChatOptions
          .builder()
          .withFunctions(functionNames)
          .build()
        );
        return chatClient.call(prompt);
    }
}

callChatClient() 方法用於註冊 Prompt 對象中的函數。隨後,它調用 ChatModel#call() 方法以從 LLM 服務處獲取響應。

5. 函數調用場景

對於用户提出的查詢或指令,我們將會涵蓋幾個基本場景:

  • LLM 決定並識別出要執行一個或多個函數
  • LLM 抱怨缺少信息以執行該函數
  • LLM 條件執行語句

我們已經討論了這些概念;因此,接下來我們將使用此功能構建聊天機器人。

5.1. 執行回調函數一次或多次

現在,讓我們研究一下當使用包含用户查詢和函數模式的提示調用 LLM 時,LLM 的行為。

我們將從一個創建訂單的示例開始:

void whenOrderInfoProvided_thenSaveInDB(String promptString) {
    ChatResponse response = this.orderManagementAIAssistant
      .callChatClient(Set.of("createOrderFn"), promptString);
    String resultContent = response.getResult().getOutput().getText();
    logger.info("The response from the LLM service: {}", resultContent);
}

令人驚訝的是,使用自然語言,我們能獲得預期的結果:

提示 LLM 響應 觀察
創建訂單,數量為 20,用户 ID 為 Jenny,並隨機生成訂單 ID 為正整數 訂單已成功創建,詳情如下:
– **訂單 ID:** 123456
– **用户 ID:** Jenny
– **訂單數量:** 20
程序創建訂單,信息來自提示。
創建兩個訂單。第一個訂單的用户 ID 為 Sophia,數量為 30。第二個訂單的用户 ID 為 Mary,數量為 40。隨機生成訂單 ID 為正整數。 訂單已成功創建:

1. **Sophia 訂單:** 訂單 ID 1,數量為 30。
2. **Mary 訂單:** 訂單 ID 2,數量為 40。

如果您需要其他幫助,請隨時提問!

程序創建兩個訂單。LLM 巧妙地要求執行函數兩次。

接下來,讓我們看看 LLM 是否能理解請求獲取用户訂單詳情的提示:

void whenUserIDProvided_thenFetchUserOrders(String promptString) {
    ChatResponse response = this.orderManagementAIAssistant
      .callChatClient(Set.of("getUserOrdersFn"), promptString);
    String resultContent = response.getResult().getOutput().getText();
    logger.info("The response from the LLM service: {}", resultContent);
}

結果與之前案例類似。LLM 成功識別出要執行的註冊函數。隨後,Spring Boot 應用程序調用該函數並返回一個或多個用户的訂單詳情。

5.2. 條件執行回調函數

讓我們考慮一個在滿足特定條件時才創建訂單的程序:

void whenUserIDProvided_thenCreateOrderIfUserHasLessThanTwoOrders(String promptString) {
    ChatResponse response = this.orderManagementAIAssistant
      .callChatClient(Set.of("getUserOrdersFn", "createOrderFn"), promptString);
    String resultContent = response.getResult()
      .getOutput()
      .getText();
    logger.info("The response from the LLM service: {}", resultContent);
}

我們已在 ChatModel Bean 中註冊了 getUserOrderFnCreateOrderFn 函數。 此外,LLM 必須確定哪個函數將為請求的動作產生最佳結果。

正如之前一樣,結果令人鼓舞:

提示 輸出 觀察
為用户 ID 為 Alex 創建訂單,數量為 25。 如果用户有超過 2 個訂單,則不要創建任何訂單。 在創建訂單時,隨機生成正整數作為訂單 ID 用户 Alex 已經有超過 2 個訂單(具體是 4 個訂單)。 因此,我不會創建新的訂單。 LLM 可以根據先前函數的輸出,條件調用下游函數。
為用户 ID 為 David 創建訂單,數量為 25。 如果用户有超過 2 個訂單,則不要創建任何訂單。 在創建訂單時,隨機生成正整數作為訂單 ID 已成功為用户 ID 為“David”創建訂單,訂單數量為 25,訂單 ID 為 42。 這次 getUserOrderFn 返回了 David 的訂單數量少於 2 個。 因此,LLM 決定請求執行 createOrderFn。
創建訂單,數量為 20 請提供您的用户 ID 以創建訂單。 LLM 在開始時識別到用户 ID 丟失,並中止了進一步處理。

6. Spring AI Advisors API

在上一節中,我們討論了應用程序的功能方面。然而,在所有功能中都存在一些常見的擔憂,例如:

  • 防止用户輸入敏感信息
  • 用户查詢的日誌記錄和審計
  • 維護對話狀態
  • 豐富提示

幸運的是,Advisors APIs 可以幫助我們始終如一地解決這些問題。我們已經在一篇文章中詳細解釋過這些內容。

7. Spring AI 結構化輸出 API 和 Spring AI RAG

LLMs 主要生成自然語言形式的響應消息。然而,下游服務通常以可讀機器格式(如 POJO、JSON 等)理解這些消息。Spring AI 能夠生成結構化輸出的能力在此發揮重要作用。

如 Advisors APIs 一樣,我們已經詳細地在其中一篇文檔中進行了説明,因此我們不會在此進行更深入的討論,而是直接進入下一個主題。

有時,應用程序需要查詢向量數據庫(Vector DB)以執行對存儲數據的語義搜索,從而檢索額外信息。隨後,從向量數據庫檢索到的結果會被用於提示(prompt),從而為 LLM 提供情境化信息。這種技術被稱為 RAG 技術,並且可以使用 Spring AI 實現它。

8. 結論

在本文中,我們探討了 Spring AI 的關鍵功能,這些功能可以幫助創建 AI 助手。Spring AI 正在不斷髮展,並提供了許多預配置的功能。然而,選擇合適的底層 LLM 服務和向量數據庫至關重要,無論編程框架如何,這一點都不可忽視。此外,優化這些服務的配置可能具有挑戰性,需要投入大量精力。儘管如此,為了應用程序的廣泛採用,仍然至關重要。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.