Java接入DeepSeek:Spring AI实现RAG与Agent全解析
2026/8/30 18:48:52 网站建设 项目流程

如果你是一名 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 API(OpenAI 兼容协议)
核心功能对话补全、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、VectorStore
DeepSeek 接入通过 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> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.0.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

需要特别提醒:Spring AI 2.0 目前可能还处于里程碑或快照阶段,正式版发布后请使用稳定版本。如果你在 Maven 中央仓库拉不到快照依赖,需要额外配置 Spring 的里程碑仓库:

<repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>

Langchain4j 的引入相对简单,直接用官方 BOM 即可:

<dependencyManagement> <dependencies> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-bom</artifactId> <version>1.0.0-beta1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>

然后按需引入模块:

<dependencies> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j</artifactId> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> </dependency> <!-- 如果用 DeepSeek 的 OpenAI 兼容接口,还需要引入这个 --> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-community-deepseek</artifactId> </dependency> </dependencies>

3.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中配置 DeepSeek:

spring: 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 定义一个 Tool

Spring 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 最近的订单,并且告诉我物流到哪里了" }

模型会经历这样的内部过程:

  1. 分析用户意图:需要查询订单和物流。
  2. 决定调用getRecentOrders("U10001")
  3. 拿到返回结果后,再决定调用getLogisticsInfo("SO12345")
  4. 整理所有信息,生成最终回复。

从开发者角度看,你的业务系统能力被“暴露”给了模型,但同时又没有直接开放数据库接口,模型只是按照它自己的理解发起调用。这也是 Agent 的核心机制之一。

5.4 Tools 调用注意事项

  • 描述要写清楚@Tool注解上的 description 是模型判断是否调用该函数的重要依据,描述越具体,模型越不会乱调用。
  • 参数校验不能省。从模型传入的参数是不可信的,方法内部必须做空值判断和格式校验。
  • 执行时间要控制。如果一个 Tool 方法需要几秒甚至更久,建议返回一个“任务已提交”的标识,通过轮询或回调获取最终结果。

6. RAG 知识库:给模型加上私有知识

对话链路通了,Tools 也能调了,但如果用户问的是你公司内部的规章制度、产品文档、系统操作手册,模型依然回答不了,因为它没有这些知识。RAG 的解决思路是:不重新训练模型,而是把文档切成片段,向量化存到向量数据库,提问时先检索相关片段,再把片段和问题一起发给模型生成答案。

6.1 RAG 流程拆解

一个最小可用的 RAG 流程包括四个步骤:

  1. 文档加载:读取 PDF、Word、TXT、Markdown 等源文件。
  2. 文档切分:把长文档按固定长度或语义边界切成片段,避免超出模型上下文限制。
  3. 向量化存储:用 Embedding 模型把文本片段转成向量,存到向量数据库。
  4. 检索增强生成:用户提问时,把问题也转成向量,在向量库里找最相似的片段,连同问题一起发给大模型。

6.2 引入向量数据库依赖

这里以 H2 内置向量数据库为例,适合本地开发和功能验证;生产环境可以替换为 Milvus、PGVector、Chroma 或 Elasticsearch。

<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-vector-store-h2</artifactId> </dependency>

6.3 配置 Embedding 模型

Embedding 模型可以单独配置。如果你有本地模型,可以通过 Ollama 接入;如果直接用 API,可以继续使用 DeepSeek 或国内其他兼容 OpenAI Embedding 的模型服务。

spring: ai: vectorstore: h2: path: ./data/vec table-name: vector_store

6.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) { // 加载目录下所有文档 List<Document> documents = FileSystemResourceLoader.builder() .resource(new FileSystemResource(path)) .build() .load(); // 切分文档 List<Document> 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”,它具备两个能力:

  1. 通过 Tools 查询订单和物流。
  2. 通过 RAG 查询产品文档。

用户问“帮我查一下订单 SO12345 的物流,顺便告诉我这个产品的退货政策”,理想状态下模型应该:

  1. 调用getLogisticsInfo("SO12345"),得到物流信息。
  2. 检索 RAG 知识库,找到退货政策内容。
  3. 综合两者回答用户。

7.2 通过 ChatClient 实现 Agent

在 Spring AI 2.0 中,最简单的方式还是通过ChatClient同时注册 Tools 和 Advisors:

@Service 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, List<String> 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(List<String> messages) {} public record ApiResponse<T>(int code, String message, T data) { public static <T> ApiResponse<T> 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, json=payload, timeout=10) print(response.json())

9. 资源占用与性能观察

虽然 DeepSeek API 方式不需要本地 GPU 显存,但 Java 应用本身的资源占用和性能表现仍然需要关注。

9.1 本地资源占用观察

  • 内存:Spring Boot 应用启动后基础内存占用约 300MB-500MB,具体取决于你引入的依赖数量和配置。如果加上了向量库和 Embedding 模型,内存会明显上升。
  • CPU:纯 API 调用应用本身 CPU 占用不高,但文档切分、向量化处理阶段会有明显的 CPU 峰值。
  • 磁盘:向量库文件会占磁盘空间,文档越多、切分越细,向量库文件越大。

9.2 响应时间分析

一次对话请求的耗时主要在三段:

  1. Spring AI 调用 DeepSeek API 的时间:通常 1-5 秒,取决于问题复杂度和模型负载。
  2. RAG 检索时间:向量库检索通常在毫秒级,但如果向量库数据量很大且没有索引,会上升到秒级。
  3. 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_reasoncontent_filter,说明触发了内容过滤策略,需要修改提示词或调整参数。

第二个常见问题是 Lombok 相关报错。项目引入 Spring AI 后,如果同时使用 Lombok,有一定概率遇到you aren't 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 能力的时候,按这条链路逐步验证即可。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询