🔥你好我是fengxin_rou这是我的个人主页 fengxin_rou的主页
❄️欢迎查看我的专栏我的专栏
《Java后端学习》、《JAVASE基础》、《JUC并发》、《redis》、《JVM虚拟机》、《MYSQL》、《黑马点评》、《rabbitmq》、《JavaWeb+AI的talis学习系统》、《苍穹外卖》

目录
[一、项目基础配置:Spring AI 对接 DeepSeek 大模型](#一、项目基础配置:Spring AI 对接 DeepSeek 大模型)
[1.1 核心配置类设计](#1.1 核心配置类设计)
[1.2 配置要点说明](#1.2 配置要点说明)
[二、AI 一键生成摘要:文章描述自动生成](#二、AI 一键生成摘要:文章描述自动生成)
[2.1 功能逻辑](#2.1 功能逻辑)
[2.2 核心实现代码](#2.2 核心实现代码)
[2.3 关键参数解析](#2.3 关键参数解析)
[三、RAG 索引构建:私有知识向量化管理](#三、RAG 索引构建:私有知识向量化管理)
[3.1 RAG 核心原理](#3.1 RAG 核心原理)
[3.2 索引全流程](#3.2 索引全流程)
[3.3 索引服务核心逻辑](#3.3 索引服务核心逻辑)
[3.4 指纹作用](#3.4 指纹作用)
[四、RAG 问答查询:流式精准回答](#四、RAG 问答查询:流式精准回答)
[4.1 问答流程](#4.1 问答流程)
[4.2 宽召回机制](#4.2 宽召回机制)
[4.3 流式问答实现代码](#4.3 流式问答实现代码)
[4.4 向量检索原理](#4.4 向量检索原理)
[5.1 Embedding 模型配置](#5.1 Embedding 模型配置)
[5.2 核心优化点](#5.2 核心优化点)
前言
在企业级知识管理场景中,自动生成内容摘要 与基于私有文档的精准问答是提升信息效率的核心需求。本文基于 Spring AI 框架,整合 DeepSeek 大模型与向量数据库,完整实现 AI 一键摘要与 RAG 检索增强生成功能,覆盖配置、编码、索引、检索全流程,兼顾入门与实战。
一、项目基础配置:Spring AI 对接 DeepSeek 大模型
1.1 核心配置类设计
大模型接入的关键是通过 Spring 依赖注入明确指定模型实现,避免多模型注入冲突。@Qualifier 注解用于精准绑定 Bean,确保 ChatClient 使用 DeepSeek 模型。
/**
* 大模型配置类:定义ChatClient Bean并绑定DeepSeek模型
*/
@Configuration
public class LlmConfig {
/**
* 创建ChatClient,指定使用deepSeekChatModel
*/
@Bean
public ChatClient chatClient(@Qualifier("deepSeekChatModel") ChatModel chatModel) {
return ChatClient.builder(chatModel).build();
}
}
1.2 配置要点说明
@Configuration:标记为配置类,Spring 启动时加载。@Bean:将方法返回值注册为 Spring 容器中的 Bean。@Qualifier:解决多ChatModel实现注入歧义,强制使用 DeepSeek 模型。
该配置是后续所有 AI 能力的基础,统一管理大模型调用入口,降低业务层耦合。
二、AI 一键生成摘要:文章描述自动生成
2.1 功能逻辑
接收文章正文 → 拼接系统与用户提示词 → 调用 DeepSeek → 结果后处理 → 返回 50 字内精简描述。系统提示词 定义 AI 角色与规则,用户提示词传递具体任务,二者结合保证输出规范。
2.2 核心实现代码
/**
* AI生成知文摘要实现类
*/
@Service
@RequiredArgsConstructor
public class KnowPostDescriptionServiceImpl implements KnowPostDescriptionService {
private final ChatClient chatClient;
/**
* 生成不超过50字的中文描述
*/
public String generateDescription(String content) {
// 非空校验
if (content == null || content.trim().isEmpty()) {
throw new BusinessException(ErrorCode.BAD_REQUEST, "正文内容不能为空");
}
// 系统提示:定义角色与输出规则
String system = "你是中文文案编辑。请基于知文正文生成简洁有吸引力的描述,不超过50字,仅输出结果";
// 用户提示:传递待处理内容
String user = "正文如下:\n\n" + content + "\n\n请直接给出不超过50字的中文描述";
try {
// 调用大模型
String result = chatClient.prompt()
.system(system)
.user(user)
.options(DeepSeekChatOptions.builder()
.model("deepseek-chat") // 指定模型
.temperature(0.8) // 创造性参数
.maxTokens(120) // 最大输出token
.build())
.call()
.content();
return postProcess(result);
} catch (Exception e) {
throw new BusinessException(ErrorCode.INTERNAL_ERROR, "大模型调用失败");
}
}
/**
* 结果后处理:格式化、去冗余、截断至50字
*/
private String postProcess(String text) {
if (text == null) return "";
// 标准化、去换行、合并空格
String t = Normalizer.normalize(text, Normalizer.Form.NFKC)
.replaceAll("\r\n|\r|\n", " ")
.replaceAll("\\s+", " ").trim();
// 去除首尾引号与标点
t = t.replaceAll("^[\"'""'']+|[\"'""'']+$", "")
.replaceAll("[。!!??;;、]+$", "");
// 按Unicode码点截断至50字
int limit = 50;
int count = t.codePointCount(0, t.length());
if (count <= limit) return t;
StringBuilder sb = new StringBuilder();
int i = 0, added = 0;
while (i < t.length() && added < limit) {
int cp = t.codePointAt(i);
sb.appendCodePoint(cp);
i += Character.charCount(cp);
added++;
}
return sb.toString();
}
}
2.3 关键参数解析
temperature:0 - 1,值越高输出越随机,摘要场景设 0.8 兼顾创意与规范。maxTokens:限制输出长度,避免内容溢出。- 后处理:解决格式混乱、字数超标问题,保证展示友好。
三、RAG 索引构建:私有知识向量化管理
3.1 RAG 核心原理
RAG(检索增强生成)通过文档切片 + 向量存储 + 指纹校验,实现私有知识精准检索,避免大模型幻觉。指纹(SHA - 256)用于判断文档是否更新,决定是否重建索引。
3.2 索引全流程
- 首次上传:前端计算 SHA - 256 与 ETag → 上传 OSS → 后端存指纹到 MySQL → 触发索引 → 文档切片存入向量库并携带指纹。
- 查询校验:问答前比对 MySQL 与向量库指纹,一致则跳过重建。
- 修改重传:指纹变更 → 删除旧索引 → 生成新索引。
3.3 索引服务核心逻辑
/**
* RAG索引服务:确保索引最新
*/
@Service
@RequiredArgsConstructor
public class RagIndexService {
/**
* 确保单篇知文索引最新
*/
public void ensureIndexed(long postId) {
// 从MySQL获取当前指纹
String currentSha = getCurrentShaFromDB(postId);
// 查询向量库已存指纹
String indexedSha = getIndexedShaFromVector(postId);
// 指纹不一致则重建索引
if (!currentSha.equals(indexedSha)) {
deleteOldIndex(postId);
buildNewIndex(postId, currentSha);
}
}
}
3.4 指纹作用
- 唯一标识文档内容,避免重复索引,提升性能。
- 保证向量库数据与源文档一致,防止检索失效。
四、RAG 问答查询:流式精准回答
4.1 问答流程
- 确保索引最新;
- 向量相似度检索上下文;
- 组装提示词;
- 流式调用大模型;
- 返回结果。
4.2 宽召回机制
先检索 20 条相似文档(宽召回),再按 postId 过滤,取前 5 条作为上下文,提升检索准确率。
4.3 流式问答实现代码
/**
* RAG问答查询服务:流式返回回答
*/
@Service
@RequiredArgsConstructor
public class RagQueryService {
private final VectorStore vectorStore;
private final ChatClient chatClient;
private final RagIndexService indexService;
/**
* 流式问答接口
*/
public Flux<String> streamAnswerFlux(long postId, String question, int topK, int maxTokens) {
// 确保索引最新
indexService.ensureIndexed(postId);
// 检索上下文
List<String> contexts = searchContexts(String.valueOf(postId), question, topK);
String context = String.join("\n\n---\n\n", contexts);
// 提示词组装
String system = "你是中文知识助手,仅依据上下文作答,不确定则说明";
String user = "问题:" + question + "\n\n上下文:\n" + context;
// 流式调用大模型
return chatClient.prompt()
.system(system)
.user(user)
.options(DeepSeekChatOptions.builder()
.model("deepseek-chat")
.temperature(0.2) // 低温度保证严谨
.maxTokens(maxTokens)
.build())
.stream()
.content();
}
/**
* 向量检索上下文:宽召回+postId过滤
*/
private List<String> searchContexts(String postId, String query, int topK) {
int fetchK = Math.max(topK * 3, 20);
// 向量相似度搜索
List<Document> docs = vectorStore.similaritySearch(
SearchRequest.builder().query(query).topK(fetchK).build()
);
List<String> out = new ArrayList<>();
for (Document d : docs) {
// 仅保留当前帖子切片
if (postId.equals(String.valueOf(d.getMetadata().get("postId")))) {
out.add(d.getText());
if (out.size() >= topK) break;
}
}
return out;
}
}
4.4 向量检索原理
用户问题经 Embedding 模型转为 1536 维向量,与向量库中文档向量计算余弦相似度,排序后取最相似结果。1536 维平衡语义表达、计算效率与存储成本。
五、关键技术细节与优化建议
5.1 Embedding 模型配置
embedding:
options:
model: text-embedding-v4 # 向量模型
dimensions: 1536 # 向量维度
5.2 核心优化点
- 指纹校验:减少无效索引,提升系统响应速度。
- 宽召回:提升检索覆盖率,避免遗漏关键信息。
- 流式输出:提升用户体验,适用于长文本回答。
- 温度参数:摘要用 0.8 增强创意,问答用 0.2 保证严谨。
结语
本文基于 Spring AI 与 DeepSeek,完整实现AI 自动摘要 与 RAG 检索问答两大核心功能,覆盖配置、编码、索引、检索全流程。该方案可直接落地到企业知识平台、文档管理系统等场景,解决私有知识高效利用与大模型幻觉问题。后续可优化文档切片策略、引入多模型切换、提升向量检索性能,进一步增强系统能力。
