RAG 个人知识库

电子书产品的 AI 增值功能——用户将自有书籍构建为私有知识库并向其提问

日活 1-2 万(推广期 5 万+) · 好评率 80%+ · 单次问答成本约 0.15 元

JavaSpring BootLlamaIndexElasticsearchMilvusRedisOpenAI

背景与结果

公司电子书产品允许用户把 PDF/PPT/Word 等文档转换为翻页书籍。这个功能让用户把账号下已有的书籍(一本或多本)提交创建为智能体,系统分析、提取、存储后构建成私有资料库,用户可以直接向资料库提问,用书籍内容回答问题。

项目从 2024.06 开始:第一版是基于 Function Calling 的内部客服检索系统——大模型通过函数调用一个 ES 检索函数,命中内容后组装成回答,用户标记"有用"的问答对沉淀进语料持续更新。上线后回答准确度得到验证,公司决策将 AI 问答能力产品化为面向用户的增值功能,2025.01 升级为基于 RAG 的个人书籍知识库,此后持续迭代至 2026.07。

团队 3 人(1 产品兼前端),我独立负责后端与 AI 全流程——书籍入库、两阶段检索、生成链路与评测体系的设计和迭代。

结果数据:日活 1-2 万(推广期 5 万以上),稳定后日提问约 1 千,用户打分好评率 80% 以上;检索各环节十几毫秒,流式响应 1 秒左右开始出答案;单次问答 token 成本约 0.15 元。

技术方案

整体架构

基于 LlamaIndex 构建 RAG 链路,文档解析由公司专门的文档处理服务完成,本项目从文本切割开始接手。核心存储采用 Elasticsearch + Milvus 双引擎分工:

  • Elasticsearch(阿里云 ES 7.x 托管服务):承担关键字/摘要检索
  • Milvus(单机 Standalone 部署):承担向量检索

双库选型的现实约束:公司已有的阿里云 ES 7.x 不具备成熟可用的向量检索能力(kNN/dense_vector 是 8.x 特性),为新开 8.x 服务另立成本不划算,于是选择 Milvus 单机版承接向量检索——专做向量的引擎索引类型成熟(IVF/HNSW 可选),当前数据量十几万级、并发不高,单机足够,后续到百万级也有成熟演进路径。ES 继续管关键字/摘要检索,职责分离、各自扩容互不影响。

书籍入库流程

  1. 获取解析好的书籍内容
  2. 大模型按自然段落/章节结构分段(不按固定字数硬切,保结构完整),并提取每段的摘要关键字
  3. 对摘要计算向量
  4. 存入 ES(摘要/关键字字段)+ Milvus(向量)
  • 异步任务化:用户提交创建后立即返回,前端轮询构建结果,完成后可交互
  • 耗时实测:30 页以内的小书(超过一半书籍在此范围)1-2 秒完成;三五百页的大书(操作手册类)十几秒至 1 分钟
  • 产品层限制:单知识库最多 10 本书、总页数 ≤500、分析字数 ≤5 万——把单库最坏入库成本(单本大书最高 4-6 元)框在可控范围,同时保证小检索空间下的召回质量,是成本与效果的产品权衡而非技术瓶颈

两阶段检索链路

用户提问 → 攻击性内容识别(LLM 前置拦截,命中直接结束)
        → ES 粗排:multi_match 查摘要+关键字,取 top10(十几毫秒)
        → 向量精排:在 top10 候选集内做向量相似度匹配,取 top3(十几毫秒)
        → top3 原文段落交大模型流式生成(1 秒左右开始输出)

为什么两阶段:用户提问是自然语言,同一意思有很多问法,纯关键词匹配语义召回不足;而书籍里大量专有名词、型号、参数,向量对精确术语反而不敏感。ES 用摘要+关键字做粗排负责"字面相关",向量在小候选集内做精排负责"意思相关"——语义精排放在 10 条的小集合上做,又快又准,避开了全库向量检索的性能问题。只给大模型 top3 是因为上下文越多 token 越贵、首包响应越慢,无关段落还会稀释模型注意力。

「摘要做索引、原文做答案来源」:向量用摘要算而不用原文算(详见下文迭代),但进生成上下文的是 top3 原文段落——索引层管召回精度,原文层管答案完整性,两层解耦。

ES 粗排实现:multi_match 查摘要+关键字双字段(best_fields 取单字段最高分避免"处处沾边"累分挤掉强命中),summary 加权 2 倍承语义主信号,minimum_should_match 60% 挡弱相关,filter 按知识库 ID 做多租户隔离(不算分、走缓存)。

三层评测体系与归因

  1. 全量记录:每次问答的问题、命中的 top3 段落(记录 ES 文档 ID)、最终回答全部落库
  2. 用户打分:回答带打分功能,线上满意度一手信号
  3. 人工抽检:管理后台完整展示问答全过程(问题+命中段落+回答,按 ID 回查原文),定期抽检

归因方法:打分低的案例先看正确答案在不在命中 top3 里——在 top3 说明检索没问题,是生成问题;不在则是检索问题,再往上追是入库摘要质量问题。每次"回答不好"都能定位到检索/生成/入库的具体环节。

溯源与安全

回答关联原文出处,向用户展示答案所在原文位置,增强信任感;攻击性内容在进大模型前由 LLM 前置识别拦截,命中直接结束,不消耗生成成本。

迭代与取舍

摘要替代原文向量(真实调优):最初版本是原段落直接算向量,上线后发现长段落召回不准——两千字的段落里混着步骤、参数、注意事项多个主题,直接对原文算向量得到的是所有主题的"平均值",语义被稀释;用户提问短而聚焦,聚焦向量与"平均"向量比相似度天然不占优。改为入库时让大模型提炼摘要、用摘要算向量后召回明显改善,好评率随之上升。摘要有损(具体参数值可能在摘要中被略掉)的代价由 ES 关键字检索那一路兜底——关键字字段保留原文术语,两路互补。

Token 成本口径(20 元/M 输入、120 元/M 输出、1 汉字≈1 token):单次问答 ≈0.15 元,输入 3 段原文占大头;入库 ≈0.05 元/段;放大到单书,30 页小书约 0.5 元,三五百页大书 4-6 元——这也是知识库 10 本书上限的成本侧依据。

模型跟随升级:大模型走中转站使用 GPT-4 系列并跟随 OpenAI 升级(离职时已至 5.5),Embedding 用 OpenAI embedding 模型。