从工程约束到设计哲学的全面拆解 — GitHub Copilot & Claude Code 的代码检索策略
代码 ≠ 自然语言文档。代码有它特殊的检索属性:
getUserById 就是搜 getUserById,不存在"语义相近"这回事。
grep 只做一件事:字符串匹配。但配合 LLM 的推理能力,效果出奇地好。
getUserById 和 fetchUserData 可能映射到相近向量。但代码调用关系是精确的,"语义相似"在这里是噪声,不是信号。LLM 承担"语义理解",grep 承担"精确定位"。职责分离,各司其职。
工具要匹配问题的本质。代码是精确符号系统,grep 是精确符号匹配工具,天然契合。RAG 是为模糊语义世界设计的,用在代码上是"杀鸡用牛刀",还杀不准。
优秀的系统设计不是用最先进的技术,而是用最合适的技术。这也是为什么 Claude Code 宁愿多次 grep,也不维护一个向量索引。
面试官问这题,真正想考察的是你对"工具与问题匹配"的判断力,而不是 RAG 知识本身。
代码中的标识符(函数名、类名、变量名)是精确符号,不是自然语言。RAG 的核心价值是处理语义模糊性,而代码检索恰恰不需要这个。"语义相似"在代码世界里往往是干扰而非帮助。
RAG 需要维护向量索引,构建成本高、更新延迟大。代码文件每分钟都在变化,grep 天然支持实时文件系统,零基础设施依赖,延迟 <50ms。
RAG 的作用是把模糊查询转换成精确检索。但在 AI 代码助手中,LLM 本身就能完成这个转换——它可以推断出应该 grep 哪些关键词,不需要向量检索这个中间层。两步协作完胜 RAG 一步检索。