AI 如今可以阅读代码仓库了,细思恐极
大家好,我是三元同学。
经常看技术博客的朋友,可能对Webpilot[1]并不陌生。这是个「能对网页内容提问的AIGC浏览器插件」。
他有什么作用呢?
比如,在阅读技术文章前,我们可以让Webpilot
对文章内容先做个总结,看完总结再阅读会更轻松。
既然这个项目这么有用,而且代码是开源的,那不看看他的实现原理说不过去。况且,我还发现了作者团队留下的乐子 —— 在Webpilot
贡献者一栏中,项目主程居然是ChatGPT
。
既然代码是ChatGPT
写的(姑且这么认为吧),那我们看代码也不要人肉看了。
今天,让我们试试 AIGC
读了项目源码后再来教我们。
应用选择
当前,代码相关的AIGC
应用的操作对象主要是「代码片段」或「某个代码文件」,比如:
-
Github Copilot
-
cursor
但我们希望应用了解整个项目,所以需要应用既能理解「代码片段」或「某个代码文件」,又能理解「代码之间的依赖关系」。毕竟,代码逻辑通常是跨文件的。比如,假设项目中存在方法fnA
,他:
-
在
a.js
中定义 -
在
b.js
、c.js
中使用
那么当提问fnA
相关问题,AIGC
应用的上下文中起码应该包括以下信息:
-
项目整体情况
-
a.js
、b.js
、c.js
的代码
才能回答好问题。
要实现类似效果,业界的常用做法是Embedding
,即「将内容实体映射为低维向量,通过向量之间的相似度判断内容关联关系」。
比如,开源项目pdfGPT[2]可以接收PDF
文档,用户就文档内容向他提问。
文档动辄几百页,GPT
一次性能够接收的token
有限,他是如何实现「就用户提问,在全文档中检索答案」呢?原理大体可以概括为:
-
将
PDF
文档分割成小的内容块 -
将内容块通过
Embedding
映射为低维向量,并存储 -
当用户提问后,首先将问题映射为低维向量
-
将3的低维向量与所有「存储的低维向量」比较,寻找关联度最高的向量
-
将「用户提问」、「与用户提问关联度最高的向量对应的内容块」组合在一起向
LLM
提问 -
获得回答
按照上述「解析PDF文档」的思路,我找到了解析代码的应用 —— bloop[3]。
bloop简介
bloop
有点类似pdfGPT
,只不过他的接收的是代码仓库,用户就代码仓库向他提问。
在官网下载bloop
桌面应用后,绑定自己的Github
账号,即可免费使用。
注意:
bloop
会要求你所有public
、private
仓库的读写权限。在意的同学可以像我一样注册个新Github
账号
我已经fork
了Webpilot
项目(就是我们要学源码的项目),这里直接让bloop
同步Webpilot
。
在
bloop
内部,这一步应该会建立代码文件的低维向量,如果我理解错了欢迎指正)
现在,我们可以就Webpilot
项目向bloop
提问了。来看看我们的第一个问题:
简单介绍下这个项目
很遗憾,第一句话就答错了 —— Webpilot
是「能对网页内容提问的AIGC浏览器插件」,而不是一个文本到图像的程序。
Webpilot
项目中确实存在MidJourney
(根据提示词生成图片的AIGC
应用)相关代码,但这样回答肯定是以偏概全了。
那这是不是意味着bloop
不中用呢?并不是的。
刚才我们已经提到,采用Embedding
的实现方式只能获得「与提问内容相关的内容」,再就这些内容向模型提问。并非是模型完全理解代码逻辑后再提问。
换句话说,对于上述「提问fnA相关问题」的例子,采用Embedding
后,我们会将下述信息整合后输入给模型:
-
项目整体情况
-
a.js
、b.js
、c.js
的代码 -
用户的提问
模型根据上述信息回答问题。
而不是模型理解项目代码逻辑后,再回答「fnA相关问题」。
所以,在向bloop
提问时,我们需要给到一些线索,比如:
-
文件名
-
函数名
-
变量名
这样,bloop
才能根据线索,通过Embedding
寻找相关内容。
当我们将「简单介绍下这个项目」修改为「根据README的信息,介绍下这个项目的用途」后,bloop
给到了我们想要的答案:
其中,README
就是我们给到的线索。
用bloop读源码
我们与bloop
的对话不仅是为了寻求答案,更是为了给bloop
提供更多线索。比如,当bloop
回答:
Webpilot
允许你与网页进行自由形式的对话,或者与其他用户进行自动的争论......
后,这个答案不仅是告诉我们的,也是告诉bloop
自己的。在回答前,他也不知道Webpilot
到底能干嘛。在回答后,我们就能继续提问:
“与网页进行自由形式的对话”这部分逻辑在哪里定义的
此时,bloop
告诉了我们关键信息 —— 应用的主要逻辑在useAskAi
方法中:
那么接下来,我们让bloop
详细解释useAskAi
方法的作用就能了解Webpilot
的实现原理:
现在让我们思考一个问题,如果我们询问:
useAskAi
方法都在哪些模块被使用?
bloop
能给出正确答案么?答案是:不太能。
这有点反直觉,毕竟,在程序员看来,作为一个代码浏览器,bloop
完全可以静态分析模块依赖关系后找到答案。
但是,bloop
是基于Embedding
技术实现的。在bloop
底层,并不存在模块依赖图,而是「代码块对应的低维向量」。
所以,bloop
能找到部分「使用useAskAi方法的模块」,但可能找错、也可能找不全。
总结
bloop
是基于Embedding
技术实现的代码问答工具,对他提问需要遵循几个原则:
-
问题尽量详细,给 bloop
更多线索
坏问题:简单介绍下这个项目。
好问题:根据README
的信息,介绍下这个项目的用途。
-
提问「详细的业务逻辑问题」时,可以分步骤提问。
坏问题:“与网页进行自由形式的对话”怎么实现的?
好问题:
-
根据
README
的信息,介绍下这个项目的用途。 -
“与网页进行自由形式的对话”怎么实现的?
一句话总结 —— bloop
了解很多「关于你项目的知识」,但在向他提问时,得先让他明白你的问题和「他了解的哪部分知识」相关。
能做到以上这点,bloop
将会是你得力的源码阅读助手。
参考资料
Webpilot: https://github.com/webpilot-ai/Webpilot
[2]pdfGPT: https://github.com/bhaskatripathi/pdfGPT
[3]bloop: https://bloop.ai/