设计 RAG 系统
问题
设计一个企业级 RAG 知识问答系统,支持文档上传、智能问答、引用溯源。
答案
一、需求分析
- 支持 PDF/Word/网页/Markdown 文档导入
- 用户提问后基于文档库回答,标注来源
- 支持多用户、权限隔离
- 回答延迟 < 3s
二、系统架构
三、核心组件设计
文档处理
| 步骤 | 方案 |
|---|---|
| PDF 解析 | unstructured / PyMuPDF |
| 分块策略 | 递归字符分割(512 |
| Embedding | text-embedding-3-small / BGE-M3 |
| 存储 | pgvector(简单)/ Milvus(大规模) |
检索策略
用户 Query → Query 改写(HyDE/多查询)
→ 向量检索 Top-20
→ BM25 检索 Top-20
→ 混合融合(RRF)
→ Reranker 重排序 Top-5
→ LLM 生成回答
引用溯源
const systemPrompt = `基于以下文档回答问题。
要求:
1. 只使用提供的文档内容回答
2. 每个声明用 [来源: 文档名, 页码] 标注
3. 如果文档中没有相关信息,说明"无法找到相关信息"
文档内容:
{context}`;
四、数据模型
documents: { id, title, source_url, user_id, created_at }
chunks: { id, document_id, content, metadata, embedding }
conversations: { id, user_id, created_at }
messages: { id, conversation_id, role, content, sources[] }
五、性能优化
| 优化项 | 方案 |
|---|---|
| 缓存 | 语义缓存(相似 Query 命中缓存) |
| 检索加速 | HNSW 索引 + 分区 |
| 生成加速 | 流式输出、Prompt 精简 |
| 成本控制 | 小模型做 Embedding/Rerank,大模型只做生成 |
常见面试问题
Q1: 分块大小如何选择?
答案:
- 太小(< 200 tokens):上下文信息不足
- 太大(> 2000 tokens):噪声多,Embedding 质量下降
- 推荐:512
1024 tokens,overlap 1020% - 考虑按语义边界分块(段落、章节)而非固定大小
Q2: 如何评估 RAG 系统效果?
答案:
- 检索评估:Recall@K(Top-K 中包含正确文档的比例)
- 生成评估:Faithfulness(答案是否忠于文档)、Relevance(答案是否相关)
- 端到端:用户满意度、引用准确率
- 工具:RAGAS、TruLens、自建评估集