面试知识库

M7 · 数据 ETL 与 RAG 知识库#

简历 Bullet Point: 构建 6 平台商品 ETL 管线 + 5 类 RAG 品类知识卡 2000+ 张 + 两段式检索(resolve_category 品类投票 + fetch_cards 精确取卡);OpenSearch Hybrid(KNN 0.7 + BM25 0.3);发现并修复科学计数法价格解析等数据质量问题


开场钩子#

category_insight 一次性语义搜索”旅行包”,结果里混进了”旅行杯""旅行枕”的卡片——query 语义相近但品类完全不同。意识到 RAG 检索不能一步到位,必须先确定”在哪个品类里找”。

改成两段式:resolve_category 先做品类投票确定目标品类,fetch_cards 按 resolved 品类精确取卡。


一、模块运作流程#

1.1 ETL 管线#

data/rag/*.csv (Amazon 原始数据)
  → scripts/etl/ (字段映射 + clean_text 清洗)
  → scripts/build_category_kb.py (聚合 → 入库门禁 → 编码 → JSONL)
  → OpenSearch bulk 索引
plaintext

5 类卡片

  • bestseller:品类头部商品
  • attribute-评分:评分分布
  • attribute-LLM多维度:LLM 生成属性分布
  • price_range:价位段
  • attribute_schema:Shopify 分类法属性骨架

卡片增强:aliases(品类别名)+ LLM 别名生成 + 分级质量门 + Shopify top-3 裁决。

1.2 两段式检索#

用户 query "推荐一个好的旅行包"


Stage 1: resolve_category(品类投票)
  ├─ 语义搜索候选卡片
  ├─ 提取每张卡的 category 字段
  ├─ 投票:出现最多的品类胜出
  └─ resolved_category = "Travel Bags"


Stage 2: fetch_cards(精确取卡)
  ├─ 用 resolved_category 做 term filter
  ├─ 只返回该品类的卡片
  └─ 不会混入 "Travel Mugs" 的卡片
plaintext

1.3 OpenSearch Hybrid#

  • Index mapping:knn_vector(lucene/cosinesimil)+ english 分词
  • Pipeline:shoppingx_hybrid_pipeline(min_max 归一 + 加权 [0.7 KNN, 0.3 BM25])
  • 中文 query 靠 KNN 向量跨语言 + 品类别名表兜底(英文语料不用 ik 分词)

1.4 精排#

RerankerClient(BGE-Reranker,SiliconFlow API + 确定性本地回退)。两条短路:首尾差距大跳过 / 候选不足跳过。


二、踩坑实录#

坑 1:一次性语义搜索混品类#

  • “旅行包”搜到”旅行杯""旅行枕”。改两段式 resolve+fetch。

坑 2:索引名 shoppingx→globex 不匹配#

  • 改了索引名但代码里硬编码旧名,静默空召回。统一配置解决。

坑 3:min_max 无信号路归零(原误抬成满分)#

  • BM25 分全为 0 时 min=max=0,归一化分母为 0。原代码给满分(1.0),改为给 0 分。

坑 4:ETL 头部款空价格 ${None:.2f} 崩溃#

  • 聚合时 top 商品价格为 None。加空值守卫。

坑 5:换环境部署须同步重建索引#

  • 远程部署没重建 OpenSearch 索引,fetch_cards 静默全空。加部署检查清单。

三、验收与量化#

指标数值
品类卡片数2000+ 张(247 品类 × 5 类)
Recall@100.983
MRR0.981
NDCG@100.754

四、面试问答#

Q1: 两段式 vs 一次性语义搜索?#

一次性搜索的 recall 可能更高(不会因为品类投票错误而漏),但 precision 差(混品类)。两段式牺牲极少 recall 换大幅 precision 提升。品类投票准确率实测很高——头部品类的卡片数量占优。

Q2: 为什么用确定性规则聚合生成卡片而不用 LLM?#

① 可复现——相同数据产出完全相同的卡片 ② 无 GPU——LLM 生成需要大量 API 调用 ③ 真实——基于真实商品数据统计,不是模型编造。LLM 只用于多维度属性分布这一类卡片。

Q3: OpenSearch 为什么用 english 而不是 ik 分词?#

语料是英文 Amazon 商品。中文 query 的跨语言靠 KNN 向量 + 品类别名表,不需要中文分词器。


五、诚实边界#

维度做了没做
数据源Amazon Kaggle 数据实时爬虫/API
卡片生成确定性规则聚合LLM 全量生成
分词english(英文语料)ik(无中文语料)
增量更新全量重建增量 upsert
语义缓存category_insight 弱时效域缓存全局语义缓存