为什么 AI 读代码比向量检索更准?聊聊代码知识库的设计取舍

5 阅读8分钟

为什么 AI 读代码比向量检索更准?聊聊代码知识库的设计取舍

做 AI 知识库的人都知道 RAG——把文档切成 chunk,向量化,用户提问时找相似 chunk,喂给大模型生成答案。

文档库这样做没问题。但代码库这样做,会出大问题。

比如你问:"修改 parseInput() 会影响哪些测试?"

向量检索能找到语义相近的代码片段,但找不到调用关系。它知道哪些代码和 parseInput "像",但不知道谁调用了它。

再比如:"这个奇怪的边界判断是为什么加的?"

向量检索完全无能为力——这个信息只存在于半年前那个 commit message 里。

这篇文章聊聊我对代码知识库的理解,以及我在做一个 IDEA 插件时做出的设计取舍。

代码知识不是平的,是四层的

代码库的知识不是一个平面,而是四个层次,每层需要不同的理解方式:

层次 4:业务意图层 —— "为什么这样设计?"
         ↑ Git 历史、Commit Message、Issue 关联


层次 3:架构层    —— "谁调用了谁?"
         ↑ 调用图、依赖关系、模块边界


层次 2:语义层    —— "这段代码做什么?"
         ↑ AI 理解、代码注释、函数命名


层次 1:语法层    —— "这个文件有什么?"
         ↑ 目录结构、类定义、函数签名

传统方案是混合多种工具来覆盖每一层:

方案语法层语义层架构层意图层
grep / ripgrep擅长不支持不支持不支持
向量化检索有限擅长不支持有限
AST 符号索引擅长有限有限不支持
调用图 / 依赖图有限有限擅长不支持
Git 历史索引不支持有限不支持擅长

没有任何单一方案能覆盖全部四个层次。

但我在做知识归档插件时,发现了一个有趣的事情——

AI 读代码时,同时在理解四个层次

当 AI 读到 WoHdrServiceImpl.java 这个文件时,它同时在做四件事:

语法层:这是一个 Service 实现类,有 validatecreateupdate 三个公开方法,依赖 WoHdrDao 和 WoModelService

语义层:这是工单头表的核心服务,负责工单的创建、校验和更新逻辑。validate 方法检查工单日期不能早于当前日期,create 方法自动生成工单编号。

架构层:它被 WoHdrController 调用,通过 WoHdrDao 访问数据库,依赖 WoModelService 做工单模型转换。

意图层:从 commit 历史看,validate 方法上个月刚重构过,原因是合并了两种工单类型,原来分开校验现在统一了。

一次阅读,四层理解。  这就是 AI 和传统工具的本质区别——AI 不需要你为每一层单独建索引。

向量检索只能做到语义层的"这段代码和工单创建相关",但 AI 能告诉你"这是工单头表的核心服务,被 Controller 调用,上个月刚因为合并工单类型重构过"。

我的设计取舍

基于这个认知,我在做 Knowledge Archiver 插件时,做了一个核心决策:不让工具分别处理每一层,而是让 AI 作为统一理解引擎,配合结构化文档做长期记忆。

取舍 1:文件即记忆,而不是向量数据库

大多数 AI 工具用向量数据库存知识。我反其道而行——AI 的分析结果直接写入 Markdown 文件。

.knowledge/
├── drafts/              # AI 生成的草稿
   └── 2026-08-10_模块-wo-management.md
docs/
├── core/                # 升格后的正式文档
   └── wo-management.md
└── INDEX.md             # 文档索引

为什么不用向量数据库?

因为知识文档的读者是人,不是机器。Markdown 文件可以:

  • 被 Git 版本控制,追踪知识的演进历史
  • 被人直接打开编辑,补充 AI 遗漏的内容
  • 零成本迁移,不依赖任何服务
  • 在代码审查时一起 review

向量数据库里的 embedding 人看不了。你的知识被锁在一个二进制索引里,离开了这个系统就什么都不是。

取舍 2:AI 一站式理解,而不是多层工具组合

传统方案需要 AST 解析器 + 向量检索引擎 + 调用图生成器 + Git 索引器,四套工具组合起来才能覆盖四个层次。

我的方案:让 AI 直接读源码,一次性完成语义层和意图层的理解。

传统方案:
  代码 → AST 解析器 → 语法索引
  代码 → Embedding → 向量库 → 语义检索
  代码 → 调用图生成器 → 依赖图 → 架构查询
  Git → Commit 索引器 → 历史检索
  四套管道,各自维护


我的方案:
  代码 + Git 历史 → AI 一次性理解 → 结构化 Markdown 文档
  一套管道,AI 做统一理解

代价是每次调用消耗 Token。收益是不需要维护复杂的索引管道,而且 AI 的理解能力远超任何单一工具。

实测对比:让 AI 读 45 个源文件后生成的工单管理模块文档,包含了完整的业务流程图、状态机、异常处理路径。同样的信息,用向量检索 + 调用图的方案,你需要先建索引、再写查询、再拼接结果——还不一定能拼出完整的业务流程。

取舍 3:多视角文档结构,而不是扁平 chunk

RAG 把文档切成等大的 chunk,丢失了结构信息。AI 拿到一个 chunk 时,不知道这是"开发视角的业务流程"还是"测试视角的验收标准"。

我的文档按 7 个视角组织章节:

视角内容AI 能自动填充?
开发视角业务流程、状态机、核心实现擅长
测试视角验收标准、边界场景部分
运维视角日志监控、常见故障部分
实施视角配置项、接口协议部分
产品视角需求背景、业务痛点人工补充
客户视角操作流程、功能入口人工补充
销售视角价值主张、核心优势人工补充

AI 读取文档时,知道当前章节是什么视角,生成内容时不会混淆。检索时也能精准加载——用户问"验收标准是什么",只需要加载测试视角章节,不用把整个文档都塞进上下文。

取舍 4:四层记忆体系,各层解决不同问题

L1 元数据索引 → 毫秒级定位模块(语法层的轻量替代)
L2 内容层     → Markdown 存储完整文档(语义层 + 架构层)
L3 检索层     → 本地优先 + AI 兜底(控制 Token 成本)
L4 输出标签   → 自动发现跨模块依赖(架构层补充)

意图层由 Git Commit 自动归档覆盖——每次提交自动提取变更意图,写入文档的变更记录章节。不需要单独的 Git 索引器,因为 AI 在归档时就已经理解了变更的业务含义。

这个方案不擅长什么?

公平地说,AI 驱动的方案也有短板:

语法层查询不是强项。  如果你需要"找到所有调用 parseInput() 的地方",IDE 自带的 Find Usages 比任何知识库都快、都准。知识库的目标不是替代 IDE 的代码导航功能。

架构层依赖 AI 判断。  没有精确的调用图,模块间的依赖关系是 AI 从 import 语句和代码结构中推导出来的,可能有遗漏。但对于业务知识文档来说,"工单模块依赖库存模块"这种粒度的信息已经够用了。

Token 成本可控但不为零。  每次 Commit 归档约 5K-15K Token,深化分析每轮约 85K-190K Token。用国产模型(DeepSeek、智谱等)成本很低,但如果项目很大、提交很频繁,需要合理规划。

总结

代码知识库不是"给代码做 RAG"那么简单。代码有结构、有层次、有历史,需要不同的理解方式。

传统方案是堆工具——每一层一个工具,然后组合。我的方案是让 AI 做统一理解引擎,用结构化文档做长期记忆。

维度传统 RAG 方案AI 驱动方案
理解引擎向量相似度AI 一次性理解
存储格式向量数据库Markdown 文件
覆盖层次语义层强,其他层需补工具语义层 + 意图层强
可维护性需要维护多套索引管道文件即记忆,零维护
可读性embedding 不可读人可直接阅读编辑
精确查询语法层精确架构层可能遗漏

两种路线各有取舍。但对于"让业务知识沉淀"这个目标来说,AI 驱动的方案更简单、更可控、更贴近人的阅读习惯。

毕竟,知识库最终是给人看的,不是给机器查的。


欢迎试用和反馈。