面试题深度解析

为什么 AI 代码助手用 grep 而不是 RAG?

从工程约束到设计哲学的全面拆解 — GitHub Copilot & Claude Code 的代码检索策略

代码检索的核心需求

代码 ≠ 自然语言文档。代码有它特殊的检索属性:

精确性要求
极高
语义模糊性
极低
标识符不变性
100%
关键洞察:代码中的函数名、变量名、类名是精确符号,不是模糊概念。搜索 getUserById 就是搜 getUserById,不存在"语义相近"这回事。
grep 的工作方式(从截图中可以看到真实示例)
# Claude Code / Copilot 实际执行的命令
grep -rn "getUserById" --include="*.ts"
grep -rn "import.*AuthService" --include="*.ts"
grep -rn "shell/" --include="*.md" --include="*.json" --include="*.js" | grep -v ".git"
用户提问
LLM 推断关键词
grep 精确匹配
返回文件路径 + 行号
LLM 读取上下文

grep 只做一件事:字符串匹配。但配合 LLM 的推理能力,效果出奇地好。

RAG 在代码检索上的三个致命缺陷
缺陷一:向量化会丢失精确符号
embedding 模型将 getUserByIdfetchUserData 可能映射到相近向量。但代码调用关系是精确的,"语义相似"在这里是噪声,不是信号。
缺陷二:索引构建成本高且过期快
每次文件变更都需要重新向量化。一个中等规模代码库(10万行)构建索引需要几分钟到十几分钟,而 grep 是即时的,直接读文件系统。
缺陷三:检索粒度难以控制
代码的 chunk 边界非常难定义。按行切?按函数切?按文件切?每种方式都会截断上下文。而 grep 返回精确行号,LLM 可以自由扩展阅读范围。

grep 方案

  • 零构建成本,随用随搜
  • 毫秒级响应(<50ms)
  • 结果 100% 精确,无假阳性
  • 天然支持正则表达式
  • 文件变化实时可见
  • 返回行号,可精确读取上下文
  • 不依赖任何额外基础设施

RAG 方案

  • 需要向量数据库
  • 构建索引耗时(分钟级)
  • 可能返回语义相近但错误的结果
  • chunk 切分策略复杂
  • 索引实时性难保证
  • 检索结果缺少精确位置信息
  • 依赖 embedding 模型质量
速度对比(10万行代码库)
grep 搜索延迟
<50ms
RAG 向量检索
200–500ms
RAG 索引构建
5–30min
工程权衡本质:RAG 的优势在于处理"意图模糊"的查询。但代码助手的查询意图通常很明确 — LLM 自己可以推断出精确的标识符,再用 grep 找到它。这是两步推理,完胜 RAG 一步检索。
LLM + grep 的协同机制(分工明确)
用户:"帮我找到处理用户登录的代码"
LLM 推断:关键词可能是 login / auth / signIn / handleLogin
grep -rn "login\|signIn\|handleAuth" --include="*.ts"
LLM 读取匹配文件 → 理解代码结构 → 回答用户

LLM 承担"语义理解",grep 承担"精确定位"。职责分离,各司其职。

代码检索场景:grep 完胜 RAG 的情况
找函数定义
grep "function getUserById" ✓
找所有调用某接口的地方
grep "\.getUserById(" ✓
找某个类的定义
grep "class AuthService" ✓
找所有 import 某模块的文件
grep "import.*lodash" ✓
找某个 TODO 注释
grep "TODO.*auth" ✓
找所有 API 路由定义
grep "router\.(get\|post)" ✓
RAG 真正的适用场景(不是代码库)
企业知识库问答
RAG 合适 — 文档语义模糊
产品文档检索
RAG 合适 — 自然语言查询
客服历史记录
RAG 合适 — 语义相似优于精确
代码库函数查找
RAG 不适合 — 符号精确性最重要

工程哲学总结

工具要匹配问题的本质。代码是精确符号系统,grep 是精确符号匹配工具,天然契合。RAG 是为模糊语义世界设计的,用在代码上是"杀鸡用牛刀",还杀不准。

优秀的系统设计不是用最先进的技术,而是用最合适的技术。这也是为什么 Claude Code 宁愿多次 grep,也不维护一个向量索引。

面试高分答法 — 结构化三层作答

面试官问这题,真正想考察的是你对"工具与问题匹配"的判断力,而不是 RAG 知识本身。

第一层:代码的本质决定检索策略

代码中的标识符(函数名、类名、变量名)是精确符号,不是自然语言。RAG 的核心价值是处理语义模糊性,而代码检索恰恰不需要这个。"语义相似"在代码世界里往往是干扰而非帮助。

第二层:工程成本与实时性

RAG 需要维护向量索引,构建成本高、更新延迟大。代码文件每分钟都在变化,grep 天然支持实时文件系统,零基础设施依赖,延迟 <50ms。

第三层:LLM 已经替代了 RAG 的"语义桥"角色

RAG 的作用是把模糊查询转换成精确检索。但在 AI 代码助手中,LLM 本身就能完成这个转换——它可以推断出应该 grep 哪些关键词,不需要向量检索这个中间层。两步协作完胜 RAG 一步检索。

加分点 +分主动说出 RAG 适合的场景(长文档、非结构化知识库),展示你理解 RAG 的本质,而非只会背优缺点列表。这展现了工程判断力。
自测:选出最佳答案
Q1: 为什么 grep 在代码检索中比向量检索更准确?
Q2: 如果让你为一个 10 万行代码库设计代码搜索,你会选哪个方案?