Java AI 核心引擎:30 天從零打造可擴展的智慧 Agent 函式庫
本篇是 IT 鐵人賽系列文章的第二天,將使用 LangChain4j 的基礎模型 API 進行最直接的 AI 互動。
在開始今天精彩的 AI 對話之前,我們先花一分鐘確認昨天建立的環境都運作正常。這個檢查步驟雖然看似瑣碎,但能避免後面遇到奇怪的問題時不知道從哪裡開始除錯。
# 檢查 Ollama 服務是否正常回應
curl http://localhost:11434/api/version
# 確認我們的 Llama 模型已經下載
ollama list | grep llama3.1
如果這兩個指令都能正常回傳結果,那就表示我們的 AI 基礎環境已經準備就緒!
確認 pom.xml
中已包含 LangChain4j 依賴(Day 1 已設定):
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-spring-boot-starter</artifactId>
<version>0.36.2</version>
</dependency>
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-ollama-spring-boot-starter</artifactId>
<version>0.36.2</version>
</dependency>
ChatLanguageModel
是 LangChain4j 框架中最基礎也是最重要的介面。我喜歡把它想像成是一座橋樑,連接我們的 Java 程式碼和背後強大的語言模型。
從開發者的角度來看,它有幾個讓人愛不釋手的特點:
generate()
方法,使用成本很低這種設計哲學很符合 Java 開發者的習慣,不會有太多意外的驚喜,但也不會有令人頭痛的複雜性。
public interface ChatLanguageModel {
// 簡單對話:輸入字串,回傳字串
String generate(String userMessage);
// 進階對話:使用 ChatMessage 物件
Response<AiMessage> generate(ChatMessage... messages);
}
現在到了最興奮的時刻!我們要建立第一個能和 AI 對話的 Java 程式。我選擇使用 CommandLineRunner
這個方式,因為它會在 Spring Boot 應用程式啟動完成後自動執行,非常適合我們做測試和驗證。
在 src/main/java/org/example/aiagentdemo/runner
目錄下建立一個新的類別:
package org.example.aiagentdemo.runner;
import dev.langchain4j.model.chat.ChatLanguageModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
/**
* AI 對話執行器 - 應用程式啟動後自動執行
*
* 使用 CommandLineRunner 介面,在 Spring Boot 應用程式啟動完成後
* 自動執行 run 方法中的程式碼
*/
@Component
public class AiChatRunner implements CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(AiChatRunner.class);
// 注入 LangChain4j 自動配置的 ChatLanguageModel Bean
@Autowired
private ChatLanguageModel chatLanguageModel;
@Override
public void run(String... args) throws Exception {
logger.info("========== 開始 AI 對話測試 ==========");
// 測試 1:簡單問候
testSimpleGreeting();
// 測試 2:技術問題
testTechnicalQuestion();
// 測試 3:繁體中文對話
testChineseConversation();
logger.info("========== AI 對話測試完成 ==========");
}
/**
* 測試簡單問候
*/
private void testSimpleGreeting() {
logger.info("\n--- 測試 1:簡單問候 ---");
String question = "你好!今天過得如何?";
logger.info("使用者: {}", question);
String response = chatLanguageModel.generate(question);
logger.info("AI 回應: {}", response);
}
/**
* 測試技術問題
*/
private void testTechnicalQuestion() {
logger.info("\n--- 測試 2:技術問題 ---");
String question = "什麼是 Spring Boot?請用兩句話說明。";
logger.info("使用者: {}", question);
String response = chatLanguageModel.generate(question);
logger.info("AI 回應: {}", response);
}
/**
* 測試繁體中文對話
*/
private void testChineseConversation() {
logger.info("\n--- 測試 3:繁體中文對話 ---");
String question = "請用繁體中文解釋什麼是 AI Agent,限 50 字以內。";
logger.info("使用者: {}", question);
String response = chatLanguageModel.generate(question);
logger.info("AI 回應: {}", response);
}
}
確認 application.properties
中的配置(沿用 Day 1 設定):
spring.application.name=ai-agent-demo
# Ollama Configuration
langchain4j.ollama.chat-model.base-url=http://localhost:11434
langchain4j.ollama.chat-model.model-name=llama3.1:8b-instruct-q4_K_M
langchain4j.ollama.chat-model.temperature=0.7
langchain4j.ollama.chat-model.timeout=PT5M
# 日誌等級設定 - 顯示詳細的 AI 互動日誌
logging.level.org.example.aiagentdemo=INFO
logging.level.dev.langchain4j=DEBUG
./mvnw spring-boot:run
成功執行後,您應該會看到類似以下的輸出:
INFO --- [main] o.e.aiagentdemo.AiChatRunner : ========== 開始 AI 對話測試 ==========
INFO --- [main] o.e.aiagentdemo.AiChatRunner : --- 測試 1:簡單問候 ---
INFO --- [main] o.e.aiagentdemo.AiChatRunner : 使用者: 你好!今天過得如何?
INFO --- [main] o.e.aiagentdemo.AiChatRunner : AI 回應: 你好!我是一個 AI 助理,隨時準備好為您提供協助。今天我運作正常,謝謝您的關心!有什麼可以幫助您的嗎?
INFO --- [main] o.e.aiagentdemo.AiChatRunner : --- 測試 2:技術問題 ---
INFO --- [main] o.e.aiagentdemo.AiChatRunner : 使用者: 什麼是 Spring Boot?請用兩句話說明。
INFO --- [main] o.e.aiagentdemo.AiChatRunner : AI 回應: Spring Boot 是建立在 Spring 框架之上的開發框架,透過自動配置和內嵌伺服器大幅簡化了 Java 應用程式的開發。它消除了傳統 Spring 應用中大量的樣板程式碼和 XML 配置需求。
INFO --- [main] o.e.aiagentdemo.AiChatRunner : --- 測試 3:繁體中文對話 ---
INFO --- [main] o.e.aiagentdemo.AiChatRunner : 使用者: 請用繁體中文解釋什麼是 AI Agent,限 50 字以內。
INFO --- [main] o.e.aiagentdemo.AiChatRunner : AI 回應: AI Agent 是能自主執行任務的人工智慧系統,可感知環境、做出決策並採取行動來達成特定目標。
INFO --- [main] o.e.aiagentdemo.AiChatRunner : ========== AI 對話測試完成 ==========
當我們第一次看到 @Autowired
就能直接注入 ChatLanguageModel
時,可能會覺得有點神奇。這背後其實是 Spring Boot 自動配置機制的功勞。
當我們在 pom.xml
中加入 langchain4j-ollama-spring-boot-starter
依賴後,Spring Boot 在啟動時會自動:
application.properties
中尋找所有 langchain4j.ollama.*
開頭的配置ChatLanguageModel
的實作類別註冊為 Spring Bean這就是為什麼我們不需要寫任何複雜的初始化程式碼,Spring Boot 都幫我們處理好了。
應用程式啟動流程:
1. Spring Context 初始化
2. 所有 Bean 建立完成
3. 應用程式完全啟動
4. 執行所有 CommandLineRunner 的 run() 方法 <-- 我們的測試在這裡執行
5. 應用程式進入運行狀態
根據 Ollama API 文件,當呼叫 generate()
方法時,LangChain4j 會透過 HTTP 與 Ollama API 進行通訊:
// 當呼叫:
String response = chatLanguageModel.generate("Hello!");
// 從實作細節分析,LangChain4j 內部處理流程如下:
// 1. 將使用者訊息轉換為 Ollama API 格式
// 2. 發送 POST 請求到 /api/chat 端點
// API 文件說明:「Generate the next message in a chat with a provided model.
// This is a streaming endpoint, so there will be a series of responses.
// Streaming can be disabled using "stream": false.」
// 3. Ollama 服務處理請求並回傳串流或完整回應
// 4. LangChain4j 解析回應並回傳字串結果
API 請求格式範例(來自官方文件):
{
"model": "llama3.2",
"messages": [
{
"role": "user",
"content": "why is the sky blue?"
}
]
}
(上述為官方文件原始範例)
在 LangChain4j 中使用時,實際請求會是:
{
"model": "llama3.1:8b-instruct-q4_K_M",
"messages": [
{"role": "user", "content": "Hello!"}
],
"stream": false
}
(模型名稱和 stream 設定根據 LangChain4j 的預設配置)
錯誤訊息:
Connection refused: localhost/127.0.0.1:11434
解決方法:
# 確認 Ollama 服務正在運行
ollama serve
# 或在另一個終端機執行任何 ollama 命令來啟動服務
ollama list
generate()
方法讓 AI 互動變得和普通方法呼叫一樣簡單最讓我印象深刻的是,從寫程式碼到看到 AI 回應,整個過程竟然如此順暢。這就是好的框架設計帶來的威力。
明天將:
感謝大家的閱讀,我們明天見!
Day 2 完成 | 明天繼續我們的 AI 冒險之旅!