程序员的 AI 神器:Cursor
之前开坑说要介绍一下各种 agent 框架,coding agent 的各种实现,一直没抽出时间来写。倒是最近“不务正业”看了一圈 AI 辅助编程的产品,想简单来聊聊程序员的 AI 工具这个轻松的话题。
自动补全类产品
事情的起因是去年我就订阅了 Github Copilot(后面简称 Copilot),一直也用得挺好。不过随着大模型的不断降价,突然对于 Copilot 这个雷打不动的订阅费有些想法了。所以也快速调研了一圈市面上的其它替代,看看有没有性价比更高的。
找 Perplexity 等帮忙推荐了一圈,在 2024 年 8 月这个时间点,看起来最有潜力作为 Github Copilot 平替的产品是 Codeium[1]。在 PyCharm 里装上插件快速体验了一下,功能上来说跟 Copilot 基本一致。从最核心的代码补全能力来说,速度挺快,但是智能程度上相比 Copilot 还是差了一些。不过 Codeium 对于个人用户使用来说是免费的,所以如果不是很在意那一点点的质量差别的话,也是个很好的选择。
在体验过程中也发现,包括 Copilot 在内的这类 IDE 插件产品,在 VSCode 下的功能要明显比 JetBrains 系列下的相同插件要强大,不知道是不是 JetBrains 的插件系统限制了一些功能的实现。所以如果不是重度依赖 JetBrains IDE 的一些功能的话,建议在 VSCode 下使用能获得最佳体验。像 TypeScript,Python,Rust,Go 这些语言的项目,使用 VSCode 已经是一个很不错的选择了。
本来还想体验一下 JetBrains 自家的 AI Assistant,原厂开发应该体验能做得更好。结果发现插件市场里一片差评。还是再等等看吧。
AI 搜索类产品
在 之前的文章[3] 中介绍过一些 AI 搜索和通用 chat 类产品,像 ChatGPT,Claude,Perplexity,Kimi 等大家应该都已经很熟悉了。在编程领域还有两个非常值得一试的产品,分别是国内的 devv[4] 和国外的 phind[5]。
这两个都可以理解成为垂直领域的 Perplexity,在上面问编程开发相关问题回答的质量会明显高于通用的搜索问答产品。在这类产品出现前,程序员解决问题的典型流程是:
在 Google 上搜索问题的关键词。 人工查看搜索结果,点击看起来最接近的链接,查看其中的具体内容,如果与自己的情况不符合,返回继续看下一个。 将网页中找到的解决方案 copy 过来,再根据自己的情况进行修改,看是否能解决。 如果无法解决,再回到 Google 查看下一个搜索结果,或者修改搜索关键词,重复这个过程。
而有了 AI 搜索的辅助,这个信息整合、结合自身情况生成特定代码的过程就会变得十分高效,给出解决方案的准确率也比之前高了不少。我现在差不多有 50%的情况会更优先选择这类产品来解决技术问题,而 Google 的作用则更像是在明确知道自己的访问目标时的一个跳转工具。
值得一提的是,devv 还提供了 Github Repo 搜索问答的功能,我在之前写 DSPy 介绍文章[6] 时就尝试过利用它来帮助理解项目库中的一些概念和具体实现。
惊艳的 Cursor
在调研自动补全类产品时也想到了之前看过的 Cursor[7]。在早期时它的功能还比较简单,官方 demo 是通过 chat 的方式自动写了一段 PyTorch 模型定义的代码,所以也没给我留下什么深刻印象。但最近尝试了一下,发现这真是一个划时代的产品,每个功能都体现出对程序员工作流程的深入理解,交互设计上也非常自然流畅,当然对于大语言模型及相关技术的使用细节上也是非常到位的,对于做 LLM 应用的同学来说也有很多值得学习的地方。所以今天介绍的主角就是它了。
自动补全和搜索的问题
如果你已经深入体验使用过 Copilot 和 ChatGPT 一段时间了,应该会发现在程序员日常工作中使用它们存在着不少改进空间。比如:
自动补全只能在光标位置触发,这就导致很多时候,你需要先删除一些代码,再让 Copilot 去补全回来。典型的场景如给一个函数添加参数,你需要在很多调用它的地方把最后部分的括号删掉,再让 Copilot 补全。 自动补全支持多行生成,但经常会发现其中有一些内容是自己不想要的,有些地方需要修改。这时候就会反复触发上面这种情况,先补全,再删一点,再补全,再删一点…… 自动补全会遵守编程语言的规定,好处是生成的代码一般是能跑的,带来的问题是如果你写的前序代码不对,那么后面也生成不出来。所以曲线救国的办法是先写注释,或者唤出 chat 来帮忙生成。 如何让自动补全时模型拿到更好的 context?这时就需要了解一些 Copilot 背后如何组装 context 的原理,才能更好地利用它。 除了写代码外,阅读别人写的代码、调试代码也非常花时间。这里就体现 chat 的优势了,但这个工作流还是比较割裂,比如你需要把错误信息拷贝下来,打开浏览器,访问 Claude,粘贴进去,等待结果,再选中相关结果复制回来,在代码的特定地方进行修改。 除了 workflow 复杂,能力上也各有限制。比如 Copilot 的 chat 里一般不支持联网搜索,而在线的 devv 等又不知道你的整个 codebase 信息,如何结合两者的优势呢?
在解决这些问题上,Devin 的演示给了一个非常面向未来的想象画面:coding agent 能够自己编辑代码,调试运行,上网搜索解决方案等,几乎是模拟了真实程序员的工作流。但现阶段的模型能力,可能还很难支撑这类产品快速产出稳定和可用的结果来。
Cursor Tab
让我们来看看 Cursor 是如何应对这些问题的。在自动补全方面,他们推出的功能叫做 Cursor Tab。它的一个本质的定位是不再局限于“补全”,而是更广义的“编辑”。比如我们前面提到的给函数加了个参数,那么在 Cursor Tab 里,它会自动识别出哪些地方调用了这个函数,然后帮你一次性把这些地方的调用都加上这个新参数,也就是按下 tab 不再是在光标后补全,而是在整个文件的多个地方 apply 编辑改动。
看描述可能不太好理解,不过只要稍微体验一下,很快就能 get 到这个功能的强大。官网上给了一些相关例子[8],具体能力包括:
多行编辑,不再需要反复触发补全。 预测用户下一个改动的地方,自动跳转。比如我给一个函数加了类型注解,模型很快能 get 到我要给这个文件里的各种函数都加上类型注解,按 tab 就能跳到下一个改动自动 apply。 自动将伪代码转换为可执行代码,如果记不住具体的 API,再也不用唤出 chat 了,直接写伪代码,Cursor 会帮你改成真实代码。 AI 支持下的重构。传统 IDE 只能做 rename,move 等基本操作,有了 Cursor Tab,上面提到的这种加参数、修改类型的操作,也能自动帮忙生成编辑改动了。
这个功能实在是讨人喜欢,看起来也是 Cursor 付费版的核心功能。
Inline Chat
一开始我还以为这也是个特殊功能,后来发现其实 VSCode 版本的 Copilot 等插件基本也有了。简单来说如果你想让 Cursor 在做生成时有一些更明确的指令输入,可以直接在编辑过程中用CMD + K
来唤出 chat 进行交互。典型的应用场景如解释代码、生成文档、生成测试、修复特定问题等。
因为 VSCode 内嵌了 terminal,所以你也可以在 terminal 里唤出 chat,让它帮你写命令行,这样就不需要切换到 Warp 里操作了,非常方便。
不过在产品体验上,Cursor 还是比 Copilot 强了不少,比如:
模型 chat 的返回一般需要一点时间,所以在 Cursor 里可以支持并发 chat,也就是说我可以在一个文件的多个地方唤起 chat,而不用等待前一个 session 生成结束才能操作下一个。 在 chat 中可以用 @
操作符灵活指定 context,这个功能可能最先是 aider 提出的?我们后面会再具体展开介绍。生成的 diff 效果也明显优于 Copilot,一目了然。
Chat
这也是 Cursor 与其它产品拉开体验差距的一个地方,当然它应该也借鉴了很多其它优秀的工具产品,例如 aider[9] 等。Chat 本身的形式大家应该很好理解,不过在 Cursor 里,把各种流程和体验细节做得非常完善,用起来极其舒服。
以前面使用 devv 等 AI 搜索工具的流程为例,现在我可以在 Cursor 中打开 Chat,发出相关需求,Cursor 在完成响应后,会直接生成一个“pull request”,我们可以直接在编辑器中看到各个改动。然后就跟 code review 一样,可以提各种修改和后续要求,也可以部分接受改动后,再对剩下的进行进一步沟通等。这比我们从网站上再把代码拷贝回来修改来说,体验要好上不少。这个交互形式也与 Cursor Tab 里生成编辑内容的理念非常一致。
Cursor Chat 中的功能也是异常强大:
支持传图片,还记得 OpenAI 发布会上从概念图到代码生成的例子吗? 类似 aider,支持用 @
来指定文件、方法等 context,背后有 codebase 索引支持。不过 Cursor 涵盖的范围更广,从文档里看,还能引入 git 提交信息,文档,整个文件夹等等。真是把程序员常用 context 信息都考虑到了。支持整个 codebase 问答,背后应该也是典型的 RAG 技术,这就弥补了前面说的 devv 等产品不了解你的 repo 的问题。 支持 web 搜索,可以在 chat 中用 @Web
触发。这又结合上了 devv 的联网能力,简直完美。支持引入文档,自动索引新知识。用 @Docs
触发,或者直接在@
后面把网页链接贴上去。比如我现在在用 FastAPI 开发,就可以直接把 FastAPI 文档地址、git 地址扔给 Cursor 检索,进一步精确 context 信息,而不是上网漫无目的地搜索。编辑器 lint 等检查出来的错误,可以一键发送到 chat 中(Cursor 会帮忙补充 prompt),生成解决方案。同样,terminal 里执行的错误也可以一键发送,非常丝滑。
这个 AI fix 生成的内容也是一个 pull request,一次性改动多行代码,这效率可不比自动补全强一个数量级?
经过测试,即使不是付费用户,也可以自己提供模型的 API key 来使用 chat 里的大多数功能。不过 Cursor Tab,自动 apply 编辑的功能缺失了,可以说刀法有点精准……
Beta 功能
此外 Cursor 还有一些实验性功能,我还没有深入尝试:
AI review,可以让 AI 帮你 review 最近改动的代码,生成一些修改建议。 Interpreter mode,类似 OpenAI 的 code interpreter,可以让 Cursor 在 chat 过程中同时执行代码,检查结果,并不断迭代。 Composer,在前面生成单文件多行修改 PR 的基础上,进一步支持多文件编辑 PR 的生成!比如简单的代码重构、拆分出新的文件,到复杂的端到端 feature 开发/bugfix,就都可以一步实现了,感觉离 Devin 的设想是不是近了很多?当然目前模型能力来说,这个功能的产出效果上还不稳定。 Shadow workspace,把上面修改代码,修复 lint 问题,执行代码,修复错误等能力结合起来,是不是就有 coding agent 的雏形了!Cursor 这里设计了个很神奇的功能,让 AI 在一个隐藏的后台工作,做各种尝试,而不会打断用户的正常操作。目前看起来是个内测功能,还没放出,所以只能推测说这个后台 agent 能够产出经过实际运行验证的更准确的代码改动。官方 blog 上也写了一些 非常有趣的技术挑战[10]。
可以看出 Cursor 团队的确是非常有想法,LLM 辅助 coding 领域可以做的有趣的探索也非常多。
展望
从上面的介绍来看,Cursor 的功能的确非常丰富强大,每一个功能点背后都包含着对于 workflow 的深入理解和 UX 的精心设计。我在自己的一些真实项目中进行了尝试,这些功能的完成度也非常不错,完全不是那种只能从头生成个简单脚本的 demo 产品,也难怪 Cursor 受到了很多开发者的欢迎。
结合 VSCode 里的各种功能和程序员日常工作的内容,我们还可以展望一下未来 Cursor 的各种可能性:
VSCode 内置了 debugger,所以是否还能进一步借助 agent 能力帮助程序员 debug?从 stack trace 信息尝试修复错误? 借助 Shadow workspace,我们是不是可以推进 TDD 的极致,由程序员来写测试/功能 spec,AI 自动在后台生成代码,提交修改 PR? 在 codebase 问答基础上,是否能根据代码来自动生成多层级的文档?可以帮助程序员和其它协作者更好地理解整个项目,又不容易出现文档与代码不一致的问题,大大提升沟通效率。
如果你对于 Cursor 背后的技术感兴趣,他们的博客也很值得一读。比如这篇文章就介绍了 他们如何构建强大高效的代码 edit 模型[11]。其中包括了评估、模型运作模式选择、训练数据生成、模型微调、投机采样优化等话题,虽然没有上 PPO 这些黑魔法,但整体做得还是非常 solid 的。
好了,今天的介绍就到这里啦。看完上面的介绍,是不是感觉 20 美元的月费花在 Cursor 上还是很值的 :)
参考资料
Codeium: https://codeium.com/
[2]Codeium 与其它产品的比较: https://codeium.com/blog/code-assistant-comparison-copilot-tabnine-ghostwriter-codeium
[3]之前的文章: https://zhuanlan.zhihu.com/p/663752574
[4]devv: https://devv.ai/zh
[5]phind: https://www.phind.com/
[6]DSPy 介绍文章: https://zhuanlan.zhihu.com/p/702228666
[7]Cursor: https://www.cursor.com/
[8]官网上给了一些相关例子: https://www.cursor.com/cpp
[9]aider: https://github.com/paul-gauthier/aider
[10]非常有趣的技术挑战: https://www.cursor.com/blog/shadow-workspace
[11]他们如何构建强大高效的代码 edit 模型: https://www.cursor.com/blog/instant-apply