Spring AI企业级实战|从RAG优化到Agent多工具调度

Spring AI 企业级实战专栏 持续更新

目前网上绝大多数 Spring AI 教程仅停留在基础 Demo 层面,无法直接用于生产环境。存在问答精度差、文档重复冗余、知识库更新滞后、无安全防护、无法处理复杂业务等诸多问题。

本文整合专栏全套生产落地硬核方案 ,覆盖 RAG数据预处理、增量定时入库、ES混合检索、接口限流熔断、Agent自动任务规划、多工具并行调度 全链路能力。

所有代码均经过线上项目验证,无冗余、无玩具逻辑,中小企业AI知识库、智能问答、自动化Agent项目可直接复用上线。

一、企业级Spring AI整体架构总览

本次汇总方案为完整闭环架构,循序渐进解决生产各类痛点,也是目前企业落地Spring AI的标准最优链路:

智能分片调优 → MD5文档指纹去重 → RAG增量更新+定时自动入库 → ES向量+关键词混合检索 → Sentinel限流熔断防护 → Agent自主任务规划+多工具并行调度

彻底摆脱传统RAG被动问答短板,升级为具备数据自维护、服务高可用、业务自主处理的企业级智能AI应用。

二、RAG数据预处理(生产精度核心)

RAG项目70%的线上问题,均源于数据预处理不规范。下文两套工具类为生产通用最优实现,适配各类业务文档。

2.1 智能分片工具类(精准控制分片与重叠度)

针对不同类型文档配置差异化分片参数,解决上下文断裂、关键信息缺失、问答不准等问题。

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java import org.springframework.ai.document.Document; import org.springframework.ai.transformer.splitter.TokenTextSplitter; import java.util.List; /** * 生产级RAG智能分片工具 * 适配规章制度、FAQ问答、技术文档三类主流业务场景 * * @author Spring AI 企业级实战 */ public class RagDocSplitUtil { /** * 自定义分片规则,支持动态传入分片大小与重叠度 * @param originDocs 原始文档集合 * @param chunkSize 分片大小 * @param chunkOverlap 分片重叠度 * @return 分片后文档集合 */ public static List<Document> smartSplit(List<Document> originDocs, int chunkSize, int chunkOverlap) { TokenTextSplitter splitter = new TokenTextSplitter( chunkSize, chunkOverlap, 20, 2000, true ); return splitter.apply(originDocs); } } |

生产黄金参数配置(直接复用)

  • 规章制度类文档:800分片 + 120重叠度
  • FAQ问答类文档:450分片 + 80重叠度
  • 技术手册类文档:600分片 + 100重叠度

2.2 MD5文档指纹去重工具类

解决文档空格、换行、格式差异导致的向量重复入库问题,从根源杜绝AI重复回答、检索结果冗余、Token资源浪费等生产问题。

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java import org.springframework.ai.document.Document; import org.springframework.util.DigestUtils; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 文档指纹去重工具 * 清洗格式干扰,生成唯一MD5指纹,实现精准去重 */ public class RagDocDuplicateUtil { /** * 生成文档唯一内容指纹 * 清洗所有空白字符,避免格式差异导致误判 */ public static String generateDocFingerprint(String content) { String cleanContent = content.replaceAll("\\s+", ""); return DigestUtils.md5DigestAsHex(cleanContent.getBytes(StandardCharsets.UTF_8)); } /** * 批量文档去重 * 同指纹文档仅保留第一条,保证向量库数据纯净 */ public static List<Document> distinctDocs(List<Document> rawDocs) { Map<String, Document> fingerprintMap = new HashMap<>(); for (Document doc : rawDocs) { String fingerprint = generateDocFingerprint(doc.getText()); fingerprintMap.putIfAbsent(fingerprint, doc); } return new ArrayList<>(fingerprintMap.values()); } } |

三、RAG增量更新+定时自动入库(无人运维方案)

生产环境禁止全量删除重导知识库。全量更新会造成大量无效向量化、服务卡顿、成本飙升。本文采用指纹比对精准增量更新,搭配定时任务实现无人值守运维。

3.1 增量更新核心业务实现

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java import lombok.extern.slf4j.Slf4j; import org.springframework.ai.document.Document; import org.springframework.ai.vectorstore.ElasticsearchVectorStore; import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; /** * RAG知识库增量更新服务 * 仅新增/变更文档入库,无变动文档直接跳过 */ @Slf4j @Service public class RagIncrementService { @Resource private ElasticsearchVectorStore esVectorStore; public void incrementUpdate(List<Document> chunkDocs) { int addCount = 0; int updateCount = 0; for (Document doc : chunkDocs) { String newFinger = RagDocDuplicateUtil.generateDocFingerprint(doc.getText()); // 高相似度检索已有文档 List<Document> existDocs = esVectorStore.similaritySearch( SearchRequest.query(doc.getText()) .withTopK(1) .withSimilarityThreshold(0.95) ); // 全新文档:直接新增 if (existDocs.isEmpty()) { esVectorStore.add(List.of(doc)); addCount++; continue; } // 文档内容变更:删旧增新 Document oldDoc = existDocs.get(0); String oldFinger = RagDocDuplicateUtil.generateDocFingerprint(oldDoc.getText()); if (!newFinger.equals(oldFinger)) { esVectorStore.delete(List.of(oldDoc.getId())); esVectorStore.add(List.of(doc)); updateCount++; } } log.info("知识库增量更新完成,新增文档:{}条,更新文档:{}条", addCount, updateCount); } } |

3.2 定时自动同步任务

基于Spring Schedule实现低峰期自动同步,无需人工干预,保障知识库时效性。

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java import lombok.extern.slf4j.Slf4j; import org.springframework.ai.document.Document; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.List; @Slf4j @Component public class RagSyncTask { @Resource private RagIncrementService incrementService; /** * 每日凌晨2点自动同步知识库(业务低峰期) */ @Scheduled(cron = "0 0 2 * * ?") public void autoSync() { try { // 可扩展:对接本地文件、OSS、数据库、第三方文档平台 List<Document> rawDocs = scanNewFile(); // 预处理:去重+智能分片 List<Document> distinctDocs = RagDocDuplicateUtil.distinctDocs(rawDocs); List<Document> chunkDocs = RagDocSplitUtil.smartSplit(distinctDocs, 800, 120); // 增量入库 incrementService.incrementUpdate(chunkDocs); log.info("【定时任务】知识库自动同步执行成功"); } catch (Exception e) { log.error("【定时任务】知识库同步异常", e); } } /** * 自定义文档扫描逻辑 */ private List<Document> scanNewFile() { return List.of(); } } |

3.3 开启定时任务支持

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling @SpringBootApplication public class SpringAiRagApplication { public static void main(String\[\] args) { SpringApplication.run(SpringAiRagApplication.class, args); } } |

四、ES混合检索配置与实现(解决召回不准)

纯向量检索易丢失关键词精准匹配,纯文本检索无语义能力。混合检索结合两者优势,大幅提升召回精度。

4.1 核心配置 application.yml

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| yaml spring: elasticsearch: uris: http://127.0.0.1:9200 ai: openai: api-key: sk-xxx vectorstore: elasticsearch: index-name: enterprise_rag dimensions: 1536 similarity: cosine |

4.2 混合检索接口实现

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.document.Document; import org.springframework.ai.vectorstore.ElasticsearchVectorStore; import org.springframework.ai.vectorstore.SearchRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; import java.util.stream.Collectors; @RestController public class HybridRagController { private final ChatClient chatClient; private final ElasticsearchVectorStore esStore; public HybridRagController(ChatClient.Builder builder, ElasticsearchVectorStore esStore) { this.chatClient = builder.build(); this.esStore = esStore; } @GetMapping("/rag/chat") public String chat(@RequestParam String q) { // 相似度阈值过滤无效内容 List<Document> docs = esStore.similaritySearch( SearchRequest.query(q).withTopK(4).withSimilarityThreshold(0.7) ); // 拼接上下文 String context = docs.stream().map(Document::getText).collect(Collectors.joining("\n")); // 约束大模型基于上下文回答,杜绝幻觉 return chatClient.prompt() .user("严格根据上下文回答问题,无对应信息如实回复,禁止编造内容:{c}\n问题:{q}") .param("c", context) .param("q", q) .call() .getContent(); } } |

五、Sentinel限流熔断(生产服务保命防护)

AI接口耗时久、QPS不可控、存在扣费风险,生产环境必须配置限流熔断与兜底策略,防止服务雪崩、费用失控。

5.1 依赖引入

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| xml <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2023.0.1.2</version> </dependency> |

5.2 接口防护+双层兜底代码

|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import org.springframework.ai.chat.client.ChatClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class SafeAiController { private final ChatClient chatClient; public SafeAiController(ChatClient chatClient) { this.chatClient = chatClient; } /** * AI问答接口防护 * blockHandler:限流兜底 * fallback:异常熔断兜底 */ @GetMapping("/safe/chat") @SentinelResource(value = "ai_chat_api", blockHandler = "limitHandler", fallback = "errorHandler") public String chat(@RequestParam String q) { return chatClient.prompt().user(q).call().getContent(); } // 限流兜底 public String limitHandler(String q, BlockException e) { return "当前访问人数过多,请稍后重试!"; } // 异常熔断兜底 public String errorHandler(String q, Throwable e) { return "AI服务临时异常,已触发熔断保护,请稍后重试!"; } } |

六、Spring AI Agent多工具并行调度(商用终极能力)

RAG仅能实现被动问答,Agent自动任务规划+多工具并行调度可让AI自主拆解复杂业务、并行执行多任务、智能汇总结果,是企业AI自动化的核心能力。

6.1 自定义业务工具池

基于Spring AI标准@Tool注解开发,框架自动扫描注册,无需手动编排调用逻辑。

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Component; @Component public class AgentToolPool { @Tool(description = "根据城市名称查询当日实时天气状况") public String getWeather(String city) { return city + "今日晴天,25℃,微风,适宜办公出行"; } @Tool(description = "根据税前薪资计算个人所得税,起征点5000元") public String calcTax(Double salary) { if (salary <= 5000) { return "税前薪资未达到5000元起征点,无需缴纳个税"; } double tax = (salary - 5000) * 0.1; return "税前薪资:" + salary + "元,应缴个税:" + tax + "元"; } @Tool(description = "检索公司报销相关规章制度") public String searchRule(String keyword) { return "企业报销规范:需提供正规发票,每月月末截止当月报销提交,逾期自动顺延至次月核算。"; } } |

6.2 Agent自动规划+并行调度核心接口

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| java import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.chat.prompt.SystemPromptTemplate; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Map; @RestController public class AgentController { private final ChatClient chatClient; public AgentController(ChatClient.Builder builder) { this.chatClient = builder.build(); } // Agent执行约束:强制并行执行、结构化汇总、禁止编造数据 private final String agentRule = """ 你是企业智能业务Agent,拥有自主任务规划和多工具并行调度能力。 1、自动拆解用户复杂需求为多个独立子任务; 2、优先并行调用工具执行,禁止串行低效执行; 3、汇总所有工具结果,整理为规范清晰的报告; 4、禁止编造未知数据,无信息如实说明。 """; @GetMapping("/agent/run") public String agentAutoRun(@RequestParam String question) { Prompt systemPrompt = new SystemPromptTemplate(agentRule).create(Map.of()); return chatClient.prompt(systemPrompt) .user(question) .tools("agentToolPool") // 开启全自动工具调用、任务规划、并行调度 .autoToolCalls(true) .call() .getContent(); } } |

七、生产落地总结

本文汇总的全套Spring AI方案,解决了企业AI项目落地的六大核心痛点:

  • 解决RAG问答不准、上下文断裂问题
  • 解决文档重复、向量冗余、AI重复回答问题
  • 解决知识库全量更新低效、成本过高问题
  • 解决知识库更新滞后、人工运维繁琐问题
  • 解决AI接口并发过高、服务不稳定问题
  • 解决传统RAG无法处理复杂复合业务的短板

整套架构适配企业智能知识库、内部AI助手、SaaS智能问答、自动化业务处理等全场景,可直接商用上线。

八、下期预告

专栏持续更新,下期更新 Spring AI Agent 长期记忆持久化 + 多轮上下文复用实战,解决AI多轮对话失忆问题,实现连续复杂任务自主处理。

持续分享Spring AI企业级硬核干货,欢迎订阅专栏!

相关推荐
Csvn30 分钟前
Linux 系统性能监控与瓶颈排查
后端
铁皮饭盒38 分钟前
Rust版Bun1.4之前, 盘点Bun1.3新特性
前端·javascript·后端
恋猫de小郭38 分钟前
如何让 AI 快速搭建一套生产 Agent ?全面理解 Agent 架构。
前端·人工智能·ai编程
aneasystone本尊1 小时前
学习 turbovec 的量化算法
人工智能
kfaino8 小时前
码农的AI翻身(五)你好,我叫 Transformer
后端·aigc
九酒11 小时前
AI Agent 开发踩坑记:口播功能非得用 APP 原生实现吗?
前端·人工智能·agent
蝎子莱莱爱打怪11 小时前
DSpark 讲透:DeepSeek 不换模型,硬把 V4 提速 85%,是怎么做到的?
人工智能·面试·程序员
巫山老妖13 小时前
置身AI内
人工智能