订阅更新

企业知识库Agent:500万文档、300 QPS,数据链路怎么设计?

Agent手册 第 10 题 约 9 分钟读完

本文目录
  1. 30秒版回答
  2. 面试官在考什么
  3. 展开一:先澄清,再估算
  4. 展开二:离线索引链路
  5. 展开三:在线检索链路和延迟预算
  6. 展开四:降级策略
  7. 追问链
  8. 加分说法 vs 减分说法
  9. 怎么挂到你的项目上
  10. 总结

30秒版回答

我会拆成离线索引链路和在线检索链路两条线,外加一个治理闭环。

先做估算:500 万文档按平均切成十几个 Chunk,量级是几千万个向量;按 1024 维 float32 估算,原始向量就要上百 GB,HNSW 图索引还有额外开销,所以要考虑量化压缩和分片。

离线链路的重点是增量和删除:基于源系统变更事件和内容哈希做增量,Chunk 有稳定 ID,按文档版本原子切换,删除和撤权优先处理。在线链路的重点是权限前置过滤和延迟预算:先按用户权限过滤,再做向量 + 关键词混合召回和重排,控制上下文 Token,流式输出。

治理上,监控数据新鲜度、索引一致性、检索命中率和答案引用率,坏答案能追溯到具体环节。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

面试官:「设计一个企业知识库问答 Agent。规模是 500 万份文档,峰值 300 QPS,要求首字延迟尽量低、回答必须带出处、不同员工只能看到自己有权限的内容。你会怎么设计数据链路?」

带数字约束的系统设计题越来越常见。这类题的考点不是你能不能说出“向量数据库”,而是你会不会根据约束做估算和取舍。

数据开发答这道题要扬长避短:模型选型、提示工程不是我们的强项,但数据接入、增量更新、权限同步、存储估算、链路监控是我们的主场。把重心放在数据链路上,比泛泛而谈 RAG 原理得分高得多。

面试官在考什么

• 能否先澄清需求、再做容量估算:存储多大、索引怎么放、在线链路延迟怎么分配。

• 离线索引链路的工程能力:解析、切分、元数据、增量、删除、版本切换。

• 权限设计:权限怎么从源系统一路继承到检索阶段。

• 在线链路的延迟预算和降级策略。

展开一:先澄清,再估算

系统设计题第一步永远是澄清需求。我会先问几个问题,并说明假设:

• 文档类型:PDF、网页、Office、工单、IM 记录?平均多长?——决定解析和切分成本。

• 更新频率:每天新增和修改多少?——决定增量链路的吞吐。

• 权限模型:按部门、按项目、按文档 ACL?权限变更频繁吗?——决定权限同步方案。

• 延迟要求:是首字延迟还是完整答案延迟?——决定是否流式输出。

• 新鲜度要求:文档更新后多久必须能被检索到?

假设澄清后得到:平均每份文档切成 12 个 Chunk,Embedding 1024 维,每天约 5 万份文档变更。下面是估算过程:

项目估算结论
Chunk 总数500 万 × 12 ≈ 6000 万单机放不下,需要分片
原始向量大小6000 万 × 1024 维 × 4 字节 ≈ 245 GB全内存成本高,考虑量化
int8 标量量化后约 1/4,≈ 61 GB(另加图索引开销)可以分几个分片放内存
Chunk 原文 + 元数据6000 万 × 约 2 KB ≈ 120 GB放 KV/文档存储,按 ID 回查
每日增量 Embedding5 万文档 × 12 ≈ 60 万 Chunk/天离线批量即可,削峰处理
在线 Embedding QPS300 QPS(问题向量化)需要独立的 Embedding 服务和扩容

这一步体现的是数据人的量级感。面试官不在意你算得多精确,在意的是你会不会算、能不能从数字推出架构决策(分片、量化、分离存储)。

展开二:离线索引链路

源系统(文档库/Wiki/工单) ──变更事件/CDC──▶ 变更队列
     │                                        │
     └──每日全量对账(兜底)─────────────────────┤
                                              ▼
   解析(版面/表格/OCR) → 清洗(去页眉页脚/去重) → 切分(按结构+长度兜底)
                                              ▼
   元数据补全(doc_id/版本/章节路径/ACL/有效期) → Embedding(批量)
                                              ▼
   写入新版本: 向量索引 + 关键词索引 + Chunk 存储
                                              ▼
   校验(数量/空内容/向量维度) → 原子切换有效版本 → 异步清理旧版本

这条链路有四个数据工程要点:

• 增量 + 全量对账双保险:变更事件可能丢,每天跑一次全量的“文档 ID + 内容哈希”对账,找出漏掉的新增、修改和删除。这和数仓里 CDC 增量 + 定期全量校验的思路一样。

• Chunk 稳定 ID:用 doc_id + 版本 + 序号生成,同一版本重复处理不会产生重复 Chunk,链路天然幂等。

• 版本原子切换:新版本全部写完并校验通过后,再一次性把文档的有效版本指针切过去,避免用户检索到“一半新一半旧”的内容。

• 删除和撤权优先级最高:新增晚几分钟可以接受,删除和撤权晚了就是数据泄露。删除事件走单独的高优先级队列。

-- 文档版本状态表:链路幂等和原子切换的核心
CREATE TABLE kb_doc_version (
  doc_id          STRING,
  version         BIGINT,
  content_hash    STRING,     -- 内容没变就跳过,避免重复 Embedding
  acl_hash        STRING,     -- 权限变化单独识别,只需更新元数据
  status          STRING,     -- parsing/embedding/indexed/active/retired
  chunk_count     INT,
  embed_model     STRING,     -- Embedding 模型版本,换模型时用于双版本
  updated_at      TIMESTAMP
);
-- 检索只读 status='active' 的版本;切换 = 新版本置 active + 旧版本置 retired

注意 acl_hash 和 content_hash 分开:很多时候文档内容没变,只是权限变了。这种情况只需要更新索引里的权限元数据,不需要重新解析和 Embedding,能省下大量计算。

展开三:在线检索链路和延迟预算

300 QPS、低首字延迟,需要给每个环节分配延迟预算。下面是一个参考分配(数值是量级示意,实际要压测):

环节做法延迟量级优化手段
身份与权限解析取用户所属部门/项目/ACL 组几毫秒权限缓存,变更时失效
问题向量化调用 Embedding 服务几十毫秒独立服务、批量推理
混合召回向量 + BM25,带权限过滤几十毫秒分片并行,过滤下推
融合重排RRF 融合 + 重排模型一百毫秒左右只对 Top 几十条重排
上下文组装去重、按 Token 预算截断几毫秒限制 Chunk 数量
模型生成流式输出首字几百毫秒流式返回、模型分级

两个关键设计:

• 权限过滤必须在召回阶段做,而不是召回后过滤。召回后过滤会出现“TopK 全被过滤掉,用户什么都查不到”的问题,还可能把无权内容带进日志和缓存。

• 混合检索:向量擅长语义相似,关键词擅长专有名词、产品型号、错误码。两路召回用 RRF(倒数排名融合)合并,因为两路分数的量纲不同,不能直接相加。

展开四:降级策略

300 QPS 的系统一定要考虑某个环节挂了怎么办:

• 重排服务超时:跳过重排,直接用融合结果。

• 向量服务异常:降级为纯关键词检索,并在回答里提示结果可能不完整。

• 模型服务限流:切换到备用模型,或者直接返回检索到的原文片段和链接。

• 检索无结果:明确回答“没有找到相关内容”,而不是让模型自由发挥。

追问链

追问一:权限变更很频繁,比如员工调岗,怎么保证及时生效?

权限不要冗余存到每个 Chunk 的完整用户列表里,而是存权限组 ID(部门、项目组、ACL 组)。员工调岗只改变“用户属于哪些组”,这部分在查询时实时解析,不需要更新索引。只有文档本身的 ACL 变化(比如文档从全员可见改为仅某部门可见)才需要更新 Chunk 元数据,而且走高优先级队列。

追问二:换 Embedding 模型,几千万向量要重建,怎么不停服?

按双版本思路做:新模型的向量写到新索引,旧索引继续服务;新索引构建完成后,用评测集对比效果,再按流量比例灰度切换,有问题随时回切。版本状态表里的 embed_model 字段就是为此准备的。这和我做数据平台迁移时用的双写双读灰度是一个思路。

追问三:怎么监控这条链路的健康度?

分四层:数据层看源端变更到索引生效的延迟、解析失败率、全量对账差异数;索引层看各版本 Chunk 数、空内容率、向量缺失率;检索层看无结果率、平均召回分数、权限过滤命中率;答案层看引用率、拒答率、用户反馈。任何一层异常都能快速定位,而不是只看到“用户说答得不好”。

加分说法 vs 减分说法

✔ 加分说法✘ 减分说法
先澄清需求,再做容量估算推导架构上来就说用某某向量数据库
增量 + 全量对账,Chunk 稳定 ID 保证幂等不做任何估算
版本原子切换,删除撤权最高优先级只追加新向量不处理删除
权限在召回阶段过滤,存权限组而非用户列表召回后再按权限过滤
给出延迟预算和降级策略没有降级方案

怎么挂到你的项目上

话术模板:“这道题我会把重点放在数据链路:先估算 Chunk 量级和存储,推导出需要量化和分片;离线链路用变更事件加每日全量对账保证不漏,用稳定 Chunk ID 和版本原子切换保证幂等和一致;在线链路权限前置过滤,混合检索加重排,并设计降级。整体思路和我做 CDC 增量同步、数据平台迁移的经验是一致的。”

总结

带数字的系统设计题,核心是估算驱动架构。数据开发的优势在离线链路:增量、对账、幂等、版本切换、权限同步,这些都是数仓里天天在做的事情。把这些讲透,再给出延迟预算和降级策略,就能在一众只会讲 RAG 原理的候选人里脱颖而出。

第二轮系统设计到这里结束。下一篇进入第三轮工程深挖:Agent 的效果怎么评估?上线前怎么证明新版本比旧版本好?

你们的知识库多久同步一次?删除的文档会及时从索引里清掉吗?评论区聊聊~

关注「Wood聊大数据」| 9年大数据老兵,聊技术、聊职场、聊成长

刷题进度保存在当前浏览器