知识图谱+语义检索:给AI编程助手装上代码大脑

作者:技术拾光

时间:2026-07-31

浏览:326

针对AI编程助手理解代码的痛点,提出igraph方案:在代码结构图基础上增加语义层,通过Tree-sitter解析、LLM生成摘要和向量化,实现自然语言检索。查询阶段采用向量与全文双通道检索及RRF融合排序,支持多模态资源挂载,具备降级策略,以提升代码理解效率。

文章目录

体验地址

Git:github.com/Ychangqing/…

知识图谱+语义检索:给AI编程助手装上代码大脑

从一个真实痛点说起

先说一个日常研发中反复出现的场景:你给AI助手发送一条指令,“帮我看看用户下单这块的逻辑”,然后它就开始疯狂grep、find,一个文件接一个文件地cat,翻十几个文件才能找到createOrder函数,再顺着调用链往下看。整个过程动辄30多次工具调用,token消耗相当可观。

问题出在哪里?根本原因在于,Agent根本不认识你的代码仓库。每次都是盲目搜索,效率极低。

后来用过CodeGraph,情况确实有所改善——Agent可以直接通过图谱查符号、展开调用链,省去了逐个文件翻找的麻烦。但使用一段时间后,发现一个根本性的限制:CodeGraph本质上是一个结构查询工具,而非语义检索工具。

你需要先知道函数名是什么,它才能帮你展开结构。可很多时候,你只清楚业务含义(比如“处理退款的逻辑”),却不清楚代码里的具体命名(是processRefund、handleRefundRequest,还是直接叫refund?)。

这就是促使我们做igraph的原因。

igraph 的核心思路

一句话概括:在代码结构图的基础上增加一层语义层,让Agent能够用自然语言直接搜索代码。

整个系统可以拆成两个阶段:

离线建库(一次性任务):源码 → Tree-sitter解析 → 提取符号和调用关系 → 存入SQLite → LLM为每个函数生成中文摘要 → Embedding向量化
在线查询(毫秒级响应):自然语言问题 → 向量化 → 文件粗筛 → 双通道精排 → RRF融合 → 图谱展开

建库阶段将所有脏活累活提前完成(解析、调LLM、调Embedding),查询阶段纯本地SQLite操作,零网络延迟。

和 CodeGraph 的区别在哪里

先说明一下,两个项目底层技术有不少重合——都用Tree-sitter解析AST、SQLite存储、MCP协议对接AI助手。但设计思路差别很大。

CodeGraph:建一张精确的代码结构图 → Agent按图索骥
igraph:建图 + 语义摘要 + 向量化 → 支持自然语言检索

用一个例子可以看得很清楚:

场景:想找“处理用户退款”的代码
CodeGraph的用法:得先猜函数名可能叫refund / processRefund / handleRefund,然后调用codegraph_node查找,找到后再展开调用链
igraph的用法:直接输入“处理用户退款的逻辑”,igraph_explore返回最相关的函数(带摘要、源码、调用链),同时关联相关的PRD需求和数据库表

更详细的对比:

维度 CodeGraph igraph
检索方式 按符号名精确查找 向量语义 + 全文关键词双通道,RRF融合排序
语义理解 无,纯AST结构 LLM为每个符号生成摘要,向量化后支持语义搜索
多模态 不支持 可挂载PRD文档和DB Schema,需求和代码自动关联
降级策略 依赖运行环境 无LLM → 启发式摘要;无Embedding → 纯全文检索
增量更新 文件监听实时同步 sha256 diff + 50%阈值摘要复用
支持语言 7种(含C/C++/Rust/C#) 5种(TS/JS/Python/Ja va/Go)

各有优劣,CodeGraph赢在实时同步和语言覆盖面,igraph赢在语义检索和多模态能力。

几个关键技术决策的思考

1. 为什么要双通道检索

最开始只做了向量检索,很快发现一个问题:用户搜索fetchUserList这种精确标识符时,向量检索的效果反而不如全文搜索。原因也很简单——向量模型按语义编码,fetchUserList和getUserData在向量空间里可能很近,但用户要的就是那个精确的名字。

所以最终做了两个通道并行:

  • Dense通道(向量KNN):擅长语义匹配,“获取用户列表”能匹配到fetchUserList
  • FTS5通道(trigram全文):擅长关键词匹配,搜fetchUser直接精确命中

两个通道的结果用RRF(Reciprocal Rank Fusion)融合:

rrfScore(d) = Σ w_c / (k + rank_c(d))

核心思想其实很简单:只看排名,不看分数。因为向量距离和BM25分数量纲完全不同,直接相加没有意义。RRF把它们统一到排名维度上做融合,简单有效。

2. FTS5 为什么选 trigram 分词器

这个选型踩过坑。一开始使用的SQLite FTS5默认的unicode61分词器,发现中文搜索基本失效——它把连续汉字当成一个巨大的token,搜索“用户”匹配不到“获取用户列表”。

换成trigram(长度为3的滑动窗口)之后,任意≥3字符的子串都能匹配。不管是中文短语“用户列表”还是英文标识符里的Trade,都能搜到。代价是小于3字符的查询词trigram无法处理(无法生成token),用LIKE子串扫描兜底。

3. LLM 摘要的批处理 + 断点续跑

一个大仓库可能有几千个文件,逐个调LLM太慢。做法是一次API调用处理一个文件的所有符号——一个有20个函数的文件只需要1次调用而不是20次。

更关键的是断点续跑。每个文件在数据库里有状态字段(pending/done/error),每次启动只处理pending状态的。中途Ctrl+C了、网络断了、API限流了,下次跑直接从断点继续,已完成的不会重跑。SIGINT信号还做了优雅处理——收到Ctrl+C后不立即退出,等当前在途的请求完成再退出,避免写了一半的脏数据。

4. 50% 阈值的增量摘要复用

增量更新时,一个文件改了1个函数,需不需要把整个文件的所有摘要都重新生成?策略是:对比每个节点的源码是否变化,如果≥50%的节点没变,就只对变化的节点重跑LLM,未变化的直接复用旧摘要。效果很直观:一个20函数的文件改了1个函数,只需要1次LLM调用(而不是整个文件重来的1次批量调用),节省95%的API成本。

5. 多模态资源挂载

这是和CodeGraph差异化最大的一个功能。实际开发中,理解代码不光要看代码本身,还要知道“这段代码对应哪个产品需求”、“操作的是哪张数据库表”。igraph可以把PRD文档(Markdown/PDF/DOCX)和DB Schema(SQL/JSON/XLSX)挂载进来。

挂载过程:解析文档 → 按章节/表维度切片 → 每个切片向量化 → 用切片向量和已有的文件向量做KNN匹配 → 相似度≥0.85建strong关联,0.70~0.85建weak关联。这样Agent查到一个函数时,能同时看到“这个函数实现的是PRD第3.2节的需求”、“它操作的是orders表”。

6. 优雅降级

不是所有人都有LLM API和Embedding服务。igraph的原则是:不管什么环境都能用,只是效果有差异。

完整模式:LLM摘要 + 向量检索 + 全文检索 + 多模态关联
↓ 没有LLM
降级1:启发式摘要(函数签名拼接)+ 向量检索 + 全文检索
↓ 没有Embedding
降级2:启发式摘要 + 纯全文检索
↓ 什么都没有
最低保障:纯AST结构图 + FTS5关键词搜索

igraph build --no-llm在完全离线环境下也能跑通,只是摘要质量差一些。

存储方案:为什么全塞进 SQLite

这个问题估计很多人会好奇。图数据为什么不用Neo4j?向量为什么不用Milvus?全文搜索为什么不用Elasticsearch?答案是场景决定选型:

igraph是一个本地开发者工具,核心诉求是零运维、开箱即用。一个.igraph/igraph.db文件搞定所有事情——关系数据、全文索引、向量索引全在里面。

  • 图遍历:用递归CTE做N跳展开,GROUP BY id + MIN(depth)天然去环。几万个节点、几跳展开,SQLite毫秒级完成。
  • 全文搜索:FTS5是SQLite内置模块,trigram分词器覆盖中英文。
  • 向量检索:sqlite-vec是个SQLite扩展,加载进来就有vec0虚拟表,支持KNN。

如果哪天要做成在线服务,这些组件可以逐个替换。但对于当前的本地工具场景,引入任何一个外部服务都是过度设计。

目前的不足

实事求是地说几个短板:

  1. 首次建库慢:要跑LLM + Embedding,比CodeGraph纯AST解析慢很多。大仓库可能要几十分钟甚至更长。
  2. 语言覆盖少:目前只支持TS/JS/Python/Ja va/Go五种,CodeGraph支持更多(包括C/C++/Rust/C#)。
  3. 没有实时watch:改了代码要手动跑igraph build触发增量更新,不如CodeGraph的文件监听自动同步方便。
  4. Embedding模型耦合:换了Embedding模型需要重新向量化所有数据,因为不同模型的向量空间不兼容。

后续计划做的事情:

  • 实时watch模式(文件监听 + 防抖 + 增量)
  • PRD图片识别(目前只提取文本内容)
  • 更多语言适配器

技术栈概览

层次 选型 理由
语言 TypeScript (ESM) 前端/全栈生态
解析 Tree-sitter (N-API) 多语言统一API
存储 better-sqlite3 + WAL 同步API、单文件
全文 FTS5 (trigram) 内置、中英文子串匹配
向量 sqlite-vec (vec0) 零额外进程
LLM OpenAI兼容API(裸fetch) 不依赖SDK
Embedding BGE-M3 via TEI,1024维 开源可自建、多语言
MCP 官方SDK,stdio传输 Claude Code / Cursor直接对接
CLI Commander.js 轻量声明式

写在最后

igraph和CodeGraph不是替代关系,更像是不同侧重点的两个方案。如果你的主要需求是结构导航(知道函数名、看调用链),CodeGraph的实时同步和语言覆盖更好。如果你更需要语义搜索、想让Agent通过自然语言理解代码、还想关联PRD和数据库,igraph可能更合适。

欢迎交流技术细节。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›