RAG 被聊成白开水之后,还能有什么新东西?如果我把"知识库"从自然语言文档换成代码反模式,它还剩什么?arXiv 上那篇叫 RAGas 的论文(2608.15857)就是这么干的:把 RAG 搬去优化智能合约的 Gas。但我不太想聊那 11% 的削减——那是最没意思的部分,有意思的是它把这个骨架暴露得很干净:检索增强增强的从来不是模型的能力,是"模型不用猜的那部分"。
Gas 优化这种任务,你直接丢给大模型,它通常会给你一堆"正确但无处下手"的建议:减少存储操作、用更高效的数据结构、把不变计算从循环里提出来。这些你都知道了,问题是哪一行?模型不知道。原因是 Gas 反模式是高度局部的知识,它精确命中的是某一种语法或语义结构——一个循环里反复计算常量表达式,或者一个状态变量在同一个事务里被反复读写。这类东西不在模型的预训练分布里,你光靠调 prompt 是调不出来的。
RAGas 做的事,就是把这种知识从模型的隐含分布里拆出来,外置成一个显式的、可检索的反模式库:六类高级别、十二个细粒度反模式。注意这个数字。十二个,对比一个大模型脑子里装的东西,少得可怜,但这恰恰是它的设计意图——它不是靠枚举把常见写法全列出来,每个反模式背后都对应着一条"为什么编译器会为这段代码多烧 Gas"的机制。说人话就是:它把优化建议从"模型发挥"变成了"检索命中"。你可以说这是降级,从工程角度我甚至赞同——命中永远比发挥可靠。
还得先纠正一个理解。做应用层的人容易把 Gas 效率问题理解成"代码写得糙、多花点钱",方向不错,但不准确。Gas 是 EVM 执行每一条指令时的计费机制,贵的是指令级别的事件:存储读写(SSTORE/SLOAD)远远贵过算术运算,这是量级上的差别,不是几倍的关系。所以一个反模式的判定,依据的不是"这段代码读起来效率高不高",而是"这段代码经过编译器之后产出的指令序列,有没有在无谓地烧钱"。前者是风格问题,后者是机制问题。这个区别决定了反模式库该按什么维度去建。
RAGas 把反模式按两个维度拆:语法结构和语义结构。语法维度好理解,就是代码的形态——有些写法编译器会照单展开成多余指令。语义维度更微妙,它指向的是"这段代码在做什么"这个层面——比如本该离线计算的哈希被搬到链上算,代码完全合法(语义上"哈希"两个字甚至不出现在源码里),但它的存在本身就决定了 Gas 消耗降不下来。两种维度并存,是它跟普通 lint 工具拉开距离的地方:lint 看形态,RAGas 尝试把"语义上低效"也纳进检索范围。这一步能不能做扎实我持保留态度——语义这层靠向量相似度去匹配,本来就容易跑偏,但方向是对的。
最贴切的类比,是你写代码的时候旁边坐了个老师傅,他什么都不干,就抱着一本故障案例集,瞄一眼你的写法,翻一下案例集,觉得跟哪个翻车模式长得像就伸手拦一下:"这段,换一种写法。"检索的环节不在你脑子里,在那本案例集里——案例集本身就是结构化的索引。
但这个类比撑到"检索到并拦下来"这一步就得收了:老师傅是看懂了你这段在干嘛才反应的,RAGas 靠的是代码片段跟反模式模板之间的相似性匹配,字面上像,机制上不是一回事——它没有一个"看懂了再归类"的环节。类比到这儿收。
回到机制。RAGas 的流水线是标准的三段:先定位,用 LLM 把合约代码里疑似浪费 Gas 的片段标出来;再检索,拿这些片段去匹配反模式库,找出最贴近的那一个;最后生成,参照匹配到的模板给出替换写法。中间那个检索环节,就是 RAG 的核心假设在用事:外置知识加针对性命中,让生成器手里有一份"该往哪个方向改"的说明书,而不是凭记忆硬猜生成方向。
你琢磨一下这个结构和"往 prompt 里塞一篇文档让它参考"的区别——塞文档是让模型"参考",反模式匹配进去是让模型"照着改"。参考和照着改,生成阶段拿到的约束强度完全不是一个量级:前者模型可以随心所欲地采纳或忽略,后者等于先把答案空间框死了,模型在框里做局部变换。我说这是降级,指的就是这个:与其指望一个概率采样系统每次都巧合地想到最优写法,不如直接告诉它"你命中了哪条模式,照着这个模式的反例改"。
实验部分有个数:在已部署的合约上最高可以减少 11% 的 Gas。11% 好看吗?不好看,尤其是在"最高"这个前提下,平均值大概率更低。但我不太把这当缺陷。这个方向的意义不在它今天能省多少,在它证明了另一件事:Gas 反模式这种知识可以被系统性归纳、被检索命中、再被用于自动修复——这条链路是通的。省 Gas 的绝对值会随着编译器升级、EVM 版本迭代、反模式库扩充而变化,但"用检索增强来解决代码性能问题"这个模式一旦被验证,能搬去的地方不止智能合约。
写到这儿打个岔。Gas 消耗有个隐蔽的坑:同样的 Solidity 代码,不同版本的编译器、不同的优化开关,最后产出的字节码差异很大,"怎么算贵"这个标准本身是会漂移的。论文的反模式库只有十二条,其中很可能有一部分跟当前编译器生态绑定——等新版本 Solidity 出来,某些反模式自动消失,又冒出新的来。这不是这篇论文的毛病,是所有把知识外置成库的系统共同要面对的维护问题:知识库是活的东西,不是一次性的。这条先记着,改天展开。
所以这篇论文让我觉得最有意思的地方,不是那 11%,也不是 RAG 又多了一个应用场景,是它顺手演示了一件事:RAG 的真正骨架,既不是知识库的类型,也不是检索的精细度,而是"把结论从模型的猜测里拿出去,变成一次检索命中"。文档可以检索、代码反模式可以检索,架构决策模式没准也能塞进去。检索增强增强的不是模型,是"模型不用再猜的那部分"。
这层想通了,回头看那些还在吵"RAG 是不是要被长上下文取代了"的争论,会觉得那根本是两个问题:塞得下和找得到是两码事。上下文再长,你也得先有办法知道该到哪儿去找。