最近在尝试将AI大模型能力集成到Java后端项目中发现市面上的资料要么是Python生态的要么就是概念讲解居多真正能跑通、能落地的JavaAI整合方案少之又少。尤其是在Spring Boot项目中如何优雅地接入OpenAI、DeepSeek等大模型并实现RAG、智能体Agent等高级功能往往需要自己摸索很久。本文将以Spring Boot 3.x为基础整合Spring AI、Spring AI Alibaba以及LangChain4j三大主流Java AI框架通过一个完整的智能客服Agent案例手把手带你从零搭建一个可运行、可扩展的Java AI应用。无论你是想为现有系统增加AI对话能力还是探索RAG知识库问答这篇文章都能提供一套可直接复用的代码模板和避坑指南。1. 背景与核心概念为什么Java开发者需要关注AI大模型在AI浪潮下Python凭借其丰富的库如LangChain、LlamaIndex在AI应用开发中占据主导。然而企业级后端服务大量基于Java特别是Spring Boot构建。让Java后端直接调用Python服务会引入额外的复杂度、网络延迟和运维成本。因此在Java生态中直接集成AI能力成为了降本增效的关键需求。核心框架解析Spring AISpring官方推出的AI应用框架。它提供了统一的ChatClient、EmbeddingClient等抽象接口让开发者能以类似使用JdbcTemplate的方式操作不同的大模型OpenAI、Azure OpenAI、Ollama等。其核心理念是“约定优于配置”通过简单的依赖和配置即可快速接入。Spring AI Alibaba阿里巴巴基于Spring AI规范开发的扩展套件。它最大的价值在于提供了对阿里云灵积模型服务平台DashScope上通义千问等模型的直接支持并且集成了阿里云OSS向量存储等能力对于国内开发者而言访问速度更快、合规性更友好。LangChain4jJava版的LangChain。它提供了极其丰富和灵活的AI应用构建模块如链Chain、智能体Agent、工具Tool、记忆Memory和检索器Retriever。其设计更偏向于灵活的编程模型适合构建复杂的AI工作流。如何选择追求快速集成、统一接口首选Spring AI。主要使用国内模型通义千问选择Spring AI Alibaba。需要构建复杂Agent、自定义工作流LangChain4j功能更强大。全都要在实际项目中它们可以共存。例如用Spring AI做基础的对话用LangChain4j构建高级Agent。本文将演示三者如何在一个项目中协同工作。2. 环境准备与版本说明在开始编码前请确保你的开发环境符合以下要求。版本兼容性是成功的第一步。基础环境操作系统Windows 10/11, macOS, 或 Linux (Ubuntu 20.04)。本文演示基于macOS/Windows。JavaJDK 17 或 21推荐17长期支持版。Spring Boot 3.x必须使用JDK 17。构建工具Apache Maven 3.6 或 Gradle 7.x。本文使用Maven。IDEIntelliJ IDEA推荐或 VS Code with Java插件。核心依赖版本这是最容易出错的环节务必核对。以下版本为2024年中旬的稳定组合。!-- 在项目的 pom.xml 中 -- parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.2.5/version !-- 使用稳定的3.2.x版本 -- relativePath/ /parent properties java.version17/java.version !-- 重要Spring AI 版本与 Boot 版本有对应关系 -- spring-ai.version0.8.1/spring-ai.version /properties dependencies !-- Spring Boot Web -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Spring AI OpenAI (接入OpenAI/DeepSeek) -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency !-- Spring AI Alibaba (接入通义千问) -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-ai-spring-boot-starter/artifactId version2023.0.1.0/version !-- 注意此版本号独立 -- /dependency !-- LangChain4j 核心 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j/artifactId version0.31.0/version /dependency !-- LangChain4j OpenAI 适配器 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-open-ai/artifactId version0.31.0/version /dependency !-- 测试 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencyManagement !-- 必须Spring AI 的依赖管理 -- dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement项目结构预览创建完成后你的项目结构应类似于java-ai-demo ├── src/main/java/com/example/ai │ ├── config // 配置类 │ ├── controller // 控制器 │ ├── service // 业务层 │ │ ├── impl │ │ └── agent // Agent相关服务 │ ├── tool // Agent工具定义 │ └── JavaAiDemoApplication.java // 启动类 ├── src/main/resources │ ├── application.yml // 主配置文件 │ └── documents // 存放用于RAG的文档 └── pom.xml3. 核心配置与多模型接入我们将配置两个模型一个国际模型DeepSeek性价比高和一个国内模型通义千问。application.yml是配置的核心。3.1 配置文件详解在src/main/resources/application.yml中进行如下配置# 应用基础配置 spring: application: name: java-ai-demo # Spring AI - OpenAI 兼容配置 (用于DeepSeek) # DeepSeek的API与OpenAI兼容base-url指向其端点 spring: ai: openai: api-key: ${OPENAI_API_KEY:sk-your-deepseek-api-key-here} # 从环境变量读取优先使用环境变量保证安全 base-url: https://api.deepseek.com # DeepSeek API地址 chat: options: model: deepseek-chat # 使用的模型名称 temperature: 0.7 # 创造性0-2之间越高越随机 max-tokens: 2000 # 单次回复最大token数 # Spring AI Alibaba - 通义千问配置 # 注意这里的配置项前缀与Spring AI OpenAI不同 alibaba: ai: dashscope: api-key: ${DASHSCOPE_API_KEY:sk-your-dashscope-api-key-here} # 阿里云灵积API Key chat: options: model: qwen-max # 可选 qwen-turbo, qwen-plus, qwen-max temperature: 0.8 # LangChain4j 配置部分通过代码配置 langchain4j: open-ai: api-key: ${OPENAI_API_KEY} # 可以复用同一个key base-url: ${spring.ai.openai.base-url} # 复用base-url model-name: ${spring.ai.openai.chat.options.model} # 复用模型名关键点说明API密钥安全${VARIABLE_NAME:default-value}语法表示优先从系统环境变量读取找不到则使用默认值。强烈建议将OPENAI_API_KEY和DASHSCOPE_API_KEY设置为环境变量避免密钥硬编码在代码中泄露。模型端点DeepSeek完全兼容OpenAI API协议所以base-url改为其官方端点即可。其他国产模型如智谱GLM、月之暗面Kimi也有类似兼容方案。配置隔离Spring AI Alibaba使用了独立的配置前缀alibaba.ai.dashscope与spring.ai.openai并列避免了冲突。3.2 配置类与Bean注入为了让不同框架的客户端在Spring容器中可用我们需要一个配置类。// 文件路径src/main/java/com/example/ai/config/AiConfig.java package com.example.ai.config; import org.springframework.ai.alibaba.dashscope.AlibabaDashCopeChatModel; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.openai.OpenAiChatModel; import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.ai.openai.api.OpenAiApi; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestClient; Configuration public class AiConfig { Value(${spring.ai.openai.api-key}) private String openaiApiKey; Value(${spring.ai.openai.base-url}) private String openaiBaseUrl; Value(${spring.ai.openai.chat.options.model}) private String openaiModel; Value(${alibaba.ai.dashscope.api-key}) private String dashscopeApiKey; /** * 配置 Spring AI 的 OpenAiChatModel (用于DeepSeek) * 这是一个标准的Spring AI ChatModel Bean */ Bean Qualifier(deepSeekChatModel) // 使用限定符区分Bean public ChatModel deepSeekChatModel() { OpenAiApi openAiApi new OpenAiApi(openaiBaseUrl, openaiApiKey, RestClient.builder()); OpenAiChatOptions options OpenAiChatOptions.builder() .model(openaiModel) .temperature(0.7) .maxTokens(2000) .build(); return new OpenAiChatModel(openAiApi, options); } /** * 配置 Spring AI Alibaba 的 ChatModel (用于通义千问) */ Bean Qualifier(qwenChatModel) public ChatModel qwenChatModel() { // AlibabaDashCopeChatModel 实现了 Spring AI 统一的 ChatModel 接口 return new AlibabaDashCopeChatModel(dashscopeApiKey); } /** * 配置 LangChain4j 的 OpenAiChatModel * 注意这是LangChain4j自己的类与Spring AI的无关 */ Bean Qualifier(langChainOpenAiModel) public dev.langchain4j.model.openai.OpenAiChatModel langChainOpenAiModel() { return dev.langchain4j.model.openai.OpenAiChatModel.builder() .apiKey(openaiApiKey) .baseUrl(openaiBaseUrl) .modelName(openaiModel) .temperature(0.7) .maxTokens(2000) .logRequests(true) // 开启请求日志调试有用 .logResponses(true) .build(); } }为什么需要Qualifier当容器中存在多个同类型ChatModel或OpenAiChatModel的Bean时Spring无法自动选择注入哪一个。使用Qualifier注解给Bean起个名字在注入时指定这个名字就能精确选择。4. 基础对话功能实战我们先实现最简单的功能通过HTTP API与不同模型进行对话。4.1 创建统一对话服务首先创建一个服务层封装对不同模型的调用。// 文件路径src/main/java/com/example/ai/service/ChatService.java package com.example.ai.service; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.SystemPromptTemplate; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.messages.UserMessage; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; Service public class ChatService { private final ChatModel deepSeekChatModel; private final ChatModel qwenChatModel; // 通过构造器注入并指定使用哪个Bean public ChatService( Qualifier(deepSeekChatModel) ChatModel deepSeekChatModel, Qualifier(qwenChatModel) ChatModel qwenChatModel) { this.deepSeekChatModel deepSeekChatModel; this.qwenChatModel qwenChatModel; } /** * 使用DeepSeek模型进行简单对话 */ public String chatWithDeepSeek(String userMessage) { // 最简单的调用将用户输入包装成UserMessage UserMessage message new UserMessage(userMessage); // 调用模型的call方法 return deepSeekChatModel.call(message).getResult().getOutput().getContent(); } /** * 使用通义千问模型进行简单对话 */ public String chatWithQwen(String userMessage) { UserMessage message new UserMessage(userMessage); return qwenChatModel.call(message).getResult().getOutput().getContent(); } /** * 带系统提示词System Prompt的对话 - 以DeepSeek为例 * 系统提示词用于设定AI的角色和行为 */ public String chatWithSystemPrompt(String userMessage) { // 1. 定义系统提示词模板 String systemText 你是一个专业的Java技术专家擅长Spring Boot和微服务架构。 你的回答应该简洁、准确并且包含代码示例。 如果用户的问题与Java无关请礼貌地拒绝回答。 ; SystemPromptTemplate systemPromptTemplate new SystemPromptTemplate(systemText); Message systemMessage systemPromptTemplate.createMessage(); // 2. 创建用户消息 UserMessage userMsg new UserMessage(userMessage); // 3. 构建Prompt包含系统消息和用户消息 Prompt prompt new Prompt(List.of(systemMessage, userMsg)); // 4. 调用模型 return deepSeekChatModel.call(prompt).getResult().getOutput().getContent(); } /** * 多轮对话示例简化版实际需要持久化历史记录 */ public String multiTurnChat(ListMessage conversationHistory, String newUserInput) { // 将历史记录和新输入合并为一个新的Prompt conversationHistory.add(new UserMessage(newUserInput)); Prompt prompt new Prompt(conversationHistory); return deepSeekChatModel.call(prompt).getResult().getOutput().getContent(); } }4.2 创建RESTful控制器暴露HTTP接口供前端或测试调用。// 文件路径src/main/java/com/example/ai/controller/ChatController.java package com.example.ai.controller; import com.example.ai.service.ChatService; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; RestController RequestMapping(/api/chat) public class ChatController { private final ChatService chatService; // 简易内存存储用于演示多轮对话。生产环境请用Redis或数据库。 private final MapString, Listorg.springframework.ai.chat.messages.Message sessionHistory new HashMap(); public ChatController(ChatService chatService) { this.chatService chatService; } PostMapping(/deepseek) public MapString, String chatWithDeepSeek(RequestBody MapString, String request) { String message request.get(message); String response chatService.chatWithDeepSeek(message); return Map.of(model, DeepSeek, response, response); } PostMapping(/qwen) public MapString, String chatWithQwen(RequestBody MapString, String request) { String message request.get(message); String response chatService.chatWithQwen(message); return Map.of(model, Qwen, response, response); } PostMapping(/deepseek-with-role) public MapString, String chatWithRole(RequestBody MapString, String request) { String message request.get(message); String response chatService.chatWithSystemPrompt(message); return Map.of(model, DeepSeek (Java Expert), response, response); } PostMapping(/multi-turn) public MapString, String multiTurnChat(RequestBody MapString, String request, RequestHeader(value Session-Id, defaultValue default) String sessionId) { String userInput request.get(message); // 获取或创建该会话的历史记录 Listorg.springframework.ai.chat.messages.Message history sessionHistory.getOrDefault(sessionId, new ArrayList()); // 调用服务这里简化实际应将AI回复也加入history String response chatService.chatWithDeepSeek(userInput); // 简单调用未传递历史 // 更新历史生产环境需要更复杂的状态管理 // history.add(new UserMessage(userInput)); // history.add(new AssistantMessage(response)); // sessionHistory.put(sessionId, history); return Map.of(sessionId, sessionId, response, response); } }4.3 运行与测试启动应用运行JavaAiDemoApplication的main方法。使用工具测试使用Postman、curl或任何HTTP客户端测试接口。请求示例 (POSThttp://localhost:8080/api/chat/deepseek){ message: 用Java写一个Hello World程序 }预期响应{ model: DeepSeek, response: 以下是Java的Hello World程序...\njava\npublic class HelloWorld {\n public static void main(String[] args) {\n System.out.println(\Hello, World!\);\n }\n}\n }至此你已经完成了Spring Boot与两个大模型的基础集成。但这只是开始真正的威力在于RAG和Agent。5. 进阶实战构建RAG智能客服Agent我们将实现一个更复杂的场景一个智能客服Agent它能根据我们提供的内部知识库如产品手册PDF回答问题并在无法回答时自动调用“人工客服”工具。这个案例将综合运用LangChain4j构建Agent工作流管理工具。Spring AI用于文档嵌入Embedding和向量存储VectorStore。自定义工具让Agent能执行特定操作。5.1 文档加载与向量化RAG核心首先我们需要将知识库文档如TXT、PDF转换为向量并存储。// 文件路径src/main/java/com/example/ai/service/RagService.java package com.example.ai.service; import org.springframework.ai.document.Document; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.ai.reader.TextReader; import org.springframework.ai.transformer.splitter.TokenTextSplitter; import org.springframework.ai.vectorstore.SimpleVectorStore; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.stereotype.Service; import org.springframework.util.FileCopyUtils; import jakarta.annotation.PostConstruct; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.List; Service public class RagService { private final EmbeddingModel embeddingModel; // Spring AI会自动注入 private final ResourceLoader resourceLoader; private VectorStore vectorStore; public RagService(EmbeddingModel embeddingModel, ResourceLoader resourceLoader) { this.embeddingModel embeddingModel; this.resourceLoader resourceLoader; } /** * 项目启动时初始化向量存储并加载知识库文档 */ PostConstruct public void init() throws IOException { // 1. 初始化一个内存向量存储生产环境可用PgVector、Redis等 this.vectorStore new SimpleVectorStore(embeddingModel); // 2. 加载资源文件下的文档 Resource resource resourceLoader.getResource(classpath:documents/product_manual.txt); String content FileCopyUtils.copyToString( new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)); // 3. 创建Document对象 Document document new Document(content); document.getMetadata().put(source, product_manual.txt); // 4. 文本分割将长文档切分为小块便于检索 TokenTextSplitter splitter new TokenTextSplitter(500, 100, 10, 1000); // 参数块大小、重叠大小等 ListDocument splitDocuments splitter.apply(List.of(document)); // 5. 将分割后的文档添加到向量存储会自动调用EmbeddingModel生成向量 vectorStore.add(splitDocuments); System.out.println(知识库文档已加载并向量化共 splitDocuments.size() 个片段。); } /** * 相似性检索根据用户问题从知识库中找出最相关的文档片段 */ public ListDocument searchRelevantDocuments(String query) { // 检索最相关的4个文档片段 return vectorStore.similaritySearch(query, 4); } /** * 构建RAG提示词将检索到的上下文和用户问题组合 */ public String buildRagPrompt(String userQuestion) { ListDocument relevantDocs searchRelevantDocuments(userQuestion); if (relevantDocs.isEmpty()) { return userQuestion; // 没有相关上下文直接返回原问题 } StringBuilder contextBuilder new StringBuilder(); contextBuilder.append(请根据以下上下文信息回答问题。如果上下文信息不足以回答问题请如实说明。\n\n); contextBuilder.append(【上下文开始】\n); for (Document doc : relevantDocs) { contextBuilder.append(doc.getContent()).append(\n---\n); } contextBuilder.append(【上下文结束】\n\n); contextBuilder.append(问题).append(userQuestion); return contextBuilder.toString(); } }5.2 定义Agent工具Agent的强大之处在于可以使用工具。我们定义一个“转接人工客服”的工具。// 文件路径src/main/java/com/example/ai/tool/ManualCustomerServiceTool.java package com.example.ai.tool; import dev.langchain4j.agent.tool.Tool; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; Component // 注册为Spring Bean public class ManualCustomerServiceTool { /** * 当AI无法回答用户问题时调用此工具转接人工客服。 * Tool 注解是LangChain4j的标记表示这是一个可供Agent使用的工具。 * param userId 用户ID * param question 用户的问题 * return 转接结果描述 */ Tool(当问题超出知识范围或用户明确要求时将对话转接给人工客服。请提供用户ID和问题摘要。) public String transferToManualService(String userId, String question) { // 这里模拟转接逻辑实际项目中可能是发送消息到工单系统、通知客服人员等。 String ticketId TICKET- System.currentTimeMillis(); String timestamp LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); // 记录日志或持久化到数据库 System.out.printf([人工客服转接] 工单ID: %s, 用户: %s, 时间: %s, 问题: %s%n, ticketId, userId, timestamp, question); return String.format(已为您创建工单【%s】并转接至人工客服。客服人员将在15分钟内通过系统消息与您联系。, ticketId); } }5.3 构建智能体Agent服务这是最核心的部分我们将使用LangChain4j的AiServices来创建一个集成了工具、记忆和RAG上下文的智能体。// 文件路径src/main/java/com/example/ai/service/agent/CustomerServiceAgent.java package com.example.ai.service.agent; import dev.langchain4j.memory.ChatMemory; import dev.langchain4j.memory.chat.MessageWindowChatMemory; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.service.AiServices; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.UserMessage; import dev.langchain4j.service.V; import com.example.ai.tool.ManualCustomerServiceTool; import com.example.ai.service.RagService; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; /** * 定义智能体的交互接口。 * LangChain4j的AiServices会根据这个接口动态生成实现类。 */ interface Assistant { // SystemMessage 定义系统提示词设定Agent的角色和行为准则 SystemMessage( 你是一个专业的智能客服助手负责解答关于公司产品的疑问。 你的知识来源于提供的产品手册。请严格根据已知信息回答。 如果用户的问题超出你的知识范围或者用户明确要求人工服务请果断调用transferToManualService工具。 回答请保持友好、专业、简洁。 ) // UserMessage 中的 {{context}} 和 {{question}} 是模板变量由调用者传入 String chat(V(context) String context, V(question) String question); } Service public class CustomerServiceAgent { private final Assistant assistant; private final RagService ragService; public CustomerServiceAgent( Qualifier(langChainOpenAiModel) ChatLanguageModel chatLanguageModel, // 注入LangChain4j的模型 ManualCustomerServiceTool manualTool, RagService ragService) { this.ragService ragService; // 1. 创建聊天记忆保留最近10轮对话 ChatMemory chatMemory MessageWindowChatMemory.withMaxMessages(10); // 2. 使用AiServices构建智能体 // 它会将接口、模型、工具、记忆绑定在一起 this.assistant AiServices.builder(Assistant.class) .chatLanguageModel(chatLanguageModel) .tools(manualTool) // 注入工具 .chatMemory(chatMemory) // 注入记忆 .build(); } /** * 主服务方法处理用户问题集成RAG和Agent */ public String answerQuestion(String userId, String userQuestion) { // 步骤1通过RAG检索相关知识 String ragContext ragService.buildRagPrompt(userQuestion); // 步骤2让Agent基于上下文和工具进行回答 // 这里将RAG构建的完整提示词包含上下文作为context变量传入 // 将原始用户问题作为question变量传入供Agent在需要时传递给工具 String answer assistant.chat(ragContext, userQuestion); return answer; } }5.4 创建Agent控制器// 文件路径src/main/java/com/example/ai/controller/AgentController.java package com.example.ai.controller; import com.example.ai.service.agent.CustomerServiceAgent; import org.springframework.web.bind.annotation.*; import java.util.Map; RestController RequestMapping(/api/agent) public class AgentController { private final CustomerServiceAgent customerServiceAgent; public AgentController(CustomerServiceAgent customerServiceAgent) { this.customerServiceAgent customerServiceAgent; } PostMapping(/customer-service) public MapString, String handleCustomerQuery(RequestBody MapString, String request) { String userId request.getOrDefault(userId, anonymous); String question request.get(question); String answer customerServiceAgent.answerQuestion(userId, question); return Map.of( userId, userId, question, question, answer, answer ); } }5.5 准备知识库文档并测试在src/main/resources/documents/目录下创建product_manual.txt内容例如产品名称AI助手API 版本v2.1 主要功能提供自然语言对话、代码生成、文本总结能力。 计费方式按调用次数计费每月前1000次免费。 技术支持如需人工帮助请在对话中明确说“转人工客服”。 故障处理如遇API超时请检查网络并重试或联系技术支持。重启应用观察日志确认文档加载成功。测试场景1知识库内问题请求POST /api/agent/customer-serviceBody{userId: user123, question: 你们的AI助手API怎么收费}预期Agent从知识库检索到“计费方式”片段并生成回答。测试场景2知识库外问题/要求转人工请求Body{userId: user123, question: 我想咨询一下企业定制方案转人工客服。}预期Agent识别到“转人工客服”关键词或判断超出知识范围调用transferToManualService工具返回工单创建成功的消息。观察控制台输出的转接日志。6. 常见问题与排查思路在集成过程中你可能会遇到以下典型问题问题现象可能原因排查步骤与解决方案启动报错No qualifying bean of type EmbeddingModelSpring AI 的自动配置未生效或依赖冲突。1. 检查pom.xml中spring-ai-openai-spring-boot-starter依赖是否正确。2. 确保spring-ai-bom的依赖管理已正确引入。3. 尝试在启动类添加EnableAutoConfiguration。调用API时报错401 UnauthorizedAPI密钥错误、过期或未设置。1. 检查application.yml中的api-key或对应的环境变量OPENAI_API_KEY、DASHSCOPE_API_KEY是否已设置且正确。2. 在代码中打印密钥前几位勿泄露完整密钥确认已注入。3. 前往对应平台检查密钥状态和余额。调用DeepSeek报错404 Not Foundbase-url配置错误或模型名称model不对。1. 确认base-url为https://api.deepseek.com。2. 确认model为deepseek-chat或deepseek-coder。3. 查阅DeepSeek官方文档确认最新API地址。LangChain4j的Agent不调用工具工具方法签名不符合要求或提示词未引导。1. 确保工具方法使用Tool注解且描述清晰。2. 确保工具方法是public的。3. 在SystemMessage中明确指示Agent在何种条件下调用工具。RAG检索结果不相关文档分割策略不合理或嵌入模型不匹配。1. 调整TokenTextSplitter的块大小chunkSize和重叠大小chunkOverlap。2. 尝试不同的嵌入模型如OpenAI的text-embedding-3-small。3. 检查检索时返回的文档数量similaritySearch的第二个参数。内存溢出 (OutOfMemoryError)加载的文档过大或向量存储未使用外部数据库。1. 对于大文档务必进行有效的文本分割。2. 生产环境务必使用外部向量数据库如PgVector, Redis, Milvus避免使用内存存储SimpleVectorStore。中文回答质量差系统提示词未指定语言或模型对中文优化不足。1. 在SystemMessage或系统提示词中明确要求“请使用中文回答”。2. 对于中文场景可优先考虑qwen-turbo、glm-4等国内模型。7. 最佳实践与工程建议将AI能力集成到生产级Java项目除了功能实现还需关注以下方面配置与密钥管理永远不要将API密钥提交到代码仓库。使用环境变量、配置中心如Apollo、Nacos或云厂商的密钥管理服务。为不同环境开发、测试、生产配置不同的模型和参数生产环境建议使用更稳定的模型版本。性能与稳定性设置超时与重试在RestClient或HTTP客户端配置合理的连接超时、读取超时并实现重试机制如使用Spring Retry。实现熔断降级使用Resilience4j或Sentinel为AI服务调用添加熔断器防止因模型服务不稳定导致整个应用雪崩。异步化处理对于耗时的AI生成任务使用Async或消息队列如RabbitMQ、Kafka异步处理避免阻塞HTTP请求线程。可观测性与监控全链路日志记录每次AI调用的请求、响应、耗时和Token使用量。LangChain4j和Spring AI都支持开启日志。指标监控通过Micrometer将调用次数、成功率、延迟等指标暴露给Prometheus并配置Grafana看板。成本监控由于AI API按Token计费必须监控Token消耗设置预算告警。RAG优化高质量数据预处理清洗、去重、格式化你的知识库文档。垃圾输入会导致垃圾输出。多路召回与重排序不要只依赖向量相似度。可结合关键词检索如Elasticsearch并对召回结果进行重排序提升准确率。引用溯源在回答中注明引用的文档片段来源增加可信度。Agent设计工具设计要精确工具的功能应单一、明确输入输出定义清晰。避免让Agent去猜测如何调用一个模糊的工具。限制Agent权限赋予Agent的工具应是安全的、无副作用的。特别是涉及写数据库、调用外部API、发送消息等操作必须有严格的权限和审计。人工审核闭环对于关键业务如客服、审核设计“人工审核”环节。Agent可生成草稿由人最终确认后发出。版本与依赖管理Spring AI和LangChain4j迭代较快锁定小版本号升级前在测试环境充分验证。注意Spring Boot主版本与Spring AI版本的兼容性参考官方文档的版本矩阵。掌握Spring AI、Spring AI Alibaba和LangChain4j这三大框架你就能在熟悉的Java和Spring生态中自如地构建各类AI增强型应用。从简单的对话接口到复杂的RAG智能体其核心模式都是相通的配置模型 - 处理数据 - 设计流程 - 集成工具。建议你从本文的示例项目出发尝试替换不同的模型、接入真实的业务数据、设计更有趣的工具逐步搭建起符合自己业务需求的AI应用。