返回AI笔记
AI Day 44

AI Day 44: 系统设计面试(2):设计一个生产级RAG系统

AI Day 44: 系统设计面试(2):设计一个生产级RAG系统

2026-05-15
系统设计RAGIngestionRetrievalChunkingReranking向量库评估循环

日期: 2026-05-15 阶段: Phase 4 — 面试冲刺 (System Design + Product + Architecture) 主题: System Design Interview — Design a Production-Grade RAG System 进度: Day 1-43 ✅ | Day 44 ← current 标签: #系统设计 #RAG #Ingestion #Retrieval #Chunking #Reranking #向量库 #评估循环


学习路径 (50-Day Full Tree)

AI/LLM 深度技术学习 50天计划
├── 第一阶段:模型基础 (Day 1-15) ✅
│   ├── Day 1-7:   Transformer/量化/训练/Prompt/RAG/向量DB/FineTune ✅
│   ├── Day 8-11:  推理优化/长上下文/多模态/Reasoning ✅
│   └── Day 12-15: Agent/MCP/评估/阶段总结 ✅
│
├── 第二阶段:工程实践 (Day 16-30) ✅
│   ├── Day 16-18: 应用架构/安全/可观测性 ✅
│   ├── Day 19-21: 生产级RAG三部曲 ✅
│   ├── Day 22-25: Agent工程化四部曲 ✅
│   └── Day 26-30: 成本/编排/测试/案例/总结 ✅
│
├── 第三阶段:金融零售AI应用 (Day 31-42) ✅
│   ├── Day 31: 金融AI(1):智能风控与反欺诈 ✅
│   ├── Day 32: 金融AI(2):智能投顾与量化策略 ✅
│   ├── Day 33: 金融AI(3):合规科技与监管AI ✅
│   ├── Day 34: 金融AI(4):信贷全链路AI ✅
│   ├── Day 35: 金融AI总结 — PM视角的AI重塑金融 ✅
│   ├── Day 36: 零售AI(1):推荐系统与个性化 ✅
│   ├── Day 37: 零售AI(2):智能客服与对话系统 ✅
│   ├── Day 38: 零售AI(3):供应链预测与优化 ✅
│   ├── Day 39: 零售AI(4):智能营销与用户增长 ✅
│   ├── Day 40: 零售AI总结 — PM视角零售智能化全景 ✅
│   ├── Day 41: CeFi × DeFi × AI 融合架构(上) ✅
│   └── Day 42: CeFi × DeFi × AI 融合(下) + 职业定位 ✅
│
└── 第四阶段:面试冲刺 (Day 43-50)
    ├── Day 43: 系统设计面试(1):企业LLM平台 ✅
    ├── Day 44: 系统设计面试(2):生产级RAG系统 ← 你在这里
    ├── Day 45: 系统设计面试(3):AI Agent系统
    ├── Day 46: 系统设计面试(4):推荐系统
    ├── Day 47-49: 产品/架构面试模拟
    └── Day 50: 总结与作品集

一、面试题

"Design a production-grade RAG (Retrieval-Augmented Generation) system for a large enterprise. It should allow employees to ask questions about internal documents (policies, manuals, reports) and get accurate answers with citations."


二、Step 1: Requirements 需求澄清 (5 min)

面试时必须问的澄清问题:

Q1: "文档规模有多大?"
  → 假设: 50万篇文档, 总计10TB (PDF/DOCX/HTML/Confluence/Slack)
  → 每天新增/更新 ~500 篇

Q2: "用户规模和QPS?"
  → 假设: 5000名员工, DAU 1500, 峰值QPS ~10

Q3: "对延迟的要求?"
  → 假设: 首token < 2s (含检索), 完整回答 < 10s

Q4: "对准确率的要求?"
  → 假设: Answer Relevance > 85%, Faithfulness > 90%
  → 不可以编造不存在的内容(金融/法律场景)

Q5: "是否需要权限控制?"
  → 假设: 是! 不同部门只能看到有权限的文档
  → HR文档只有HR部门能查, 财务报告只有财务+管理层能查

Q6: "支持哪些文档类型?"
  → 假设: PDF / DOCX / HTML / Markdown / Confluence / Slack messages

功能性需求 (Functional):
  ├── 文档摄入: 批量导入 + 增量同步 + 实时更新
  ├── 智能问答: 自然语言提问 → 精确回答 + 引用来源
  ├── 多轮对话: 支持上下文追问
  ├── 权限控制: 基于用户角色过滤可检索文档
  ├── 引用溯源: 每个答案标注来源文档和段落
  └── 反馈循环: 用户评价回答质量, 持续改进

非功能性需求 (Non-Functional):
  ├── 延迟: E2E < 5s (P95), 首token < 2s
  ├── 准确率: Relevance > 85%, Faithfulness > 90%
  ├── 可用性: 99.9%
  ├── 安全: 文档级权限, PII过滤, 审计日志
  ├── 成本: 控制在合理范围(< $20K/month)
  └── 可扩展: 文档从50万→500万平滑扩展

三、Step 2: Estimation 规模估算 (3 min)

文档处理估算:
  文档总量: 500K documents, ~10TB raw
  平均每文档: ~20 pages, ~5000 tokens
  总Token: 500K × 5000 = 2.5B tokens of source text
  Chunks (avg 512 tokens): 2.5B / 512 ≈ 5M chunks
  向量维度: 1536 (OpenAI) or 768 (open-source)
  向量存储: 5M × 1536 × 4bytes = ~30GB
  元数据存储: 5M × 500bytes = ~2.5GB

查询估算:
  DAU: 1500
  每用户: ~10次查询/天
  日查询: 15,000 queries/day
  峰值QPS: 15000 / 86400 × 5 ≈ 0.87 ≈ 1 QPS
  → 不是高并发问题, 核心挑战在检索质量

成本估算:
  Embedding (Ingestion):
    5M chunks × $0.02/1M tokens × 512 = ~$50 (一次性)
    增量: 500 docs/day × 10 chunks × $0.02/1M = 几美分/天

  Embedding (Query):
    15K queries/day × $0.02/1M tokens × 100 = ~$0.03/day

  LLM Generation:
    15K queries × (2000 input + 500 output) tokens
    Input: 15K × 2000 × $2.5/1M = $75/day
    Output: 15K × 500 × $10/1M = $75/day
    月成本: ~$4,500/month

  Vector DB (Qdrant Cloud/Pinecone):
    5M vectors × 1536 dim ≈ $200-500/month

  总月成本估算: ~$5,000-7,000/month

四、Step 3: High-level Architecture 高层架构 (8 min)

生产级RAG系统四大Pipeline:

┌─────────────────────────────────────────────────────────────┐
│                    RAG System Architecture                   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              1. Ingestion Pipeline                    │   │
│  │  Sources → Parse → Chunk → Embed → Index → Store     │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              2. Retrieval Pipeline                    │   │
│  │  Query → Rewrite → Embed → Search → Rerank → Filter  │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              3. Generation Pipeline                   │   │
│  │  Context Assembly → Prompt → LLM → Citation → Output │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │              4. Evaluation Loop                       │   │
│  │  Feedback → Metrics → Analysis → Improvement         │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
详细架构图:

  ┌──────────┐   ┌──────────┐   ┌──────────┐
  │ Confluenc│   │  S3/GCS  │   │  Slack   │
  │    e     │   │  Files   │   │ Messages │
  └────┬─────┘   └────┬─────┘   └────┬─────┘
       │               │               │
       └───────────────┼───────────────┘
                       │
              ┌────────▼────────┐
              │ Ingestion Queue │  (Kafka / SQS)
              └────────┬────────┘
                       │
              ┌────────▼────────┐
              │ Document Parser │  (Unstructured / LlamaParse)
              │ PDF/DOCX/HTML   │
              └────────┬────────┘
                       │
              ┌────────▼────────┐
              │  Chunking       │  (Semantic / Recursive)
              │  + Metadata     │
              └────────┬────────┘
                       │
              ┌────────▼────────┐
              │  Embedding      │  (OpenAI / Cohere / BGE)
              └────────┬────────┘
                       │
              ┌────────▼────────┐         ┌──────────────┐
              │  Vector DB      │◄───────►│  Metadata DB │
              │  (Qdrant)       │         │  (PostgreSQL)│
              └────────▲────────┘         └──────────────┘
                       │
                       │ Retrieval
                       │
              ┌────────┴────────┐
  User ────► │ Query Service    │
  Query      │ Rewrite→Search  │
              │ →Rerank→Filter  │
              └────────┬────────┘
                       │
              ┌────────▼────────┐
              │ Generation Svc  │
              │ Context+Prompt  │
              │ →LLM→Citation   │
              └────────┬────────┘
                       │
              ┌────────▼────────┐
              │ Response + Refs │
              └─────────────────┘

五、Step 4: Detailed Design 深入设计 (12 min)

5.1 Ingestion Pipeline — 文档摄入

Document Parsing (文档解析):

挑战:
  ├── PDF: 有些是扫描件(需OCR), 有表格/图表
  ├── DOCX: 嵌入图片, 复杂格式
  ├── HTML: 需要清理导航/广告等噪音
  └── Confluence: API拉取, 处理层级结构

解析方案选型:
  ┌─────────────┬──────────────┬──────────────┬──────────┐
  │ Tool        │ 优点         │ 缺点         │ 适用     │
  ├─────────────┼──────────────┼──────────────┼──────────┤
  │ Unstructured│ 开源/多格式  │ 表格处理一般 │ 通用     │
  │ LlamaParse  │ 表格/图表好  │ 付费/API     │ 复杂PDF  │
  │ Docling     │ IBM开源      │ 社区较小     │ 结构化   │
  │ PyMuPDF     │ 快速/轻量    │ 只支持PDF    │ 简单PDF  │
  └─────────────┴──────────────┴──────────────┴──────────┘

  推荐: Unstructured(通用) + LlamaParse(复杂PDF fallback)

表格处理:
  方案1: 将表格转为Markdown文本 → 嵌入到chunk中
  方案2: 将表格截图 → 多模态模型理解
  方案3: 将表格提取为结构化JSON → 专门的Table QA
  推荐: 方案1为主, 复杂表格用方案2兜底

Chunking策略 — 最影响质量的环节

Chunking策略对比:

策略1: Fixed-size Chunking (固定大小)
  实现: 每512 tokens切一刀, overlap 50 tokens
  优点: 简单/快速/可预测
  缺点: 可能从句子中间切断, 丢失语义
  适用: 结构简单的文本

策略2: Recursive Character Splitting (递归分割)
  实现: 按 \n\n → \n → . → 空格 逐级尝试分割
  优点: 尽量保持段落/句子完整
  缺点: chunk大小不均匀
  适用: 大部分场景(LangChain默认)

策略3: Semantic Chunking (语义分割)
  实现:
    1. 逐句计算embedding
    2. 计算相邻句子的余弦相似度
    3. 相似度骤降处 = 语义边界 → 在此切分
  优点: 每个chunk语义完整
  缺点: 计算成本高(需要embed每个句子)
  适用: 高质量要求场景

策略4: Document Structure Aware (结构感知)
  实现: 利用文档标题/章节层级来切分
  优点: 保留文档结构, 天然语义边界
  缺点: 需要文档有良好结构
  适用: 有层级结构的文档(手册/政策)

策略5: Agentic Chunking (LLM驱动)
  实现: 用LLM判断每个段落的主题是否与前一个一致
  优点: 最高质量的语义切分
  缺点: 成本极高(需要对每个段落调LLM)
  适用: 少量关键文档

我们的方案 — 混合策略:
  ├── 结构化文档(政策/手册): 策略4 (Structure Aware)
  ├── 普通文档(报告/邮件): 策略2 (Recursive) + overlap
  ├── 关键文档(合同/法规): 策略3 (Semantic)
  └── 参数: chunk_size=512, overlap=50, min_chunk=100

Metadata Enrichment (元数据增强):
  每个chunk附带:
    ├── source_doc_id: 源文档ID
    ├── doc_title: 文档标题
    ├── section_title: 所在章节标题
    ├── page_number: 页码
    ├── chunk_index: 在文档中的顺序
    ├── doc_type: 文档类型(policy/manual/report)
    ├── department: 所属部门
    ├── access_level: 权限级别
    ├── created_at: 文档创建时间
    ├── updated_at: 最后更新时间
    └── summary: LLM生成的chunk摘要(可选,提升检索)

5.2 Retrieval Pipeline — 检索服务

检索流程 (Query → Results):

Step 1: Query Rewriting (查询改写)
  问题: 用户query经常模糊/不完整/口语化
  例: "上次那个报销政策改了什么?" → 需要扩展为具体查询

  方案A: LLM改写 (推荐)
    Prompt: "将以下用户问题改写为更适合检索的查询,
            生成3个不同角度的搜索query"
    Input: "上次报销政策改了什么?"
    Output:
      1. "最新报销政策变更内容"
      2. "差旅费用报销标准更新"
      3. "2026年报销规则修改"

  方案B: HyDE (Hypothetical Document Embedding)
    1. 让LLM先生成一个"假设的答案"
    2. 用这个假设答案的embedding去检索
    3. 因为答案和文档的语义空间更近, 检索更准
    优点: 对抽象问题检索效果好
    缺点: 多一次LLM调用, 增加延迟

Step 2: Multi-path Retrieval (多路召回)
  ├── Dense Retrieval (向量检索):
  │   Query → Embedding → Vector DB Top-K (K=20)
  │   优点: 语义理解好
  │   缺点: 精确匹配差(专有名词/编号)
  │
  ├── Sparse Retrieval (关键词检索):
  │   Query → BM25 → Elasticsearch Top-K (K=20)
  │   优点: 精确匹配好(合同编号/人名)
  │   缺点: 不理解同义词
  │
  └── Hybrid (混合检索):
      Score = α × Dense_Score + (1-α) × Sparse_Score
      α = 0.7 (可调, 根据评估结果)

      为什么Hybrid > 单一:
        Dense漏的, Sparse能补(精确匹配)
        Sparse漏的, Dense能补(语义理解)
        实测: Hybrid比单一Dense提升10-15% Recall

Step 3: Reranking (重排序)
  问题: 初始检索返回20个结果, 排序不够精确

  Cross-Encoder Reranker:
    ├── 输入: (Query, Chunk) pairs
    ├── 模型: Cohere Rerank / BGE-Reranker / cross-encoder
    ├── 输出: 精确的相关性分数
    ├── 从Top-20筛选到Top-5
    └── 延迟: ~100-200ms (可接受)

  为什么需要Reranker:
    Bi-encoder (embedding): 快但不够精确(独立编码Q和D)
    Cross-encoder (reranker): 慢但精确(联合编码Q和D)
    两阶段组合 = 又快又准

Step 4: Permission Filtering (权限过滤)
  方案A: Post-retrieval Filtering (检索后过滤)
    1. 检索Top-K (不考虑权限)
    2. 过滤掉用户无权限的文档
    问题: 可能过滤后剩余不足, 需要多检索一些

  方案B: Pre-retrieval Filtering (检索前过滤) ← 推荐
    1. 在向量检索时直接加metadata filter
    2. filter: {"access_level": {"$in": user.access_levels}}
    优点: 更高效, 不会浪费检索quota
    缺点: 需要向量库支持metadata filtering (Qdrant/Weaviate都支持)

  方案C: 分Collection存储
    1. 每个权限组一个Collection
    2. 查询时只搜索用户有权限的Collections
    优点: 完全隔离
    缺点: 跨权限文档需要多个Collection查询

5.3 Generation Pipeline — 生成服务

Context Assembly (上下文组装):

  模板:
  ┌─────────────────────────────────────────────┐
  │ System Prompt:                               │
  │   你是企业知识助手。                          │
  │   规则:                                       │
  │   1. 只基于提供的文档回答                     │
  │   2. 如果文档中没有相关信息,说"我无法确认"   │
  │   3. 每个观点必须标注来源[Doc X, Page Y]      │
  │   4. 不要编造信息                             │
  │                                               │
  │ Retrieved Context:                            │
  │   [1] Title: 差旅报销政策(2026版)              │
  │       Source: HR-Policy-2026.pdf, Page 12      │
  │       Content: "国内差旅住宿标准..."           │
  │                                               │
  │   [2] Title: 报销流程指南                      │
  │       Source: Finance-Guide.docx, Page 5       │
  │       Content: "报销审批流程..."               │
  │                                               │
  │   [3] ...                                      │
  │                                               │
  │ Conversation History:                          │
  │   User: 出差住宿标准是多少?                    │
  │   Assistant: 根据[1], 国内出差...              │
  │   User: 那国际出差呢?    ← current query       │
  └─────────────────────────────────────────────┘

Citation Generation (引用生成):
  方案1: Inline Citation (推荐)
    LLM生成时直接标注: "根据[1]差旅报销政策, 国际出差住宿标准为..."

  方案2: Post-hoc Citation
    LLM先生成答案, 再用NLI模型匹配每句话对应哪个源文档

  方案3: Sentence-level Grounding
    对答案的每个句子, 用entailment模型验证是否有文档支撑
    无支撑的句子标记为"推测"

Streaming策略:
  ├── SSE (Server-Sent Events) 流式返回
  ├── 先返回文字, 最后附上引用列表
  └── 如果检测到幻觉, 中断生成(Guardrail)

5.4 向量数据库选型

向量库对比 (2026):

┌──────────┬────────────┬────────────┬──────────┬──────────────┐
│ Vector DB│ 优点       │ 缺点       │ 适用规模 │ 特色功能     │
├──────────┼────────────┼────────────┼──────────┼──────────────┤
│ Qdrant   │ 性能好     │ 社区相对小 │ 1M-1B    │ 多向量/过滤  │
│          │ Rust写的   │            │          │ Sparse向量   │
│          │ 过滤快     │            │          │              │
├──────────┼────────────┼────────────┼──────────┼──────────────┤
│ Weaviate │ 混合搜索好 │ 内存占用高 │ 1M-100M  │ 内置BM25     │
│          │ 多模态     │            │          │ GraphQL API  │
├──────────┼────────────┼────────────┼──────────┼──────────────┤
│ Pinecone │ 全托管     │ 贵/锁定   │ 1M-1B    │ Serverless   │
│          │ 运维零     │            │          │ Sparse+Dense │
├──────────┼────────────┼────────────┼──────────┼──────────────┤
│ Pgvector │ 与PG集成   │ 大规模慢  │ <5M      │ 一个DB搞定   │
│          │ 简单       │ 功能少    │          │ SQL查询      │
├──────────┼────────────┼────────────┼──────────┼──────────────┤
│ Milvus   │ 大规模好   │ 部署复杂  │ 1B+      │ GPU加速      │
│          │ 功能全     │            │          │ 分布式       │
└──────────┴────────────┴────────────┴──────────┴──────────────┘

我们的选择: Qdrant
  原因:
  ├── 5M向量, 中等规模, Qdrant性能足够
  ├── 支持metadata过滤(权限控制必须)
  ├── 支持Sparse向量(Hybrid Search原生支持)
  ├── 自部署+云托管都有
  └── Rust实现, 性能/内存效率好

5.5 缓存策略

三层缓存:

Layer 1: Exact Match Cache (精确匹配)
  ├── Key: hash(query + user_permissions)
  ├── Value: 完整response + citations
  ├── TTL: 24h
  ├── 命中率: ~5-10%
  └── 延迟: < 10ms

Layer 2: Semantic Cache (语义缓存)
  ├── 计算query embedding
  ├── 搜索缓存向量库, 相似度 > 0.95 → Hit
  ├── 命中率: ~15-25%
  ├── 注意: 必须考虑权限! 不同权限的用户不能复用
  └── 延迟: < 50ms

Layer 3: Retrieval Cache (检索缓存)
  ├── 缓存embedding结果, 避免重复embed同一query
  ├── 缓存reranking结果
  └── 命中率: ~20%

总缓存命中率: ~30-40%
成本节省: ~30% LLM调用费用

六、Step 5: Evaluation Loop 评估循环

RAG评估 — 最容易被忽略但最重要的部分

为什么评估难:
  ├── 没有标准答案(不像分类任务)
  ├── 质量是主观的(不同人判断不同)
  ├── 需要评估多个维度(检索+生成)
  └── 需要持续评估(数据变化导致质量变化)

RAGAS评估框架 (业界标准):

┌────────────────┬──────────────────────────────────────┐
│ 指标           │ 说明                                 │
├────────────────┼──────────────────────────────────────┤
│ Faithfulness   │ 答案是否忠于检索到的Context          │
│                │ (不编造Context中没有的信息)           │
│                │ Target: > 90%                         │
├────────────────┼──────────────────────────────────────┤
│ Answer         │ 答案是否和问题相关                   │
│ Relevance      │ Target: > 85%                         │
├────────────────┼──────────────────────────────────────┤
│ Context        │ 检索到的Context是否包含回答所需信息  │
│ Recall         │ Target: > 80%                         │
├────────────────┼──────────────────────────────────────┤
│ Context        │ 检索到的Context中有多少是有用的      │
│ Precision      │ (过多无关context = 噪音)             │
│                │ Target: > 70%                         │
└────────────────┴──────────────────────────────────────┘

评估实施:

1. 自动评估 (Daily):
   ├── 维护一个Golden Test Set (200+ Q&A pairs)
   ├── 每日自动运行RAGAS评估
   ├── 指标低于阈值 → 自动告警
   └── 代码: ragas.evaluate(dataset, metrics=[...])

2. LLM-as-Judge (Continuous):
   ├── 对每次实际查询, 用另一个LLM评分
   ├── 评分维度: 是否回答了问题 / 是否有引用 / 是否忠实
   ├── 低分答案进入人工审核队列
   └── 成本: ~$0.01/evaluation (用小模型)

3. 人工评估 (Weekly):
   ├── 随机抽样50个query-answer pairs
   ├── 领域专家评分 (1-5分)
   ├── 标注问题类型(幻觉/遗漏/格式差/正确)
   └── 作为Fine-tune和改进的依据

4. 用户反馈 (Continuous):
   ├── 👍/👎 按钮 (每次回答后)
   ├── "答案不准确" → 可选填原因
   ├── "找不到相关文档" → 触发Gap Analysis
   └── 反馈数据用于持续优化

Quality Dashboard:
  ┌────────────────────────────────────────────┐
  │  RAG Quality Dashboard (Last 7 Days)       │
  ├────────────────────────────────────────────┤
  │  Faithfulness:  92.3% (↑1.2%)  ████████▌  │
  │  Relevance:     87.1% (↓0.5%)  ████████▏  │
  │  Context Recall: 81.5% (↑2.0%) ████████   │
  │  User Satisfaction: 4.2/5 (↑0.1)          │
  │  Unanswerable Rate: 8.3% (↓1.1%)          │
  └────────────────────────────────────────────┘

七、Step 6: 扩展讨论

7.1 多租户RAG

多租户挑战:
  ├── 不同团队的文档不能交叉检索
  ├── 但有些文档是全公司共享的
  ├── 权限可能是层级的(部门→组→个人)
  └── 部分团队可能需要独立的Embedding模型

架构方案:

Collection策略:
  ├── shared_knowledge: 全公司共享文档
  ├── dept_{dept_id}: 部门级文档
  └── team_{team_id}: 团队级文档

查询时:
  user_collections = [
    "shared_knowledge",
    "dept_engineering",
    "team_backend"
  ]
  results = vector_db.search(
    query_embedding,
    collections=user_collections,
    filter={"access_level": {"$lte": user.clearance}}
  )

7.2 增量更新

增量更新Pipeline:

Challenge:
  文档更新/删除时, 对应的chunks和vectors也要更新
  不能简单重建全部索引(50万文档太慢)

方案: Change Data Capture (CDC)

1. 文档变更检测:
   ├── Confluence Webhook → 实时通知
   ├── S3 Event Notification → 新增/修改/删除
   └── 定时扫描 → checksum对比

2. 增量处理:
   新增文档: Parse → Chunk → Embed → Insert
   更新文档: Delete old chunks → Re-process → Insert new
   删除文档: Delete all related chunks + vectors

3. 索引一致性:
   ├── 用doc_id关联所有chunks
   ├── 更新时用事务: Delete + Insert (原子性)
   └── 异步重建不影响查询(双写策略)

4. 版本管理:
   ├── 保留文档历史版本
   ├── 用户可以选择"查当前版本"或"查历史版本"
   └── 审计要求: 保留完整变更历史

7.3 多语言支持

多语言RAG挑战:
  ├── 文档是中文, 用户用英文提问(反之亦然)
  ├── 专业术语的跨语言对齐
  └── 不同语言的Chunking策略不同

方案:

方案A: 多语言Embedding (推荐)
  ├── 使用多语言模型: Cohere multilingual / BGE-M3
  ├── 中文文档和英文query在同一语义空间
  ├── 不需要翻译, 直接跨语言检索
  └── 优点: 简单 / 缺点: 质量不如单语言

方案B: 翻译后检索
  ├── 将所有文档翻译为英文(或统一语言)
  ├── 检索时先翻译query再搜索
  └── 优点: 质量高 / 缺点: 翻译成本

方案C: 双塔索引
  ├── 每个文档同时存中文和英文embedding
  ├── 查询时根据query语言选择对应索引
  └── 优点: 灵活 / 缺点: 存储2倍

我们的方案: 方案A (多语言Embedding) + 关键文档方案B兜底

7.4 多模态RAG

多模态挑战:
  ├── 文档中有图表(架构图/流程图/数据图)
  ├── 图表包含重要信息, 纯文本RAG会丢失
  └── 用户可能问"那个架构图里的组件有哪些?"

方案:

1. 图片描述 → 文本化:
   使用Vision LLM(GPT-4o/Claude)为图片生成文字描述
   将描述作为额外chunk存入向量库

2. 多模态Embedding:
   使用CLIP/SigLIP将图片和文本映射到同一空间
   支持文本query检索图片

3. 表格结构化:
   将PDF中的表格提取为Markdown/JSON
   对结构化数据支持SQL-like查询

混合方案:
  PDF → 文本chunks + 图片描述chunks + 表格Markdown chunks
  → 统一embedding + 统一检索

八、常见追问及应答

追问 1: "Chunking大小怎么选?"

回答:
  没有银弹, 取决于:
  ├── 文档类型: 技术文档(256-512), 长报告(512-1024)
  ├── 模型context: chunk_size < model_context / 10
  ├── 查询类型: 精确事实(小chunk), 概述理解(大chunk)
  └── 实验验证: 最终靠评估指标决定

  经验法则:
  ├── 起始: 512 tokens, overlap 50
  ├── 然后用Golden Test Set测试不同大小
  ├── 256 / 384 / 512 / 768 / 1024 各跑一遍
  └── 选RAGAS分数最高的

追问 2: "如何处理答案中的幻觉?"

回答:
  三道防线:

  1. Prompt Engineering:
     "Only answer based on the provided context.
      If the context doesn't contain the answer, say 'I don't have
      enough information to answer this question.'"

  2. NLI Verification:
     对答案每个句子, 用NLI模型验证是否被Context entail
     Score < 0.5 → 标记为"未验证"

  3. Confidence Scoring:
     综合Context Relevance + NLI Score + Model Confidence
     低置信度答案:
       ├── 添加警告标记
       ├── 推荐用户查看原始文档
       └── 进入人工审核队列

追问 3: "文档量从50万增长到500万怎么办?"

回答:
  Scaling Strategy:

  1. 向量库: Qdrant分片(Sharding)
     ├── 按部门分片(天然的数据分区)
     ├── 或按时间分片(热数据/冷数据)
     └── Qdrant支持自动分片, 透明扩展

  2. Ingestion: 并行化
     ├── 当前: 单Worker处理
     ├── 扩展: Kafka + 多Consumer Worker
     └── 目标: 处理速度从100 docs/hr → 10K docs/hr

  3. 缓存: 更积极
     ├── 增加缓存容量
     ├── 预计算热门查询
     └── 按部门预热缓存

  4. 分层存储:
     ├── Hot: 最近3个月的文档 (SSD/内存)
     ├── Warm: 3-12个月 (SSD)
     └── Cold: >12个月 (HDD/对象存储)

追问 4: "如何衡量RAG系统的ROI?"

回答:

  成本:
    ├── 基础设施: ~$5K/month
    ├── LLM API: ~$5K/month
    ├── 开发维护: 2 engineers × $15K/month = $30K
    └── 总成本: ~$40K/month

  收益:
    ├── 员工效率提升:
    │   5000员工 × 30min/day节省 × $50/hr = $62.5K/day
    │   月收益: ~$1.25M/month
    ├── 减少重复咨询: HR/IT support ticket减少40%
    ├── 决策加速: 找信息从2h → 5min
    └── 合规风险降低: 减少信息不一致导致的合规问题

  ROI: (1.25M - 40K) / 40K ≈ 30x
  → 这就是企业愿意投资RAG的原因

九、面试评分要点

RAG系统设计评分标准:

Must-have (必须提到, 否则扣大分):
  ├── Chunking策略的选择和理由
  ├── Hybrid Search (不能只有Dense)
  ├── Reranking (检索质量的关键)
  ├── 权限控制 (企业场景必须)
  ├── 评估方案 (如何知道RAG是否work)
  └── Citation (答案必须可溯源)

Nice-to-have (提到加分):
  ├── Query Rewriting / HyDE
  ├── Semantic Cache
  ├── 增量更新Pipeline
  ├── 多语言/多模态
  └── 成本分析

Red flags (面试官会扣分):
  ├── 只用Dense Retrieval, 不提Hybrid
  ├── 不提权限控制(企业场景必须)
  ├── 不提评估("怎么知道你的RAG好不好?")
  ├── Chunk size说"512就行"不给理由
  └── 不提幻觉处理

十、今日总结

Day 44 核心收获:

1. RAG四大Pipeline:
   Ingestion → Retrieval → Generation → Evaluation
   每个环节都有多种策略选择

2. 最影响质量的三个环节:
   ├── Chunking: 切分策略决定了检索的上限
   ├── Hybrid Search + Reranking: 检索质量的关键
   └── Evaluation Loop: 没有评估 = 盲人摸象

3. 企业RAG特殊要求:
   权限控制 + 审计日志 + 引用溯源 + 多租户

4. 面试关键:
   不要只画架构, 要深入Chunking/Retrieval/Evaluation
   说清楚每个选择的Why和Trade-off

明天: Day 45 — 设计一个AI Agent系统

参考资源: