Appearance
RAG 服务化与企业级工程
方向定位:聚焦 RAG 从"能跑"到"扛得住、安全合规、可水平扩展"的工程命脉——回答企业级 RAG 与 demo 级 RAG 之间的真实差距。包括分段瓶颈识别(embedding/召回/rerank/LLM 四段吞吐差两个数量级)、Token 维度限流(TPM/RPM 替代 RPS)、三级缓存矩阵(按 KB 版本失效)、Continuous Batching 吞吐-延迟权衡、企业级权限控制(Pre-filtering + 多租户三种隔离 + 动态权限)、百万级文档存储架构(MySQL+ES+MinIO+Kafka)、HNSW 参数调优、状态外置与水平扩展、WebSocket vs SSE、多模态 RAG(音频/视频)。不研究文档切分(→ RAG 文档处理与 Chunk 工程)、不深入检索质量优化(→ RAG 检索质量与排查)、不讨论 RAG 整体动机(→ RAG 基础与评估体系)。 当前版本:v0.2 首次构建:2026-05-15 最近更新:2026-05-19 文件名日期同步:2026-05-15 来源数:3 篇(08, 23, 26)
方向定位
RAG 服务化与企业级工程研究的核心问题是:"demo 跑通后,如何让 RAG 扛 800 QPS、过安全审计、做多租户隔离、水平扩展不掉数据"。它的边界包括:
- 包含:四段链路吞吐能力分布、分段瓶颈识别方法、Token 限流的 TPM/RPM 双闸口、三级缓存矩阵与 KB 版本失效、Continuous Batching 长尾权衡、Pre-filtering 权限控制、多租户三种隔离粒度(Metadata/Partition/Collection)、动态权限缓存、向量库选型对比、百万级文档存储架构、HNSW 参数与冷热分层、状态外置与水平扩展、WebSocket vs SSE 选型、多服务器 WebSocket 部署、ASR/CLIP/视觉大模型多模态检索
- 不包含:Chunk 切分策略(→《RAG 文档处理与 Chunk 工程》)、Query 改写与 Rerank 质量算法(→《RAG 检索质量与排查》;本方向只讲 Rerank 在容量层面的影响与限流策略)、检索质量评估指标定义(→《RAG 基础与评估体系》)
- 与相邻方向的区别:本方向只回答"扛得住、过审计、能扩容",不回答"切得对不对""找得准不准"
服务化与企业级工程是 RAG 从 demo 走到生产的护城河——不解决这些问题,再准的检索也无法上线服务真实流量。
知识图谱
- 分段瓶颈识别
- 四段:embedding / 召回 / rerank / LLM
- 吞吐差两个数量级
- 崩的几乎一定是 LLM 段
- 一刀切扩容是浪费
- Token 限流
- 入口 RPS ≠ LLM token 消耗
- 长 query 短 query 成本差 25 倍
- 限流位置:LLM Gateway 前
- 维度:user_id × model_name
- 双闸口:TPM + RPM
- 三级缓存矩阵
- query→embedding:零风险
- 检索结果(query→docs):KB 版本失效
- query→answer:高风险,仅 FAQ 白名单
- 三道防线:KB 版本号 + TTL 分级 + 命中后 cosine 校验
- Continuous Batching
- 吞吐翻 3~5 倍
- 同 batch 长尾被放大
- P99/P50 > 5 倍 = 长尾问题
- 在线/离线/强 SLA 三场景策略
- Pre-filtering 权限控制
- Post-filtering 三个根本问题
- 数据访问 vs 展示层
- JWT 服务端验证
- 四种权限元数据模型
- 多租户三种隔离粒度
- Metadata:低成本低安全
- Partition:中等
- Collection:物理隔离最彻底
- 推荐:Partition + Metadata 双重防护
- 动态权限
- 不写死在 Chunk 元数据
- 关系型数据库实时 JOIN
- Redis 短时缓存 + 离职主动失效
- 存储架构
- MySQL:元数据
- ES:向量+关键词(5000 万 chunk × 2048 维 ≈ 400GB)
- MinIO:原始文件
- Redis:缓存/Session
- Kafka:异步任务
- HNSW 参数
- m=16, ef_search=100
- O(log N) 复杂度
- 冷热分层 SSD+HDD
- 状态外置
- 文件→MinIO,任务→Kafka,Session→Redis
- 服务无状态,前面加 LB
- WebSocket vs SSE
- SSE 单向,WebSocket 双向
- RAG 选 WS:要支持停止生成
- 多服务器:粘性会话 vs Redis Pub/Sub
- 多模态 RAG
- 音频:ASR → 文字稿 → 时间戳切分
- 视频帧 Embedding(CLIP)vs 视觉大模型描述
核心概念
概念 1:四段链路吞吐能力分布——崩的几乎一定是 LLM
来自字节 AI 平台架构面真题(26 号笔记)。
链路结构:embedding → 向量召回 → rerank → LLM 生成
| 段 | 资源 | 单实例吞吐 | 相对成本 |
|---|---|---|---|
| ① embedding(文字转向量) | CPU | 几千 QPS / 节点 | 1x(基准) |
| ② 向量召回(找近邻,Faiss/Milvus) | 单机内存 | 几百~千 QPS | 5~10x |
| ③ rerank(cross-encoder 候选重排) | 单卡 GPU | 几十 QPS | 30~50x |
| ④ LLM 生成(写答案) | 单卡 GPU | 个位数 QPS(output 1k token ≈ 1~3 秒) | 100x+ |
结论:晚上活动崩的几乎一定是 LLM 段,先去看 LLM 排队队列长度,别先翻 nginx 日志。最容易翻车的回答是"加机器、上 GPU、换更大的模型"——根本错误是没把链路分段。一刀切扩容会出现"最贵的 GPU 闲着、瓶颈段还是没救"的尴尬局面。
Rerank 段的算法层减负(候选规模优先、分层精排、长尾砍头部稳)属于检索质量方向,详见《RAG 检索质量与排查》框架 4~8;本方向只讲"算法已经优化到位后,容量怎么稳"。
概念 2:限流单位必须从 RPS 切换到 token
入口 nginx 看到的是 1 个请求,但到 LLM 那里这 1 个请求可能烧 200 token、也可能烧 5000 token——成本差 25 倍。
| 限流单位 | 问题 |
|---|---|
| RPS(按请求数) | 限严了便宜请求白白被拒,限松了贵请求照样烧爆 GPU |
| Token(按 input + output) | 与 GPU 真实代价对齐 |
正确做法:把限流挪到 LLM Gateway 前面,按 input token(tokenizer 实算)+ output token(预估值)的总和做配额,按 user_id × model_name 维度配 TPM / RPM 双闸口。
概念 3:缓存命中率不是越高越好——按风险等级分层启用
三种 RAG 缓存的安全性差一个数量级:
| 缓存类型 | 失效条件 | 风险 |
|---|---|---|
| query→embedding | embedding 模型版本变 | 零风险 |
| 检索结果(query→docs) | 知识库 (KB) 版本变 | 中等:旧 KB 命中导致答案过期 |
| query→answer | KB 变 + query 语义相似度 | 高:旧答案是定时炸弹 |
优先顺序应该是先零风险、再可控风险、最后高风险,而不是按命中率高低决定上线顺序。
概念 4:权限控制是数据访问层问题——不是展示层问题
来自吴师兄公众号文章(08 号笔记)。
后置过滤(Post-filtering)的三个根本问题:
| 问题 | 说明 | 影响 |
|---|---|---|
| 数据访问已发生 | 向量检索本身就是数据读取,不管是否展示 | 违反最小权限原则,过不了安全审计 |
| Top-K 名额被占用 | 用户只能访问 40% 文档时,Top-5 实际可用只剩 Top-2 | 检索质量严重下降 |
| 多租户信息泄漏 | 不同租户文档共享向量空间,检索时相互"可见" | 合规场景不可接受 |
权限控制不是展示层的问题,是数据访问层的问题。你在错误的地方做了正确的事。
概念 5:多租户隔离三种粒度——选型取决于合规要求
| 策略 | 物理隔离 | 安全性 | 成本 | 适用场景 |
|---|---|---|---|---|
| Metadata 过滤 | 否 | 低(bug 可暴露全量数据) | 低 | 内部低敏感知识库 |
| Partition 隔离 | 部分 | 中 | 中 | 中等安全的 SaaS |
| Collection 隔离 | 完全 | 高 | 高 | 金融/医疗强合规 |
推荐方案:Partition + Metadata 双重防护(纵深防御)。任何单一防线都可能失败,所以叠加多层。
概念 6:状态外置——水平扩展的核心
| 状态类型 | 外置方案 |
|---|---|
| 文件 | MinIO 对象存储 |
| 异步任务 | Kafka(多机消费同一 topic) |
| Session | Redis(Session 共享) |
| 数据 | MySQL / ES |
服务本身不保存任何状态 → 随时可以扩缩容,前面加负载均衡即可。接口无状态 vs 有状态:
- 无状态接口(可任意横向扩展):搜索、生成、文档列表查询、健康检查
- 有状态接口:文件上传(→ 改 MinIO)、WebSocket 长连接(→ Redis Pub/Sub)
概念 7:经验内化风险——RAG 调用外部大模型的隐性数据外泄
来自 [商业策略/10] SaaS 数据生死局 [来源 #4]。RAG 系统调用外部大模型 API 时存在一个被低估的隐性风险——即便原始数据"用完即焚",大模型已通过调用过程"偷学"了行业业务规律。
三步走偷师机制:
- 调取资料:通过 API 抓取业务数据(成本明细、销售折扣等)
- 分析算账:算力分析数据,给出精准商业结论
- 经验内化(关键):删除原始数据后,行业成本波动规律、提成返点逻辑等隐藏知识已被内化为底层能力——偷走的不是数字,而是"老中医看病经验"
对 RAG 工程的直接影响:
- 本方向(多租户隔离 / 权限控制)解决的是显性数据泄漏(A 租户能否看到 B 租户文档)
- 经验内化是隐性数据泄漏(即便文档隔离了,调用外部模型的"中间过程"依然在喂养通用模型)
三大防御手段在 RAG 上的工程对应:
| 商业策略原概念 | RAG 工程实现 | 与本方向其他概念的接合 |
|---|---|---|
| 业务黑盒(只给结论) | RAG 系统在 Prompt 构造层做"数据脱敏中间件",关键指标用枚举/分桶替代精确值 | 与概念 4「Pre-filtering」叠加:先过滤再脱敏 |
| 私有化部署(算力下乡) | 用百亿级开源模型(Qwen2.5 / DeepSeek V3)本地推理替代外部 API | 与概念 6「状态外置」镜像:把"模型"也当作可外置/可内置的状态 |
| 数据水印 | 在 RAG 输出中嵌入用户/租户专属标记,用于事后法律取证 | 与多租户隔离形成"事前隔离 + 事后取证"组合 |
与药饵攻击(《AI 系统安全攻防体系》案例 A)的对比: 药饵攻击是"对手主动污染你的训练数据",经验内化是"你主动用 API 喂养对手"——攻击源相反,结果一致:行业知识被通用模型吸收。RAG 工程师应同时防御两条路径。
方法论与框架
框架 1:分段瓶颈识别图——任何 RAG 性能讨论的第一张图
实操动作:把当前业务的 embedding / 召回 / rerank / LLM 单实例 QPS 写下来贴在墙上。任何 RAG 性能讨论的第一张图就是这个——没有这张图就讨论扩容,必然是浪费 GPU。
框架 2:Token-based 限流的工程实现
最简版本:
位置:LLM Gateway 层(自研 / Portkey / LiteLLM)
存储:Redis 令牌桶
维度:user_id × model_name 二维配额
input token:tokenizer 精确计算
output token:预估上限(如 max_tokens=800)
扣额时机:调用 LLM 之前
超额处理:429 直接拒掉 或 进入排队队列
双闸口:TPM(每分钟 token 数)+ RPM(每分钟请求数)框架 3:Continuous Batching 场景选择矩阵
机制:多条请求塞同一个 GPU 一起跑(vLLM 等主流推理框架的默认机制,2026-05 时点)。 收益:吞吐翻 3~5 倍。 代价:你的请求必须等"队友"——同 batch 里只要有人写超长答案,整条 batch 都要等他写完,你的延迟被拖到他的水平。
| 场景 | 是否开 continuous batching | 原因 |
|---|---|---|
| 在线客服 | 开,但盯紧 P99 延迟 | 吞吐重要,但用户感知延迟不能爆 |
| 离线批处理 | 无脑开 | 吞吐唯一目标,延迟无所谓 |
| 强 SLA(金融/医疗等延迟可预测场景) | 反而用固定 batch | 长尾延迟不可接受 |
长尾被放大的诊断方法:
- 分桶看 P50 / P95 / P99 延迟随 batch size 的变化
- 同时把 input / output token 长度分布画出来
- 如果 P99 / P50 > 5 倍,说明长尾被 batch 放大
- 修复路径:① 用
max_tokens强约束输出长度 ② 把长输入用户分到独立 pool
框架 4:三级缓存矩阵与启用优先级
| 缓存类型 | 命中省什么 | 失效条件 | 风险 | 启用顺序 |
|---|---|---|---|---|
| ① query→embedding | 一次 embedding 推理 | embedding 模型版本变 | 零风险 | 第一优先 |
| ② 检索结果(query→docs) | 召回 + rerank 两段 | 知识库 (KB) 版本变 | 中等 | 第二优先(按 KB 版本失效) |
| ③ query→answer | 整条链路 | KB 变 + query 语义相似度 | 高 | 仅在 FAQ 类白名单场景启用 |
query→answer 缓存的三道防线(启用前必须配齐):
- 缓存 key 含 KB 版本号:ETL 跑完
KB_VER += 1,旧 key 自然失效,无需手动 invalidate - TTL 按知识稳定性分级:FAQ 类 24h,政策类 1h,实时数据类 0(不缓存)
- 命中后做轻量校验:把当前 query 重新 embedding,与缓存中原 query embedding 做 cosine 相似度,< 0.95 视为不同问法,不命中
反向操作建议:先列"什么 query 不能缓存"的负面清单(含时间、含个人化、含计算),剩下的才进缓存——而不是先缓存了再补漏。
框架 5:Pre-filtering 实现架构
用户请求 → JWT Token 服务端验证(不信任前端参数)
→ 解析用户权限(dept/role/classification)
→ 构造 metadata filter 条件
→ 只在有权文档子集中做向量检索
→ 返回结果四种权限元数据模型(这些字段是在《RAG 文档处理与 Chunk 工程》Chunk 元数据基础上的企业级扩展):
| 模型 | 字段示例 | 适用场景 |
|---|---|---|
| 部门级 | dept_id = ["finance", "hr"] | 按部门划分知识库 |
| 角色级 | required_role_level = 3 | 按职级分层访问 |
| 文档密级 | classification = "confidential" | 政府/军工/金融 |
| 用户白名单 | allowed_user_ids = ["u001"] | 精细化个人级控制 |
框架 6:向量数据库 Pre-filtering 能力对比
| 向量数据库 | Filter 支持 | Pre-filtering 效率 |
|---|---|---|
| Milvus | 完整,复杂布尔表达式 | 高(索引级过滤) |
| Qdrant | 完整,payload filter | 高(与向量搜索完全集成) |
| Weaviate | 支持,where filter | 中高 |
| Chroma | 基础,仅 eq/in | 中 |
| FAISS | 不原生支持 | 低(需外部实现) |
框架 6.1:多租户 RAG 隔离——PM 视角的 5 条工程决策规则
框架 6 给出了向量库 Pre-filtering 能力对比,本框架从 PM / 产品负责人视角把多租户 RAG 隔离拆解为 5 条需要做决策的工程规则。
商业含义:RAG 多租户隔离是 B 端 Agent SaaS 的合规准入门槛。金融、医疗、政企客户通常在合同中明确"数据泄漏即解约 + 赔偿",单次检索错漏(A 租户召回 B 租户文档)的事故成本可能等于该客户 5-10 年 ARR。
| # | 工程规则 | PM 决策点 | 风险 / 机会 |
|---|---|---|---|
| 1 | tenant_id 必须是检索链路的第一道 filter,在向量相似度计算之前执行(Pre-filtering),而非在结果返回后过滤(Post-filtering) | 选型时优先选原生支持 Pre-filtering 的向量库(Milvus / Qdrant),见框架 6 对比 | 🚨 Post-filtering = 向量库已经"看过"无权文档,过不了安全审计 |
| 2 | 双重防护:Partition + Metadata,任何单一防线都可能失败 | 与概念 5 三粒度对齐:内部低敏感用 Metadata;中等 SaaS 用 Partition + Metadata;金融强合规用 Collection 隔离 | 🚀 纵深防御可作为安全卖点写入合同 SLA |
| 3 | 检索结果必须做 tenant_id 二次校验——即使 Pre-filtering 正确执行,也要在应用层校验返回文档的 tenant_id 与当前租户一致 | 工程成本极低(一行代码),但缺失时出事故无法自辩 | 🚨 缺失校验 = 审计报告不合格 |
| 4 | 向量库厂商的租户隔离能力直接影响选型——不同厂商的 Pre-filtering 效率差异显著 | 选型决策表(补充框架 6 的 PM 视角)见下方 | 🚀 选对向量库 = 省掉大量自建隔离层的工程成本 |
| 5 | 经验内化防御与显性隔离必须并行——即便文档隔离了,调用外部模型 API 的"中间过程"仍在喂养通用模型 | 与概念 7(经验内化风险)联动:高敏感租户应使用本地推理(Qwen / DeepSeek)替代外部 API | 🚨 显性隔离 + 隐性泄漏 = 合规审计的盲区 |
向量库选型决策表(PM 视角补充):
| 向量数据库 | Pre-filtering | 多租户原生支持 | PM 选型建议 |
|---|---|---|---|
| Milvus | 索引级过滤,效率高 | Partition Key 原生支持按 tenant 分区 | 首选:大规模多租户 SaaS |
| Qdrant | Payload filter 完全集成 | 支持 Payload 索引做租户过滤 | 首选:中小规模、快速上线 |
| Weaviate | Where filter,中高 | 支持多租户模式(v1.20+) | 可选:已有 Weaviate 技术栈的团队 |
| Chroma | 仅 eq/in,基础 | 无原生多租户 | 不推荐:生产多租户场景 |
| FAISS | 不原生支持 | 无 | 不推荐:需要自建全部隔离层 |
可行动项:
- P0 → 对照上述 5 条规则,逐条检查当前 RAG 系统的隔离状态,输出"隔离缺口清单"(PM + 工程,2 周内完成)
- P1 → 若当前向量库不支持 Pre-filtering,立项评估迁移到 Milvus / Qdrant 的成本与时间线(工程,1 月内完成评估报告)
(来源:多租户 Agent 隔离设计实践,B2B SaaS 工程向,2026-05-20;与 Agent工程实践与工具生态 第四章联动)
框架 7:动态权限变更设计原则
- 不要:把权限写死在 Chunk 元数据里(部门重组时要更新数千条记录)
- 要:权限关系存关系型数据库,Chunk 只存 doc_id,检索时实时 JOIN
- 缓存优化:Redis 短时缓存(30-60s)accessible_doc_ids
- 离职即时生效:权限服务触发离职事件时,同步删除该用户所有缓存条目
TTL 权衡:60 秒 TTL 意味着权限变更最多 60 秒延迟,离职场景需主动失效。
框架 8:百万级文档存储架构
存储分工原则:
MySQL → 文档元数据(文件名、路径、上传时间、分类、用户)无大字段,几 GB 搞定
ES → 向量数据 + 关键词,真正的存储大头
MinIO → 原始文件对象存储
Redis → 缓存/Session
Kafka → 异步任务ES 存储规模估算:
百万文档 × 50 chunk/文档 = 5000 万 chunk
5000 万 × 2048 维 × 4 字节 ≈ 400 GB 向量数据ES 存储优化手段:
| 手段 | 效果 |
|---|---|
| HNSW 向量索引(ES 8.x+) | 检索速度提升 10x+,无需暴力遍历 |
| 冷热分层(SSD + HDD) | 热数据高性能,冷数据低成本 |
检索层优化:
- 先过滤再向量搜索:用 term 查询缩小候选集,再做向量相似度计算(计算量减少 90%+)
- HNSW 参数:
m=16(每层邻居数),ef_search=100(检索候选数),准确率与延迟实测最优平衡点 - 缓存热门查询:80% 查询集中在 20% 热门问题,Redis 缓存命中率可达 40%+
实测性能:5000 万条 2048 维向量,P99 延迟 ≤100ms。
HNSW 检索复杂度是 O(log N),和维度关系不大,所以 2048 维 vs 1024 维差异没想象中大
框架 9:文件上传双层限制
业务层限制:
- 单次上传 ≤20 个文件,单文件 ≤50MB
- 文件类型白名单:PDF、Word、TXT、Markdown
系统层限制(真正的瓶颈在文档解析和向量化):
- 50MB PDF 可能有几百页,解析+切片+向量化全流程 ≈ 几分钟
- 20 个大文件同时上传 → 任务队列堆积
解决方案:异步处理——上传后立刻返回成功,后台 Kafka 异步消化(具体的切分策略、表格/列表/图片处理见《RAG 文档处理与 Chunk 工程》),前端进度条 + 完成通知。
防恶意上传:
- 按用户维度:每天上传总量 ≤500MB
- 按 IP 维度:限制并发上传数
- 每天 Embedding 额度限制
框架 10:WebSocket vs SSE 选型
| 特性 | SSE | WebSocket |
|---|---|---|
| 通信方向 | 单向(服务端 → 客户端) | 双向 |
| 优雅中断生成 | 不支持(只能关闭整个连接) | 支持(客户端发 stop 消息) |
| 流程进度推送 | 可以 | 可以 |
| 适用场景 | 简单"问-答"流式 | 需要中断、多阶段进度的 RAG 流程 |
RAG 选 WebSocket 的原因:
- 用户需要"停止生成"功能
- 处理流程长(检索→重排→prompt 拼装→生成),需要多阶段进度推送
- 客户端可在任何阶段发消息取消任务
WebSocket 多服务器部署:
方案 1:粘性会话(Sticky Session)
nginx
upstream backend {
ip_hash; # 同一 IP 路由到同一台服务器
server 192.168.1.1:8080;
server 192.168.1.2:8080;
}- 优点:配置简单
- 缺点:服务器挂了,上面所有连接全断
方案 2:Redis Pub/Sub 消息广播(高可用推荐)
- 服务器收到推送消息 → 发布到 Redis 频道
- 所有服务器订阅该频道
- 持有目标连接的服务器负责推送
- 优点:服务器挂了,用户重连即可
框架 11:多模态 RAG 处理流程
纯音频场景:
音频 → ASR → 文字稿(带时间戳)→ 按时间戳切分 → Embedding → 向量库
查询 → 语义检索 → 相关片段 + 时间戳 → 生成回答ASR 模型选择:
| 模型 | 类型 | 特点 |
|---|---|---|
| Whisper(OpenAI) | 开源 | 多语言,综合性价比最高 |
| FunASR(阿里) | 开源 | 中文优化 |
| SenseVoice(阿里) | 开源 | 多模态语音 |
| 阿里云/腾讯云/火山引擎 | 商用 API | 稳定,按量付费 |
视频(需要画面信息):
方案 A:帧 Embedding(CLIP 系列)
视频抽帧(每秒 1 帧)→ 多模态 Embedding → 向量库
查询 → 同模型向量化 → 检索最相关帧 → 定位时间戳- 缺点:计算成本高(1 小时视频 = 3600 帧,每帧都要 Embedding)
方案 B:视觉大模型描述(最新趋势)
视频片段 → Qwen-VL / InternVL / GPT-4V → 结构化文字描述(含画面/动作/场景)
→ 按时间戳切分 → 向量化检索- 优点:理解画面语义关系,描述质量高
- 缺点:成本高,处理慢,token 消耗大
案例库
案例 1:电商客服 RAG 800 QPS 扛量改造(GPU 没加,P95 30s→1.8s)
场景:白天 200 QPS 平稳,晚上整点活动推送瞬间冲到 800 QPS,LLM 段排队 30 秒,前端大面积超时。
改造四步法:
| 步骤 | 动作 | 关键设计 | 效果 |
|---|---|---|---|
| 1 | embedding 缓存先上 | key = query 文本 hash;embedding 模型版本变才失效 | 热门问题命中率 60%+,embedding 段 CPU 占用降一半 |
| 2 | 检索结果缓存按 KB 版本失效 | key = (q_emb 量化, KB_VER);KB ETL 跑完版本号 +1,旧 key 自然过期 | 向量库 + rerank QPS 降 35%,rerank GPU 不再排队 |
| 3 | token 配额挡在 LLM 前 | Redis 令牌桶,user_id × model 维度;input tokenizer 实算 + output 预估上限 800;超额 429 | LLM 队列长度从 200+ 降到 < 20,雪崩消失 |
| 4 | query→answer 缓存有限开 | 仅 FAQ 类白名单 intent,TTL 1h,命中前 cosine ≥ 0.95 二次校验 | FAQ 流量整链路命中率 45%,活动峰值 LLM 调用量降 35% |
改造前后对比(数据来源:内部回归集,2026-05):
| 指标 | 改造前 | 改造后 | 变化 |
|---|---|---|---|
| 峰值 QPS | 800 | 800 | 不变 |
| LLM 实际调用 QPS | 800 | 520 | -35% |
| P95 延迟 | 30s | 1.8s | -94% |
| 超时率 | 12% | 0.3% | -97.5% |
| 单次请求成本 | 基准 | -35% | -35% |
最关键的事:GPU 没加,靠分段缓存 + token 限流救回来。
案例 2:字节 AI 平台架构面真题——容量维度错位
候选人答"加机器、换大显卡",面试官追问"你算过单卡 token/s 折成 QPS 是多少吗?"候选人卡住——这道题表面问扩容,实际考的是能否区分"入口 RPS"和"LLM token 消耗"两个完全不同维度的容量。
案例 3:金融保险 5000 份合同多租户隔离
- 场景:5000 份合同文档,按保险公司分租户
- 方案:Qdrant Partition 隔离 + Metadata 双重过滤
- 缓存 TTL 权衡:60 秒 TTL 意味着权限变更最多 60 秒延迟,离职场景需主动失效
案例 4:京东面试现场——后置过滤的安全审计陷阱
面试官追问:用户用 Post-filtering 实现权限——"你在错误的地方做了正确的事"。
- 数据访问已经发生:向量数据库已经检索出了无权文档,只是 UI 没展示
- 不能过安全审计:违反最小权限原则
- 修复方向:迁移到 Pre-filtering,在向量相似度计算之前用权限条件过滤
案例 5:单卡 LLM 吞吐量级参考
- 单卡 LLM 生成 output 1k token 约 1~3 秒
- 折合单卡 QPS:个位数到十几个(取决于模型大小、output 长度、是否开 batching)
- 因此当入口 QPS 上千时,必须靠限流 + 缓存 + batching 把 LLM 实际调用量压下来
案例 6:派聪明 RAG 简历写法(用数据替代"实现 XXX 功能")
设计文档切片引擎,512 token 递归切分 + 段落感知,检索精确率 68% → 89%
ES HNSW + 混合检索,支撑百万级 chunk,2048 维向量 P99 延迟 ≤100ms
bge-reranker-v2-m3 重排,Top-5 命中率提升 23%,MRR 0.61 → 0.78
WebSocket + Redis Pub/Sub,支持多服务器流式推送和高可用
Kafka + MinIO 异步流水线,单日处理能力 5000+ 文档关键洞察
- RAG 扛量不靠堆 GPU,靠分段+限流+缓存三件套——四段链路吞吐差两个数量级,最贵的 GPU 经常闲着,瓶颈段照崩。先画分段瓶颈图再讨论扩容
- 限流单位是 token 不是 RPS——长 query 短 query 成本差 25 倍,按 RPS 限流要么过严要么过松;TPM/RPM 双闸口才与 GPU 真实代价对齐
- 缓存按风险等级启用,不是按命中率高低——零风险 embedding 缓存先上、KB 版本失效检索缓存第二、FAQ 白名单 answer 缓存最后;先列"什么不能缓存"的负面清单
- 权限是数据访问层问题,不是展示层问题——Post-filtering 看似能用,但向量库已经检索过无权文档,过不了安全审计。Pre-filtering 是企业级 RAG 与 demo 级的硬差距
- 多租户隔离是纵深防御问题——单一防线必有失效场景,Partition + Metadata 双重防护是工程默认值
- 动态权限不能写死在 Chunk 元数据里——部门重组会要更新数千条记录;正确做法是 doc_id 关联+关系型数据库 JOIN+Redis 短缓存+离职主动失效
- 状态外置是水平扩展的命脉——文件→MinIO,任务→Kafka,Session→Redis,服务无状态才能任意扩缩容
- WebSocket 比 SSE 适合 RAG——流程长(检索→重排→prompt→生成)+ 用户要"停止生成"+ 多阶段进度推送,SSE 单向连接撑不住
- HNSW O(log N) 让 2048 维 vs 1024 维差异不明显——别为了"省存储"降维度而牺牲语义精度,性能瓶颈基本不在维度上
- content batching 长尾要监控 P99/P50——比值 > 5 倍说明被 batch 拖了,max_tokens 强约束 + 长输入用户独立 pool 是修复路径
- Chunk 切分讲质量,本方向讲性能——质量差再快也没用,性能不行再准也上不了线,两者是 RAG 工程的两条主线
- 多租户 RAG 隔离的商业价值远超工程成本——tenant_id Pre-filtering + Partition 双重防护的工程成本极低(选对向量库后几乎是配置项),但缺失时单次数据泄漏事故的赔偿可达客户 5-10 年 ARR。向量库选型时"是否原生支持多租户"应作为一票否决项——自建隔离层的成本远高于换库[来源 #5]
相关链路
- 上一步:为什么要 RAG?怎么评? → 《RAG 基础与评估体系》——任何扛量改造都要先有指标基线
- 上游:切分质量决定异步流水线消化什么 → 《RAG 文档处理与 Chunk 工程》——文件上传双层限制下游接的就是该方向的切分管道
- 上游:检索算法决定 Rerank/缓存命中模式 → 《RAG 检索质量与排查》——Rerank 算法层的减负(候选规模、分层精排)与本方向的容量层兜底(限流、超时回退)需配合使用
待探索问题
- 多模型混合部署的 token 配额怎么分配:同一用户调用 Sonnet 和 Haiku 的 token 应不应该统一计费?还是按"成本权重"折算后再限?
- 缓存命中后的"鲜度感知":query→answer 缓存命中时,是否要在响应中带上
cached_at/kb_version字段,让前端可以在 UI 上提示"该答案基于 X 日前数据"? - 限流 vs 排队的产品决策:超额时直接 429 还是进入排队(带预估等待时间)?两种体验对客服场景的转化率影响如何度量?
- 多租户的成本分摊模型:Partition 隔离的实际存储成本怎么按租户计费?热点租户与冷门租户怎么差异化定价?
- 多模态 RAG 的存储爆炸:视频帧 Embedding(每秒 1 帧)+ 视觉大模型描述双方案叠加,存储成本是否可控?什么时点应该选 A 还是 B?
- 混合云部署的权限同步:私有化部署 + SaaS 的混合架构下,权限服务的状态怎么保持一致?
来源索引
| # | 来源 | 提炼日期 | 主要贡献章节 |
|---|---|---|---|
| 1 | 吴师兄公众号文章(企业级 RAG 权限控制) | 2026-04-03 | Pre-filtering 三大根本问题、四种权限元数据、向量库 Filter 对比、多租户三种隔离、动态权限设计 |
| 2 | 派聪明 RAG 真实面试题(阿里飞猪一面) | 2026-04-13 | 百万级文档存储架构、ES HNSW 参数、文件上传双层限制、状态外置、WebSocket vs SSE、多模态 RAG、简历写法 |
| 3 | AI 落地面试深水区·第 11 课(字节 AI 平台架构面) | 2026-05-15 | 四段链路吞吐分布、Token 限流 TPM/RPM、三级缓存矩阵与 KB 版本失效、Continuous Batching 长尾、电商客服 800 QPS 改造案例 |
| 4 | [商业策略/10] SaaS 数据生死局——大模型虹吸与三大防御手段 | 牛透社(用户提供正文) / 2026-04-13 | 概念 7(经验内化风险)/ 业务黑盒、私有化、数据水印在 RAG 工程上的对应 |
| 5 | 多租户 Agent 隔离设计实践:RAG 检索层隔离与向量库选型 | 用户提供文本(B 端 SaaS Agent 工程向)/ 2026-05-20 | 框架 6.1(多租户 RAG 隔离 5 条工程决策规则 + 向量库选型决策表)/ 关键洞察 12 |
演进记录
- v0.3(2026-05-20) — 由 /route-knowledge-pm 路由触发:新增框架 6.1"多租户 RAG 隔离——PM 视角的 5 条工程决策规则"(含向量库选型决策表 PM 补充 + 可行动项 P0/P1);新增关键洞察 12(多租户 RAG 隔离的商业价值远超工程成本);来源索引 +1(#5)
- v0.2(2026-05-19) — 与《RAG 检索质量与排查》理顺分工:概念 1 下加引用,明确 Rerank 算法层减负归属检索方向,本方向只讲容量层兜底。框架 5 权限元数据明确建立在 Chunk 元数据基础之上。框架 9 文件上传与 Chunk 方向打通。新增"相关链路"段,串起上游评估/切分/检索三条线。
- v0.1(2026-05-15) — 首次构建,由 /route-knowledge 路由分析触发。聚合 RAG/08(权限控制)、RAG/23(存储+扩展+多模态)、RAG/26(800 QPS 服务化)三个来源,初始化方向定位、知识图谱、核心概念(四段瓶颈/Token 限流/缓存风险分层/Pre-filtering/多租户三粒度/状态外置)、方法论 11 大框架(瓶颈图/Token 限流实现/Continuous Batching/三级缓存矩阵/Pre-filtering 架构/向量库对比/动态权限/百万级存储/文件上传双层/WebSocket-SSE/多模态)、案例库(800 QPS 改造/字节真题/金融多租户/京东审计/单卡量级/简历写法)与 11 条关键洞察。