从零开始搭建知识库 · EP04 · 检索篇(基础篇收官)
检索参数在能力栈里的位置
「从零开始搭建知识库」系列第四期。EP01 论证建库,EP02 跑通存与找的闭环,EP03 验证数据准备的坑,本期拆检索本身:bl knowledge retrieve 的完整参数面,稠密召回、稀疏召回、重排三个段位,22 条命令对照实测。实验库沿用 EP03 的污染库(zj0knmrbye,8 文档 27 切片,烂 Excel 占 11 片),基线复跑与 EP03 留痕逐位一致,库零漂移。
先更新一张 EP03 发过的通道分工表,其中一行经本期核验有误,一并更正:
| 需求 | 正确通道 | 说明 |
|---|---|---|
| 知识库建库 | 百炼控制台(网页) | 含排序模型选择;mode 创建后不可改,本期实测坐实 |
| 知识库文档导入 | bl knowledge doc upload --file <path> --index-id <id> 或控制台 |
勘误:EP03 所写「导入无命令」不成立,CLI 实有 31 条 knowledge 子命令 |
| 知识库检索(参数实验) | bl knowledge retrieve --index-id <id> --query <text> |
已标 deprecated,参数面完整,本期 22 条全走它 |
| 知识库检索(应用集成) | bl knowledge search --query <text> --agent-id <id> |
接棒命令,走已部署检索服务,agent-id 来自 service list --scene search |
| 多模态临时附件 | bl file upload --file <path> --model <model> |
DashScope 48 小时存储,与知识库索引无关 |
勘误成因:EP02 核验时本机 reference 文件已包含全部命令,我只查了当期要用的几条,把「我查到的」当成了「存在的」。本期补跑 doc upload 闭环:上传临时 md(不带 index-id 只进数据中心)→ file get 状态 PARSE_SUCCESS → file delete 清理,全流程通过。
调参第一步:读库配置
调参先看配置,不是先动参数。bl knowledge info --index-id zj0knmrbye 的关键返回:
| 字段 | 实测值 | 调参含义 |
|---|---|---|
| rerankModelName | qwen3-rerank | 建库时选定,一直生效,裸检索本来就走重排 |
| rerankMinScore | 0.2 | 重排打分低于此值的候选不进结果 |
| enableRewrite | true | 检索前改写 query 的库级开关 |
| embedding | text-embedding-v4 | 稠密路向量模型 |
实测现象:--rerank 加与不加,五条返回逐位一致。flag 的作用是确认现状,不是启动功能。传导验证用换模型完成:--rerank-model qwen3-rerank-hybrid 跑同一 query,五条分数整体变化(0.7226 档变 0.6878 档),排位一个不动,证明参数确实传到了服务端,链路通畅。
--rerank-mode 在查询时无效。证据链两条:custom 模式加指令「优先返回2026年现行版制度」,返回与基线逐位一致;mode 填入不存在的值 xxx,命令正常执行不报错。无效值被静默忽略,说明该参数在查询时不被服务端消费。官方文档对应条款:排序模型模式仅创建知识库时可选,创建完成后无法修改。想换 mode,动库,不动 query。
参数语义:top-k 是候选池,top-n 是重排窗口
| 参数 | 管什么 | 实测证据 |
|---|---|---|
--dense-similarity-top-k / --sparse-similarity-top-k |
两路召回各捞多少进候选池 | 单设任一路行为不变;双设 5+5,total 从 27 变 6 |
--rerank-top-n |
从候选池端出几条 | 设 10 返回 10 条,设 3 返回 3 条 |
| rerankMinScore(库级) | 分数低于阈值的候选被过滤 | top-n 100 + 双路 200,只返回 17 条 |
total 字段的语义是进入重排环节的候选池大小:27 对应全库切片,6 对应两路召回合并后的池子(两路之和与 total 非严格相等,池内有去重)。池子收窄后前两名分数不变,第三名开始换人。
极端参数触发服务端 400,报错原文值得整段抄录:
{
"message": "dense_similarity_top_k + sparse_similarity_top_k >= rerank_top_n", "api_code": "Index.InvalidParameter"}
两路召回之和必须大于等于重排窗口,这是三段位流水线的数学约束:1+1 配 10 拒收,2+2 配 10 同样拒收。服务端把架构约束写进了报错。另:旧参数 --top-k 已废弃,替代者为 --rerank-top-n,官方口径最大召回上限 20。
重排救不了脏数据:对照矩阵
EP03 遗留问题:库里 2023 旧版与 2026 现行版并存,旧版检索排第一,重排能纠正吗?
| 测试 | 命令增量 | 结果 |
|---|---|---|
| B1 | --rerank |
与基线逐位一致,旧版 0.7226 第一 |
| B2 | --rerank --rerank-mode similar |
与基线逐位一致 |
| B3 | --rerank --rerank-mode custom --rerank-instruct "优先返回2026年现行版制度" |
与基线逐位一致 |
| B4 | 碎片霸榜题(问新疆发货)加 --rerank |
烂 Excel 碎片 0.7982 仍第一 |
机制原因:重排的打分对象是「候选切片与 query 的文本相关度」,不是业务正确性。旧版那句「报销单与发票原件装订后交财务部王会计处」与「报销发票怎么提交」的字面相关度就是高,打分越准旧版排得越稳。换 hybrid 模型的对照佐证:五条分数整体变化,排位零变化。排位由文本相关度决定,模型选择只影响分数量纲。
表达鸿沟同属参数补不上的类型。同一事实两种问法:「报销发票怎么提交」新旧两版贴身肉搏;换成口语的「发票交了之后多久能报下来」,top5 变成旧版 0.4700 加四条烂 Excel 碎片,现行版掉出前五。检索匹配字面不匹配意图,这是检索漏召回的第一根因。库配置中的 enableRewrite 是平台对该问题的库级补偿。
检索不准的排查顺序
22 条命令压成四条,从上往下走:
- 证据在场检查:top5 无正确答案,问题在语料或问法,调参无用
- 双问法对照:同一事实字面问一遍口语问一遍,top1 漂移说明问法与文档措辞距离大
- 参数调整:top-k 管池子,top-n 管返回条数,数学约束摆在那
- 重排期望管理:它让更相关的排前面,不生产正确答案
前两条的执行者是文档的业务归属方,管库的人负责跑对照。与 EP03 的分工一致:数据的地道靠源头,找的手艺才轮得到你。
与生态其他组件的衔接
- EP03 钩子的兑现:上期预告「脏库上调参,比干净库上更能暴露机制差异」,本期兑现且结论再进一层:机制差异确实暴露了(total 语义、400 约束、mode 锁定),但重排救不了脏数据本身,参数调的是找的手艺,改不了库里有什么
- 应用挂载(EP05):EP03 遗留的「实验文档去留裁决」现在有了实测依据:旧版制度与烂 Excel 不删的话,重排、模式、参数都压不下去,EP05 挂载 Agent 前需先做清理决策
- 检索服务化:retrieve 标记 deprecated,search 走已部署检索服务(同 query 五条分数逐位一致,metadata 含重排分与耗时),新项目集成建议评估 search 路径
复现路径
npm install -g bailian-cli
bl auth login --api-key sk-xxxxx
bl knowledge info --index-id 你的库id
bl knowledge retrieve --index-id 你的库id --query "报销发票怎么提交" --dense-similarity-top-k 5 --sparse-similarity-top-k 5
先读库配置,再动参数;调参前跑双问法对照,top1 漂移先修语料。
22 条检索命令均实测执行于百炼 CLI 1.17.1,request_id 与完整 JSON 返回留痕于项目仓库。命令格式可能随版本更新调整,以官方文档为准。API Key 在控制台密钥管理页创建,新用户有免费额度。