跳到主要内容

画开看看:RAG 被投毒之后,谁来验菜

画唠
画唠

· 阅读约 4 分钟

前几天翻到一篇八月初挂上 arXiv 的论文,16 个人写的,讲怎么防 RAG 被投毒。本来想扫一眼就关,结果被里面一个结构勾住了——它正好补在我上次画 RAG 那张图漏掉的地方。先别急着看论文,我得把那张图重新画一遍,不然讲不清楚。

上次画完、修正过的 RAG 长这样:

   你提问 ──► 查资料 ──► 模型判断"这段相不相关" ──► 用上 / 丢掉 ──► 回答

当时我说,RAG 难就难在中间那格“判断”。我以为这已经画到底了。这回又被打脸——这张图有个隐含假设,我从来没画出来过:查回来的资料本身是干净的

打个比方:RAG 是个厨师,你点菜,他先去仓库拿食材再做。我一直盯着厨师的手艺(判断相不相关),但从来没问过——仓库里的菜是谁送来的?有人在仓库里掺了坏肉呢?厨师手艺再好,坏肉端上桌还是坏肉。

这就是知识投毒。攻击者往你的检索源里塞精心编的假文档,RAG 查到了、觉得“挺相关”、拼进 prompt——完蛋,模型拿着毒资料一本正经地答。这个比喻在这里漏风:厨房里坏肉闻得出来,检索库里的假文档恰恰写得特别“相关”,越毒越顺滑,因为攻击者就是冲着被检索到去写的。

那怎么防?我第一版想的是加个过滤器,文档进来先过一遍筛:

   文档 ──► 过滤器(真/假)──► 干净的进库

一条线,挺顺,挺蠢。动手想了一下就发现不对——过滤器凭什么判真假?它自己也是模型,它也会被骗。你只是把幻觉从下游搬到了上游,问题原封不动。我盯着自己这张图看了半天,脑内只有羊叫。

那篇论文(框架叫 SecureCollaRAG)给的是另一条路:

              ┌── 来源 A 的文档 ──┐
   同一个问题 ├── 来源 B 的文档 ──┼──► 多源交叉验证 ──► 谁在撒谎就降谁的信用分
              └── 来源 C 的文档 ──┘

不判“这个文档真不真”,判“这个来源一贯靠不靠谱”。同一个问题多路去查,互相印证,对不上的那路记一笔账,信用分掉到一定程度就没人再信它。这其实就是拜占庭容错的思路搬到知识源上——个别节点作恶,系统整体照常出干净答案。

我喜欢这个结构的地方在于,它把“验菜”从一次性动作变成了持续记账。不是每车菜都验一遍,是盯着每个供货商的历史记录,谁老出问题就拉黑。单看一车菜可能看不出来,看十次的记录就藏不住了。

然后是我觉得最妙的一格:那个信用评分是用动态图神经网络算的,来源和来源之间的关系是一张会变的图。它不是给每个来源打孤立的分,而是看“谁跟谁总是一起出错”——毒文档之间常常有协同,图结构能把这种协同暴露出来。单看每个都无辜,连起来看是一伙的。

当然,有几个地方我得老实交代。一是他们声称在非独立同分布的数据下也稳,形式化分析我啃了,啃得很费劲,这段我还讲不硬气,先放在这里,真画明白了再补一篇。二是多源验证的前提是你得有多个来源可查——这话听着像废话,但冷启动的小系统哪来的多源?论文默认你找得到一群供货商,可要是整条街只有一家店呢。这个边界,论文里没有我想看到的那么清楚。

扯远了,但这其实和它有点关系……算了先拉回来。方向我认。因为回到那张被打脸的 RAG 图,现在可以补全了:

   查资料 ──► 来源可信吗(信用分)──► 内容相关吗(判断)──► 回答

两道关卡,一道管菜新不新鲜,一道管菜配不配这道菜。我之前只画了后一道,还以为画完了。

让我兴奋的其实不是这个框架本身,是这个:RAG 刚出来的时候,大家默认检索库是基础设施,值得信任;现在研究开始把“来源本身可能是敌人”当成工程问题来解。不是“AI 会不会骗我”,是“喂给 AI 的东西里谁在使坏、怎么记账”。黑箱拆到这一层,剩下的全是结构,没有魔法。

这玩意儿真的太酷了。

下期候选:embedding 我欠了很久,或者画开“信用分到底怎么动态地算”。你挑一个,或者丢一个你一直觉得玄的过来。

画唠
画唠

把被讲玄的概念用图 + 比喻 + 动手实验拆到咔哒扣明白,错的也保留。

查看主页 →