Java开发者AI应用实战:Spring AI 2.0 + DeepSeek + RAG + Agent全链路

发布时间:2026/8/30 18:48:53
Java开发者AI应用实战:Spring AI 2.0 + DeepSeek + RAG + Agent全链路 如果你是一名 Java 开发者最近在苦恼“AI 应用开发难道只能 Python”那这篇内容可以直接收藏。这次我们看的不是某个零散 Demo而是把 Java AI 应用开发的主干路径一次性走通Spring AI 2.0 Langchain4j DeepSeek Tools RAG Agent。这套组合在 2026 年回头看依然是 Java 后端做 AI 应用最主流、最值得优先投入的一条学习路线。它不是“能不能用”的问题而是“怎么在自己的 Spring Boot 工程里稳定地用起来”的问题。先说结论这个教程实战链路包含六个核心点——通过 Spring AI 2.0 的统一抽象接入 DeepSeek 大模型用 Tools 让模型调用 Java 方法用 RAG 把私有知识库接进问答流程用 Agent 完成多工具、多轮对话的编排同时用 Langchain4j 做另一条并行选型方案。文章会带着你完成环境准备、最小项目启动、DeepSeek 接入、函数调用、知识库问答、Agent 编排、接口 API 封装和批量任务最后给出一套可以直接参考的排查清单。如果你已经有一个 Spring Boot 后端工程不想为了 AI 能力再单独搭一套 Python 服务这篇文章就是给你写的。1. 核心能力速览能力项说明项目类型Java AI 应用开发实战技术栈核心技术Spring AI 2.0、Langchain4j、DeepSeek、Tools、RAG、Agent主要功能大模型对话、函数调用、私有知识库问答、多工具 Agent 编排、REST API 封装推荐环境JDK 17、Spring Boot 3.x、Maven 3.8模型接入DeepSeek APIOpenAI 兼容接口、也可替换为 OpenAI / Ollama / 其他兼容服务向量化存储Spring AI VectorStore、Langchain4j EmbeddingStore可选内存 / PGVector / Milvus / Redis启动方式Maven 命令或 IDE 直接启动 Spring Boot 服务是否支持 API支持可通过 REST Controller 暴露对话接口是否支持批量任务支持可在 Java 侧用线程池 / 任务队列批量调用适合读者Java 后端工程师、Spring Boot 用户、正在做企业级 AI 应用落地的人需要说明的是Spring AI 和 Langchain4j 并不是“二选一”的对立关系。Spring AI 的优势在 Spring 生态自动装配、依赖注入、Spring Boot 集成体验Langchain4j 则更贴近 Python LangChain 的分层抽象。两者都支持 DeepSeek它们的定位差异会在第 4 章展开。2. 适用场景与使用边界先回答一个实际问题这条技术栈到底能用在哪些场景最典型的场景是企业内部知识库问答。把产品文档、运维手册、制度文件切块后向量化用户提问时先检索相关片段再让大模型基于检索结果生成回答能显著减少幻觉。第二个典型场景是业务系统智能助手比如客服工单助手、订单查询助手模型通过 Tools 调用订单服务、用户服务把“对话”变成“可执行的操作”。第三个场景是内容生成与自动化流水线把 Java 后端已有的业务数据喂给模型做摘要、分类、标签提取再走批量任务。但也要明确边界。首先这是服务端应用开发方案不是模型训练教程也不是 Prompt 调优大全你至少需要理解 ChatGPT 或 DeepSeek 的基本使用方式。其次Spring AI 2.0 虽然已经进入稳定迭代阶段但 AI 生态更新很快生产环境建议锁定 Maven 版本不要直接跟着快照版本跑。再次RAG 不是“把文档丢进去就能精准回答”切块策略、Embedding 模型、检索重排序都会影响效果后续要单独调优。合规方面必须强调接入 DeepSeek 或其他模型服务时要注意 API Key 的权限管理不要把密钥提交到 Git 仓库处理用户隐私数据、企业内部资料、版权内容时要先确认来源合法和授权范围如果 Agents 调用真实业务操作接口例如下单、退款、删除必须加权限校验、人工确认和操作审计。技术能跑通是第一步能安全上线才是关键。3. 环境准备与前置条件下面是完整的检查清单基于通用 Spring Boot 开发环境具体版本需要按你的实际工程调整。基础环境JDK推荐 JDK 17部分 Spring Boot 3.x 工程也支持 JDK 21。Maven3.8 以上建议配置阿里云或腾讯云 Maven 镜像下载依赖更快。IDEIntelliJ IDEA 或 Eclipse 均可IDEA 体验更好。Git用于管理代码版本和后续更新。Docker如果要接 Milvus、PgVector、Redis 等向量数据库会用 Docker 更省事。账号与模型服务DeepSeek 开放平台账号申请 API Key。确认 DeepSeek API 的 base-url 和模型名通常兼容 OpenAI 协议常见模型标识是deepseek-chat如果需要推理增强模型可以关注deepseek-reasoner一类标识。确认你所在地区的网络访问是否正常这里不展开网络代理相关内容按你的实际运行环境配置即可。磁盘与资源如果只调用云端 DeepSeek API本地资源占用很小一个普通开发机足够。如果要本地跑 Embedding 模型或通过 Ollama 部署推理模型需要考虑 GPU 显存和内存具体显存占用要按你选择的模型参数和上下文长度测试不能一概而论。Spring Boot 工程本身占用一般在几百 MB 内存以内但叠加 IDA 和 Docker 后建议开发机至少 16GB 内存。端口检查Spring Boot 默认使用8080端口如果本地已有其他服务监听提前改用8081或其他空闲端口server: port: 8081检查端口占用可以使用下方命令# Linux / macOS lsof -i :8080 # Windows netstat -ano | findstr :8080如果端口已经被占用要么结束对应进程要么给 Spring Boot 换一个端口。4. 快速启动Spring AI 2.0 最小项目先别急着上 RAG 和 Agent第一步是跑通一个最小 Spring Boot 工程。推荐直接去 Spring Initializr 生成工程也可以在自己已有的 Spring Boot 工程中手动加依赖。这里给出手动配置的两种依赖写法注意版本号要替换为你选定的稳定版本。4.1 引入 Spring AI BOM在pom.xml中使用 Spring AI BOM 统一管理版本parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.3.x/version relativePath/ /parent properties java.version17/java.version spring-ai.version1.1.x/spring-ai.version /properties dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement4.2 添加 OpenAI 兼容 StarterDeepSeek 兼容 OpenAI 协议所以优先引入spring-ai-starter-model-openaidependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency /dependencies实际上Spring AI 的 OpenAI Starter 会自动配置一个ChatModel你把 base-url 指向 DeepSeek 的地址后就能直接当 DeepSeek 客户端用。4.3 最简配置在application.yml中写入 DeepSeek 配置spring: application: name: java-ai-demo ai: model: chat: openai openai: api-key: ${DEEPSEEK_API_KEY} base-url: https://api.deepseek.com chat: options: model: deepseek-chat temperature: 0.7这里用环境变量DEEPSEEK_API_KEY注入密钥避免把 API Key 写死在配置文件中。如果启动报 404检查 base-url 是https://api.deepseek.com还是https://api.deepseek.com/v1不同版本的 OpenAI 兼容客户端拼接路径规则不完全一样遇到问题就补上/v1再试。4.4 第一个对话接口Spring AI 2.0 中最常用的高抽象 API 是ChatClient。创建一个服务类import org.springframework.ai.chat.client.ChatClient; import org.springframework.stereotype.Service; Service public class ChatService { private final ChatClient chatClient; public ChatService(ChatClient.Builder builder) { this.chatClient builder.build(); } public String chat(String message) { return chatClient.prompt() .user(message) .call() .content(); } }然后在 Controller 中暴露接口import org.springframework.web.bind.annotation.*; import java.util.Map; RestController RequestMapping(/api/ai) public class AiController { private final ChatService chatService; public AiController(ChatService chatService) { this.chatService chatService; } PostMapping(/chat) public MapString, String chat(RequestBody MapString, String request) { String answer chatService.chat(request.get(message)); return Map.of(answer, answer); } }启动 Spring Boot 应用后测试curl -X POST http://localhost:8080/api/ai/chat \ -H Content-Type: application/json \ -d {message: 用一句话介绍 Java}如果返回正常Spring AI DeepSeek 的最小链路已经打通。这一步是所有后续功能的基础先确保它能稳定复现。5. DeepSeek 接入、Tools 与 Agent 实战最小项目跑通后接着进入本轮实战的核心模型接入、函数调用和 Agent 编排。这三部分在 Spring AI 2.0 中是一层层叠加的。5.1 DeepSeek 接入配置细节与响应读取DeepSeek 的接入方式可以理解为“通过 OpenAI 客户端协议访问 DeepSeek 服务”。这里有几个容易踩坑的细节。第一模型标识要分清。deepseek-chat对应通用对话模型deepseek-reasoner对应推理模型。推理模型在返回时可能先输出大段推理过程再输出最终答案如果你发现“接口调通了但是content为空”很可能是因为响应的reasoning_content被当作最终内容了读取时要做兼容。第二temperature 参数要按场景调。代码生成和格式化输出建议用偏低的0.2到0.4开放式的文案生成可以用0.7到0.9。生产环境建议把温度、最大 Token 数等参数放到配置中心方便动态调整。第三超时和重试要单独配置。云端大模型接口的耗时波动比普通 REST 接口大长文本生成可能几十秒甚至更久。Spring AI 底层 HTTP 客户端的连接超时、读取超时、最大重试次数都要调大否则容易出现“请求断了但模型还在生成”的状态。spring: ai: openai: api-key: ${DEEPSEEK_API_KEY} base-url: https://api.deepseek.com chat: options: model: deepseek-chat temperature: 0.7 max-tokens: 2048 client: connect-timeout: 30s read-timeout: 120s5.2 Tools 函数调用让模型能用 Java 方法Tools 是 Spring AI 中很能提升工程价值的功能。它的核心逻辑是把 Java 方法注册给模型模型在回答问题时如果需要实时数据或执行计算就会生成一个函数调用请求Spring AI 再把请求转发给对应 Java 方法拿到结果后让模型继续组织回答。先创建一个工具类import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Component; Component public class CalculatorTools { Tool(description 计算两个数字相加的结果) public double add(double a, double b) { return a b; } Tool(description 计算两个数字相乘的结果) public double multiply(double a, double b) { return a * b; } }在构造ChatClient时注册工具import org.springframework.ai.chat.client.ChatClient; import org.springframework.stereotype.Service; Service public class ToolChatService { private final ChatClient chatClient; public ToolChatService(ChatClient.Builder builder, CalculatorTools calculatorTools) { this.chatClient builder .defaultSystem(你是一个计算助手需要根据用户问题选择合适的计算方法。) .defaultTools(calculatorTools) .build(); } public String ask(String question) { return chatClient.prompt() .user(question) .call() .content(); } }测试时向/api/ai/chat发送类似“计算 12345 乘以 6789 等于多少”的问题模型会自动选择multiply方法。如果返回结果正确说明 Tools 链路已经跑通。Tools 的实际应用远不止加减乘除。把订单查询、库存查询、工单状态、用户信息查询等内部服务封装为Tool方法模型就能成为业务系统的“智能操作入口”。但要注意涉及写操作、删除操作的工具必须做权限校验和人工确认。5.3 Agent 实战多轮对话与多工具编排在 Spring AI 2.0 中Agent 并不是一个黑盒框架而是“模型 Tools 记忆 任务编排”的组合。最简单的 Agent 可以理解为模型能记住上下文并根据用户目标自动决定调用哪些工具、调用几次、何时给出最终回答。要实现多轮记忆需要在ChatClient中加入 Advisor。Advisor 是 Spring AI 用来在对话前后做处理的组件记忆、检索增强、敏感词过滤都可以通过 Advisor 实现。import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; import org.springframework.ai.chat.memory.InMemoryChatMemory; import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class AgentConfig { Bean public ChatMemory chatMemory() { return new InMemoryChatMemory(); } Bean public ChatClient agentChatClient(ChatClient.Builder builder, CalculatorTools calculatorTools, ChatMemory chatMemory) { return builder .defaultSystem(你是 Java AI 助手可以调用工具回答计算和业务问题。) .defaultTools(calculatorTools) .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()) .build(); } }使用的时候先创建一个会话String answer agentChatClient.prompt() .user(如果我有 10 个苹果又买了 20 个一共有多少个) .call() .content();再追问同一个会话String followUp agentChatClient.prompt() .user(如果我再平均分给 5 个人每个人能分到几个) .call() .content();这里的关键点是Agent 不是简单地“把历史消息拼起来”。通过ChatMemory和 AdvisorSpring AI 会自动维护会话历史并把历史消息、工具调用结果一起组织成新的提示词。这样用户不需要反复提及前文信息Agent 也能做出符合上下文的操作。如果你的 Agent 需要更复杂的任务拆解比如“先查库存再计算价格最后生成订单摘要”可以把这些步骤封装成多个Tool并设计好每个工具的描述。模型的工具选择能力取决于工具描述是否清晰参数是否明确这一点在工程化时要多花时间打磨。6. RAG 知识库实战RAGRetrieval-Augmented Generation检索增强生成是目前解决大模型幻觉最常用的方案。Java 侧做 RAG 的流程可以用四句话概括加载文档、切块、向量化、检索回答。6.1 加载文档与切块Spring AI 提供了文档读取和切块的抽象。下面是一个典型流程读取 PDF 或 Markdown 文档按 Token 切块然后写入向量存储。import org.springframework.ai.document.Document; import org.springframework.ai.reader.pdf.PagePdfDocumentReader; import org.springframework.ai.transformer.splitter.TokenTextSplitter; import org.springframework.ai.vectorstore.SimpleVectorStore; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.ai.embedding.EmbeddingModel; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; Configuration public class RagConfig { Bean public VectorStore vectorStore(EmbeddingModel embeddingModel) { return SimpleVectorStore.builder(embeddingModel).build(); } public void loadDocuments(VectorStore vectorStore) { PagePdfDocumentReader reader new PagePdfDocumentReader(classpath:docs/manual.pdf); ListDocument documents reader.get(); TokenTextSplitter splitter new TokenTextSplitter(); ListDocument chunks splitter.apply(documents); vectorStore.add(chunks); } }切块策略直接影响检索效果。TokenTextSplitter适合通用场景中文文本建议根据标点符号、标题结构做二次处理避免把一个完整语义单元拆成两半。切块太小上下文不完整切块太大检索出来的内容噪声多。这个参数要用自己的数据集多测几轮。6.2 Embedding 模型配置Embedding 模型负责把文本转成向量。Spring AI 统一通过EmbeddingModel接口抽象你可以选择 OpenAPI 兼容的 Embedding 服务也可以选择本地 Ollama、Qwen 等模型。这里给出 Ollama 本地 Embedding 的配置思路spring: ai: ollama: base-url: http://localhost:11434 embedding: options: model: qwen2.5:7b如果你使用云端 Embedding 服务需要按对应服务的要求配置 API Key 和模型标识。需要注意DeepSeek 对话模型接口通常不会用于 EmbeddingRAG 链路中的 Embedding 模型要么选 OpenAI 兼容服务要么选本地模型不能想当然地把对话模型直接用成 Embedding 模型。6.3 检索问答完成向量化后问答阶段把向量检索器和问答模型组合起来。最简单的方式是在ChatClient上添加QuestionAnswerAdvisorimport org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor; import org.springframework.ai.vectorstore.VectorStore; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class RagChatConfig { Bean public ChatClient ragChatClient(ChatClient.Builder builder, VectorStore vectorStore) { return builder .defaultSystem(你是一个企业内部知识库助手只能根据提供的资料内容回答资料中没有的内容请明确说明不知道。) .defaultAdvisors(new QuestionAnswerAdvisor(vectorStore)) .build(); } }调用时用户问题会先被检索匹配的文档片段会自动拼进上下文模型再基于这些内容生成回答String answer ragChatClient.prompt() .user(根据知识库产品的退货周期是多久) .call() .content();如果回答中出现了知识库里没有的信息说明检索或提示词约束还需要调整。生产环境建议增加引用来源返回方便用户核对答案来自哪一篇文档。6.4 向量库选型建议开发阶段直接用内存版SimpleVectorStore就够了重启后重新加载数据调试方便。生产环境建议使用 PGVector、Milvus、Redis 等支持持久化的向量存储配合 Docker 部署再根据数据量设计检索和过滤策略。如果知识库数据量大还要考虑混合检索、重排序等优化这部分已经属于 RAG 的进阶专题。7. 接口 API、批量任务与性能观察7.1 把 AI 能力封装成 REST API实际项目中前端或外部系统不会直接操作ChatClient而是调用你的 REST 接口。一个可用的接口封装需要考虑请求参数、响应格式、异常处理、超时控制和日志记录。RestController RequestMapping(/api/ai) public class AiApiController { private final ChatService chatService; public AiApiController(ChatService chatService) { this.chatService chatService; } PostMapping(/chat) public ChatResponse chat(RequestBody ChatRequest request) { String answer chatService.chat(request.message()); return new ChatResponse(answer); } public record ChatRequest(String message) {} public record ChatResponse(String answer) {} }生产环境至少要补充用户身份标识、会话 ID、API Key 限流、结果缓存、审计日志。大模型接口的返回值可能不稳定响应结构设计要预留扩展字段。7.2 批量任务设计批量任务是 Java AI 应用开发中很常见的需求例如批量给商品生成标题、批量给客户消息打标签、批量总结工单内容。Java 侧可以直接用线程池配合CompletableFuture做并发调用import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class BatchDemo { private final ChatService chatService; private final ExecutorService executor Executors.newFixedThreadPool(5); public BatchDemo(ChatService chatService) { this.chatService chatService; } public ListString batchChat(ListString messages) { ListCompletableFutureString futures messages.stream() .map(message - CompletableFuture.supplyAsync(() - chatService.chat(message), executor)) .toList(); return futures.stream() .map(CompletableFuture::join) .toList(); } }并发数要参考 DeepSeek API 的限流策略不要盲目把线程池调大。更稳妥的做法是引入消息队列把任务先入队再由消费者按固定速率调用模型接口失败任务自动重试。7.3 性能观察如果你调用的是云端 API性能瓶颈主要在模型接口延迟和 Token 消耗而不是本机 CPU。可以重点记录三个指标单次请求耗时、生成 Token 数量、请求失败率。Spring AI 的调用建议捕获日志统计 p50、p95 耗时。如果你在本地用 Ollama 部署模型就要重点观察 GPU 显存占用和内存占用。显存占用取决于模型精度、上下文长度和并发请求数需要以实际部署环境测试为准。降低显存占用的常见手段包括选择量化模型、控制最大上下文 Token 数、限制并发数。无论哪种方式都要关注 Token 成本。RAG 场景中每个问题都会携带检索片段上下文越长 Token 成本越高。建议在系统提示词和向量检索条数之间做平衡避免检索出的相关内容过多导致响应变慢、成本上升。8. 常见问题与排查方法问题现象可能原因排查方式解决方案启动报错API Key 缺失环境变量未注入或配置未读取检查环境变量DEEPSEEK_API_KEY是否设置在 IDE 或运行脚本中配置环境变量不要写死在代码里调用接口返回 401API Key 无效或已过期在 DeepSeek 平台检查 Key 状态重新生成 API Key并检查是否包含多余空格调用接口返回 404base-url 路径不对缺少/v1或拼接错误查看日志中的完整请求 URL调整 base-url 为带/v1的地址再测试接口调通但content为空推理模型把最终答案放在reasoning_content中打印完整响应对象读取响应时兼容reasoning_content和content字段Maven 依赖下载缓慢中央仓库网络不稳定检查 Maven 日志配置阿里云 / 腾讯云 Maven 镜像RAG 回答效果差切块策略不合理或 Embedding 模型与文档语言不匹配查看检索到的片段是否相关调整切块大小换用更适合中文的 Embedding 模型VectorStore 启动失败Redis / PGVector / Milvus 未启动或连接配置错误检查数据库服务状态和连接参数启动对应服务确认 host、port、用户名密码正确批量任务部分失败并发超过模型 API 限流查看失败请求的状态码和错误信息降低并发数加入失败重试和指数退避端口被占用本地 8080 已被其他服务使用netstat/lsof检查端口修改server.port或释放端口Java 内存溢出批量任务队列堆积历史消息过多查看 JVM 内存和 GC 日志限制最大上下文 Token 数及时清理会话内存这里要特别提醒遇到问题时先看日志再改配置不要一上来就怀疑框架。Spring AI 底层请求日志和响应日志会暴露大量线索生产环境建议把 AI 调用日志单独输出到一个文件中方便回溯每一次 Prompt 和工具调用结果。9. 最佳实践与使用建议最后把这套链路实战下来最值得记住的经验写出来按优先级排第一先把最小项目跑通再叠加复杂功能。Spring AI DeepSeek 的对话链路是整个体系的地基。很多人在一开始就同时搞 RAG、Agent、多模型切换结果分不清问题出在哪一层。先让一个curl请求稳定返回再往上加 Tools加 RAG加记忆每一步都有明确验证点。第二把 API Key 和模型参数纳入配置管理体系。不要硬编码在代码里更不要提交到公开仓库。用环境变量、配置中心或密钥管理服务同时把 model、temperature、max-tokens 等参数配置化方便灰度调整。第三RAG 调优必须看检索结果而不是只看最终回答。如果模型答错了先确认检索到的文档片段是否包含正确答案。如果检索结果不对切块、Embedding、重排序都有问题如果检索结果是对的但模型答错了再调提示词或回答约束。第四Tools 的工程边界要清晰。只把读操作和幂等操作直接暴露给模型。写操作、支付、删除等敏感操作必须在工具内做二次校验、人工确认和操作审计。尤其在做 Agent 时模型可能理解错用户意图设计要给自己留后路。第五批量任务必须做好限流和重试。云端模型接口不是无限调用的按 API 文档的限流要求控制 QPS。任务要记录进度失败要重试重试要退避长时间运行要能断点续跑。第六守住合规底线。上传给模型的文档、用户对话内容、企业私有资料都要先确认是否允许发送到外部模型服务。涉及肖像、声音、版权内容的功能必须获得授权。这不是技术问题却是上生产环境之前最重要的问题。如果只做一件事把第 3 章到第 5 章的最小对话、Tools、RAG 三段代码完整跑一遍你就能体会到 Java 做 AI 应用的基础手感。之后再拆 Agent、批量任务、多向量库、混合检索都会顺理成章得多。这套组合值得投入时间它可能是 Java 后端工程师接入 AI 时代成本最低的一条通道。