嘿,各位码农朋友们,最近咱们技术圈又双叒叕在“哭丧”了。这回的主角,是前两年刚被捧上神坛的RAG(检索增强生成)

“RAG已死!”一些文章标题耸动得像个八卦小报。起因是一些很牛的AI编程工具,比如Claude Code和OpenAI Codex,它们官方承认:“我们不用那套复杂的向量数据库和嵌入(Embedding)索引了,我们用……Grep。”

等等,Grep?就是Linux里那个诞生于1973年、长得像 grep -r "bug" . 的古董命令?这感觉就像听说SpaceX最新火箭不用超级计算机导航了,改用算盘和指南针一样荒诞。

别急,这事儿不仅不离谱,背后还藏着挺有意思的技术哲学。咱们今天就来聊聊这场“RAG之死”和“Grep复兴”背后的幽默反转。


第一章:那个被嫌弃的“过度热心的图书管理员”

先打个比方,帮你理解旧式RAG是如何工作的。传统的RAG,就像一位过度热心的图书管理员

设想一下,你要研究“如何用Python给女朋友写个自动发晚安消息的脚本”。你去一座巨型图书馆(你的代码库),这位管理员(RAG系统)在你来之前就忙疯了。他必须在任何读者来临之前,把全宇宙的书都读一遍,然后用一种只有他自己懂的神秘符号(向量)给每本书、每个章节(文本块Chunks)贴上标签(建立索引)。这个过程叫 “预处理” ,非常耗时间。

等你终于提问时,他不是直接去找那本《Python撩妹指南》,而是把你的问题也翻译成同一种神秘符号。然后,他就在自己建立的庞大索引里疯狂做“符号连连看”:“嗯,你问的‘爱’和这本书里‘心碎’的余弦相似度高达87%!和这本‘晚安,月亮’的相似度也有85%!这一定是你想要的!” 于是,他热情地塞给你一堆《失恋心理学》、《如何走出情伤》、《月亮诗集》……唯独漏掉了真正对的那本。

这就是旧式RAG的三大“职业病”:

  1. 准备工作累死人:每次接手一个新项目,都得把整个代码库“分块、嵌入、建索引”,像个强迫症患者在一丝不苟地给图书馆上百万本书重新分类。
  2. 翻译失真:把一句清晰的“查找所有叫 getUserID 的函数”翻译成模糊的语义向量,就像把一首精悍的唐诗翻译成摩斯电码,再从摩斯电码翻译回现代汉语。意思可能还是那个意思,但精髓全丢了。
  3. 总猜错你的“精确”心思:代码世界是精确至上的。getUserById 就是 getUserById,不是 fetchPersonByIdentifier。但在语义的世界里,它俩描述的是同一个行为,简直是“双胞胎”。当你只想找前者时,RAG常常把后者这个“替身”错认成正主带给你。

于是,Claude Code那帮人一拍大腿:“我们为什么不让LLM(大语言模型)自己当那个直接去书架找书的聪明读者呢?它完全有能力自己看分类牌、看目录,自己判断下一步去哪找!”


第二章:LLM“Grep神探”的破案实录:一个四步工作流

这就是新范式的核心:LLM驱动的多轮Grep搜索。LLM摇身一变,成了个思维敏捷、熟悉代码库的侦探,而Grep就是它手里最好用、最顺手的放大镜。

咱们用一个真实的“案情”来还原一下“探案”过程。假设你给AI侦探委派一个任务:“嘿,当用户在咱们的网页上点了‘登录’按钮后,整个系统的日志模块是怎么一步步记录这个操作的?把完整的证据链给我找出来。”

如果是旧RAG侦探,他会直接从档案室(向量数据库)根据“登录日志”的语义,翻出一堆模糊相关的旧案卷,比如“错误日志机制”、“用户会话管理”、“数据库写入API”的代码块,扔给你说:“都在这里了,嫌疑人可能混在其中,自己排查一下吧。” 然后,他就下班了。

而我们的新Grep侦探,则会采取以下多轮、动态的办案策略:

  • 第一轮:广撒网,锁定嫌疑文件(工具:Grep - files_with_matches 模式)
    “嗯,‘登录’这个人类词汇在代码里,对应的技术关键词可能是 loginsigninauth。先把包含这些词的文件都找出来,看看嫌疑人都藏在哪几个窝点。”

    侦探用放大镜(Grep)设定模式为“只返回文件名”,在整个项目里一扫,报告:“长官,三个文件有重大嫌疑:userController.jsauthService.pyapp.js。”

  • 第二轮:查看核心嫌疑人的活动记录(工具:Grep - content 模式)
    authService.py 听起来最像核心作案现场,‘登录’的真正处理逻辑很可能在这。先别急着通读全文,看看‘login’这个词在这个文件里每次出现时,它‘身边’(上下文)都在干什么。”

    侦探把放大镜调到“内容”模式,设定“显示匹配行前后各5行代码”,发现“login”这个词附近,跟着一个函数调用:logActivity('user_login', user.id)。关键线索浮出水面!

  • 第三轮:深入核心现场,勘察全貌(工具:FileRead)
    logActivity 这个函数就是关键凶手!现在必须完整阅读它的‘供词’。看看它整个函数体到底写了啥,是怎么把‘用户登录’这个信息从头到尾记录下来的。”

    侦探直接翻开 authService.py 这本书,找到 logActivity 函数的开始和结束,完整读了一遍。恍然大悟:“报告!它不仅记录了‘谁、在什么时间登录’,还把用户的IP地址、浏览器User-Agent、登录结果(成功/失败)这些从请求对象里扒出来的细节,连同时间戳一起,组合成一个JSON对象,全部塞进数据库的 activity_logs 表里了!”

  • 第四轮:顺藤摸瓜,追查下游链条(工具:Grep - content 模式)
    “数据是成功写库了,但前端页面上那个‘登录成功,正在跳转…’的友好提示,又是谁读取这个日志、在什么时机弹出来的呢?”

    侦探梅开二度,再次举起Grep放大镜,这回搜索的关键词是 "登录成功" 这个中文字符串。通过 output_mode: "content" 直接看匹配片段的上下文,一路追踪到前端 loginComponent.jsx 文件里的一个 useEffect 钩子。案件彻底告破,完整的证据链清晰呈现。

看到了吗?整个过程,侦探靠的不是别人给的不靠谱“摘要”或“小道消息(语义相似度)”,而是从现场(代码)亲手找到的精确线索(函数名、变量名、特定字符串),步步为营,自主决策下一步行动。而代码库,恰好就是一个充满了这种精确线索的、为Grep量身定做的巨型宝库。这个动态的、推理引导的检索过程,是任何静态的预检索都难以复制的。


第三章:古老Grep,凭什么叫板“黑科技”?因为它是“功夫大师”

你可能还是不信:这都用了几十年的老古董,在速度上能跟人家毫秒级响应的向量搜索比吗?

嘿,这就像一个60岁的功夫大师和一个20岁只会王八拳的拳击手打架,大师凭的是“更快、更准、更省力”的巧劲,而不是蛮力。

现代的Grep工具,比如Claude Code底层真正调用的ripgrep (rg),早就不是当年的吴下阿蒙。它是一个用Rust语言从头重写的性能怪兽,专为在大型代码库里快速搜索而生。

它的“快”靠的是五层精妙过滤和顶级内力,而不是烧CPU:

  1. 眼观六路,自动“偷懒”(.gitignore 剪枝):你让它搜你的项目代码,它就真的只搜你的代码。node_modules 文件夹里有几万个第三方依赖文件?.git 文件夹里有历史记录?ripgrep 默认会读取你的 .gitignore 文件,这些“无关人等”它连看都不看一眼,直接从目录树中“剪掉”整个分支。这就像你要在你家找钥匙,你首先会把搜索范围限定在家里,而不会先把整栋楼邻居家翻个底朝天。
  2. 耳听八方,并行“影分身”(多线程):剩下需要搜的文件,它不会一个一个傻傻地看。ripgrep 会像鸣人一样使出一个多线程“影分身之术”,用线程池并行处理多个文件。一个“分身”负责遍历目录产生文件路径,多个“工人分身”并行搜索不同文件,结果通过无锁队列汇总。
  3. 招式凌厉,向量化速读(SIMD):对于单个文件,逐字节地找关键词就像读书时一个字一个字地看。ripgrep 利用现代CPU的 SIMD(单指令多数据流)指令,一次能并行比较32个字节,如同用机关枪扫射,快速锁定搜索词的首字符可能出现的位置,只在命中时才做完整匹配。
  4. 内力深厚,数据免搬(mmap零拷贝):对于大文件,传统方式是把数据从硬盘读到内核空间,再从内核空间复制到用户空间供程序使用。ripgrep 使用 mmap(内存映射)技术,让程序直接访问内核的Page Cache,省掉一次昂贵的数据复制,就像武侠小说里高手隔空取物,内力直达。
  5. 场景完美,规模恰好(数据量有限):最根本的是,你一个项目的代码,撑死了几百兆字节(MB)。现代计算机把这小身量的所有文本文件从内存里过一遍,考虑约30GB/s的内存带宽,纯粹的数据搬运时间下界仅为 8毫秒。加上实际匹配的CPU开销,一次搜索总共也就几十到一百多毫秒。你眨个眼的功夫,它已经搜完好几遍了。

当数据量小到一定程度时,暴力就是最强的优雅。 预先建索引这种“高射炮打蚊子”的操作,完全没必要。学术界(ISSTA ‘26上发表的 GrepRAG 论文)甚至做了实验,证实对于代码补全任务,让LLM自己写ripgrep命令去找代码上下文,效果直接碾压了基于Embedding的RAG。根本原因是:代码里**95%**的搜索关键词是类名、函数名、变量名这种精确标识符。这就好比,在全是数字的书里找404这个字符串,用精确搜索当然比“找一个可能有‘未找到’含义的数字”的模糊搜索快得多。


第四章:同行怎么看?一场“精确”与“语义”的华山论剑

当然,江湖上不是只有Claude Code和Codex这一种练法。它们的最大对手 Cursor,就练了一套完全不同的功夫——双索引架构

  • Cursor的“左右互搏”

    1. 左手画圆(语义索引):Cursor背后,用 Turbopuffer 向量数据库存储了超过100亿个向量!用户查询时,先embedding,再在向量海里做最近邻搜索。这解决的是“我不知道具体函数名,但想找一个处理用户认证的模块”这类模糊概念问题。
    2. 右手画方(精确搜索索引,Instant Grep):更绝的是,Cursor内部给代码搞了个 “三字符倒排索引” (Trigram Index)。比如把“OAuth”切成“OAu”、“Aut”、“uth”三个连续字符组合,为每个组合维护一个包含它的文件列表。搜的时候,能找到所有Trigram的交集,极大缩小需精确匹配的文件范围。这本质是给Grep加了强力外挂。
  • 一场“心口不一”的黑色幽默:最有趣的是,Cursor 2025年泄露的一份内部系统提示(System Prompt)里,grep_search 被明确标注为 “主要探索工具 (MAIN exploration tool)”,而 codebase_search(语义搜索)只是在概念性查询时,才被拿出当替补。一家把语义搜索当核心卖点、全家桶全上的公司,内部却让Grep打头阵。这充分说明,在代码搜索这个具体任务上,“精确匹配找到已知符号”远比“语义理解找到相似概念”来得高频和确定。向量检索解决的是Grep覆盖不到的长尾,而不是反过来。

  • Codex的“无招胜有招”:而OpenAI的Codex呢?它更绝,连专属的GrepTool都没给,直接让LLM通过一个通用的 shell 工具,自己去命令行执行 rgfind 这些原生命令。它选择了一条和Claude Code殊途同归的“零索引”道路,但追求了更大的灵活性。

所以,零索引和双索引,不是技术优劣之分,而是场景选择。Cursor要服务包含海量巨型仓库的企业级用户,索引是必须的。Claude Code和Codex主要服务开发者的本地项目,零索引能带来零启动、零维护的极致简洁。


第五章:等等,这个方案有“吞金兽”Bug!它怎么解决的?

听到这里,一个巨大的质疑肯定会从你聪明的脑袋里冒出来:“这种来来回回、反复grep、read的模式,不是疯狂烧Token吗?上下文窗口是不是瞬间就爆了?”

你说到点子上了!向量数据库厂商Milvus(Zilliz)的工程师就专门写过一篇檄文,标题就叫 《我为什么反对Claude Code的纯Grep检索?它实在太能烧Token了!》 。他们实测发现,调试一个小bug,Claude Code花了14轮工具调用、32.2k Token才找到埋藏在500行噪声里的10行关键代码,堪称“大海捞针”的Token燃烧机。

面对这个“吞金兽”Bug,Claude Code的开发者们早备好了三张“省钱符咒”:

  • 省钱符咒一:对话缓存(Prompt Cache)的神技。API很聪明,它能发现你每一轮提问,90%的前缀(比如系统提示、前面几轮的历史)都和上一轮一模一样,只是末尾追加了新结果。这时候,它可以复用上一次的“思考过程”,只为新增部分付全价,前面累积的大头按约十分之一的价格打骨折。有分析称,这招能降低**81%**的成本。
  • 省钱符咒二:自动“压缩饼干”(Auto-Compaction)。当对话历史长到快要撑爆上下文窗口时,系统会自动触发一个“压缩”任务。它会像把一堆没用的旧报纸做成一个压缩饼干一样,用LLM对早期的搜索历史(一大堆grep结果、读过的代码)生成一段简要的摘要,然后用这段摘要替换掉原始的、冗长的历史消息,直接腾出空间。
  • 省钱符咒三:派出“探索小分队”(子Agent)。还记得前面说的侦探吗?对于特别复杂、需要大范围搜索的任务,主侦探可以派出一支“探索小分队”(Explore子Agent)。小分队带着专属的只读工具,进入一个独立的、干净的子上下文里去地毯式搜索。在里面产生的所有信息噪音和Token消耗都由小分队自己承担,最后只把一份精炼的“行动总结报告”交还给主侦探,完美隔离了上下文污染。

这三板斧下去,暴力多轮搜索的成本虽然仍高于精准检索,但在个人开发的规模上,已经变得完全可接受,换来了零索引、零维护的巨大工程便利。


尾声:死的不是“检索增强”,是“教条主义”

所以,回到那个耸人听闻的标题:RAG真的死了吗?

别闹了,RAG活得好好的,它只是打破了一种思想牢笼,回归了本质。

“检索增强生成”这个宽广的范式——先去检索信息,再塞给模型生成答案——是AI能在外界知识基础上思考的永恒真理。Claude Code做的事,完全符合这个

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐