文章

Semantic Code Search(以 Go 语言为例)

基于 RAG 的思路,如果要实现语义代码搜索,需要:

  • a) 将代码块(最好是以函数为单位)作为一个 document,对函数内容使用一个对代码特化的 embedding 模型进行向量化,同时提取函数本身的 metadata(函数签名,所在文件,行数等)
  • b) 将 user query 向量化,然后用向量数据库/搜索引擎找其 top K 相似的片段
  • c) (optional) 对结果进行 rerank,输出给用户

对于 b 和 c ,有向量数据库(例如 qdrant 或者 milvus)和 rerank 模型搞定。对于 a,需要有工具去对不同的语言进行语法上的处理。幸好编程语言是结构化(或者说人工设计)的语言,其语法都可以根据固定的规则去解析。例如 go,有 gopls,一个 language server,是 Language Server Protocol 的一个实现。具体来说,LSP 是一种协议,不同语言可以通过实现这个协议,来给 IDE 工具提供诸如自动补全、跳转等等功能(yes,就是 vscode 用来支持各种语言的方式)。

但是 LSP 是针对实时的,如果要对整个项目进行导出,需要使用一种叫 LSIF 的格式,将其导出成一个静态的文件。LSIF 由 Sourcegraph 维护,已升级成 SCIP,但仍提供 LSIF 兼容的工具。针对 go,可以使用 lsif-go(已废弃)或者 scip-go 将项目的索引以 LSIF 格式导出。如果使用 scip-go,还需要使用 scip 工具转换一下 LSIF 格式。

Sourcegraph 是一个 GitHub 上的工具,提供一种类似在线 IDE 的方式去查看项目源码。它家也做了一个叫 Cody 的工具,可以对代码库进行提问,猜测这一系列工具链就是为 Cody 服务的。

References

License:  CC BY 4.0