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 索引plaintext5 类卡片:
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" 的卡片plaintext1.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@10 | 0.983 |
| MRR | 0.981 |
| NDCG@10 | 0.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 弱时效域缓存 | 全局语义缓存 |