考察点
这道题出自蚂蚁集团智能体与大模型应用方向一面,很考察候选人对检索技术本质的理解,而不是「RAG 是银弹」的思维定式。面试官想听你讲清楚:grep 和向量检索各自的匹配机制是什么、代码检索这个具体场景的需求特点是什么、为什么精确匹配在代码场景反而赢了。追问可能往「什么场景该用 RAG」「代码检索有没有更好的方案(AST、符号索引)」走。
参考答案
两种检索的本质区别
grep 是字面精确匹配:按字符串或正则逐行扫描文件,命中与否是确定性的。你搜 getUserInfo,它返回所有包含这个字符串的行,一个不多一个不少。它没有索引预处理,每次实时扫描,毫秒到秒级出结果。
RAG 检索是语义近似匹配:提前把文档切成 chunk,用 embedding 模型编码成向量存进向量库;查询时把 query 也编码成向量,做近似最近邻(ANN)搜索取 top-k。它按「语义相似度」排序,命中是概率性的——返回的是「最像的 k 个」,不保证包含你想要的,也不保证排序正确。
一句话概括:grep 给你确定性,RAG 给你语义泛化能力。代价和收益正好互换。
代码场景为什么 grep 赢了
代码检索的需求特点和自然语言问答很不一样,逐条对一下:
第一,代码查询大多是精确符号查找。Agent 在代码库里干活,典型动作是「找这个函数定义在哪」「这个类有哪些调用方」「这个报错字符串从哪里抛的」。函数名、变量名、错误码都是精确字符串,grep 一搜一个准。向量检索反而可能召回一堆语义相近但名字不同的函数,漏掉真正要的那个——embedding 对「语义」敏感,对「符号」恰恰不敏感。
第二,代码库是高频变动的。开发者每次改代码,RAG 的索引就得增量更新:重新切 chunk、重新算 embedding、更新向量库。索引滞后就召回旧代码,这在编程场景是致命的——Agent 拿着昨天的代码改今天的文件。grep 没有索引,永远搜的是磁盘上的最新状态,零维护成本。
第三,确定性和可解释性。Agent 的决策链条里,工具结果不可靠会级联放大错误。grep 没搜到就是真没有,Agent 可以放心换策略;向量检索没召回,你无法区分是「不存在」还是「embedding 没 embed 好」,这个不确定性很难处理。
第四,成本结构。grep 是免费的 CPU 操作;RAG 要维护 embedding 推理、向量库、更新管道一整套基础设施。对代码这种结构化、符号化的数据,这套投入产出不划算。
但 grep 也不是全部:Agent 的检索是分层的
面试时别把话说死。Claude Code 实际上保留了语义搜索能力(某些版本提供相关工具),因为确实存在 grep 解决不了的查询——「处理用户认证的逻辑在哪个文件」,这种问题没有确定的关键词,语义检索就有价值。更完整的代码检索体系还有更专业的层次:语言服务器(LSP)提供的「跳转到定义」「查找引用」是基于 AST 和符号表的,比 grep 还精确;ctags、tree-sitter 这类索引介于两者之间。
所以准确的答案是:Agent 检索代码的主食是精确匹配(grep/glob),辅以语义检索兜底模糊查询,理想形态是接入 LSP 级别的符号索引。选型的原则是按查询类型选工具,而不是一种技术包打。
对比表收尾
| 维度 | grep | RAG 向量检索 |
|---|---|---|
| 匹配机制 | 字面/正则精确匹配 | embedding 语义相似度 |
| 结果确定性 | 确定性,可复现 | 概率性,top-k 近似 |
| 预处理 | 无,实时扫描 | 切 chunk + 建向量索引 |
| 数据更新 | 零成本,永远最新 | 需增量更新索引 |
| 擅长 | 符号、标识符、错误码 | 模糊语义、自然语言问题 |
| 基础设施 | 无 | embedding 服务 + 向量库 |
可能的追问
- 那企业知识库问答为什么用 RAG 不用 grep? 答:自然语言文档里用户的问法和文档的写法很少字面重合(「怎么请假」vs「年假申请流程」),精确匹配大量漏召,语义泛化正是刚需;且文档更新频率远低于代码。
- 代码做 RAG 有哪些已知难点? 答:切 chunk 难(按函数/类切还是按行数切,切错语义就碎)、embedding 模型对代码符号不敏感、跨文件依赖关系向量表达不了,所以有专用代码 embedding 模型和基于 AST 的切分方案。
- grep 在大 monorepo 里性能够吗? 答:纯 grep 扫百万级文件会慢,工程上用 ripgrep(多线程 + 内存映射)或先建倒排索引的工具(如 zoekt),这属于「精确匹配的加速」,不是转向语义检索。