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企业级硬核干货,欢迎订阅专栏!

相关推荐
yuhuofei20211 小时前
【Python入门】Python中的字典dict
python
吴佳浩1 小时前
AI Infra 的真相:Go 没输,rust也不是取代
后端·rust·go
INFINI Labs1 小时前
Elasticsearch 6/7/8 到 Easysearch 2.x 迁移指南
大数据·elasticsearch·mybatis·向量·snapshot
噢,我明白了1 小时前
QueryWrapper的使用
java
小柒儿3361 小时前
汪进进:深水区里以质立身,做长期价值的践行者
大数据·人工智能
Chase_______1 小时前
【Java基础 | 15】集合框架(中):Set、HashSet、TreeSet 与哈希表
java·windows·散列表
救救孩子把2 小时前
88-机器学习与大模型开发数学教程-8-6 矩阵分解与低秩近似在推荐系统中的应用
人工智能·机器学习·矩阵
_codemonster2 小时前
Git 最常用操作和原理
大数据·git·elasticsearch