Spring Boot 4.0 整合 Spring AI 2.0:企业知识库与 AI 客服
前言
把用户问题直接发给大模型,会得到语言流畅但无法核验的回答。企业客服更需要三件事:先找企业内部资料,只让模型基于资料回答,最后把引用来源返回给用户。
本章接入 Spring AI 2.0 ChatClient,完成检索、Prompt 拼接、模型调用和降级。没有 API Key 时使用确定性演示模型,仍然可以验证完整链路。
读者需要完成前面的 Web API 与 Spring AI 基础。源码位于 dvsusan/spring-boot4-demo。
最终结果
新增接口:
POST /api/v1/chapter7/ai/chat请求:
{
"question": "订单签收后怎么申请退款?"
}回答包含 answer、sources 和 aiAnswered。没有匹配资料时不允许模型猜答案,直接返回“知识库没有足够信息”。

图 1:知识检索先于模型调用,模型只获得受限上下文,响应保留可核验来源。
第 1 步:引入 Spring AI 2.0
根 pom.xml 导入 BOM:
<dependencyManagement>
<dependencies>
<!-- 统一管理 Spring AI ChatClient、模型和向量组件版本。 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>Web 模块添加:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-client-chat</artifactId>
</dependency>项目默认只引入 ChatClient 和演示模型,保证无模型密钥也能启动。需要调用真实 OpenAI 兼容接口时,再追加厂商 Starter:
<!-- 仅配置真实模型时加入,避免默认应用被未使用的模型自动配置影响。 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>项目固定 Spring AI 2.0.0。
第 2 步:配置演示与远程模式
demo:
chapter7:
ai:
# 没有密钥时使用确定性的 DemoChatModel。
remote-enabled: ${DEMO_AI_REMOTE_ENABLED:false}
model: ${DEMO_AI_MODEL:qwen-plus}添加真实模型 Starter 后,再配置供应商:
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY}
base-url: ${OPENAI_BASE_URL:https://api.openai.com}
chat:
options:
model: ${DEMO_AI_MODEL:gpt-4.1-mini}真实调用前必须注入密钥,并按供应商修改 Base URL 和模型名。不要把密钥提交到 Git。
第 3 步:先检索企业知识
教学版 KnowledgeRetriever 按关键词打分,返回最多两篇资料:
public List<KnowledgeDocument> search(String question) {
String normalized = question == null ? "" : question.trim();
return documents.stream()
.map(document -> new ScoredDocument(
document,
score(document, normalized)
))
.filter(scored -> scored.score() > 0)
.sorted(Comparator
.comparingInt(ScoredDocument::score)
.reversed())
.limit(2)
.map(ScoredDocument::document)
.toList();
}生产环境可替换成 Elasticsearch BM25 + 向量召回 + RRF 融合。检索结果必须继续执行租户、文档权限和可见范围过滤。
第 4 步:构造有边界的系统提示词
private static final String SYSTEM_PROMPT = """
你是企业客服助手。
只能根据提供的知识库资料回答。
如果资料不足,必须明确说“当前知识库没有足够信息”,不能猜测。
回答控制在 120 字以内,并给出引用来源标题。
""";Prompt 中不能要求模型“尽可能回答”。知识不足时允许拒答,才是企业客服需要的安全行为。
第 5 步:调用 Spring AI ChatClient
String context = documents.stream()
.map(document -> "【" + document.title() + "】\n"
+ document.content())
.reduce("", (left, right) -> left + right + "\n");
String content = chatClient.prompt()
.system(SYSTEM_PROMPT)
.user(userPrompt)
.call()
.content();回答同时返回检索到的来源标题。模型服务异常时,代码返回“AI 服务暂不可用”,并保留来源列表,让前端可以降级展示原文。
第 6 步:启动并验证演示模式
java -jar demo-web/target/demo-web-1.0.0-SNAPSHOT.jar \
--spring.profiles.active=chapter7 \
--server.port=18107
curl -sS -X POST http://localhost:18107/api/v1/chapter7/ai/chat \
-H 'Content-Type: application/json' \
-d '{"question":"订单签收后怎么申请退款?"}'预期关键字段:
{
"data": {
"answer": "演示模型已收到知识库上下文...",
"sources": ["订单退款规则"],
"aiAnswered": true
}
}再提问资料库没有的问题:
curl -sS -X POST http://localhost:18107/api/v1/chapter7/ai/chat \
-H 'Content-Type: application/json' \
-d '{"question":"火星基地如何报税?"}'预期 aiAnswered=false 且来源为空。
第 7 步:切换真实模型
设置环境变量:
OPENAI_API_KEY='<your-key>' \
OPENAI_BASE_URL='https://api.openai.com' \
DEMO_AI_MODEL='gpt-4.1-mini' \
DEMO_AI_REMOTE_ENABLED=true \
java -jar demo-web/target/demo-web-1.0.0-SNAPSHOT.jar \
--spring.profiles.active=chapter7 \
--server.port=18107使用通义千问兼容端点时,替换 Base URL 和模型名。真实调用会产生费用,测试时必须限制调用次数和输入长度。
第 8 步:运行测试
mvn -pl demo-web -am \
-Dtest=Chapter7AdvancedIntegrationTest \
-Dsurefire.failIfNoSpecifiedTests=false \
testSpring AI 用例验证有资料问题返回正确来源、无资料问题拒绝编造。本次使用无密钥演示模型,未调用外部大模型。
RAG 不是把整份文档塞进 Prompt
生产 RAG 至少还要处理文档分块、Embedding、权限过滤、召回数量、重排序、上下文长度、引用定位和模型评测。直接拼接整份文档会带来 Token 成本、隐私泄露和无关信息干扰。
常见问题排查
| 现象 | 原因 | 处理方式 |
|---|---|---|
| 应用启动提示缺少 API Key | 远程 Starter 已启用但没有密钥 | 配置环境变量或使用演示模式 |
| 回答没有引用来源 | 检索结果未进入响应 DTO | 返回文档 ID、标题和片段位置 |
| 模型回答了资料外内容 | System Prompt 或检索上下文过宽 | 限定资料、拒答规则并增加评测 |
| 中文检索效果差 | 关键词分词不足 | 使用中文分词、向量或混合检索 |
| 响应变慢或成本升高 | 上下文过长或调用次数过多 | 限制 TopK、分块和回答长度 |
练习题
把两篇来源正文控制在总计 1000 字以内,并要求回答中的引用编号与 sources 数组对应。再增加一个无权限文档,验收它不会出现在检索结果和回答中。
总结
Spring AI 提供统一 ChatClient 和模型接入,企业 RAG 的可靠性仍来自检索质量、权限过滤、Prompt 约束、引用返回和降级路径。
下一篇使用 Testcontainers 把这些依赖基础设施的测试放进可重复的真实容器环境。
上一节:企业级性能调优
下一节:Testcontainers 集成测试
相关阅读:Spring AI 2.0
返回课程目录
13 个企业级实战项目 · 源码 + 教程 + 答疑
简历包装指导AI Agent 实战高并发·微服务Offer 导向持续更新3000+ 同行交流1V1 答疑3 天包退
覆盖高并发、微服务、分布式与 AI Agent:100万QPS短链、企业智能知识库、商城微服务、SaaS点餐、秒杀、刷题小程序、代码生成器、AI Agent 等。券后 ¥129(原价 ¥159),不满意 3 天包退。
