AI技术 · 2026-10-15

当 MaxKB 遇上 RAG 比赛

从 TrustRAG 方案到索引提速的迁移实践

一篇金融监管问答竞赛 Top10 方案的博文,给了把方法论搬到 MaxKB + DeepSeek Harness 的灵感。索引慢的三大元凶——自动生成关联问题、本地 CPU 向量模型、分段过碎——逐一排查,再接上混合检索与重排,检索效果和索引速度都能改善。

倪禾 · 实践笔记 · 最后更新 2026 年 10 月

用 MaxKB 搭了一阵 DeepSeek Harness,把课程讲义、论文笔记和教学文档灌进去做检索增强生成(Retrieval-Augmented Generation, RAG),效果不尽如人意。最明显的痛点是索引构建速度:一份几百页的 PDF 喂进去,向量化和索引要等很久,文档数量稍微上去就排队。检索质量也有问题——有时候问的东西明明在文档里,却检索不到,或者检索回来的内容文不对题。

恰好读到一篇博文,记录了 2025 年一场金融监管制度智能问答比赛中 Top10 方案的方法论(作者致Great,项目名为 TrustRAG)。方案里有些做法,比如混合检索加重排、召回多但喂模型少、检索结果持久化复用,直觉上可以迁移到 MaxKB 上。这篇文章不是逐条翻译那篇博文,而是把它验证过的策略,对照 MaxKB 的架构和我的实际配置,拆成可操作的改造路径。

一、竞赛方案在做什么

先简要交代 TrustRAG 方案做了什么,方便理解后面迁移的依据。这场竞赛的题目是金融监管制度的智能问答——给定一批 docx 格式的监管文件,参赛者要构建系统回答选择题和问答题。TrustRAG 团队的方案分七步,和检索直接相关的是前三步:

文档预处理

用 Python 解析 docx,统计每段的 token 长度、检测表格和空表格,把结构化内容导出为 JSON 和 Parquet。核心目的:索引前先瘦身,剔除无效段落。

句子级切块

用自研的 SentenceChunker 做句子级切块,对比了 256、512、768、1024 四种 chunk 长度。结论:256 召回率最佳。每个 chunk 用 MD5 生成唯一 ID,切块结果与元数据分离存储。

第三步是检索本身。方案用 BM25 和向量检索做混合召回(权重 0.3 和 0.7),各自召回 Top-15 后用 bge-reranker-large 重排,最终只取前 6 条喂给模型。团队的解释是:召回太多会引入噪音,模型反而答不准。此外,检索结果持久化到 Excel 里,重复查询直接复用,省掉再算一遍的代价。

这个方案的验证逻辑值得留意:每一步的参数选择都有实验对照(四种 chunk 长度做消融),不是凭感觉调。这正是迁移到自己的系统时最该学的——不是照抄参数,而是照抄方法。

二、MaxKB 索引为什么慢

MaxKB 是开源的知识库问答系统,内置文档解析、向量化和检索的完整流水线。我的配置是 MaxKB 社区版 + DeepSeek API 做生成端。索引慢的现象是:上传一份 200 页的 PDF,从解析到向量化完成要等好几分钟甚至更久,文档一多就排队。排查下来有三个元凶,权重从大到小排列。

元凶一:自动生成关联问题

MaxKB 从 v1.7.0 起有一个功能:每个分段上传后,自动调一次大语言模型为该分段生成若干"关联问题"(similar questions),存入索引供后续匹配。设计意图是让用户用自然语言提问时更容易命中——模型预生成的问题和用户提问的措辞更接近。

问题是,如果一个文档切了 500 个分段,就要调 500 次 LLM。即便用的是 DeepSeek API,排队和限流也会让索引时间从几十秒膨胀到几十分钟。这个功能默认开启,很多用户不知道它的代价。

排查建议:打开 MaxKB 管理后台,进入知识库设置 → 文档处理设置,找到「问题生成」选项。如果文档量大且对索引速度敏感,先关掉它做一次对比测试。关掉后索引速度的提升通常是最显著的。如果确实需要关联问题,可以在索引完成后再单独触发生成,而不是阻塞在索引流程里。

元凶二:本地 CPU 向量模型

MaxKB 内置了一个默认的向量模型(Embedding Model),跑在本地 CPU 上。好处是零配置,坏处是 CPU 推理速度远低于 GPU。一段几百字的文本,CPU 向量化可能要几百毫秒,500 个分段累计就是几分钟。竞赛方案用的是独立的向量检索服务,和生成完全解耦,速度不受本地硬件限制。

解法是把向量模型从本地 CPU 挪到 GPU 或 API。两个路径:一是用 Xinference 或 vLLM 在有 GPU 的机器上部署 bge-m3 模型,MaxKB 通过 API 调用;二是直接接硅基流动(SiliconFlow)等平台的 Embedding API,按量计费,成本极低。bge-m3 是一个多语言向量模型,中文效果稳定,维度 1024,竞赛方案用的 bge 系列也是同一家族。

元凶三:分段过碎或过长

MaxKB 默认的分段策略会按固定长度切,有时候切得太碎——一段就一两句话,导致分段数量膨胀,索引时间线性增长。反过来,切得太长也不好:单个分段太长,向量表示的语义被稀释,检索时匹配精度下降。竞赛方案的消融实验里,256 token 召回率最好,但这个数字不能照搬——竞赛语料是监管文件,段落短且结构规整;换一批长论文或讲义,最优长度可能不同。

建议的调整方向:在 MaxKB 的知识库设置里切换到高级分段模式,把分段长度设到 300–500 字(中文),按标题切分(如果文档有结构化标题),重叠(overlap)设 30–50 字防止切断上下文。这样分段数会明显减少,索引速度和检索质量都有改善空间。

索引慢三大元凶排查路径示意图
图 1 · 索引慢的三层排查:先关问题生成做基线测试,再换向量模型部署方式,最后调分段参数。

三、检索效果怎么提

索引速度解决后,检索质量是第二件事。TrustRAG 方案在检索上验证了三个策略:混合检索、重排、少喂结果。这三个策略在 MaxKB 里都有对应配置,不需要写代码。

混合检索:向量 + 全文

纯向量检索擅长语义匹配——用户问"贷款利率上限",能命中"融资成本管制"这类不同措辞的段落。但它对专有名词和数字不敏感:文档里写了"第七条",用户也问"第七条",向量检索可能反而匹配不上。BM25 全文检索正好互补,它对精确词匹配强。竞赛方案的混合权重是 BM25 占 0.3、向量占 0.7,偏向语义但保留词面兜底。

MaxKB 从 v1.6.0 起支持多路召回的重排。在知识库设置里,打开「混合检索」选项,它同时走向量检索和全文检索,然后合并结果。权重可以在设置里调,建议先从默认值开始,用评测集测一轮再微调。

重排:召回多,喂模型少

重排(Reranking)是竞赛方案里最关键的一步。向量检索和 BM25 都是"双塔"模型——查询和文档分别编码再算相似度,速度快但精度有限。重排模型是"交互"模型——把查询和每条候选文档拼在一起送进模型,让模型判断相关性,精度高但慢。所以策略是:先用快模型召回 Top-15,再用重排模型从中挑出最相关的。

竞赛方案最终只取重排后的前 6 条喂给 DeepSeek 生成答案。这个"少喂"策略看似浪费了召回的结果,实则重要:上下文太长,模型注意力会被稀释,反而答不准。在 MaxKB 里,这对应检索结果数量(Top N)的设置。默认值可能偏高,建议先设到 5–6,用实际问答效果对比。

重排模型推荐 bge-reranker-v2-m3,和向量模型同属 BAAI 家族,中文表现稳定。部署方式和向量模型一样——通过 Xinference 跑 GPU,或接硅基流动 API。MaxKB 的重排设置在知识库 → 检索设置里,选好模型后打开重排开关即可。

环节竞赛方案MaxKB 对应配置建议参数
向量检索bge 系列模型向量模型设置bge-m3(API 或 GPU)
全文检索BM25 权重 0.3混合检索开关开启,权重默认后调
重排bge-reranker-large重排模型设置bge-reranker-v2-m3
喂模型数量前 6 条Top N5–6 起步
结果复用持久化 Excel内置缓存开启检索缓存

查询优化

竞赛方案对查询做了一层处理:选择题把选项拼进查询里再检索,让模型有更多上下文判断。MaxKB 也有对应的「问题优化」开关,开启后系统会先对用户输入做一次改写——比如补全省略的主语、把口语化的提问改写成更接近文档表述的形式——再去检索。这个功能同样依赖一次 LLM 调用,有延迟代价,但对模糊提问场景的效果提升明显。建议在高频问答场景开启,实时性要求高的场景关掉。

四、用评测集驱动调参

前面说的每个参数——分段长度、混合权重、Top N、是否开问题优化——都不能凭直觉拍板。竞赛方案之所以可信,是因为每一步都有消融实验支撑。迁移到自己的系统,最低成本的做法是攒一个评测集。

  1. 攒 30–50 道问答

    从日常真实提问里挑,或者让模型基于文档生成候选问题再人工筛。每道题写清楚问题和期望答案(不需要逐字匹配,能判断对错即可)。30 道是下限,50 遹以上趋势稳定。

  2. 用「命中测试」跑基线

    MaxKB 有命中测试功能:输入问题,看检索回了哪些分段、来自哪个文档。用评测集逐题跑一遍,记录命中率和命中率(期望答案所在分段是否出现在 Top N 里)。这就是改造前的基线。

  3. 每次只改一个参数

    关掉问题生成 → 跑一遍。换向量模型 → 跑一遍。开混合检索 → 跑一遍。开重排 → 跑一遍。改 Top N → 跑一遍。每次只动一个变量,才能归因。竞赛方案对比四种 chunk 长度就是这个逻辑。

  4. 看趋势不纠结单点

    某道题从命中变不命中,不一定是退步——可能是评测集标注的期望答案本身有偏差。看整体命中率和答题正确率的变化趋势,而不是盯个别案例。

评测集不需要一次攒到位。先攒 10 道,跑一轮看方向对不对,再逐步补到 30–50 道。最大的价值不在数字本身,而在于每次改参数后有一个客观的对照——否则改完只会觉得"好像好了一点",说不清是真好还是心理作用。

五、几个容易踩的坑

DeepSeek 用 chat 不用 reasoner

DeepSeek 有 chat 和 reasoner 两种模式。reasoner(推理模型)会先做一段思维链再输出答案,延迟高,而且不支持 temperature 参数。RAG 场景里检索结果已经提供了上下文,模型不需要长链推理,用 chat 模式配合 temperature=0 贪心解码就够了,速度快且输出稳定。

增量更新而非全量重建

MaxKB v1.9.1 起支持「仅向量化非成功的分段」——如果索引中途失败了,重试时只处理失败的分段,不用从头来。文档更新时也类似:只对变更的文档重新索引,其余不动。改完配置后别急着全量重建,先用增量更新验证效果。

一个隐蔽的坑:换向量模型后,旧索引的向量维度和新模型可能不一致(比如从 768 维换到 1024 维),这会导致旧索引完全失效,必须全量重建。换模型前先确认维度是否一致;如果不一致,挑一个空闲时段做全量重建。

版本方面,MaxKB V2 于 2025 年 7 月发布,社区版不限并发和文档数量。到 2026 年 6 月已经更新到 v2.10 LTS。如果还在用 v1.x 版本,很多检索相关的功能(混合检索、重排、增量更新)要么不支持,要么体验差。建议先升到 v2.x 再做以上优化——升级本身就能解决一部分性能问题。

参考资料