为什么攻击力大于50这种问题不该只靠RAG?
好家伙,
前面已经写了两篇 RAG 相关的文章.
一篇讲 RAG 是什么:
text
让大模型先查资料,再回答问题.
一篇讲微调和 RAG 的区别:
text
微调解决怎么答.
RAG解决根据什么资料答.
今天继续补一个很重要的问题:
text
RAG 到底有没有边界?
这个问题很实际.
比如我现在有一张装备配置表,里面有装备名,攻击力,防御力,品质,套装等字段.
然后我问:
text
把所有攻击力大于 50 的装备筛选出来.
这个问题能不能交给 RAG?
我的结论是:
text
可以让 RAG 辅助理解,但不应该只靠 RAG 做最终筛选.
因为这类问题本质上是精确查询.
而 RAG 最擅长的是语义检索.
这两个东西不是一回事.
0.背景:我以为RAG可以查所有东西
一开始接触 RAG 时,很容易有一种感觉:
text
既然我把文档和配置表都导入知识库了,
那我是不是可以问任何问题?
比如:
text
这个字段是什么意思?
有哪些文档提到了德鲁伊?
套装描述的方法是什么?
攻击力大于 50 的装备有哪些?
哪个配置表里有 battle_monitor?
这些问题看起来都像是在查资料.
但它们其实不是同一种问题.
有些问题是语义问题:
text
这个字段是什么意思?
套装描述的方法是什么?
有哪些文档提到了德鲁伊?
有些问题是结构化查询:
text
攻击力大于 50 的装备有哪些?
品质等于 SSR 的角色有哪些?
按照战力从高到低排序.
统计每个职业有多少个技能.
RAG 更适合前一类.
数据库更适合后一类.
如果把所有问题都丢给 RAG,很容易出现看起来能答,但结果不稳定的问题.
1.先定义一个问题
我们固定一个例子:
text
把装备配置表中所有攻击力大于 50 的装备筛选出来.
假设配置表长这样:
text
id name attack defense quality
1 木剑 12 0 N
2 铁剑 35 2 R
3 巨剑 68 5 SR
4 龙牙剑 120 10 SSR
5 法杖 42 1 R
这个问题真正想要的结果是:
text
巨剑 attack=68
龙牙剑 attack=120
也就是说,它需要严格执行一个条件:
text
attack > 50
这里不是"语义上差不多".
这里是精确的大于关系.
2.RAG会怎么处理这个问题
如果我们让 RAG 来处理这个问题,它大概会这样走:
text
用户问题
-> 生成 embedding
-> 去向量数据库检索相似片段
-> 找到和"装备""攻击力""大于50"相关的文本
-> 把这些片段交给大模型
-> 大模型尝试筛选出结果
这个流程看起来好像没问题.
但注意:
RAG 检索的是语义相似.
它不是在执行:
sql
SELECT * FROM equipment WHERE attack > 50;
它更像是在问:
text
哪些文本片段和"攻击力大于50的装备"这个问题比较像?
这就有区别了.
3.为什么RAG容易漏查
第一个问题是漏查.
向量数据库通常会取 Top K.
比如:
text
Top 5
Top 10
Top 20
如果装备表有 10000 行,攻击力大于 50 的装备有 3000 个.
那你取 Top 10,肯定不可能拿到全部.
因为 RAG 不是全表扫描.
它只是找最相似的前几条.
所以如果你问:
text
所有攻击力大于50的装备
RAG 很可能只返回一部分.
它不是故意漏.
而是它的检索机制就不是为"全量筛选"设计的.
4.为什么RAG容易误查
第二个问题是误查.
比如有些装备行里写着:
text
攻击力成长: 5
最大攻击力: 50
推荐攻击力: 60
攻击力描述: 对高攻击敌人生效
这些文本都可能和"攻击力大于50"语义相关.
但它们不一定满足:
text
attack > 50
大模型看到这些片段后,还可能混淆字段:
text
基础攻击力
成长攻击力
最大攻击力
推荐攻击力
技能攻击倍率
如果配置表字段很多,名字又接近,只靠文本语义就容易判断错.
而数据库不会这样.
数据库只看字段和值:
sql
WHERE attack > 50
满足就是满足.
不满足就是不满足.
5.数据库会怎么处理这个问题
如果这个配置表已经进入数据库,那问题就很简单.
SQL 可以这样写:
sql
SELECT id, name, attack, defense, quality
FROM equipment
WHERE attack > 50
ORDER BY attack DESC;
结果是确定的.
如果用代码处理 Excel,也可以很直接:
python
result = [
row
for row in equipment_rows
if int(row["attack"]) > 50
]
数据库或代码适合做:
text
1. 精确筛选
2. 排序
3. 统计
4. 聚合
5. 去重
6. 分组
比如:
text
攻击力大于50
品质等于SSR
按照战力排序
统计每个职业技能数量
找出价格最高的10件装备
这些都应该优先交给结构化查询.
6.RAG和数据库应该怎么分工
我现在比较认可的分工是:
text
RAG负责理解问题和找资料.
数据库负责精确查数据.
大模型负责解释结果.
比如用户问:
text
把所有攻击力大于50的装备筛选出来.
更合理的流程是:
text
用户问题
-> RAG 或大模型理解意图
-> 判断要查 equipment 表
-> 判断字段是 attack
-> 生成结构化查询条件 attack > 50
-> 数据库执行查询
-> 大模型把结果整理成人能读懂的回答
也就是说,RAG 可以帮忙理解:
text
攻击力 可能对应 attack 字段
装备 可能对应 equipment 表
但真正的筛选应该是:
text
数据库执行 attack > 50
这就稳定很多.
7.一个更合理的系统流程
如果要做一个项目知识库 + 配置查询系统,我觉得可以这样设计:
text
用户问题
-> 意图识别
-> 判断是语义问答还是结构化查询
如果是语义问答:
text
问题: 攻击力字段是什么意思?
流程:
RAG 检索字段说明和配置文档
-> 大模型基于资料解释
-> 返回来源
如果是结构化查询:
text
问题: 攻击力大于50的装备有哪些?
流程:
识别表和字段
-> SQL / 代码执行筛选
-> 大模型整理结果
画成一条链:
text
用户问题
-> 大模型理解意图
-> RAG 找字段说明
-> 结构化查询筛数据
-> 大模型生成最终回答
这里大模型不是直接拍脑袋回答.
它是在调度不同工具:
text
RAG 查语义资料
SQL 查结构化数据
代码做计算
8.什么时候用RAG
RAG 适合这些问题:
text
这个字段是什么意思?
这个配置表的用途是什么?
有哪些文档提到了德鲁伊?
某个系统的部署流程是什么?
这个接口的鉴权方式是什么?
这些问题的特点是:
text
需要理解文档
需要找相关片段
答案可能分布在多处资料
最好能带来源
RAG 就很合适.
因为它做的是:
text
语义检索 + 基于资料回答
9.什么时候用数据库
数据库适合这些问题:
text
攻击力大于50的装备有哪些?
SSR品质的角色有多少个?
按照价格从高到低列出前10个道具.
每个职业分别有多少个技能?
找出没有配置图标的装备.
这些问题的特点是:
text
条件明确
字段明确
需要全量扫描
需要准确结果
需要排序统计
这就应该交给数据库.
因为数据库就是为这种问题设计的.
10.如果只用RAG会发生什么
如果硬要让 RAG 单独做"攻击力大于 50",可能会出现这些结果:
text
1. 只找到了部分装备
2. 把攻击力等于50的也算进来
3. 把最大攻击力大于50误认为基础攻击力大于50
4. 漏掉字段名不是 attack 但含义是攻击力的行
5. 如果表太大,Top K 根本覆盖不到全部数据
这些问题在聊天场景里可能看不出来.
但在配置查询场景里很危险.
因为用户要的不是一个"大概相关"的答案.
用户要的是:
text
准确列表
这就必须交给结构化查询.
11.总结
这次想清楚的点是:
text
RAG 不是万能查询系统.
RAG 的强项是:
text
语义检索
资料解释
文档问答
来源引用
数据库的强项是:
text
精确筛选
排序
统计
聚合
全量查询
所以对于这个问题:
text
把所有攻击力大于50的装备筛选出来.
更合理的答案不是:
text
让 RAG 直接回答.
而是:
text
RAG 帮我理解字段和表.
数据库帮我执行 attack > 50.
大模型帮我整理结果.
最后一句话总结:
text
RAG 负责查资料.
数据库负责查数据.
大模型负责把结果讲明白.
把这三个角色分清楚,项目里的 AI 查询系统才会更稳定.