企业级 RAG 实现 Retrieval Augmented Generation:让 AI 基于私有知识库回答问题
RAG 工作流程 1 2 3 文档 → 分块 (Chunking) → 向量化 (Embedding) → 存储 (Vector DB) ↓ 用户问题 → 向量化 → 相似度搜索 → 检索上下文 → 注入 Prompt → LLM → 回答
项目结构 1 2 3 4 5 6 7 8 9 10 11 12 src/main/java/com/example/rag/ ├── RAGApplication.java ├── controller/ │ └── RagController.java ├── service/ │ ├── DocumentService.java # 文档加载与分块 │ ├── EmbeddingService.java # 向量化 │ └── RetrievalService.java # 检索 ├── repository/ │ └── VectorStoreConfig.java # 向量数据库配置 └── model/ └── DocumentChunk.java # 分块实体
Step 1: 文档加载与分块 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Service public class DocumentService { public List<DocumentChunk> loadAndChunk (String filePath) { Document document = new ClassPathResourceDocumentReader (filePath) .read(); TextSplitter splitter = new TextSplitter (500 , 100 ); List<Document> chunks = splitter.split(document); return chunks.stream() .map(doc -> new DocumentChunk (doc.getContent(), doc.getMetadata())) .toList(); } }
Step 2: 向量化并存储 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Service public class EmbeddingService { @Autowired private EmbeddingModel embeddingModel; @Autowired private VectorStore vectorStore; public void indexDocuments (List<DocumentChunk> chunks) { for (DocumentChunk chunk : chunks) { Embedding embedding = embeddingModel.embed(chunk.getContent()); vectorStore.add(chunk.getContent(), embedding, chunk.getMetadata()); } } }
Step 3: 检索并增强生成 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 @Service public class RetrievalService { private final ChatClient chatClient; private final VectorStore vectorStore; public String answer (String question) { Embedding questionEmbedding = embeddingModel.embed(question); List<Document> relevantDocs = vectorStore.similaritySearch( VectorStore.SearchRequest.builder() .query(questionEmbedding) .topK(5 ) .build() ); String context = relevantDocs.stream() .map(Document::getContent) .collect(Collectors.joining("\n" )); String prompt = """ 基于以下参考资料回答问题。如果资料中没有答案,请如实说明。 参考资料: %s 问题:%s """ .formatted(context, question); return chatClient.prompt() .user(prompt) .call() .content(); } }
向量数据库选型 数据库 特点 适用场景 InMemoryVectorStore 无需安装,测试用 开发调试 PostgreSQL + pgvector 企业级,支持 SQL 联合查询 生产环境 Milvus 海量向量,高性能 大规模 RAG Qdrant 轻量,支持云原生 微服务架构
常见优化 分块策略 : overlap=50~100 字符,减少边界丢失元数据过滤 : 按时间、来源、标签预过滤重排序 (Rerank) : 用 BGE-Reranker 二次排序