本文来自微信公众号: 碳基智 ,作者:碳基智
去年那会儿RAG好像还是版本答案,我身边的每个解决方案架构师在跟客户聊的时候都是言必谈RAG,好像不用这个就赶不上这波AI热潮。
但Claude Code却一反常态,放弃了用RAG的方式,改用了50年前就开始流行的Grep,完全跟潮流背道而驰。
这对于一直吹嘘AI新范式的新贵们而言非常不寻常,于是我想也许可以去探究一下这背后的原因。
1
2025年5月,Anthropic工程师Boris Cherny在一次播客中透露:Claude Code早期使用了RAG(检索增强生成)+本地向量数据库的方案,团队花了几个月时间验证,最终结论是全部砍掉,换成grep。
他是这么说的:
Early versions of Claude Code used RAG+a local vector database,but we found pretty quickly that agentic search generally works better.It outperformed everything,by a lot.
注意措辞,大幅碾压所有方案。
我现在常用的Codex实际上也是这样的逻辑,不建索引、不用embedding、不用RAG。Cursor虽然是走RAG起家的,但3月份他们泄露的Agent System Prompt里面也写着grep_search is your MAIN exploration tool,RAG只在概念性查询时作为补充。
不同的case得出了同样的结论:
在代码搜索场景下,Agent+grep\>RAG+向量数据库。
2
RAG全称Retrieval-Augmented Generation(检索增强生成),工作流程是:
预处理阶段:把文档/代码切成若干片段(chunk),用embedding模型把每段转换成一个高维向量(通常768维或1536维浮点数数组),存入向量数据库
检索阶段:用户提问时,把问题也转成向量,在向量空间中用余弦相似度找"距离最近"的文档片段
生成阶段:把检索到的片段喂给大模型,让模型基于这些片段回答
逻辑很好理解,大模型不可能一次读完所有文档(上下文窗口有限),那就先筛一遍,只把最相关的给它看。
grep诞生于1974年,原理极其简单:输入一个关键词/正则表达式,grep从第一行扫到最后一行,把所有匹配的行列出来。
不用理解,也没有语义,纯粹的字符串匹配。
问题来了,为什么50年前的技术,能在但凡能讲新范式就绝口不提老概念的AI圈,打败看起来是版本答案的顶流技术?
3
原因一:代码是精确匹配场景
代码和自然语言有本质区别。自然语言中,"如何配置用户登录"和"authentication setup guide"说的是同一件事,但字面完全不同——这是embedding存在的核心价值。
但代码里,变量名就是含义本身。你要找handleUserLogin这个函数,直接搜handleUserLogin就行了。不存在"语义相近但名字不同"的情况。程序员已经把语义编码在标识符里了。
研究数据支撑:在LongMemEval的116个代码搜索问题上,grep的平均准确率显著高于向量检索,且这个结论在Claude Code、Codex CLI、Gemini CLI三个框架上都稳定复现。
原因二:向量检索有结构性失败模式
实际案例:用户搜"如何导出个人银行流水用于贷款审核",embedding返回"长江流域水文站每月发布河岸流水监测报告"——因为"银行流水"和"河岸流水"在向量空间里距离很近。余弦相似度0.82,看起来"相关",实际是垃圾。
代码场景:user_id在auth模块和logging模块里语义完全一样,作用完全不同。embedding无法区分。
向量相似度搜索不能实现'找出最相关的信息'这个目标,这是RAG在生产环境中失败的根本原因。
grep不会犯这种错。grep要么找到精确匹配,要么告诉你没找到。它的失败模式是确定性的,有就有,没有就没有,不存在答非所问的幻觉。
原因三:RAG在代码场景有五个工程级问题
索引永远追不上代码变化:代码库是活的,有人merge了PR,索引就过期了。重新索引大型项目要几十分钟到几小时。grep搜到的永远是实时的。
chunk切分破坏代码结构:RAG的切分通常按token数暴力切割,把一个函数切成两半是常有的事。
embedding压缩丢信息:把validateUserSession(token,refreshToken)压成1536维向量,信息密度和把"用户登录验证"四个字压成同维度的向量完全不同。代码的语义更精确,embedding的信息损失更严重。
语义相似≠代码相关:同一个变量在不同模块里作用完全不同,embedding无法区分上下文。
流水线复杂度:RAG需要代码解析→chunk切分→embedding生成→向量存储→查询→排序,每个环节都可能出问题。grep一行命令搞定。
4
得益于Claude Code不久前的那次开源,大家对它的设计都有了源码级的了解。
它实现的是一套Agent驱动的多轮迭代搜索系统:
LLM收到用户问题后,自主决定搜索策略
调用grep搜关键词→读取结果→判断是否足够
不够的话,调整关键词再搜一轮
或者用glob找到文件路径→读取文件内容→发现新线索→继续搜索
整个过程没有向量、没有embedding、没有索引、没有预处理。每次从零开始。但它不是盲目搜索,它每一轮的搜索关键词都是基于上一轮结果动态调整的。
这跟人类程序员探索新代码库的方式一模一样:
看目录结构→grep函数名→读关键文件→追踪调用链→再grep。
工具设计上精细度做得很好,因此成本控制也很理想:
GrepTool:三种输出模式(文件名/内容/计数),head_limit参数控制返回量,防止context爆炸
GlobTool:按文件名模式匹配,快速定位目标文件
FileReadTool:按行范围读取,精确控制token消耗
5
这里我也学习到了一些技术趋势,总结分享给大家。
趋势一:从预处理型架构到实时型架构
预处理型的核心逻辑是提前把数据处理好,用户来了直接查。好处是检索快,但维护成本高、有过期风险、筛选逻辑固化。
实时型的核心逻辑是不做预处理,每次让Agent实时获取和判断。优势是零维护、零配置、永远最新,劣势是比较依赖模型推理能力。
这中间发生临界转变的节点在于,上下文窗口大幅提升了,以前不能做到的塞爆模型上下文窗口的动作可以做到了,那么瓶颈自然不再是检索,而AI也有了足够的推理能力去解决这个问题。
趋势二:Agent驱动的主动检索取代被动预检索
传统RAG是一次性被动检索:把问题向量化→查top-K→喂给模型。就像你去图书馆,馆员替你选好5本书放桌上,你只能从这5本里找答案。
Agentic Search是多轮主动检索:模型自己决定找什么、怎么找、找到后要不要继续找。就像你自己走进图书馆,先看索引卡→找到一本→翻了几页发现线索→再去找另一本→直到找到答案。
这背后,核心的决定逻辑,还是模型能力的持续增长。
趋势三:The Bitter Lesson(苦涩的教训)又一次验证了
Rich Sutton在2019年发表的《The Bitter Lesson》是AI领域最有影响力的文章之一(据传OpenAI员工每天早上朗读)。核心论点只有一句话:
70年AI研究的最大教训是:利用计算能力的通用方法最终总是最有效的,而且优势非常明显。
历史反复证明这个规律:
Boris Cherny明确引用了Bitter Lesson来解释Claude Code的设计哲学:
一切都是模型。随着模型变得更好,它会吸纳一切其他东西。与其花精力构建复杂的检索工程,不如押注模型能力的提升。
趋势四:确定性工具在AI时代更有价值
AI时代最稀缺的东西是确定性。
grep给的是确定性承诺:搜processPayment就是精确匹配这个字符串。找到了就是找到了,没找到就是没有。失败原因只有一种:搜索词不对。
向量检索给你的是概率性结果:余弦相似度0.82,可能相关。找到了不一定对(银行流水vs河岸流水),没找到不一定没有(可能是embedding质量问题)。失败原因可能是embedding模型、语义偏差、chunk切分策略、索引过期、维度设置——调试是噩梦。
当一个AI Agent要做20轮迭代搜索时,每一轮的可靠性会累加。如果单次搜索99%可靠,20轮后是0.99²⁰=82%。如果单次95%可靠,20轮后是0.95²⁰=36%。
确定性工具的可靠性是100%(给定关键词,结果完全确定)。概率性工具的可靠性永远\<100%。在多轮迭代的Agent架构下,这个差距将被指数级放大。
当然,grep不是银弹,它有自己明确适用的场景,RAG也不是一无是处,只是恰好在代码搜索这个场景下,grep比RAG更适合。
AI时代,够用就好的思维可能会是一种更为高阶的认知能力。
