面试知识库

M18 · 品类知识库两段式检索重构(从建卡到检索)#

背景与问题#

category_insight 的 RAG 链路原本是「对全库 2044 张卡做 KNN+BM25 hybrid top-30 → cross-encoder 精排 top-K → 按 card_type 分组提炼」。三个结构性毛病:

  1. 检索目标错配:知识库按品类组织(每品类固定四类卡)、下游按 card_type 消费 (价格卡只要一张、骨架卡只取首卡),但检索却做全局卡片 top-K——attribute 卡占库 64%,会把其他类型的卡挤出头部;跨品类污染要靠「只取首卡」这类补丁硬兜。
  2. 非标准 query 接不住:别名表只有十几条手写;中文/口语 query 全靠多语言向量兜底。
  3. 代码里一堆伺候症状的补丁:search_text 重复品类名提权、RERANK_BYPASS_MARGIN 短路、「候选 ≤ top_k 也要精排」……都是在给错配的检索目标擦屁股。

核心决策:检索的本质是「定位品类」,不是「检索卡片」#

重构为两段式:第一段 resolve_category(hybrid 命中按品类投票,置信度=票仓占比; 歧义时 reranker 只对 2 条「品类名+别名」消歧)→ 第二段 fetch_cards(term 按品类 精确取全)。零漏召、零跨品类污染,从结构上消掉整类问题——上面那些补丁全部删除。

配套数据侧三刀:

  • LLM 别名扩展:每品类 5-10 条中英别名进 BM25(aliases^1.5)与编码文本,带 (模型,品类)磁盘缓存。这是第一段接住「旅行收纳」类 query 的关键数据。
  • 分级质量门:price_range 需 ≥100 有价样本、评分分布 ≥50——30 个样本切 p33/p66 是噪声;达不到只缺卡不剔品类。
  • Shopify 桥接 top-3 + LLM 裁决:单最近邻会出「car care 配 Baby health items」 这类语义近语用错的匹配,纯相似度阈值治不了;LLM 可全拒,裁决带缓存。

工具输出新增 matched_category / resolution_confidence:主 loop 能分清「没匹配上」 和「品类真没数据」,低置信转 web_search——把不确定性显式交给上层而非静默空结果。

效果(Top-K=10,远程 OpenSearch)#

集合旧逻辑新逻辑
品类自指集 recall/mrr/ndcg0.958 / 0.821 / 0.7681.000 / 1.000 / 0.965
LLM 口语改写集(新基线)—(旧逻辑 400 崩)0.800 / 0.800 / 0.769

口语集 8 条 miss 中 7 条是 Amazon 类目近义兄弟品类(语义等价),真错 1 条。 全链路冒烟:「旅行收纳」从错锚 travel duffel bags(0.39) 修正为 travel accessories(0.82);库里没有的品类(咖啡杯)置信度如实压到 0.26。

踩过的坑#

  • 单子路 hybrid + pipeline 400:disable_bm25 后 hybrid 只剩 KNN 一路,归一化 管道的双权重与子路数不匹配直接 400。旧金标全是品类名从没触发;口语金标一来就炸。 潜伏 bug 被更难的评测集逼出来——先校尺子再改 Agent 又一例证。
  • 评测脚本不加载 .env:编码静默退化 256 维哈希对 1024 维真向量库,指标全假。 与建库脚本的 P0 同源,这次把 load_dotenv 补进了所有评测入口。
  • 设计中途反转:原方案有「CJK 判定关 BM25」,别名入库后中文 query 的 BM25 不再 必然全零,关掉反而丢词面信号——方案要随数据前提更新,不是定了就不动。

面试可讲点#

  • 「检索问题重构为品类定位 + 结构化取卡」——识别数据组织形态与检索目标的错配, 比调参数/换模型的收益大一个量级,且删掉的补丁比新增的代码多。
  • 投票式品类定位:同品类多卡互为佐证(单张跑题卡抢不动票仓),置信度有概率语义。
  • rerank 的正确用法:从「排 30 张长文本卡」缩到「歧义时排 2 条品类描述」,延迟与 成本都降,且只在需要时花。
  • 追问可能:投票的卡数偏置(稀疏品类票仓小)怎么办?→ 已知局限,候选是按品类 归一 or 卡数加权的取舍;真实修法是 registry 化(品类一条文档)而非卡片投票。

遗留与后续#

  • 部署硬依赖:新代码要求新索引 mapping(category.raw / aliases),上线 gcjp 前 必须先在远端跑 build_category_kb.py 重建索引,否则 fetch 静默全空。
  • SEMANTIC_TOKENS 关 BM25 会连带关掉别名词面路(「送」「适合」中文高频词),待评估。
  • RRF 融合、增量 upsert、冷启动飞轮(未命中 query 回流建卡)、真实 query 金标集。