RAG知识库
RAG(Retrieval-Augmented Generation)知识库是 夜月AI应用平台 的核心功能之一,支持向量检索和图谱检索双模式,帮助用户构建基于私有知识的智能问答系统。
核心特性
- 3种向量存储后端:Redis、PgVector、Milvus
- 文档智能解析:支持PDF、Office、Markdown等多种格式
- 文本分块:可配置分块大小和重叠
- 嵌入生成:自动生成文本向量
- 可配置检索:topK、相似度阈值等参数可调
- 流式对话:支持SSE流式输出
工作流程
mermaid
graph LR
A[文档上传] --> B[文档解析]
B --> C[文本分块]
C --> D[嵌入生成]
D --> E[向量存储]
F[用户查询] --> G[查询嵌入]
G --> H[向量检索]
E --> H
H --> I[上下文注入]
I --> J[LLM生成回答]向量存储后端
Redis
适合小规模部署,简单易用。
yaml
rag:
vector-store:
type: redis
host: localhost
port: 6379
index: nitemoon-embeddingsPgVector
适合中等规模,基于PostgreSQL。
yaml
rag:
vector-store:
type: pgvector
url: jdbc:postgresql://localhost:5432/nitemoon
table: embeddingsMilvus
适合大规模部署,专业向量数据库。
yaml
rag:
vector-store:
type: milvus
host: localhost
port: 19530
collection: nitemoon-embeddings文档解析
支持多种文档格式:
| 格式 | 解析器 | 说明 |
|---|---|---|
| Apache Tika | 支持文字和图片提取 | |
| Word | Apache Tika | .doc, .docx |
| Excel | Apache Tika | .xls, .xlsx |
| PowerPoint | Apache Tika | .ppt, .pptx |
| Markdown | 内置解析器 | 原生支持 |
| TXT | 内置解析器 | 纯文本 |
文本分块
可配置的分块策略:
yaml
rag:
chunking:
chunk-size: 500 # 分块大小(字符数)
chunk-overlap: 50 # 重叠大小
separators: # 分隔符优先级
- "\n\n"
- "\n"
- "。"
- "!"
- "?"检索参数
yaml
rag:
retrieval:
top-k: 5 # 返回结果数
similarity-threshold: 0.7 # 相似度阈值
max-context-length: 4000 # 最大上下文长度使用场景
知识问答
java
// 创建知识库
KnowledgeBase kb = new KnowledgeBase();
kb.setName("产品文档");
knowledgeBaseService.save(kb);
// 上传文档
documentService.upload(kb.getId(), new File("product-doc.pdf"));
// 查询
RAGResponse response = ragService.query(
kb.getId(),
"如何配置RAG知识库?"
);智能客服
java
// 配置RAG参数
RAGConfig config = RAGConfig.builder()
.topK(3)
.similarityThreshold(0.8)
.build();
// 查询
RAGResponse response = ragService.query(
knowledgeBaseId,
userQuery,
config
);代码示例
创建知识库
java
@Service
public class KnowledgeBaseService {
public KnowledgeBase create(String name, String description) {
KnowledgeBase kb = new KnowledgeBase();
kb.setName(name);
kb.setDescription(description);
return repository.save(kb);
}
}文档上传和解析
java
@Service
public class DocumentService {
public void upload(Long kbId, File file) {
// 解析文档
String content = documentParser.parse(file);
// 文本分块
List<String> chunks = textChunker.chunk(content);
// 生成嵌入
for (String chunk : chunks) {
float[] embedding = embeddingModel.embed(chunk);
// 存储到向量数据库
DocumentFragment fragment = new DocumentFragment();
fragment.setKbId(kbId);
fragment.setContent(chunk);
fragment.setEmbedding(embedding);
fragmentRepository.save(fragment);
}
}
}RAG查询
java
@Service
public class RAGService {
public RAGResponse query(Long kbId, String query) {
// 生成查询嵌入
float[] queryEmbedding = embeddingModel.embed(query);
// 向量检索
List<DocumentFragment> results = vectorStore.search(
kbId,
queryEmbedding,
5, // topK
0.7 // similarityThreshold
);
// 构建上下文
String context = results.stream()
.map(DocumentFragment::getContent)
.collect(Collectors.joining("\n\n"));
// LLM生成回答
String prompt = String.format(
"基于以下上下文回答问题:\n\n%s\n\n问题:%s",
context, query
);
String answer = chatModel.generate(prompt);
return new RAGResponse(answer, results);
}
}最佳实践
- 合理设置分块大小:太小会丢失上下文,太大会影响检索精度
- 调整相似度阈值:根据业务场景调整,避免返回不相关结果
- 选择合适的向量存储:根据数据规模和性能需求选择
- 定期更新知识库:保持知识库内容的时效性
- 监控检索质量:定期评估检索效果,优化参数