首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >当 AI 编码助手需要理解你的代码:从 Grep 到项目知识体系的构建

当 AI 编码助手需要理解你的代码:从 Grep 到项目知识体系的构建

作者头像
tunsuy
发布2026-05-19 12:11:13
发布2026-05-19 12:11:13
30
举报

❝AI 编码工具不用向量搜索,靠 Grep 就能理解代码库?那我们的项目需要预先构建什么样的知识体系来帮助 AI?❞


一、AI 编码助手是怎么"看懂"你的项目的?

你可能已经在用 Claude Code、Cursor、Copilot 这类 AI 编码工具。你抛出一个需求,AI 能从你的项目中找到相关代码、理解模块关系、生成符合项目风格的代码。但你有没有想过:「它到底是怎么"看懂"你几万行代码的?」

一个直觉的答案是:预先把代码分块、生成 embedding、存入向量数据库,用户提问时跑语义搜索找到相关代码片段——这就是经典的 RAG(Retrieval-Augmented Generation)方案。但 Claude Code 的创建者 Boris Cherny 在多个公开场合揭示了一个让人意外的事实:

❝"Early versions of Claude Code used RAG + a local vector db, but we found pretty quickly that agentic search generally works better."❞

❝"Plain glob and grep, driven by the model, beat everything."❞

「Claude Code 不用 RAG,不用 embedding,不建索引。核心搜索就靠 LLM 驱动的 Grep。」 2026 年 3 月泄露的 Claude Code 源码也证实了这一点——源码中没有任何 embedding、vector、similarity search 相关实现。更有意思的是,OpenAI 的 Codex CLI 独立做出了几乎相同的架构选择。两个互为竞争对手的产品殊途同归,这不太可能是巧合。

这引出了两个值得深入讨论的问题:

  1. 「为什么 Grep 在代码搜索场景下够用,甚至比向量搜索更好?」
  2. 「既然 AI 主要靠搜索来理解代码,我们的项目应该预先准备什么来帮助它搜得更准?」

二、为什么 Grep 打败了向量搜索

要理解 AI 编码工具的代码搜索,需要了解三个层面:搜索是怎么运转的、为什么暴力搜索够快、以及代码搜索为什么天然适合精确匹配。

2.1 LLM 驱动的多轮搜索循环

Claude Code 的搜索机制可以用一句话概括:「LLM 自己决定搜什么、用什么工具搜、搜到后要不要继续搜,直到信息充分为止。」

整套机制的核心是一个工具调用循环:LLM 分析用户问题 → 选择搜索工具发起调用 → 拿到结果后决定下一步。具体可用的搜索工具包括:GrepTool(正则搜索文件内容)、GlobTool(按文件名模式查找)、FileReadTool(读取指定文件的指定行范围)、AgentTool(启动子 agent 做独立的多步探索)。此外还有 LSP 工具提供 "go to definition" 等精确的语义操作。

以一个真实搜索过程为例:当你问 Claude Code "bridge 系统是怎么追踪 GrepTool 调用的?"时,LLM 实际执行了四轮搜索——第 1 轮用 Grep 广撒网找到 4 个相关文件;第 2 轮切换到 content 模式看上下文代码片段;第 3 轮用 Read 读取完整文件找到了工具映射表、摘要生成函数和活动解析器;第 4 轮追踪引用链,一次 Grep 同时找到类型定义、轮询逻辑和 UI 渲染三个文件。最终拼出完整的数据流转链路。

这种"主动搜索"模式和传统 RAG 的"被动检索"有本质区别:传统 RAG 在问题出现之前就预先决定"你可能需要看什么",一次性塞一批代码块进 context;而 Agent 模式下,每一步搜什么都由上一步的发现决定——这条搜索路径是任何预检索方案都猜不出来的。

2.2 暴力搜索在本地项目上足够快

Claude Code 底层用的不是古老的 GNU grep,而是 ripgrep——用 Rust 重写的现代实现。它通过五层过滤(.gitignore 剪枝 → 路径限制 → 文件类型过滤 → 二进制检测 → 正则匹配)把搜索范围层层缩小,再配合 SIMD 向量化加速、Boyer-Moore 跳跃、操作系统 Page Cache、mmap 零拷贝、多线程并行等手段,在 4,500 文件(95 万行代码)的项目上搜索耗时仅 0.09~0.10 秒,比 GNU grep 快 25~33 倍。

更本质的原因在数据规模:开发者本地项目通常在 MB 到几百 MB 之间。一个 250MB 的代码库在 Page Cache 命中的情况下(日常开发项目几乎总是命中),按 30GB/s 的内存带宽算,数据搬运下界仅约 8 毫秒。「这个量级根本用不着离线索引。」

2.3 代码搜索天然适合精确匹配

一项系统性研究(GrepRAG, ISSTA '26)揭示了一个关键事实:「代码搜索的关键词 95% 是标识符——类名(36%)、方法名(41%)、变量名(18%)」。标识符本身就是代码的语义,getUserById 就是 getUserById,不会被改述成 fetchPersonByIdentifier。在这个基准上,即使是单轮 Grep 检索,代码补全效果也超过了 embedding RAG 基线(Exact Match 38.61% vs 24.99%)。

这与自然语言搜索形成鲜明对比。自然语言中"词汇不匹配"是常态——同一个概念有十几种表达方式。但代码里的函数名、类名是程序员亲手埋的精确锚点,Grep 几乎总能命中。「Claude Code 选择放弃 embedding,不是因为向量检索本身不行,而是因为代码搜索恰好是 Grep 最适合的地方。」

2.4 Codex CLI 的验证:殊途同归的零索引

OpenAI 的 Codex CLI 的代码搜索架构和 Claude Code 惊人地相似:「同样不建索引、不用 embedding、不用向量数据库。」 社区提交的向量索引功能请求被 OpenAI 团队关闭,明确表示 "not currently on our roadmap"。

但两者的实现路径有一个关键分歧——「搜索工具的封装方式不同」

  • 「Claude Code」 为搜索封装了「专用工具」:GrepTool 有三种输出模式(files_with_matches / content / count)和 head_limit 等参数,GlobTool 做文件名匹配,FileReadTool 按行范围读取。每个工具有明确的参数 schema,LLM 通过结构化的工具调用来使用它们。
  • 「Codex CLI」 没有专门的搜索工具。它的核心工具是 shell(执行任意 shell 命令)和 apply_patch(专用 diff 格式编辑文件),此外还有 update_planview_imageweb_searchspawn_agent 等。「所有代码搜索操作通过 shell 工具完成」——LLM 直接组合 rgfindcatgit 等 Unix 命令来搜索代码。

Codex 的多个 system prompt 文件中都写了同一条指令:

❝"When searching for text or files, prefer using rg or rg --files respectively because rg is much faster than alternatives like grep."❞

搜索模式同样是多轮迭代:Grep → 读文件片段 → 调整关键词 → 再搜。

方面

Claude Code

Codex CLI

搜索工具

专用工具(GrepTool、Glob、Read),有结构化参数

通过 shell 执行 rg、find、cat,无专用搜索工具

索引

子 agent

内置(Explore、Plan 等类型,context 隔离)

内置(spawn_agent / send_message / wait_agent)

编辑方式

Edit(字符串替换)

apply_patch(diff 格式)

两种路径的核心分歧在搜索工具的封装程度上。Claude Code 把 Grep 封装成带结构化参数的专用工具,LLM 不需要解析原始 shell 输出,减少出错概率,也让系统更容易控制信息量(比如 GrepTool 的 head_limit 默认 250 条,即使搜到 10,000 条匹配也只返回前 250 条)。Codex 让模型直接写 shell 命令调用 rg,给予最大灵活性(可以自由组合管道、正则、路径过滤),但需要模型自己处理非结构化的文本输出。

2.5 行业验证:连 Cursor 也把 Grep 放在第一位

即使是把语义搜索当核心卖点的 Cursor(为此构建了 100 亿+ 向量、1,000 万+ 命名空间的向量基础设施),在其 2025 年泄露的 Agent system prompt 中,grep_search 被明确标注为"主要探索工具"(MAIN exploration tool),codebase_search(语义搜索)只在"概念性查询"时作为补充。「向量检索解决的是 Grep 覆盖不到的长尾,而不是反过来。」

当然,Grep 方案也有明确的成本代价:多轮搜索意味着更多的 token 消耗。Claude Code 通过 prompt cache(92% 的 prompt 前缀在相邻轮次间相同,成本降低约 81%)、auto-compaction(对话历史自动压缩)、子 agent context 隔离三层机制来控制,但本质 tradeoff 不变——「用更多的搜索轮次换取零索引、零维护、零启动延迟的工程简洁性」


三、既然 AI 靠搜索,项目该准备什么?

上面的分析揭示了一个核心事实:「AI 理解你项目的主要方式是搜索代码、读取文件。」 它不是预先"学习"了你的项目,而是在每次对话中实时搜索、逐步拼凑出对项目的理解。

这直接引出一个实践问题:「既然 AI 主要靠搜索来理解代码,我们应该做什么来帮助它搜得更准、理解得更快?」

社区目前有两种主流思路:

思路

做法

代表

「构建向量知识库」

预先分块 → embedding → 向量库

Greptile、Continue Embeddings

「构建结构化上下文」

项目规则文件 + 知识文档 + 规范的代码结构

CLAUDE.md、.cursorrules、ADR

前面的分析已经说明,对于大多数本地项目,向量知识库的 ROI 算不过来(建设成本高、维护成本高、代码搜索场景下收益有限)。「真正高杠杆的投入方向是第二种:构建"结构化上下文"。」

但"结构化上下文"具体该包含什么?这就涉及到一个很具体的问题:「有没有必要给项目预先加上架构设计文档、模块说明这类知识文档?」


四、项目知识文档:有没有必要预先准备?

答案是分层的:「有些知识文档必须有,有些锦上添花,有些则完全可以不做。」 关键判断标准是:这份文档提供的信息,AI 能不能通过搜索代码自己推断出来?

4.1 AI 搜索能力的边界

回顾第二章的分析,AI 的代码搜索能力有三个特点:

  • 「精确匹配极强」:函数名、类名、常量名,Grep 一搜就中
  • 「代码结构推断能力强」:通过目录结构、import 关系、接口定义,AI 能快速理解模块划分和依赖关系
  • 「"为什么"类信息无法推断」:代码告诉 AI "做了什么"和"怎么做的",但不能告诉它"为什么这么做"

基于这个边界,我们可以把项目知识分成三类:

知识类型

AI 能否自行推断

是否需要文档

举例

「代码结构和实现」

能通过搜索获取

不需要专门文档

函数签名、调用关系、数据流转

「约束和规范」

代码中隐含但不显式

「必须有文档」

分层约束、命名规范、错误处理规则

「决策和背景」

完全无法推断

「强烈建议有文档」

为什么选 MongoDB、为什么用 Temporal

4.2 必须有的:项目规则文件

这是投入产出比最高的知识文档,也是唯一一种「不需要 AI 搜索就能直接获取的知识」——它被直接注入 system prompt。

一份好的项目规则文件应该包含 AI 无法从代码推断的约束信息:

代码语言:javascript
复制
├── 架构约束
│   ├── 分层规则(Service → Logic → Repo,禁止跨层调用)
│   ├── 依赖方向(Logic 之间禁止循环依赖)
│   └── 模块边界(各模块的职责范围)
│
├── 编码规范
│   ├── 命名规范(Manager 类用 XXXManager、CRUD 方法用 Create/Get/Update/Delete)
│   ├── 错误处理(用 fmt.Errorf 包装、error 必须是最后一个返回参数)
│   └── 注释要求(导出函数必须有注释)
│
├── 开发工作流
│   ├── 新增功能的标准流程(Entity → Repo → Logic → Service)
│   └── 修改现有代码的检查清单
│
└── API 约定
    ├── 路由格式(/api/v1/{module}/{action})
    ├── 分页规范(默认页码 1,默认每页 20)
    └── 错误码体系

「为什么这些信息无法通过搜索代码获取?」 因为它们是"应该怎么做"的规范,而不是"代码里实际做了什么"的事实。代码可能存在不符合规范的地方,AI 如果只从代码推断,可能会学到错误的模式。

4.3 强烈建议有的:架构决策文档

「Architecture Decision Records(ADR)是最容易被忽视但价值极高的知识文档。」 它回答的是"为什么"——这恰恰是 AI 无论怎么搜代码都推断不出来的信息。

举几个例子:

  • 「为什么选 Temporal 做工作流引擎?」 AI 看到代码用了 Temporal,但不知道你评估过哪些替代方案、Temporal 解决了什么痛点。没有这个背景,AI 在涉及工作流的修改中可能会建议不合适的方案。
  • 「为什么用 MongoDB 而不是 MySQL?」 数据模型的灵活性需求、嵌套文档的场景、未来的扩展方向——这些决策背景直接影响 AI 如何设计新的数据结构。
  • 「为什么模块边界这样划分?」 比如为什么 ChaosTest 模块依赖 Task 模块而不是独立实现,背后有业务语义的考量。

「ADR 不需要很长,一个决策记录 3~5 段话就够。」 关键是记录"考虑了什么"、"选择了什么"、"为什么"。放在项目的 docs/adr/ 目录中,AI 需要时可以搜索和读取。

4.4 锦上添花但非必须的:详细模块说明文档

这是最容易产生争议的一类。很多团队会问:「要不要给每个模块都写一份详细的说明文档,包括模块职责、核心流程、数据模型、接口说明?」

我的判断是:「大部分情况下不需要单独维护模块说明文档。」 理由有三:

「第一,AI 能通过搜索获取大部分信息。」 回顾 Grep 搜索的实际表现——AI 通过 4 轮搜索就拼出了 bridge 系统的完整工具追踪链路。模块的接口定义、函数签名、数据结构,AI 读代码就能理解。你写一份"Task 模块提供了 Create、Get、Update、Delete 四个接口"的文档,AI 搜一下 service/task.go 也能知道。

「第二,模块文档极容易过时。」 代码变了文档没更新是常态。过时的文档比没有文档更危险——AI 会参考错误的信息生成代码。而项目规则文件(架构约束、编码规范)相对稳定,一年可能只改几次。

「第三,好的代码结构本身就是最好的模块说明。」 清晰的目录结构让 AI 用 Glob 几秒定位到模块;规范的命名让 Grep 一步精确匹配;完善的 GoDoc/JSDoc 注释让 AI 读文件就能理解意图;接口驱动设计让 AI 看 interface 就知道模块契约。「代码规范是 Grep 方案的加速器——代码写得好,AI 搜得就准。」

「例外情况」:如果模块涉及复杂的状态机、非直观的流程编排、或跨多个服务的交互链路,用一份简短的流程说明或状态转换图来辅助是值得的。比如 Temporal Workflow 的节点执行流程、DAG 的调度逻辑,这些光看代码不容易一眼理清。

4.5 不需要的:代码级 API 文档

如果你的代码已经有完善的注释(GoDoc、JSDoc、Swagger 注解),「额外维护一份代码级的 API 文档没有意义」。AI 直接读注释比读外部文档更可靠,因为注释和代码在同一个文件里,不存在不一致的风险。

这也是为什么编码规范中要求"每个导出函数必须有注释"——这些注释不只是给人看的,也是给 AI 看的。


五、投入优先级与分场景决策

5.1 投入优先级排序

优先级

投入方向

成本

收益

维护频率

「P0」

项目规则文件(CLAUDE.md / .cursorrules)

极低

极高

一年几次

「P1」

保持代码结构清晰(命名规范、分层清晰、注释完善)

极高

持续

「P2」

架构决策文档(ADR)

每次重大决策

「P3」

复杂流程的简要说明

流程变更时

「P4」

LSP 集成(gopls、tsserver)

一次性

「P5」

向量知识库

低~中

持续

「核心原则:优先投入那些 AI 无法通过搜索代码自行获取的知识,且不容易过时的信息。」

5.2 分场景决策

「中小项目(几百文件、几万行)」

  • 项目规则文件 + 好的代码结构 + Grep 就够了
  • 关键架构决策写 ADR
  • 不需要向量知识库,不需要详细模块文档

「大型项目(上千文件、十几万行)」

  • 上述所有 + 复杂模块的流程说明
  • 可考虑轻量级代码结构索引(如 Aider RepoMap 思路)
  • 可评估混合搜索插件(如 Beacon)

「超大规模 / 多仓库(GB 级 monorepo)」

  • 上述所有 + 向量知识库的价值开始体现
  • 跨仓库的模块关系文档变得必要
  • 可评估 Greptile 或自建 embedding 方案

5.3 一个实践建议:从规则文件开始

如果你的项目目前什么知识文档都没有,「花两个小时写一份项目规则文件」是回报最高的第一步。它应该回答 AI 在帮你写代码时最常遇到的问题:

  • 代码应该放在哪个目录?(架构分层)
  • 新功能的标准开发流程是什么?(开发工作流)
  • 有哪些强制性的编码约束?(不能做什么)
  • 接口和数据结构有什么规范?(API 约定)

与其花两周搭一套向量知识库,不如花两小时写一份好的规则文件。前者是给 AI 建了一个复杂的检索系统,后者是直接把最重要的知识喂给了 AI。


六、总结:让代码自己说话

回到开头的问题:AI 编码助手到底是怎么"看懂"你的项目的?

答案已经清楚了:「它主要靠搜索。」 LLM 驱动 Grep 在代码搜索场景下足够好用,因为代码里的标识符天然是精确搜索的锚点。Claude Code 和 Codex CLI 殊途同归地选择了零索引方案(2.4 节),Cursor 也把 Grep 放在语义搜索之前(2.5 节)。这不是巧合,而是代码搜索这个特定场景的数据特性和规模决定的。

基于这个事实,项目该做的不是去建一套复杂的向量知识库,而是:

  1. 「写好规则文件」——把 AI 无法从代码推断的约束和规范直接告诉它
  2. 「记录关键决策」——把"为什么这么做"写进 ADR,这是 AI 搜遍代码也找不到的信息
  3. 「让代码本身更可搜索」——清晰的结构、规范的命名、完善的注释,每一项都在帮 AI 更准确地理解你的代码

「有时候,最好的基础设施不是你额外建设的系统,而是你精心组织的代码本身。」 好的代码结构让 Grep 一步命中,好的注释让 Read 一次看懂,好的规则文件让 AI 不用搜就已经知道。这三者的组合,在大多数项目上,比任何向量知识库都管用。

❝觉得有用的话,「点赞👍 + 分享👀 + 收藏⭐」 一键三连,下次找起来方便,也能让更多人看到。❞

点击 👨头像 关注我,一起探索 AI 领域的更多可能 ✌️

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-05-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 有文化的技术人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、AI 编码助手是怎么"看懂"你的项目的?
  • 二、为什么 Grep 打败了向量搜索
    • 2.1 LLM 驱动的多轮搜索循环
    • 2.2 暴力搜索在本地项目上足够快
    • 2.3 代码搜索天然适合精确匹配
    • 2.4 Codex CLI 的验证:殊途同归的零索引
    • 2.5 行业验证:连 Cursor 也把 Grep 放在第一位
  • 三、既然 AI 靠搜索,项目该准备什么?
  • 四、项目知识文档:有没有必要预先准备?
    • 4.1 AI 搜索能力的边界
    • 4.2 必须有的:项目规则文件
    • 4.3 强烈建议有的:架构决策文档
    • 4.4 锦上添花但非必须的:详细模块说明文档
    • 4.5 不需要的:代码级 API 文档
  • 五、投入优先级与分场景决策
    • 5.1 投入优先级排序
    • 5.2 分场景决策
    • 5.3 一个实践建议:从规则文件开始
  • 六、总结:让代码自己说话
    • 点击 👨头像 关注我,一起探索 AI 领域的更多可能 ✌️
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档