Spring AI入门与实战:集成Tools、RAG与Agent构建Java大模型应用

📅 发布时间:2026/8/30 11:35:26
Spring AI入门与实战:集成Tools、RAG与Agent构建Java大模型应用
先别急着去背一堆零散的 API 文档。这次我们来看的是目前 Java 生态里最值得关注的一条 AI 开发主线Spring AI 入门与实战同时把 Langchain4j、Tools、RAG、Agent 这四块全部串起来。很多做 Java 后端的朋友已经发现了现在做 AI 应用Python 教程铺天盖地但到了 Java 这边资料要么太碎要么直接甩给你一个看不懂的 Demo。这篇文章要做的就是把 Spring AI 从 0 到 1 讲清楚重点是“能不能用”“怎么用”“跑到什么程度算通”。先说结论Spring AI 不是一个花架子框架它是 Spring 官方出的 AI 应用开发抽象层定位很像当年 Spring Boot 统一 MVC 一样目标是统一 Java 接入大模型的方式。它支持 OpenAI、通义千问、DeepSeek、Ollama 本地模型等主流模型来源也提供了 RAG 所需的 Embedding、向量数据库、文档加载、切块等全套组件更高层的 Agent 编排能力也正在快速补齐。Langchain4j 则是另一个思路很接近的 Java 库两者不完全冲突但如果你只选一条路建议先把 Spring AI 搞透。这篇文章会围绕一条完整的实操链路展开先搭一个能跑通的 Spring AI 工程再依次打通基础对话、Tools 函数调用、RAG 知识库问答、Agent 多轮任务编排最后再补上结构化输出、批量任务、接口封装、资源占用和常见踩坑。整个过程中会给出可以复制的 Java 代码、Maven 依赖、配置文件和调用示例带你真正落地而不是停留在概念层面。1. 核心能力速览在做任何代码操作之前先把 Spring AI 和 Langchain4j 这套组合的能力边界看清楚这样你才知道该在什么场景下用它而不是人云亦云。能力项说明项目定位Spring 官方提供的 AI 应用开发框架抽象大模型接入、提示词模板、RAG、Agent 等能力当前配套Spring AI Langchain4j Spring AI Alibaba可对接 OpenAI、通义千问、DeepSeek、Ollama 等主要功能对话补全、流式输出、结构化输出、Tools 函数调用、文档加载、Embedding、向量检索、RAG 知识库、多智能体编排核心优势Java 技术栈统一、Spring Boot 原生集成、配置驱动、模块化设计硬件要求使用云端大模型 API 时无 GPU 要求使用 Ollama 等本地模型时建议 16G 内存以上显存按模型大小评估支持平台跨平台只要能跑 JDK 17 即可启动方式Spring Boot 标准启动mvn spring-boot:run 或打包后 java -jar 运行是否支持 API支持Spring Boot 应用本身就是 Web 服务可自行暴露 REST 接口是否支持批量任务支持底层是 Java 代码可以随意写循环、线程池、消息队列做批量处理适合场景Java 后端接入 AI 能力、企业内部知识库问答、Agent 工具调用、自动化流程编排需要注意一点Spring AI 的模块和版本演进非常快不同版本之间的 API 可能有差异。更稳妥的做法是锁定一个稳定版本比如当前常见的 1.0.x 系列或者直接使用 Spring AI Alibaba 的 BOM 来统一版本管理。后面我会给你一套可以直接跑的依赖组合。2. 适用场景与使用边界Spring AI 适合谁来用核心答案是已经有 Java 后端工程想把 AI 能力嵌进现有业务系统的团队。它不是给你做模型训练的也不是图形化拖拽平台它解决的问题是“Java 代码如何标准化地调用大模型能力、如何把业务数据喂给模型、如何让模型帮你执行任务”。典型场景包括企业内部知识库问答把公司文档、技术规范、产品手册加载进来实现基于私有知识的问答系统。智能客服工单处理接入对话模型自动分类、摘要、回复草稿生成。业务助手 Agent让模型根据用户需求调用查询订单、查库存、订会议室等业务工具。文档自动化处理批量解析 PDF、Word、Excel提取结构化信息后持久化。代码辅助工具结合 RAG 让模型基于团队内部代码规范回答问题。但也要说清楚边界。Spring AI 本身不解决模型质量问题模型回答不准确你需要从提示词、知识库切块、检索策略和模型选型上找原因。它也不擅长做复杂的 AI 训练、微调这部分需要走到 Python 生态或者专门的训练平台。还有一点是“实时性”如果模型 API 不稳定你的应用需要有超时、重试和降级方案不能把 AI 服务当成普通数据库来依赖。关于合规和边界所有通过 API 发送给云厂商模型的数据都要先确认是否允许外发私有化部署优先考虑 Ollama 或私有网关涉及用户隐私、人脸、声音、版权材料时必须确认授权后才能使用。RAG 知识库里的文档也不能直接拿未授权内容来“喂”模型商用前一定要核对数据来源合法性。3. 环境准备与前置条件在开始写代码之前先检查环境。Spring AI 对 JDK 版本有明确要求JDK 17 是最低门槛建议直接用 JDK 21。构建工具选 Maven 或 Gradle 都行下面统一用 Maven 做示例。环境项推荐版本/配置JDK17 或 21Maven3.8Spring Boot3.3.x 或 3.4.x需与 Spring AI 版本兼容IDEIDEA 或 Eclipse 均可建议 IDEA 社区版/旗舰版API Key使用云模型时准备 OpenAI / 通义千问 / DeepSeek 的 API Key本地模型可选Ollama按需拉取 qwen2.5、llama3、embedding 模型向量数据库可选Milvus、Pgvector、Redis、Chroma 等按需选择这里有一个容易混淆的点Spring AI 有独立版本号Spring Boot 也有独立版本号两者不能随便混用。推荐的做法是直接使用 Spring AI Alibaba 的 BOM 或者 Spring AI 官方 BOM由 BOM 统一管理版本避免依赖冲突。后面我会给出具体的 dependencyManagement 配置。如果你打算在本地跑模型建议内存 16G 以上磁盘预留 20G 以上。Ollama 拉取的模型文件都存在本地尤其是 7B 以上的模型对内存和磁盘都有要求。用云端 API 则没有这些硬件压力只需要保证服务器能访问对应的 API 网关即可。4. 初始化 Spring AI 工程这一节直接开始建工程。先用 Spring Initializr 或者 IDEA 内置的 Spring Boot 创建向导建一个基础工程。如果你用的是 IDEA直接 New Project - Spring Initializr选择 Java 17 或 21依赖先只选 Spring Web 和 Lombok可选。创建好之后在 pom.xml 中加入 Spring AI 相关依赖。这里建议使用 Spring AI Alibaba 的 BOM因为它的版本兼容性维护得比较好而且对国内模型通义千问、DeepSeek支持更友好。parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.3.5/version relativePath/ /parent properties java.version17/java.version spring-ai.version1.0.0/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 dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-bom/artifactId version1.0.0/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency !-- 使用通义千问时替换为 spring-ai-alibaba-starter -- !-- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter/artifactId /dependency -- /dependencies注意Spring AI 的版本更新很快上面的版本号只是演示。实际项目里建议以官方文档或者阿里云 OpenSearch 页面上展示的最新稳定版本为准。依赖配好之后配置 application.yml。如果你使用 OpenAI 兼容接口spring: application: name: spring-ai-demo ai: openai: base-url: https://api.openai.com api-key: ${OPENAI_API_KEY} chat: options: model: gpt-4o-mini temperature: 0.7如果你在国内使用通义千问可以用 DashScope 标准接口spring: ai: dashscope: api-key: ${DASHSCOPE_API_KEY} chat: options: model: qwen-plus如果你手头没有云 API Key想先零成本跑通可以用 Ollama 加载本地模型spring: ai: ollama: base-url: http://localhost:11434 chat: options: model: qwen2.5:7b启动方式就是标准的 Spring Boot 启动。第一次跑的时候重点看日志里是否有模型相关的 Bean 初始化成功以及是否出现连接模型服务的网络错误。下面给一个最简单的 Controller 测试。RestController RequestMapping(/api/chat) public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient.Builder builder) { this.chatClient builder.build(); } GetMapping(/simple) public String simple(RequestParam String message) { return chatClient.prompt(message).call().content(); } }这里用到了 Spring AI 1.0 里推荐的 ChatClient 编程模型。它比早期的 ChatModel 更顺手支持链式调用、默认系统提示词、结构化输出等能力。启动后访问curl http://localhost:8080/api/chat/simple?message你好请用一句话介绍自己如果返回了一段正常的模型回复说明基础链路已经通了。这里要先确认一件事模型能不能通取决于网络和 API Key。如果报 401检查 Key如果报超时检查网络和 base-url。5. Tools 函数调用让大模型学会“动手”对话通了之后下一步就是 Tools。Tools 是 Agent 的底层能力它的作用是让模型在对话过程中发现“单靠模型知识回答不了的问题”时主动调用你注册好的 Java 方法。比如用户问“查询一下订单 10086 的状态”模型本身不知道订单数据但它可以决定调用一个名为 queryOrder 的工具然后把工具返回结果组织成自然语言回复。Spring AI 里实现 Tools 非常直观只需要在 Bean 方法上标注 Tool 注解。以订单查询为例Component public class OrderTools { Tool(name queryOrderStatus, description 根据订单号查询订单当前状态) public String queryOrderStatus(String orderId) { // 实际项目中这里会查数据库或调用订单服务 if (10086.equals(orderId)) { return 订单 10086 已发货预计 3 天内送达; } return 未找到订单 orderId; } }然后在构建 ChatClient 的时候把工具注册进去RestController RequestMapping(/api/tools) public class ToolsController { private final ChatClient chatClient; public ToolsController(ChatClient.Builder builder, OrderTools orderTools) { this.chatClient builder .defaultTools(orderTools) .build(); } GetMapping(/order) public String queryOrder(RequestParam String orderId) { return chatClient.prompt(查询订单 orderId 的状态并用自然语言回复我) .call() .content(); } }启动后访问curl http://localhost:8080/api/tools/order?orderId10086如果模型返回“订单已发货预计3天内送达”说明 Tools 生效了。验证的关键点在于模型是不是真的走了一次工具调用而不是靠猜。要判断这一点可以在日志里打开 Spring AI 的调试级别观察模型请求里是否出现了 tool_calls 相关字段。用 Tools 时有几个细节要注意。第一Tool 的 description 一定要写得清楚模型是靠描述来决定是否调用这个工具的。第二方法参数不要用复杂对象能拆成 String 或基本类型最好模型生成 JSON 参数时会更容易命中。第三工具方法要快不要让模型在等待中反复超时如果工具内部有慢操作建议加缓存或异步处理。Langchain4j 里也有对应的 Tool 注解用法和 Spring AI 很像。如果团队里已经在用 Langchain4j也可以直接迁移。两者在 Tools 层面的设计目标是一致的把 Java 方法暴露给模型。6. RAG 知识库实战从文档到可问答的知识库RAG 是当前企业落地 AI 最实在的方向。核心思路很简单模型不知道的知识我们先从自己的文档库里检索出来再拼到提示词里让模型基于这些材料回答。这样既不需要微调又能保证回答来自可控的文档来源。Spring AI 的 RAG 链路包含五个环节文档加载 - 文档切块 - Embedding 向量化 - 向量存储 - 检索增强生成。先看文档加载和切块。以读取 resources 下的 markdown 文件为例Component public class RagService { private final VectorStore vectorStore; public RagService(VectorStore vectorStore) { this.vectorStore vectorStore; } public void loadDocuments() { Resource resource new ClassPathResource(docs/help.md); var reader new MarkdownDocumentReader(); var documents reader.read(resource); // 切块策略每 500 个 token 一块重叠 50 个 token var tokenTextSplitter new TokenTextSplitter(500, 100, 50, true); var chunks tokenTextSplitter.apply(documents); // 写入向量数据库 vectorStore.write(chunks); } }切块策略对 RAG 效果影响非常大。切得太小语义不全切得太大检索噪声高。500 token 左右、带少量重叠是一个比较通用的起步配置。实际项目中建议准备几组文档做对比测试评估每组切块参数的检索命中率。Embedding 的配置也非常重要。Spring AI 默认会使用模型厂商自带的 Embedding 模型。如果你用的是本地 Ollama 模型可以配一个本地 embedding 模型spring: ai: ollama: embedding: options: model: nomic-embed-text向量数据库这边Spring AI 支持 Milvus、Pgvector、Redis、Chroma 等。如果你已经有 PostgreSQL 数据库用 Pgvector 是最省事的方案不需要额外维护一个专用向量库。Milvus 更适合大规模向量检索的场景。这里以 Pgvector 为例dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-pgvector-store-spring-boot-starter/artifactId /dependencyspring: ai: vectorstore: pgvector: index-type: HNSW distance-type: COSINE_DISTANCE dimensions: 1536注意 dimensions 必须和 Embedding 模型输出的向量维度一致。如果你使用 OpenAI 的 text-embedding-3-small维度是 1536使用通义千问 embedding 模型维度取决于具体模型常见是 1024。这个值配错了写入向量库时会直接报错。文档入库之后就可以做检索问答了RestController RequestMapping(/api/rag) public class RagController { private final ChatClient chatClient; public RagController(ChatClient.Builder builder, VectorStore vectorStore) { this.chatClient builder .defaultSystemPrompt( 你是一个企业内部知识库助手。 请只根据提供的文档内容回答问题。 如果文档中没有相关信息请明确回答“文档中没有找到相关信息”。 不要编造内容。 ) .build(); this.vectorStore vectorStore; } GetMapping(/ask) public String ask(RequestParam String question) { // 先检索相关文档片段 var searchRequest SearchRequest.builder() .query(question) .topK(5) .build(); var similarDocs vectorStore.similaritySearch(searchRequest); // 拼装到提示词里 String context similarDocs.stream() .map(doc - doc.getContent()) .reduce(, (a, b) - a \n---\n b); return chatClient.prompt() .system(根据以下文档内容回答问题\n context) .user(question) .call() .content(); } }关于 RAG 查询还有一个进阶操作叫做混合检索加重排。向量检索擅长语义匹配但对关键词精确匹配可能不够灵敏。Langchain4j 和 Spring AI Alibaba 都提供了混合检索相关的示例可以在向量检索之外叠加 BM25 或全文检索再用重排模型把两个结果集合并排序。这样做的好处是用户问“2024年Q3营收”这种带精确数字的问题时关键词命中不会被向量相似度淹没。RAG 最常见的坑有三个一是文档没切好一个大文档被切得支离破碎检索时找不到关键段落二是 embedding 模型维度配置错误数据写不进向量库三是测试时只问一个问题就说“效果不行”没有建立评估集。正确的做法是准备 20 到 50 个真实业务问题每个问题标注正确答案所属文档批量验证命中率。7. Agent 开发把 Tools 和 RAG 组合成自动化流程Tools 和 RAG 单独都能用但 Agent 的意义在于把多个工具、多轮检索、决策过程串成一个自主流程。简单说Agent 是一个“会自己决定下一步干什么”的模型循环它接收用户目标判断需要调用哪些工具拿到工具结果后再判断是否完成目标没完成就继续下一步。Spring AI 现在对 Agent 的抽象还在发展中但结合 ChatClient、Tools、RAG已经可以搭建出实用的小 Agent。更细的智能体编排可以借助 Langchain4j 的 AiServices它提供了比较成熟的对象化 Agent 封装。以 Langchain4j 为例一个典型 Agent 长这样public interface Assistant { String chat(String userMessage); } public class AssistantAgent { private final Assistant assistant; public AssistantAgent() { this.assistant AiServices.builder(Assistant.class) .chatLanguageModel(OpenAiChatModel.builder() .apiKey(System.getenv(OPENAI_API_KEY)) .modelName(gpt-4o-mini) .build()) .tools(new OrderTools(), new UserTools(), new CalendarTools()) .retriever(contentRetriever) .build(); } }这个接口只定义一个方法AiServices 会在运行时自动生成实现类把 Tools、Retriever 都编排进去。当用户提的问题需要查订单时模型会调用订单工具需要查知识库时会触发检索器。整个过程对调用方来说就是一个普通的 Java 接口。如果你想控制 Agent 的流程也可以手动编排。下面是一个简化的“计划-执行-检查”循环public class SimpleAgent { private final ChatClient chatClient; private final ListTool tools; public String execute(String userGoal) { String systemPrompt 你是一个任务规划助手。你的目标是用可用工具完成用户任务。 每次回复必须给出 1. 思考过程 2. 要调用的工具和参数 3. 如果任务已结束输出最终结果 可用工具%s .formatted(toolDescriptions()); String response chatClient.prompt() .system(systemPrompt) .user(userGoal) .call() .content(); // 实际项目中需要解析 response 中是否包含工具调用 // 如果有执行工具再把结果拼回上下文继续调用模型。 return response; } }这里演示的是原理真实生产系统里建议直接用框架封装好的 Tool 和 Agent 编排能力不要自己解析 JSON tool_calls除非你有非常特殊的流程需求。Agent 场景下最容易出问题的是“循环失控”。模型可能反复调用同一个工具或者在一个错误结果上无限循环。生产环境必须设置最大迭代次数比如 5 轮或 10 轮超出就强制终止并返回超时信息。同时要给每个 Agent 任务分配唯一链路 ID方便日志追踪和问题排查。8. 结构化输出让模型返回合法 JSON在很多业务场景里你不需要模型返回自然语言而是希望它直接给你一个结构化的 JSON 对象。Spring AI 对这一块支持得比较完善。以解析用户输入的报销单信息为例public record ExpenseInfo( String date, String merchant, BigDecimal amount, String category, String description ) {}调用时使用 ChatClient 的实体方法ExpenseInfo expense chatClient.prompt() .system(从用户输入中提取报销信息如果某项缺失返回 null。) .user(我昨天在星巴克消费了 58 元买了咖啡。) .call() .entity(ExpenseInfo.class);模型返回结果后Spring AI 会自动把 JSON 解析成 ExpenseInfo 对象。如果模型返回的 JSON 不符合 Java record 字段会抛解析异常你需要在代码里做兜底。try { ExpenseInfo expense chatClient.prompt() .user(input) .call() .entity(ExpenseInfo.class); return expense; } catch (Exception e) { log.warn(结构化输出解析失败原始输入: {}, input, e); return null; }结构化输出的运用场景非常多信息抽取、意图识别、SQL 生成、数据分析、多步 Agent 的状态传递等。它也是把 AI 能力嵌入后端工作流的关键一步因为 Java 代码最擅长的就是处理类型安全的对象而不是字符串拼接。Langchain4j 里也有类似功能它支持把接口方法返回值直接映射成实体类比如在 Assistant 接口里定义ExpenseInfo extractExpense(String userInput)AiServices 会负责解析。9. 接口 API 与批量任务Spring AI 项目本身是 Spring Boot 应用天然可以对外暴露 REST 接口。上面几节的 Controller 已经是最基础的 API 示例。实际项目中你需要考虑接口鉴权、限流、超时、异常处理和批量任务设计。下面设计一个完整的 API 封装示例RestController RequestMapping(/api/ai) public class AiApiController { private final ChatClient chatClient; private final ObjectMapper objectMapper; PostMapping(/chat) public ResponseEntityChatResponse chat(RequestBody ChatRequest request) { String content chatClient.prompt() .system(request.systemPrompt()) .user(request.message()) .call() .content(); ChatResponse response new ChatResponse( request.messageId(), content, Instant.now().toString() ); return ResponseEntity.ok(response); } }批量任务方面可以直接用 Java 的线程池或者 Spring 的异步能力。假设你要批量处理 1 万个用户的文本分类Service public class BatchClassifyService { private final ChatClient chatClient; private final ExecutorService executor Executors.newFixedThreadPool(10); public ListClassifyResult batchClassify(ListString texts) { ListFutureClassifyResult futures texts.stream() .map(text - executor.submit(() - classify(text))) .toList(); ListClassifyResult results new ArrayList(); for (FutureClassifyResult future : futures) { try { results.add(future.get(30, TimeUnit.SECONDS)); } catch (Exception e) { // 单条失败不影响整体 results.add(new ClassifyResult(ERROR, e.getMessage())); } } return results; } }批量任务的核心原则是单条失败不要拖垮整个批次每条任务要有超时控制建议给每条任务分配唯一 ID记录开始时间、结束时间、模型返回内容、异常信息失败后要支持重试重试次数建议 2 到 3 次且要有退避策略。对于超大批量任务不建议直接在 Controller 里同步执行而是把任务投递到消息队列或数据库任务表由后台 worker 消费。这样接口可以快速返回任务 ID前端轮询任务状态用户体验更好。10. 资源占用与性能观察Spring AI 的资源占用分两个层面应用自身资源占用和模型推理资源占用。使用云端模型 API 时Spring Boot 应用本身只需要常规内存一般 512MB 到 1GB 堆内存就够用。真正消耗资源的是高并发请求因为每个请求都在等待模型返回HTTP 连接和线程池可能被打满。要重点观察 Tomcat 线程池使用率、HttpClient 连接池状态和接口耗时分布。使用本地 Ollama 模型时资源瓶颈主要在模型推理侧。Ollama 进程会加载模型进内存7B 模型量化版通常需要 6G 到 8G 内存13B 模型需要 14G 左右32B 模型不建议 32G 内存以下的机器尝试。显存需求同样取决于模型大小和量化精度。下面是本地部署时的观察要点观察项方法模型进程内存通过ollama ps查看当前加载的模型及内存占用推理响应速度用 curl 统计接口首 token 延迟和总延迟并发能力用压测工具模拟并发请求观察排队时间失败率统计超时、连接断开、模型加载失败的比例磁盘占用检查 Ollama 模型存储目录确认模型文件大小如果本地模型响应太慢优先考虑几个手段换更小的量化版模型、减少上下文长度、降低并发数、使用 GPU 加速。Spring AI 侧还可以设置超时参数避免接口被慢模型拖死。spring: ai: openai: chat: options: temperature: 0.7 client: connect-timeout: 10s read-timeout: 60s日志方面把 Spring AI 的日志级别临时调到 DEBUG可以看到完整的请求和响应体对排查非常有帮助logging: level: org.springframework.ai: DEBUG生产环境不要开 DEBUG否则日志量会非常大而且可能把 Prompt 中的业务数据打到日志里存在数据泄露风险。更推荐的方式是只记录请求 ID、耗时、token 用量和错误信息不记录完整消息内容。11. 常见问题与排查方法实践过程中几乎一定会遇到下面这些问题列成表格方便对照排查。问题现象可能原因排查方式解决方案启动报依赖冲突Spring AI 版本与 Spring Boot 版本不兼容看 Maven 依赖树定位冲突 jar使用官方 BOM 统一版本升级或降级 Spring Boot调用模型报 401API Key 不对或未设置检查环境变量和配置从配置中心或环境变量读取正确的 Key调用模型报超时网络不通或模型服务端响应慢用 curl 直接测试模型 API 连通性检查网络代理调大 read-timeoutTools 没有生效Tool 注解扫描不到未注册到 ChatClient看 Bean 是否加载看请求日志里是否出现 tools 字段确认 Tools 类是否为 Spring BeandefaultTools 是否传入了对应实例RAG 检索结果为空切块后文档未写入向量库或 embedding 维度配置错误检查向量库中是否有数据similiaritySearch 是否返回空重新调用 loadDocuments检查写入日志结构化输出解析异常模型返回 JSON 与 target 类型不匹配打印原始返回内容检查字段名和类型加强系统提示词约束增加兜底逻辑批量任务部分失败单条超时或模型限流查看任务失败日志和状态码增加超时、重试和退避失败任务单独补偿本地模型响应很慢模型太大或内存不足观察 ollama ps 和 CPU/内存换更小的模型升级硬件日志打印完整消息有数据泄露风险日志级别 DEBUG检查日志配置生产环境使用 WARN只记录关键元信息端口被占用已有服务占用 8080lsof -i:8080或netstat -ano修改server.port或停掉旧进程还有一个很隐蔽的问题模型 API 限流。云厂商通常会对单账号并发数做限制批量任务跑得快不一定更好反而容易触发 429 限流。建议在批量任务里加一个简单的速率控制比如每请求间隔 100 毫秒或者使用令牌桶限流。12. 最佳实践与使用建议最后整理几条实战经验按优先级排开。第一先跑通最小案例再展开。不要一开始就搭 RAG 加 Milvus 加 Agent 全家桶。先用一个 ChatClient 跑通对话再逐步加 Tools、加 RAG、加 Agent 编排。每一层都验证通过后再往上叠。第二Prompt 和切块参数要版本化。Prompt 文本不要硬编码在代码里放到配置中心或模板文件里方便调整和对比。RAG 切块参数切块大小、重叠大小、topK建议做成配置项方便做效果对比实验。第三建立评估集。RAG 和 Agent 效果不能靠感觉准备一批真实问题标注期望答案或期望命中的文档每次改动后跑一遍评估集。没有评估集你根本不知道改切块参数是变好还是变坏。第四管控成本。每次调用都涉及 token 费用。在日志里记录 input token 和 output token建立监控。对长上下文场景控制发送给模型的内容长度不要无脑把整个知识库拼进 Prompt。第五做好降级方案。AI 服务不可用是常态接口层要捕获异常返回降级提示比如“AI 服务暂时不可用请稍后再试”。不要把模型错误直接抛给前端。第六数据合规。所有发送给模型的数据都要做合规评估。涉及个人隐私、商业机密、未公开业务数据时优先使用私有化部署方案比如 Ollama 或企业内网模型网关。API Key 不要在前后端代码里明文暴露也不要提交到 Git 仓库。第七注意模型版本变化。云厂商会不定期下线或升级模型版本API 返回格式也可能调整。上线前锁定模型版本关注厂商公告。Spring AI 版本升级时重点测试 ChatClient、Tools、VectorStore 三个模块是否兼容。13. 总结与下一步Spring AI 这套链路真正值得投入的原因是它让 Java 后端开发者从模型调用的繁琐细节中解放出来把注意力放回业务流程本身。现在通过一个 Spring Boot 工程你就能完成对话、函数调用、知识库问答和 Agent 任务编排这在两年前是不可想象的。如果你今天只做一件事建议先跑通 ChatClient Tools 这个组合。这是所有 Agent 功能的地基而且验证成本最低。跑通之后再做 RAG你会发现知识库问答的难点根本不在代码而是在文档切块和检索质量上。最后再尝试 Agent 编排把 Tools、RAG、多轮调用串成一个完整的业务助手。最容易踩的坑依然是版本兼容问题。Spring AI 和 Spring Boot 的版本对应关系、Spring AI Alibaba 的开源版本差异、向量数据库驱动的兼容性这些都会在集成时消耗不少时间。建议新建项目时直接参考官方示例仓库的版本组合不要凭记忆乱配。接下来的扩展方向可以看这几个一是 Spring AI Alibaba 生态和阿里云百炼、通义千问结合得更紧密适合国内业务落地二是 Langchain4j 的对象化 Agent 编程模型如果你熟悉接口驱动设计上手会很快三是 Agentic RAG让 Agent 在回答过程中按需多次检索、追问和修正比传统单轮 RAG 更适合复杂问题。掌握了本文这条主线后续学习这些方向都不是从零开始而是能力叠加。