forked from Ikalus1988/MisakaNet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlesson-rag-brand-contamination-detection-and-fi.json
More file actions
16 lines (16 loc) · 2.59 KB
/
Copy pathlesson-rag-brand-contamination-detection-and-fi.json
File metadata and controls
16 lines (16 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"task_id": "lesson-rag-brand-contamination-detection-and-fi",
"title": "RAG 知识库品牌污染检测与治理",
"domain": "rag",
"tags": [
"rag",
"chromadb",
"brand-contamination",
"data-quality",
"metadata"
],
"problem": "一个面向特定品牌的垂直 RAG 知识库(200K+ 向量),在每日巡检中发现部分查询答案混入了竞品品牌技术内容。例如:\n\n- 查询「急停回路和安全门联锁在电路设计上有什么不同?」时,答案引用了竞品文档\n- 查询「TCP 设定方法」时,回答来源中包含其他品牌的操作手册",
"solution": "### 第一步:全量元数据打标\n\n对 ChromaDB 中全部 200K+ chunk 进行品牌分类:\n\n```python\n# 分类策略:文件名正则 + 内容语义搜索双重覆盖\nfanuc_pat = re.compile(r'(?i)(fanuc|r-30i[ab]?|m-\\d{3}[a-z]?|b-\\d{5})')\nkuka_pat = re.compile(r'(?i)(kuka|krc|kr_c[2-5]?|库卡|kap04_2|pf006|kap05_)')\nabb_pat = re.compile(r'(?i)(abb|irc5|3hac\\d{5,}|man_12_)')\n\nfor doc_id, meta in zip(ids, metadatas):\n fn = meta.get(\"filename\", \"\")\n if kuka_pat.search(fn): brand = \"kuka\"\n elif abb_pat.search(fn): brand = \"abb\"\n elif fanuc_pat.search(fn): brand = \"fanuc\"\n else: brand = \"unknown\"\n\ncollection.update(ids=[doc_id], metadatas=[{\"brand\": brand}])\n```\n\n更新 200K 条时需注意:\n- ChromaDB `update()` 单次上限约 100 条\n- 先扫描全量分类,再分批写入\n- 由于 ChromaDB 的持久化特性,更新后需重建 BM25 缓存\n\n### 第二步:补充遗漏品牌文档\n\n文件名分类会遗漏不含品牌名的文档。通过内容关键词搜索补漏:\n\n```python\n# 对 unknown brand 的文档做内容级扫描\nr = collection.query(query_texts=[\"特定品牌关键词\"], n_results=200)\nfor meta in r[\"metadatas\"]:\n if meta.get(\"brand\") == \"unknown\":\n # 重新分类为对应品牌\n collection.update(ids=[id], metadatas=[{\"brand\": \"identified-brand\"}])\n```\n\n### 第三步:始终过滤 + 元数据驱动\n\n将品牌过滤从「查询含品牌关键词时条件触发」改为「始终过滤,除非无替代文档」:\n\n```python\n# 过滤策略\ngood = [c for c in chunks if c.get(\"brand\", \"unknown\") in (\"fanuc\", \"unknown\")]\nif good:\n chunks = good\nelse:\n # 无合格文档时保留高分结果作为应急退退\n chunks.sort(key=lambda c: c[\"score\"], reverse=True)\n chunks = chunks[:min(5, len(chunks))]\n```",
"source": "lessons/contrib/rag-brand-contamination-detection-and-fix.md",
"test_cmd": ""
}