← lab.ranzi.space
RAG 话术检索系统
Retrieval-Augmented Generation
让 32B 大模型说出「师傅味」——不靠微调改模型,靠检索喂话术
用 2000 条真实话术做参考库,每次对话实时检索最相关的 3 条注入 prompt
一、什么是 RAG?
一句话解释

RAG = 开卷考试。模型做题(回答用户)的时候,允许它翻书(检索话术库),而不是全靠自己死记硬背。

类比:想象你是一个新入行的算命师傅。客户问你问题时,你可以翻一本「师傅语录」——里面记录了老师傅的 2000 条经典话术。你看两眼找找感觉,然后用自己的话回答。这就是 RAG。
三个核心组件
COMPONENT 1
话术库
1851 条师傅话术
按阶段和话题分类
+
COMPONENT 2
检索引擎
BM25 关键词匹配
找最相关的 3 条
+
COMPONENT 3
大模型
Qwen 32B
参考话术生成回复
二、为什么用 RAG 而不是微调?
我们的实验结论 核心决策
方案 优势 劣势 结论
7B 微调
(v5/v6 QLoRA)
风格像师傅 听不懂话、答非所问
推理能力弱
✗ 不采用
32B 原版
(无 RAG)
推理强、听得懂 没有师傅味
回答像 AI 客服
△ 不够好
32B + RAG
(当前方案)
推理强 + 风格对 需要维护话术库 ✓ 最终选择
底层逻辑:模型的「智商」靠参数量(7B→32B),模型的「人设」靠数据注入(微调 or RAG)。RAG 的优势是不改模型本身——话术不满意改话术库就行,不用重新训练。
RAG vs 微调 成本对比
微调(QLoRA) RAG
修改风格 重新训练(3-6小时 GPU) 改 JSONL 文件(5 分钟)
添加新话题 造数据 → 训练 → 合并 加几条到话术库
发现说错话 难以精确修正 删/改对应话术
依赖 GPU 训练阶段需要 完全不需要
三、工作原理(一次对话的完整流程)
当用户说「最近感情不太顺」时,发生了什么?
STEP 1
阶段判断
判定当前是 pain 阶段
STEP 2
BM25 检索
在 pain 阶段话术中
搜「感情 不顺」
STEP 3
取 Top-3
返回最相关的
3 条话术
STEP 4
注入 Prompt
话术作为参考
放入 system prompt
STEP 5
32B 生成
模型参考话术
生成自然回复
关键点:检索出来的话术不是直接返回给用户的。它是「参考材料」——模型看了这些话术,学到了措辞风格和内容方向,然后用自己的话重新组织回复。
注入 Prompt 的实际样子
# system prompt 最后会附加这样一段内容: [当前阶段:痛点共鸣] 缘主已经初步信任你了。现在开始讲命盘的问题... [以下是风格参考话术,供你模仿措辞和节奏] 参考 1(姻缘/pain):你的婚姻宫不是很理想的, 多婚的命局。缘主先天命盘的夫妻宫被相刑,相害, 是婚姻中属于不稳定的格局... 参考 2(婚姻/pain):去年两个人感情就出现问题, 有当值刑着自己夫妻宫... 参考 3(事业/pain):如果做投资则容易亏损、资金 被套,三角债或有外债难以收回... [排盘数据] 四柱:年庚午 月己卯 日己卯 时辛未 五行缺:水 日主偏弱...

模型同时看到:① 阶段指令 ② 话术风格参考 ③ 排盘数据 ④ 用户对话历史,然后综合生成回复。

四、BM25 检索算法
BM25 是什么?纯离线 零依赖

BM25(Best Matching 25)是搜索引擎的核心算法之一,和 Google 搜索的底层逻辑相似。它做的事情很简单:给定一个查询词,在一堆文档里找最相关的几条

类比:就像你在一本 2000 页的书的索引里查「感情不顺」,索引会告诉你第 45 页、第 231 页、第 789 页最相关。BM25 就是自动建索引+查索引的工具。

相比更复杂的向量检索(需要 embedding 模型),BM25 的优势:

  • 零依赖:纯 Python 实现,不需要任何 AI 模型或 GPU
  • 毫秒级:2000 条话术的检索 < 5ms
  • 可解释:匹配的是具体关键词,你能看到为什么命中这条
  • 中文友好:用 jieba 分词,对中文命理术语效果好
BM25 打分公式(简化版)
# 核心思想:一个词越「稀有」且在某条话术里出现越多,这条话术的得分越高 score(查询, 话术) = Σ 每个查询词的权重 × 在这条话术里的匹配度 # 两个关键因子: IDF(逆文档频率)= 这个词在整个话术库里有多「稀有」 → 「感情」出现在 500 条话术里 → IDF 低(太常见,区分度差) → 「夫妻宫」只出现在 30 条里 → IDF 高(稀有=有区分度) TF(词频)= 这个词在某条话术里出现了几次 → 出现 3 次 > 出现 1 次 → 匹配度更高 # 最终:稀有词匹配多次的话术排最前面
直觉理解:如果用户说了「夫妻宫相刑」,BM25 会发现「夫妻宫」和「相刑」都是稀有词(高 IDF),同时包含这两个词的话术得分最高。比起只匹配到「感情」这种高频词的话术,它更精准。
我们的 BM25 实现:rag_index.py
# 文件位置:~/Desktop/fortune_teller_app/rag_index.py(146 行) # 启动时自动加载,无需手动操作 class RAGIndex: def __init__(self, library_dir): # 1. 读取 3 个 JSONL 文件 # 2. jieba 分词建立倒排索引 # 3. 预计算每条话术的 BM25 参数 def search(self, query, stage=None, n=3): # 1. 对 query 做 jieba 分词 # 2. 如果指定 stage,只在该阶段的话术里搜 # 3. BM25 打分排序 # 4. 返回 Top-N 条 # 调用示例: results = rag.search("感情不顺 婚姻问题", stage="pain", n=3) # → 返回 3 条 pain 阶段的、和"感情不顺 婚姻问题"最相关的话术
五、话术库详解
1851
总话术条数
3
数据来源
4
对话阶段
12+
话题分类
三个数据来源
文件 条数 来源 特点
video_cleaned.jsonl 948 B 站视频字幕提取 教学为主,风水/面相/八字知识
realcase_cleaned.jsonl 551 真实案例对话 最有价值 — 真实的师傅话术风格
synthetic_cleaned.jsonl 352 AI 合成数据 补充覆盖面,含异议处理话术
每条话术的结构
{ "text": "你的婚姻宫不是很理想的。多婚的命局...", "topic": "姻缘", // 话题:姻缘/事业/财运/全项... "quality": 5, // 质量评分:3-5 分 "stage": "pain" // 对话阶段:trust/pain/solution/close }
四个对话阶段 阶段控制

话术库按「销售漏斗」的四个阶段标注,检索时按当前阶段过滤,避免过早推销:

Trust(建立信任)
讲性格、说好话、展示准确度。「你这个人日主己,田园一样包容温和...」
目标:让客户觉得「这人看得准」
Pain(痛点共鸣)
讲问题、引共鸣、适度恐吓。「你的五行缺水比较严重,泄耗你的因素很多...」
目标:让客户意识到「我确实有问题」
Solution(方案暗示)
暗示有办法、社交证明。「之前有个缘主跟你类似,做完之后明显好了很多...」
目标:让客户主动问「怎么办」
Close(成交)
报价、处理异议。「法金是随缘的,看你自己的心意...」
目标:完成转化
话术库分布
trust
284 条
pain
773 条
solution
286 条
close
211 条
teaching
461 条(教学,特殊)

注:teaching 类话术不在主对话流程中使用,仅作为知识补充检索。

六、完整对话流水线
一次请求的完整路径
用户发消息: "我是1990年3月15日下午2点出生的男的" ① 检测生日 → detect_birthday() 提取 (1990, 3, 15, 14) ↓ ② 排盘引擎 → bazi_engine.calculate() 生成完整排盘 → 四柱、十神、五行旺衰、神煞、大运、流年... ↓ ③ 阶段判断 → judge_stage() 用 7B 小模型快速判定 → 当前是 "trust" 阶段 ↓ ④ 数据过滤 → trust 阶段只给模型看好的数据 → 隐藏:五行缺失、合冲刑害、煞气 ↓ ⑤ RAG 检索 → BM25 在 trust 话术中搜索 → 返回 3 条风格参考话术 ↓ ⑥ Prompt 拼装 → system_prompt + 阶段指令 + RAG话术 + 排盘数据 ↓ ⑦ 32B 生成 → Ollama API 调用 qwen2.5:32b → 参考话术风格,结合排盘数据,生成回复 ↓ ⑧ 后处理 → 检查是否有推销内容泄露 → trust/pain 阶段出现推销词 → 强制重新生成 ↓ ⑨ 返回用户 → "你这个人啊,日主己,田园一样包容温和..."
阶段控制的双保险机制 防推销泄露

为了防止模型在不该推销的时候推销,系统有三层防护

  • 第一层:RAG 阶段过滤 — 检索时只搜当前阶段的话术,trust 阶段不会命中 close 话术
  • 第二层:排盘数据过滤 — trust 阶段隐藏五行缺失、煞气等负面信息,模型看不到就不会说
  • 第三层:输出过滤 — 生成后检查是否包含「法事」「化解」等推销词,如果有则强制重新生成
七、交互演示:BM25 检索

输入用户可能说的话,看 BM25 会检索到哪些话术:

阶段过滤:
点击「检索」查看结果
八、RAG 技术方案对比
BM25 vs 向量检索 vs 全文搜索
BM25(我们用的) 向量检索(FAISS/Chroma) 全文搜索(ES)
原理 关键词匹配+统计权重 语义相似度(embedding) 倒排索引
需要 GPU 不需要 建索引时需要 不需要
外部依赖 jieba(10MB) embedding 模型(500MB+) ElasticSearch 服务
语义理解 弱(靠关键词) 强(理解同义词)
2000 条的速度 < 5ms < 10ms < 10ms
适合场景 中文话术检索 跨语言/多义词场景 大规模数据集
为什么选 BM25?
我们的话术库只有 2000 条,且都是中文命理领域的专业术语。在这个场景下,关键词匹配已经足够准确。向量检索的优势(理解「不开心」≈「心情差」)在命理话术中体现不大,因为师傅用的词汇是相对固定的(「五行缺水」「夫妻宫」「犯太岁」)。

如果将来话术库扩展到 1 万条以上,或需要跨话题的语义理解,可以升级到向量检索。
未来升级路径
  • 短期:继续完善 BM25 话术库质量,增加更多真实案例
  • 中期:BM25 + 向量检索混合(hybrid search),取两者优势
  • 长期:14B 微调 + RAG 组合,推理和风格都在模型内部解决
算命 LLM · RAG 话术检索系统教程 · 2026-04-10
话术库版本:1851 条(v2 清洗后)· BM25 检索 · Qwen2.5-32B