Java接入DeepSeek:Spring AI实现RAG与Agent全解析

发布时间:2026/8/30 18:48:53
Java接入DeepSeek:Spring AI实现RAG与Agent全解析 如果你是一名 Java 开发者想做 AI 应用开发但一直觉得自己要先去啃 Python、PyTorch、Transformers 才能入场那么这次的内容可以帮你省掉这条弯路。这次我们来看的是Spring AI 2.0 Langchain4j DeepSeek Tools RAG Agent这套组合核心目标只有一个用 Java 开发 AI 应用并且能落地到生产级别。不是简单调一个聊天接口就结束而是把函数调用、知识库检索、Agent 编排这些真实项目里躲不开的能力全部跑通。先说几个关键结论如果你想用 Java 技术栈接入大模型目前主流选择就两个一个是 Spring 官方出品的Spring AI另一个是专门为 Java 设计的Langchain4j。两者都能对接 DeepSeek都支持 Tools 函数调用、RAG 知识库和 Agent 编排。从材料和对当前生态的观察来看Spring AI 2.0 的优势是深度融入 Spring Boot 生态你有多少 Spring 开发经验迁移成本就有多低Langchain4j 的优势是设计上更贴近 LangChain 的使用习惯功能覆盖面更全而且很多模型适配器可以直接复用。本文会带你完成的内容包括如何用 Spring Boot 快速搭建 DeepSeek 对话服务如何通过 Tools 让模型调用你自己的业务方法如何基于 Embedding 向量库实现 RAG 知识库问答如何把 Tools 和 RAG 组合成一个可运行的 Agent最后再补充批量任务、接口设计、资源占用和常见问题排查。无论你是做企业级应用还是个人项目这套流程都能直接参考。能力项说明技术栈Java 17、Spring Boot 3.x、Spring AI 2.0 / Langchain4j模型接入DeepSeek APIOpenAI 兼容协议核心功能对话补全、Tools 函数调用、RAG 知识库、Agent 编排是否支持本地模型可以但需要按实际模型和框架适配是否支持批量任务支持通过异步任务 并发控制实现启动方式Spring Boot 标准启动mvn spring-boot:run或打包运行接口能力REST API可暴露给外部系统调用适合人群Java 后端开发、微服务架构团队、企业应用开发者1. 核心能力速览在开始写代码之前先把这套组合的能力边界和选择逻辑搞清楚。下面这张表可以帮你在项目立项或技术选型阶段快速判断方向。能力项Spring AI 2.0Langchain4j项目背景Spring 官方项目社区驱动的 Java AI 框架Spring Boot 集成原生集成自动配置提供 Spring Boot Starter对话完成支持 ChatClient 编程模型支持 ChatLanguageModel 抽象函数调用 Tools支持Tool注解支持Tool注解RAG 流程包含 EmbeddingModel、VectorStore 抽象包含 EmbeddingModel、ContentRetriever、VectorStoreDeepSeek 接入通过 OpenAI 兼容协议配置直接支持 OpenAI 兼容协议学习成本低Spring 开发者友好中概念较多参考 LangChain适用场景企业级 Spring Boot 项目需要复杂 AI 编排逻辑的项目关于 Spring AI 2.0 和 Langchain4j 的选择这里给一个更实操的判断标准如果你的项目已经是 Spring Boot 架构团队对 Spring 生态很熟优先选 Spring AI因为它会跟随 Spring Boot 的版本发布节奏走升级链路更顺如果你需要更灵活的 AI 编排能力比如多种模型切换、复杂的 Prompt Template 管理Langchain4j 的设计会更直接。两者并不是互斥的实际上很多项目会同时引入让 Spring AI 负责 Web 层和基础设施Langchain4j 负责 AI 编排层。有一点需要提前说明2026 年的时间节点上Spring AI 2.0 和 Langchain4j 的版本迭代都比较快具体 API 可能在不同版本之间有差异。本文的代码基于常见的稳定写法你实际开发时以官方 GAV 坐标和文档为准。2. 适用场景与使用边界这套技术栈最适合以下三类场景第一类企业知识库问答。公司内部有大量文档、工单、规章制度传统搜索只能做关键词匹配用户真正想要的是“用自然语言问系统直接给答案并附上引用来源”。通过 RAG 流程先把文档切片、向量化存储再在每次提问时检索相关片段交给大模型生成最终答案。这种方式能明显降低幻觉因为模型回答时有了食材而不是凭空发挥。第二类业务系统智能助手。比如 CRM 系统里销售人员想查“上周华东区订单金额TOP10”系统不需要把数据库字段暴露给用户而是把查询能力封装成 Tools让模型理解自然语言后自动调用。这个场景下大模型是“大脑”真正执行数据查询和业务逻辑的是你写的 Java 方法。第三类自动化流程编排。比如客服工单自动分类、合同关键信息提取、多轮对话中自动调用外部 API 查询物流状态。这类任务不是单纯“聊天”而是需要模型在对话过程中主动决策该调用哪个工具、需要什么参数然后根据工具的返回值继续回答。使用边界也必须提前说清楚不要用大模型直接处理核心业务逻辑。模型输出是概率性的同样的输入可能得到不同的输出关键业务判断一定要有规则校验和人工兜底。RAG 不能保证 100% 准确。切片策略、Embedding 模型、检索召回都会影响最终效果上线前必须用测试集评估。涉及企业敏感数据时必须评估合规风险。如果调用外部大模型 API数据会离开你的服务器敏感信息要么脱敏要么选择私有化部署模型。Tools 权限控制要严格。模型可以发起函数调用那么你的函数一定要做入参校验、权限校验、频控防止被恶意 Prompt 注入。3. 环境准备与前置条件在写业务代码之前先把开发环境准备好。以下是一份通用检查清单每一项都建议先确认好再继续。3.1 基础环境JDK 17 及以上。Spring Boot 3.x 要求 JDK 17 起步Spring AI 2.0 也基于这个基线。建议直接用 JDK 21无论是虚拟线程还是后续框架兼容性都会更好。Maven 3.8 或 Gradle 8.x。推荐 Maven和 Spring 官方文档的示例保持一致排查依赖冲突也更方便。Spring Boot 3.3。Spring AI 2.0 需要较新的 Spring Boot 版本具体以你引入的 Spring AI BOM 对应的 Boot 版本为准。DeepSeek API Key。登录 DeepSeek 开放平台创建 API Key注意 Key 不要提交到 Git 仓库。3.2 依赖准备Spring AI 2.0 的依赖管理方式比较特殊。你需要在pom.xml中先引入 BOM再引入具体模块dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.0.0-SNAPSHOT/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement需要特别提醒Spring AI 2.0 目前可能还处于里程碑或快照阶段正式版发布后请使用稳定版本。如果你在 Maven 中央仓库拉不到快照依赖需要额外配置 Spring 的里程碑仓库repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositoriesLangchain4j 的引入相对简单直接用官方 BOM 即可dependencyManagement dependencies dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-bom/artifactId version1.0.0-beta1/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement然后按需引入模块dependencies dependency groupIddev.langchain4j/groupId artifactIdlangchain4j/artifactId /dependency dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-open-ai/artifactId /dependency !-- 如果用 DeepSeek 的 OpenAI 兼容接口还需要引入这个 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-community-deepseek/artifactId /dependency /dependencies3.3 端口与网络Spring Boot 默认端口是8080。如果你本机 8080 被占用可以在application.yml里修改端口server: port: 8088调用 DeepSeek API 时需要注意网络连通性。如果公司网络有防火墙限制需要确认 API 域名可以正常访问。如果你是本地开发直接使用默认配置即可。4. 快速启动Spring Boot 集成 DeepSeek 对话这一节我们用最短路径跑通第一个 DeepSeek 对话接口。无论你后面要加 RAG 还是 Agent第一步都是先确认模型连接正常。4.1 创建 Spring Boot 项目方式有两种一是直接去 Spring Initializr 生成二是用 IDE 创建。依赖只需要Spring Web其他 AI 相关依赖我们手动添加。4.2 配置 application.yml在src/main/resources/application.yml中配置 DeepSeekspring: application: name: spring-ai-demo ai: openai: base-url: https://api.deepseek.com api-key: ${DEEPSEEK_API_KEY} chat: options: model: deepseek-chat temperature: 0.7关键点说明base-url 必须指向 DeepSeek 的 OpenAI 兼容地址Spring AI 会通过这个地址调用/chat/completions接口。api-key 从环境变量读取不要硬编码在配置文件中。model 使用deepseek-chat如果要用推理增强模型可以换为deepseek-reasoner。4.3 编写 ChatClient 调用代码Spring AI 2.0 中最常用的编程模型是ChatClient它是一个链式 API类似 Spring WebFlux 的WebClient风格RestController RequestMapping(/api/chat) public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient builder.build(); } PostMapping public ChatResponse chat(RequestBody ChatRequest request) { String answer chatClient.prompt() .user(request.message()) .call() .content(); return new ChatResponse(answer); } public record ChatRequest(String message) {} public record ChatResponse(String answer) {} }4.4 启动并测试启动 Spring Boot 应用使用 curl 或 Postman 测试curl -X POST http://localhost:8088/api/chat \ -H Content-Type: application/json \ -d {message: 你好请用一句话介绍你自己}预期返回结果是 JSON 格式的模型回复。如果调用成功说明 Spring AI DeepSeek 链路已经打通。如果报错优先检查 API Key 是否正确、base-url 是否拼写错误、网络是否能访问api.deepseek.com。5. Tools 函数调用让模型使用你的业务方法有了基础对话下一步就是Tools 函数调用这是从“聊天机器人”走向“业务助手”的关键一步。模型本身不知道你的订单数据、库存数据、用户数据但它可以在对话中声明“我需要调用某个函数参数是这些”然后由你的 Java 代码真正执行。5.1 定义一个 ToolSpring AI 2.0 中Tools 的定义方式非常简洁只需要在 Spring Bean 的方法上加上Tool注解Component public class OrderTools { Tool(description 查询指定用户最近订单信息参数为用户ID) public String getRecentOrders(String userId) { // 这里可以是真实的数据源查询比如 MySQL、Redis、外部 API return 用户 userId 最近的订单订单号 SO12345金额 599.00 元状态已发货; } Tool(description 查询指定订单号的物流状态) public String getLogisticsInfo(String orderNo) { if (SO12345.equals(orderNo)) { return 订单 orderNo 已到达武汉转运中心; } return 未找到订单 orderNo 的物流信息; } }5.2 让 ChatClient 使用 Tools修改 ChatClient 的构建方式把 Tool 注册进去RestController RequestMapping(/api/chat) public class ChatController { private final ChatClient chatClient; public ChatClientController(ChatClient.Builder builder, OrderTools orderTools) { this.chatClient builder .defaultTools(orderTools) .build(); } }5.3 测试 Tools 调用发起对话{ message: 帮我查一下用户 U10001 最近的订单并且告诉我物流到哪里了 }模型会经历这样的内部过程分析用户意图需要查询订单和物流。决定调用getRecentOrders(U10001)。拿到返回结果后再决定调用getLogisticsInfo(SO12345)。整理所有信息生成最终回复。从开发者角度看你的业务系统能力被“暴露”给了模型但同时又没有直接开放数据库接口模型只是按照它自己的理解发起调用。这也是 Agent 的核心机制之一。5.4 Tools 调用注意事项描述要写清楚。Tool注解上的 description 是模型判断是否调用该函数的重要依据描述越具体模型越不会乱调用。参数校验不能省。从模型传入的参数是不可信的方法内部必须做空值判断和格式校验。执行时间要控制。如果一个 Tool 方法需要几秒甚至更久建议返回一个“任务已提交”的标识通过轮询或回调获取最终结果。6. RAG 知识库给模型加上私有知识对话链路通了Tools 也能调了但如果用户问的是你公司内部的规章制度、产品文档、系统操作手册模型依然回答不了因为它没有这些知识。RAG 的解决思路是不重新训练模型而是把文档切成片段向量化存到向量数据库提问时先检索相关片段再把片段和问题一起发给模型生成答案。6.1 RAG 流程拆解一个最小可用的 RAG 流程包括四个步骤文档加载读取 PDF、Word、TXT、Markdown 等源文件。文档切分把长文档按固定长度或语义边界切成片段避免超出模型上下文限制。向量化存储用 Embedding 模型把文本片段转成向量存到向量数据库。检索增强生成用户提问时把问题也转成向量在向量库里找最相似的片段连同问题一起发给大模型。6.2 引入向量数据库依赖这里以 H2 内置向量数据库为例适合本地开发和功能验证生产环境可以替换为 Milvus、PGVector、Chroma 或 Elasticsearch。dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-vector-store-h2/artifactId /dependency6.3 配置 Embedding 模型Embedding 模型可以单独配置。如果你有本地模型可以通过 Ollama 接入如果直接用 API可以继续使用 DeepSeek 或国内其他兼容 OpenAI Embedding 的模型服务。spring: ai: vectorstore: h2: path: ./data/vec table-name: vector_store6.4 文档处理 Service创建一个文档处理服务把指定目录下的文档加载、切分并写入向量库Service public class RagService { private final VectorStore vectorStore; private final EmbeddingModel embeddingModel; private final TokenTextSplitter textSplitter; public RagService(VectorStore vectorStore, EmbeddingModel embeddingModel) { this.vectorStore vectorStore; this.embeddingModel embeddingModel; this.textSplitter new TokenTextSplitter(); } public void importDocuments(String path) { // 加载目录下所有文档 ListDocument documents FileSystemResourceLoader.builder() .resource(new FileSystemResource(path)) .build() .load(); // 切分文档 ListDocument splitDocuments textSplitter.apply(documents); // 写入向量库 vectorStore.add(splitDocuments); } }6.5 问答接口集成 RAG修改 ChatClient 的构建方式加入检索增强RestController RequestMapping(/api/rag) public class RagController { private final ChatClient chatClient; public RagController(ChatClient.Builder builder, VectorStore vectorStore) { this.chatClient builder .defaultAdvisors(new QuestionAnswerAdvisor(vectorStore)) .build(); } PostMapping(/ask) public String ask(RequestBody ChatRequest request) { return chatClient.prompt() .user(request.message()) .call() .content(); } public record ChatRequest(String message) {} }QuestionAnswerAdvisor是 Spring AI 提供的 RAG 自动装配器它会先检索向量库中与用户问题最相关的片段再把片段作为上下文附加到 Prompt 中最后调用模型生成回答。6.6 RAG 效果验证导入一份测试文档例如product-manual.txt内容包含你的产品功能说明。然后向/api/rag/ask提问{ message: 产品支持哪些导出格式 }如果回答能准确引用文档中的内容说明 RAG 流程已经生效。特别注意文档中是否有“根据提供的资料”这类提示性内容——如果你没有在 Prompt 中设计引用格式模型可能会直接复述文档内容效果验收时需要在构建 Prompt 时加上“请基于资料回答如果资料中没有答案请直接说明”等约束。6.7 RAG 效果优化的几个方向切分策略固定长度切分简单但容易切断语义可以尝试按章节标题、段落边界切分。召回数量可以调整QuestionAnswerAdvisor返回的 topK 数量片段太多会稀释有用信息太少又容易漏掉关键内容。重排序如果召回结果不理想可以引入 Rerank 模型对召回片段做精细排序。混合检索向量检索擅长语义匹配但关键词精确匹配弱可以结合 BM25 等稀疏检索做混合召回。7. Agent 编排把 Tools 和 RAG 组合起来单个 Tools 调用的流程比较固定而 Agent 的核心是让模型自己决定执行顺序。用户可能提出一个需要两步或三步才能完成的任务Agent 会不断循环“分析当前状态 - 决定调用哪个工具 - 观察返回值 - 再分析再调用”直到最终完成任务或达到最大轮次。7.1 一个最小 Agent 场景假设我们构建一个“智能客服 Agent”它具备两个能力通过 Tools 查询订单和物流。通过 RAG 查询产品文档。用户问“帮我查一下订单 SO12345 的物流顺便告诉我这个产品的退货政策”理想状态下模型应该调用getLogisticsInfo(SO12345)得到物流信息。检索 RAG 知识库找到退货政策内容。综合两者回答用户。7.2 通过 ChatClient 实现 Agent在 Spring AI 2.0 中最简单的方式还是通过ChatClient同时注册 Tools 和 AdvisorsService public class CustomerServiceAgent { private final ChatClient chatClient; public CustomerServiceAgent(ChatClient.Builder builder, VectorStore vectorStore, OrderTools orderTools) { this.chatClient builder .defaultSystem(你是智能客服助手需要根据用户问题调用可用工具回答并站在客户角度提供清晰简洁的答案。) .defaultTools(orderTools) .defaultAdvisors(new QuestionAnswerAdvisor(vectorStore)) .build(); } public String chat(String userMessage) { return chatClient.prompt() .user(userMessage) .call() .content(); } }这样一个轻量级 Agent 就成型了。虽然它没有复杂的反思、规划、记忆机制但已经能覆盖相当多的单轮工具调用和知识库问答场景。如果要做更复杂的 Multi-Agent 协作可以让不同 Agent 分角色处理不同任务比如一个 Agent 负责理解用户意图另一个 Agent 负责检索数据再通过一个调度器串联起来。7.3 Agent 开发的关键思路先跑通单工具再组合多工具。不要一上来就设计一个复杂的 Agent 流程先把每个 Tool 单独测好。给模型足够的上下文。System Prompt 中说明工具的使用规则、回答风格、隐私边界能显著减少模型乱调用工具的概率。设置最大调用轮数。防止模型在工具之间无限循环比如 Spring AI 中可以设置maxIterations。保留中间日志。Agent 的每一步决策都需要记录否则出问题根本无法回溯。8. 接口 API 设计与批量任务处理项目落地时AI 能力往往不是一个孤立服务而是被上层业务系统调用。这里给出一个相对完整的接口设计方案以及批量任务的处理思路。8.1 接口设计示例建议把对话、RAG、批量任务分别拆成独立接口模块RestController RequestMapping(/api) public class AiApiController { private final CustomerServiceAgent agent; private final RagService ragService; private final TaskExecutor taskExecutor; public AiApiController(CustomerServiceAgent agent, RagService ragService, TaskExecutor taskExecutor) { this.agent agent; this.ragService ragService; this.taskExecutor taskExecutor; } PostMapping(/chat) public ApiResponse chat(RequestBody ChatRequest request) { return ApiResponse.success(agent.chat(request.message())); } PostMapping(/rag/import) public ApiResponse importDocs(RequestBody ImportRequest request) { ragService.importDocuments(request.path()); return ApiResponse.success(导入完成); } PostMapping(/batch/chat) public ApiResponse batchChat(RequestBody BatchChatRequest request) { // 提交异步批量任务 String taskId UUID.randomUUID().toString(); taskExecutor.execute(() - processBatch(taskId, request.messages())); return ApiResponse.success(任务已提交taskId taskId); } private void processBatch(String taskId, ListString messages) { messages.forEach(message - { try { String answer agent.chat(message); // 写入结果文件或数据库 System.out.println(Task taskId message processed: answer); } catch (Exception e) { // 记录失败日志便于重试 System.err.println(Failed to process message: message , error: e.getMessage()); } }); } public record ChatRequest(String message) {} public record ImportRequest(String path) {} public record BatchChatRequest(ListString messages) {} public record ApiResponseT(int code, String message, T data) { public static T ApiResponseT success(T data) { return new ApiResponse(0, success, data); } } }8.2 批量任务设计要点异步执行 任务 ID。调用方提交任务后立即拿到 taskId不用同步等待结果。逐条记录状态。每条消息的处理结果独立记录成功或失败一目了然。并发控制。如果 DeepSeek API 有 QPS 限制批量任务要加信号量或线程池限制最大并发数避免触发限流。失败重试。对网络超时、5xx 错误可以做指数退避重试但不要无限重试。结果持久化。处理完的数据写入数据库或文件方便后续用 taskId 查询进度和结果。8.3 Python 调用示例批量任务接口也可以直接通过 Python 脚本调用方便测试和对接外部系统import requests import json url http://localhost:8088/api/batch/chat payload { messages: [ 查询用户 U10001 的订单, 退货政策是什么, 订单 SO12345 到哪了 ] } response requests.post(url, jsonpayload, timeout10) print(response.json())9. 资源占用与性能观察虽然 DeepSeek API 方式不需要本地 GPU 显存但 Java 应用本身的资源占用和性能表现仍然需要关注。9.1 本地资源占用观察内存Spring Boot 应用启动后基础内存占用约 300MB-500MB具体取决于你引入的依赖数量和配置。如果加上了向量库和 Embedding 模型内存会明显上升。CPU纯 API 调用应用本身 CPU 占用不高但文档切分、向量化处理阶段会有明显的 CPU 峰值。磁盘向量库文件会占磁盘空间文档越多、切分越细向量库文件越大。9.2 响应时间分析一次对话请求的耗时主要在三段Spring AI 调用 DeepSeek API 的时间通常 1-5 秒取决于问题复杂度和模型负载。RAG 检索时间向量库检索通常在毫秒级但如果向量库数据量很大且没有索引会上升到秒级。Tools 执行时间取决于你的业务方法本身耗时数据库查询、外部 API 调用等都要算进来。9.3 降低响应时间的建议开启 HTTP 连接池Spring Boot 默认的 RestClient 连接池配置可能不够可以调整最大连接数和超时时间。缓存高频问答对完全相同的提问可以直接缓存结果跳过模型调用。异步化非核心链路如果 AI 接口不要求同步返回可以改成异步模式提升接口吞吐量。监控大模型调用成本每次调用都会消耗 token在生产和开发环境都要做好用量统计。10. 常见问题与排查方法下表汇总了这套技术栈最常见的几个问题按问题现象、可能原因、排查方式和解决方案整理问题现象可能原因排查方式解决方案启动后页面打不开端口被占用或服务未启动查看启动日志检查端口占用更换端口或重启服务调用 DeepSeek API 报 401API Key 错误或环境变量未生效检查application.yml和启动参数重新配置DEEPSEEK_API_KEY调用 DeepSeek API 报 404base-url 地址不对检查 base-url 是否包含/v1路径根据模型服务文档调整地址模型返回空内容流式输出或响应解析有问题查看日志中模型原始响应关闭流式输出测试或调整超时时间Spring AI 依赖拉取失败版本或仓库配置不对检查 Maven 仓库配置和依赖坐标加入 Spring 里程碑仓库或使用稳定版Tools 没有被调用Tool 描述不清楚或未注册打印模型完整请求日志完善Tooldescription确认已注册RAG 检索结果不相关切分策略或 Embedding 模型问题单独测试检索结果查看片段内容调整切分策略、换 Embedding 模型批量任务卡住线程池耗尽或 API 限流查看日志中异常堆栈降低并发数增加重试机制内存溢出 OutOfMemoryError文档加载过多或线程数过大堆转储分析查看 GC 日志分批处理文档限制最大并发数10.1 高频错误分析第一个常见问题是 Spring AI 连接 DeepSeek 不输出 content。从实际经验看这类问题通常发生在模型返回内容为空但 HTTP 状态码是 200 的场景。此时不要急着怀疑框架先抓原始响应日志。可以临时把日志级别调到 DEBUG查看模型返回的原始 JSON。如果返回的content字段本身就是空的那么问题在模型服务端如果返回值里finish_reason是content_filter说明触发了内容过滤策略需要修改提示词或调整参数。第二个常见问题是 Lombok 相关报错。项目引入 Spring AI 后如果同时使用 Lombok有一定概率遇到you arent using a compiler supported by lombok的报错。这通常是因为 Lombok 版本和 JDK 版本不兼容。解决方案是升级 Lombok 到最新版本或者在 Maven 编译插件中显式指定编译器版本。第三个常见问题是向量库内存占用异常。如果使用 H2 内存模式存储向量在导入大量文档时会发生OutOfMemoryError: insufficient memory。解决方案是把向量库切换到文件模式或使用独立向量数据库服务。11. 最佳实践与合规建议当你把整套流程跑通之后下面的最佳实践可以直接应用到你自己的项目里。11.1 工程化实践第一次开发先小参数验证。先用最小上下文、最低模型参数把流程跑通确认链路没问题后再加复杂功能。保留一套最小可运行配置。把能跑通的基础版本提交到 Git 单独分支作为回归测试的基线。目录结构按功能拆分controller只做参数校验和响应封装service负责业务逻辑和 AI 编排tools放函数定义config放模型配置和向量库配置。Prompt 和代码分离。不要把超长 System Prompt 写死在代码里放到配置中心或单独的文件方便调优时修改。建立日志体系。每次模型请求、Tool 调用、RAG 检索都要记录入参、出参、耗时这是后续调优和排障的基础。重点关注大模型调用安全。对提交给模型的内容做敏感信息过滤对模型返回的内容做合规审查防止提示词注入和数据泄露。大模型只能作为辅助能力。核心业务流程要保留人工确认机制特别是涉及资金、合同、隐私等敏感操作时必须由人工最终确认。11.2 合规与授权接入 DeepSeek API 时确认企业是否有数据出域合规要求敏感数据不能直接发送到外部模型服务。如果搭建 RAG 知识库文档来源必须确认版权情况不要上传未授权的商业文档、他人隐私信息或受保护内容。涉及用户个人信息处理时要遵守相关隐私保护法律法规做脱敏、加密、匿名化处理。Tools 中的操作权限要收敛不能让模型随意执行高权限操作。生产环境发布 AI 功能前要有内部测试和效果复核流程。技术能力边界之外更重要的永远是合规边界和用户信任边界。12. 总结与下一步这次我们完整跑通了Java Spring AI 2.0 Langchain4j DeepSeek Tools RAG Agent这条技术链路。从最简单的对话接口开始逐步加入函数调用、知识库检索最后组合成 Agent并且把批量任务、接口设计和排查思路也一并覆盖。对于 Java 开发者来说这套组合最值得尝试的点在于你不需要换技术栈不需要学 Python不需要自己部署大模型就能快速构建出带 AI 能力的业务系统。而且 Spring AI 和 Langchain4j 都在快速发展中后续模型能力升级也只需要调整配置和依赖版本。建议你先跑通第一节的对话环境然后做两件事一是给模型加一个自定义工具比如查本地数据库或调第三方接口这是理解 Agent 工作原理最直观的方式二是找一份内部文档做 RAG 导入体验知识库问答和纯模型生成之间的差异。最容易踩的坑其实是配置细节base-url 的路径、环境变量是否生效、依赖版本是否匹配这三点优先排查。后续可以继续扩展的方向包括接入本地模型通过 Ollama 或 llama.cpp实现数据不出域的私有化方案引入 Milvus 等分布式向量数据库支持更大规模知识库使用更复杂的 Multi-Agent 编排框架处理多角色协作任务把 Spring Cloud Gateway 加在前面做 AI 网关统一管理模型路由、限流和成本统计。建议收藏备用等你想给项目接入 AI 能力的时候按这条链路逐步验证即可。