尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

腾讯云ES支撑千亿级AI知识库检索架构实践

发布时间:2026/9/29 19:49:13

资讯中心
01
ARTICLE

腾讯云ES支撑千亿级AI知识库检索架构实践

腾讯云ES支撑千亿级AI知识库检索架构实践
1. ima的千亿级知识库到底在解决什么问题1.1 规模是怎么涨起来的ima 刚对外那阵子最火的一批用法并不是简简单单聊天而是把 ima 当知识库工具来用。市场上流传很广的 mark 的 AI 产品经理知识库本质就是一套整理好的产品经理资料集里面塞满了产品文档、竞品拆解、提示词模板、访谈纪要用户把它导进 ima 之后搜索、问答、提炼都能在一个对话框里完成。这种产品形态对后台的存储和检索系统是个复合型挑战。大家看到的是前端对话流畅但支撑一次提问的底层要先在知识库里找到最相关的几个片段才能喂给大模型生成答案。这个“找到最相关片段”的过程就是知识库检索引擎的核心工作。先给“千亿级”一个可执行的解释后面所有技术判断都以这个口径为准。从内容规模上讲这套知识库平台线上累计承载的知识内容按 token 粒度折算已经超过千亿。一个 token 大概是 1.5 个中文字符千亿 token 对应 1500 亿字符以上的原始文本。如果每个知识切片按 500 字符左右切那就是 3 亿级别的切片数量。这个规模已经没法靠单机数据库、靠简单的 like 查询去扛了。从请求规模上讲也很有压力。知识库问答是交互式的用户发一个问题期望一两秒内看到回答其中留给检索的时间预算通常只有 200-300 毫秒而像 ima 这种面向大量用户的平台高峰时段的检索 QPS 上万并不夸张。检索底座在这种量级下还能稳定工作才是真正的难点。以下所有架构设计和参数都来自我参与同类知识库产品后端演进时的实践积累ima 线上具体数值会有差异但方法论是通用的。1.2 AI知识库检索底座要同时扛住四件事我梳理下来问题核心集中在四点后续所有架构决策都是围绕它们展开的。第一是语义检索能力。用户问“怎么规划AI产品路线图”原文里可能写的是“产品演进方向”或者“版本节奏安排”字面上没有一个词对得上。这就是 RAG 应用里最常见的问题必须靠向量检索或者某种形式的语义匹配来解决。第二是精准过滤能力。知识库是多租户产品每个用户和团队有独立的知识空间平台上又有大量公开知识库。一次查询先要按 kb_id 把范围锁到一个或几个知识库里再叠加权限字段、文档类型、时间范围等条件。检索必须支持把过滤和召回并行做掉否则先召回再过滤数据量一大效率就崩了。第三是低延迟。交互式问答场景下检索做慢了后面大模型生成不管多快体验都起不来。我们内部要求检索阶段 P95 必须控制在 300ms 以内超过这个值产品侧就会开始投诉。第四是成本可控。数据增长是非线性的切分后的切片数、向量字段的存储放大都需要提前算清楚。如果不做冷热分离、不做生命周期管理光磁盘成本就能把项目拖垮。这四个要求放到一起传统 MySQL 的 like 查询不行纯全文检索差点语义纯向量数据库又扛不住多租户过滤和复杂文档更新。这就是为什么最后技术选型落在了 Elasticsearch而且是腾讯云 ES 的托管形态上。2. 技术选型为什么没选专用向量库而是选了腾讯云ES2.1 候选方案横向对比当年做选型的时候组里列过四类方案自建 ES 集群、腾讯云 ES、Milvus 这类专用向量库、PGVector 或者 Redis 这种“顺手方案”。结论是一边对比一边淘汰。Milvus 的向量检索能力确实强但它有两个绕不过去的短板。一是多租户过滤能力偏弱虽然支持标量过滤但在数据量达到亿级切片后过滤条件下做向量检索的工程复杂度很高索引裁剪和内存规划都得自己处理。二是知识库检索不光是向量标题关键词、正文精确词、作者、时间这些条件都要一起参与在 Milvus 里做这套等于再写一个搜索引擎显然不划算。PGVector 和 Redis 的向量能力适合中小规模到了千亿内容、亿级切片的量级不管是查询并发还是水平扩展都撑不住这个基本没有争议。自建 ES 在技术上完全可行但我们当时把运维成本一算就犹豫了版本升级、滚动重启、磁盘均衡、跨可用区容灾、内核 bug 修复这些都得自己养团队。尤其向量检索这种新特性版本迭代特别快自建意味着要么锁死在旧版本要么频繁做升级演练。腾讯云 ES 最终胜出核心就一句话它把 ES 该有的能力都托管了还针对云上场景做了冷热分层、快照归档到对象存储、内核优化这些增强。选它相当于把“伺候集群”这件事外包出去把精力留给检索质量本身。四类方案的取舍关系可以用一张表直观表示方案全文检索向量检索多租户过滤运维成本结论自建 ES强支持强高需专职团队可行但成本高腾讯云 ES强支持强低托管最终选择Milvus弱很强偏弱中高不适合混合检索PGVector/Redis弱一般一般低撑不住规模2.2 一个引擎同时干完三件事倒排、向量、过滤从原理上讲知识库检索场景对引擎的需求其实是三件事的组合倒排索引负责精确词匹配向量索引负责语义召回过滤条件负责多租户和权限控制。ES 是少数能在一个系统里同时满足这三者的引擎。这里有个很多人容易忽略的点知识库搜索不能只有向量。实际调优下来BM25 关键词检索的贡献非常大尤其是用户输入里带有专有名词、产品名、模型名的时候。比如问“腾讯云ES的向量检索参数”向量能召回大概方向但“腾讯云ES”“vector”这类精确词必须靠倒排去锁定。纯向量方案在这类场景下会把语义相近但不相关的文本带进来答非所问。而过滤能力放在同一个引擎里最大的好处是不用维护多份数据。权限过滤、知识库过滤如果跟检索分离每次查询要先在某处查权限再跑到向量库查内容延迟和一致性都很难控制。ES 的 filter context 可以把过滤条件和召回并行执行这在多租户场景里是保命的设计。2.3 选择托管形态的隐性好处展开说几个我们后来吃到红利的点希望大家选型时能提前看到。第一是弹性扩缩容。这类产品流量有明显的波峰波谷活动期间检索 QPS 翻几倍。腾讯云 ES 可以通过调整节点规格和数量来应对不需要提前囤一堆硬件。第二是内核增强云厂商版本的 ES 在写入性能、压缩算法、向量检索稳定性上都有额外优化这些优化自己从开源社区拿不到。第三是运维兜底集群健康检查、慢日志、告警都开箱即用我们只用专注业务指标。当然选托管不是没有代价最大的代价是“黑盒感”。有些定位诡异的高 CPU 问题底层细节看不到得靠云厂商售后配合排查。建议选型阶段就把厂商售后响应机制、巡检报告模板这些讲清楚别只看演示上的花活。3. 总体架构设计从文档进去到答案出来3.1 一次知识对话背后的六层链路用户感知到的只是一个对话框但一次提问背后其实是完整的技术链路。我习惯把它拆成六层接入层接收用户请求做身份认证、参数校验。处理层对问题做改写和纠错补全缩写、纠正错别字、把口语化问法转成检索友好句式。检索服务层真正的检索逻辑都在这里包括生成 query 向量、混合召回、权限过滤、粗排。存储索引层核心是腾讯云 ES 集群同时配合对象存储存放原始文件和快照配合消息队列做写入缓冲。模型服务层提供向量化模型、重排模型和对话大模型。应用层组装最终答案流式返回给前端。这里的关键在于检索服务层和存储索引层之间的配合。检索不是一把梭把用户原始问题丢进 ES而是先做 query 改写再同时走倒排和向量两条路召回融合排序最后把 top 结果返回。整体架构数据流是用户上传文档 → 对象存储 → 消息队列 → 切分和向量化服务 → 腾讯云 ES用户提问 → 检索服务 → 混合召回 → 重排 → 大模型生成 → 前端。3.2 写入链路解析、切分、向量化、批量入库知识库的数据写入很多人以为就是“文档传上去、ES 建个索引”这么简单。实际上写入链路的质量直接决定检索效果的上限。第一步是格式解析。用户上传的文档五花八门PDF、Word、Markdown、网页收藏、Excel。PDF 有的还是扫描件要接 OCR。这个阶段踩过的坑是解析库对复杂表格的识别率不稳定表格内容往往被拆得七零八落。后来针对表格单独做了结构化抽取保留表格标题和行列语义检索效果明显上了一个台阶。第二步是智能切分。切片粒度直接影响召回质量。切太碎单个切片信息量不够检索到的片段往往答非所问切太大又容易混入无关内容降低命中精度。我们的经验是以 300-500 个字符为一个基本块优先按 Markdown 标题、段落边界来切遇到超长段落再按句子边界切同时保留标题路径作为切片的上下文字段。这一步定下来之后向量检索的命中率提升比调任何参数都明显。第三步是向量化。Embedding 模型选的是 1024 维用批量接口一次处理 128 条异步并发控制避免打爆模型服务。这里有个细节是切片在切分后和向量化前最好先在中间存储里落一份方便模型升级后重放否则模型一升级全量重跑的成本特别高。第四步是写入 ES。写入用 bulk 接口一批 500-1000 条单批控制在 5-15MB 左右并发 8-16。切分和向量化是 CPU/GPU 密集操作为避免上游波动打爆 ES中间还加了一道消息队列做削峰写入端按消费者模式匀速消费。每个切片用 doc_id 加序号生成确定的 _id这样重放数据不会产生重复文档天然支持幂等。3.3 检索链路改写、混合召回、重排、送大模型检索链路的第一个环节是 query 改写。用户的问题可能是“这个产品对标谁”这种指代不清的表述改写模块会结合会话上下文补全实体。改写对最终效果的影响被很多人低估同一个问题改和不改TOP 结果的命中率能差 10 个点以上。改写之后生成 query 向量同时发起两种检索一个是翻倒排用 BM25 匹配标题和正文另一个是翻向量索引做语义召回。两边各自召回 50-60 条然后做混合融合。早期我们用的是加权求和但 BM25 分数和余弦相似度的分布完全不同加权系数很难调换了一版才稳定下来这个细节后面单独讲。融合排序后还要过一次重排。重排用的是 cross-encoder 模型对粗排召回的结果逐对计算相关性最终只保留 5 条作为大模型的上下文。粗排和精排分离是 RAG 检索的标准动作核心目的是控制成本向量模型和 BM25 都是便宜的批量计算cross-encoder 贵但只跑在 top 50 上整体延迟和成本就控住了。整个检索阶段的时间预算必须算清楚。我们当时把 P95 压在 250ms 左右组成大概是query 改写 20ms、向量化 40ms、ES 检索 150ms、重排 30ms剩下的缓冲留给抖动。如果某一段超了就会挤压大模型生成的预算用户体感直接变差。4. 千亿级规模下的索引与参数设计4.1 先算账容量规划、分片数量、节点规模千亿级这个量级所有设计必须先算账不能凭感觉。下面以 3 亿切片为例做一套完整的估算过程大家在不同规模下可以按比例替换。估算项数值原始文本约500GB千亿token折算后切片向量1024维 float323亿切片约1.2TB正文倒排索引约650GB元数据字段约90GB主分片合计约2TB副本1份后磁盘需求约4TB预留60%余量后约6.5TB单分片容量我们控制在不高于 40GB。按这个标准2TB 主数据对应 50-60 个主分片加上 1 份副本一共 100-120 个分片。节点规模上建议热节点 12 台、温节点 6-8 台规格 8 核 32G再配 3 台独立主节点其中 1 主 2 备用。分片数这里想多说一句。分片不是越多越好分片太多会导致每个分片的数据量太小、查询扇出增加分片太少则单个分片过大迁移和恢复都很慢。通用的法则是单分片 30-50GB同时参考集群 CPU 核数让分片总数不要超过数据节点 CPU 总核数的 3-5 倍不然收尾的线程池会先扛不住。4.2 Mapping 设计正文、向量、元数据分清楚Mapping 是 ES 上最容易出问题的配置之一。我们的原则是默认关闭 dynamic 映射所有字段显式声明宁可多写几行配置也不让 ES 自动推断。刚才算过存储向量占了大头这里更要把向量字段设计好。HNSW 参数上m 控制每个节点的最大连接数我们取 16ef_construction 控制建索引时的候选集大小取 100。这两个参数是索引质量和内存的权衡建好索引后想再调整需要重建索引所以务必在建库前想清楚。正文和标题走 IK 分词用 ik_max_word 做索引分词、ik_smart 做检索分词。标题字段额外保留一个 raw 的 keyword 子字段用于精确匹配和排序。所有用于过滤的字段比如 kb_id、permission、source_type一律用 keyword 类型不能交给分词器处理否则过滤条件会被切词切得支离破碎。这里给一个可以直接抄的 mapping 骨架{ settings: { number_of_shards: 60, number_of_replicas: 1, refresh_interval: 30s }, mappings: { dynamic: false, properties: { doc_id: { type: keyword }, kb_id: { type: keyword }, doc_title: { type: text, analyzer: ik_max_word, search_analyzer: ik_smart, fields: { raw: { type: keyword } } }, chunk_index: { type: integer }, content: { type: text, analyzer: ik_max_word, search_analyzer: ik_smart }, content_vector: { type: dense_vector, dims: 1024, index: true, similarity: cosine, index_options: { type: hnsw, m: 16, ef_construction: 100 } }, section_path: { type: keyword }, source_type: { type: keyword }, permission: { type: keyword }, create_time: { type: date }, update_time: { type: date } } } }refresh_interval 调成 30s 而不是默认的 1s对大批量写入非常关键。知识库场景下切分写入的数据并不要求写入后立即可见适当放宽刷新间隔可以把写入吞吐提升好几倍。需要注意的是 IK 分词插件需要提前在集群上安装配置腾讯云 ES 一般支持这类常用插件没有的话要跟售后确认开启方式。4.3 冷热分层与索引生命周期千亿级的成本底线千亿级内容不能全部放在热节点上。知识库里大量数据是低频访问的用户半年前导入的参考资料可能一个月都不会被检索到。我们把集群设计成热、温、冷三层。热节点用 SSD承载最近 7 天写入的高频数据检索性能最敏感。温节点用普通磁盘承载活跃知识库的历史数据保留完整的检索能力。冷节点实际上不常驻集群而是把索引快照归档到对象存储按需恢复。腾讯云 ES 的冷热分层方案支持设置节点冷热属性和快照仓库可以直接复用。索引名字按时间滚动每天一个索引后缀配合生命周期策略自动处理。策略的规则大致是索引创建 7 天后转入温阶段做一次 force merge 把段数压到 1提升查询性能30 天后转入冷阶段生成快照推送到对象存储没有再被访问的旧索引可以设置保留时间自动删除。一个参考策略如下PUT /_ilm/policy/kb_ilm_policy { policy: { phases: { hot: { actions: { rollover: { max_age: 7d, max_size: 50GB } } }, warm: { actions: { force_merge: { max_num_segments: 1 } } }, cold: { actions: { searchable_snapshot: { snapshot_repository: cos_repo } } }, delete: { actions: { delete: {} } } } } }写生命周期策略的时候要注意dense_vector 字段在冷热迁移中有一些兼容性限制。迁移到冷层后向量字段不应该再承担在线检索查询时优先命中热温层。如果有用户访问冷数据方案是先把对应索引恢复到温层再提供检索把这个“恢复动作”封装在检索服务里用户无感知。4.4 混合检索的融合策略BM25 和向量怎么和谐共处这部分是整个检索质量的关键也是我们调得最久的一块。单个 BM25 召回精确词很强但同义表达召回不回来单个向量召回语义能力强但专有名词容易被相似向量带偏。正确的做法是两边都召回再做融合排序。ES 8.8 之后的版本原生支持 RRF 融合。RRF 不直接比对 BM25 分数和向量分数而是把每个候选在这两个列表里的排名取倒数加权相加好处是对两套分数尺度不敏感鲁棒性比加权求和好得多。线上用的检索语句大致是这个形态POST /kb_index/_search { size: 60, query: { bool: { must: [ { multi_match: { query: AI产品经理能力模型, fields: [doc_title^3, content], type: best_fields } } ], filter: [ { term: { kb_id: kb_oid123 } }, { terms: { permission: [read] } } ] } }, knn: { field: content_vector, query_vector: [], k: 60, num_candidates: 500, filter: { term: { kb_id: kb_oid123 } } }, rank: { rrf: { window_size: 100, rank_constant: 60 } } }几个参数的经验值k 和 num_candidates 是召回规模我们取 k60、num_candidates500大约是 k 的 8-10 倍。HNSW 的 ef_search 默认值是 100如果相关性不够可以往上调但要注意查询 CPU 开销。如果集群版本不支持原生 RRF就在检索服务里分别执行两个查询再在代码里按 1/(rank60) 叠加效果一样。权限过滤必须同时出现在 query 的 filter 和 knn 的 filter 里。这个细节不处理好就会出现“全文检索带权限、向量召回不带权限”的严重数据泄露问题属于上生产前必须检查的红线项。5. 上线后踩过的坑与排查实录5.1 高频问题速查表把这些年线上遇到的问题整理成了表运维同学照着查能省很多时间。症状可能原因处理动作集群磁盘水位持续上涨冷热分层未覆盖全部索引启用 ILM旧索引转冷并快照到对象存储写入吞吐上不去refresh_interval 太频繁bulk 批太小调 refresh_interval 到 30s批量提到 1000 条查询 P95 明显变慢分片热点、filter cache 未命中重新平衡分片过滤条件全部进 filter context向量召回答非所问切片太碎或纯向量排序权重过高优化切分规则开启混合检索加大标题加权堆内存 OOM 或长 GC大量聚合、超大 size 分页用 doc values 排序限制返回条数必要时拆索引文档更新后检索到旧内容批量写入和索引刷新延迟用确定 _id 幂等写入配合版本控制接受最终一致性分词导致搜索不到IK 词典缺词、专有名词被切碎维护自定义词典添加同义词配置5.2 三个印象深刻的线上案例第一个案例是冷热分层缺失引发的雪崩。上线初期图省事所有索引统一放热节点结果数据量涨到 500GB 以上时磁盘水位长期在 85% 附近集群频繁做分片 relocation查询延迟忽高忽低。排查下来根因是冷热策略只对新索引生效历史索引还躺在热层。后来把生命周期策略补齐历史索引批量转温层又给冷数据开了对象存储快照磁盘水位回落到 60% 以下集群才算稳定。第二个案例是向量检索把 CPU 打爆。有一版 knn 参数拍脑袋设了 num_candidates10000配合每天千万级的检索请求高峰期 CPU 直接顶到 100%查询 P95 飙到 800ms。问题本质是 num_candidates 控制了每次查询要扫描的向量候选数量设得过大等于把 HNSW 图遍历的代价全部暴露出来。把它调回 500并针对访问量最高的几个知识库单独建了小索引P95 从 800ms 回到了 200ms 上下。第三个案例是融合排序的不稳定。早期用加权求和融合 BM25 和向量分数表现在线上就是同一类问题今天能答对、明天就答不对因为两套分数分布随数据量变化会漂移。换成 RRF 融合之后再结合 A/B 实验对比了 3 组参数效果稳定了很多。这件事给我最大的启发是在检索排序环节少依赖需要精细调参的加权方案多依赖对分布鲁棒的排名融合方案。5.3 监控体系与容量水位管理知识库检索服务上线后我们建立了三层监控。第一层是 ES 集群本身的健康度。日常盯的是分片状态、节点堆内存与 GC 耗时、磁盘水位、慢查询日志、写入拒绝数。腾讯云 ES 控制台自带这些指标告警比自己搭 Grafana 省事。第二层是检索服务业务指标。包括检索 QPS、P95/P99 延迟、空结果率、重排后 TOP 命中率。空结果率这个指标特别值得看它出现异常往往意味着 query 改写器带崩了或者向量化服务降级了而不是 ES 出问题。第三层是容量水位。我们每个月用存储预测公式过一遍下月数据量等于当前量加日均写入量乘 30 再乘存储放大系数。当预测磁盘用量超过集群容量的 70%就提前加节点或者调冷热策略绝不等告警响了再处理。6. 一点个人体会整套架构做下来我最想分享的体会是千亿级 AI 知识库的瓶颈绝大多数时候不在引擎本身而在接入引擎之前的数据组织方式。切片怎么切、标题怎么留、权限怎么过滤这些看起来不性感的工作对检索质量的影响远大于把某个搜索参数调大一倍。另一个体会是别迷信纯向量检索。当年选型时放弃专用向量库后来在线上一次又一次得到验证知识库检索是“过滤加精确词匹配加语义召回”三件事的组合任何一个单独拿出来都不能覆盖全部需求。腾讯云 ES 这类托管引擎最大的价值不是某个单一能力特别强而是把三件事的复杂度打包成了可运维的默认项。最后分享一个保留了很久的小技巧索引命名规范用知识库维度加时间维度比如 kb_reader_index_v1_20240618配合别名切换这样无论是数据迁移、回滚还是容量规划都有清晰的抓手。这个规范看起来不起眼但在千亿级规模的运维现场它能让你在凌晨三点排查问题时少掉一半头发。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。