机器之心最近有个报道。
编辑:佳琪、蛋酱
最近,AI 编程工具 Cursor 可谓是风头无两,受到了全球用户的热烈追捧。
这个 Cursor 是一个基于 VS Code 的代码编辑器,它为 AI 编程提供了很多强大的新功能,吸引了编程和人工智能领域的广泛关注。
不久前,著名播客主持人 Lex Fridman 邀请了四位 Cursor 的团队成员进行了一场技术讨论,聊了聊他们的工作以及未来的探索方向。

想看视频的朋友可以点击这里:视频地址
接下来,我们整理了 Lex Fridman 与 Cursor 团队创始人 Michael Truell、Sualeh Asif、Arvid Lunnemark 和 Aman Sanger 的对话内容,让大家更深入地了解这个团队的故事:
Cursor 的起源
那么,Cursor 的起源故事到底是什么呢?
关于Cursor的故事,聊聊我们的发现
大约在2020年,OpenAI推出了一篇关于缩放损失的研究论文。这一时刻,似乎给这个领域带来了明显的进展。虽然我们的想法不多,但看起来只要拥有更多的计算能力和数据,模型就能变得更强大。
顺便提一下,关于缩放损失的话题,我们可以聊上好几个小时。不过简单来说,这篇论文只是众多研究中的一部分,这些研究都提出了一个观点:在机器学习中,模型和数据的规模越大,效果就越好。
说白了,越大越好,这个结论似乎是显而易见的,虽然这还有很多可以探讨的地方。
确实,这还有很多值得深入讨论的内容。
是的。在那段时间,我们中有些人进行了许多概念上的讨论:这种技术究竟会对各个知识工作者领域产生怎样的影响?随着论文中提到的理论收益逐渐明确,我们开始觉得,如果想在人工智能领域有所作为,其实可以直接动手,而不是非得读个博士学位。如今,我们有了一整套可以构建的实用系统。
而接下来,令一切变得顺畅的关键时刻,是我们提前获得了GPT-IV的使用权。大约在2022年底,我们开始对这个模型进行调整,提升其能力,效果真是让人惊叹。在此之前,我们已经在多个项目上有所尝试。由于Copilot、缩放损失的研究,还有我们对于这项技术的兴趣,我们一直在完善一些程序员工具,但那些工具却显得非常具体。因此,我们开始为需要在Jupyter Notebook中工作的金融专业人士开发工具,或者尝试利用这些模型进行静态分析。
接着,GPT-IV的升级让我们意识到,这确实是使得之前的理论收益得到了实际的体现。在那个时刻,我们感觉可以立即构建出更多的工具。而且如果我们持续进行下去,这不仅仅是一个临时解决方案,所有的编程都将围绕这些模型展开,涉及不同的编程环境和类型。因此,我们开始构想一个更宏大的愿景。
代码的差异在哪里?
让代码审查变得更轻松的奇妙功能
说到 Cursor,它有个特别吸引人的功能,就是它的 diff 接口。简单来说,模型会用红色和绿色来展示代码的修改部分,而你可以直接在聊天窗口看到这些变化,甚至可以选择接受这些修改。
我们其实可以有好几种不同的 diff 展示方式。为了提升自动完成功能的体验,我们特别优化了 diff 接口,让它在处理大代码块时能够更清晰。现在,我们也在努力改进另一个 diff 功能,专门针对处理多个文件的场景。总的来说,当你用自动完成功能时,读取速度得快得飞起。虽然在任何情况下速度都得快,但在自动完成的时候,注意力集中在一个地方,眼睛可不可能同时关注太多内容。
我们反复尝试了好几次,才让这个功能顺利运作。第一次我们用蓝色划线来标注,之前的方式让人有点困惑,像 Google Docs 一样显示要删除的代码,有时候你能看到划线,然后新代码就冒出来了,确实容易分散注意力。后来我们尝试了不同的方式,包括用红色突出显示。
在后续的迭代中还发生了一些小趣事。你只要按住 Mac 上的选项键,系统就会把一段代码高亮出来,显示可能的修改。在这个例子中,输入的内容和建议都会变成蓝色,以此提示你人工智能的建议。如果你想真正看到建议,就得按住选项键,放开后就能看到原来的代码。
这确实是用户体验设计中的一个迷人领域。你想要的就是引导程序员轻松完成阅读,简简单单,这样才是最理想的状态。
为了完成这项工作,你需要智能模型。目前的算法虽然结构复杂,但缺乏真正的智能。设计算法确实需要智慧,但你并不在意具体使用哪个,你只希望模型能有效执行任务。
不过,随着模型的智能化,能做出的修改也会越来越复杂。因此,随着变化的加大,人类需要进行的验证工作也会增多。
毕竟,没有人愿意把所有时间都花在审查代码上。我觉得可以利用语言模型显著提升审查体验,比如通过某些技巧引导审查者关注关键区域。如果代码是通过这些语言模型生成的,而不是由其他人编写的,审查的体验就会变得更友好。审查过程应该围绕审查者设计,让他们的工作尽可能愉快、简单和高效。
聊聊机器学习的点滴
你有没有感觉到,Cursor 的编辑器简直让人觉得像是 AGI(通用人工智能)在身边?其实,它的背后有不少机器学习的秘密呢!
Cursor 实际上是结合了我们自定义的模型和一些顶尖的模型来一起工作的。一些像 Tab 和 Apply 这样的热门功能,都是经过微调后展现出来的效果。
这些先进的模型在给出代码修改建议和草稿方面做得相当不错,但在细节生成上却常常会碰壁。特别是当处理大文件时,像 Sonnet 和 o1 这样的模型,有时会出现低级错误,比如搞错代码顺序什么的。
为了应对这些挑战,我们采取了这样的策略:先让模型生成一个大概的代码修改建议,然后再训练另一个模型,将这些建议应用到真实的代码文件里。
顺便提一下,Apply 功能会观察你的代码并给出新的建议。虽然对我们人类来说,看起来简单,但对模型来说可不是那么容易哦!
很多人可能会以为 Apply 功能的算法是固定的,但其实并非如此。
是啊,市面上有一些其他 AI 编程工具的类似功能,但它们经常会崩溃。大家以为只要有简单的匹配就能实现这些功能,结果却发现有至少 40% 的情况下会失败。

我觉得未来的趋势是,这些模型会变得越来越聪明。而 Apply 还有个好处,就是让最聪明的模型在生成代码时,使用更少的 tokens,降低延迟和成本。
其实呢,你可以先给模型一个大致的代码草图,然后它再负责完善细节。这样做比直接让模型从零开始写完整个代码要容易多了。我觉得,随着模型的智能化逐步提升,未来可能会有更简单的模型负责具体的实现,而更复杂的模型则专注于高层次的规划。也许会出现像 o1 这样的强大模型,负责生成高级别的设计,再让一些定制模型来逐步执行。
如果你有兴趣的话,我们可以一起聊聊怎么让这个过程变得更高效。
那么,你可能会好奇,我们是怎么提升 Cursor 的处理速度的呢?
让速度提升的关键之一就是「投机编辑」。这其实是从投机解码发展而来的。你可以利用投机解码的一大优势:在大多数情况下,尤其是语言模型生成内容时,由于内存的限制,一次性处理多个 tokens 会比逐个生成更快。因此,当你查看每秒生成的 tokens 时,会发现处理 prompt tokens 的速度远快于逐个生成的情况。
我们的方法和传统的投机解码有点不同。传统方式是先用一个小模型来预测代码,再由更大的模型来验证。不过,因为我们对已有代码的样式、格式和逻辑非常熟悉,所以可以直接把原始代码片段输入到模型中,让它来判断哪些地方需要改动。大多数情况下,模型会觉得:「这些代码没问题,直接使用就行。」
这样一来,你就能同时处理多行代码,并对大量代码片段做相同的操作。最终,当模型生成的文本与原始代码有出入时,它会产生新的 tokens,我们则根据这些匹配的程度来判断何时需要重新对代码块进行推测。
GPT vs Claude
那么,究竟哪个 LLM 更擅长编码呢?在编程方面,GPT 和 Claude 到底谁更厉害呢?

大模型编程能力排名
说实话,没有哪个模型能够在所有领域都绝对领先。简单来说,如果我们把速度、代码编辑能力、处理大量代码的能力、上下文理解等作为标准,Pareto 模型的表现确实不错。不过,我现在觉得 Sonnet 是最棒的。o1 也挺有趣,推理能力很强,但在理解你的意图上,感觉还是不如 Sonnet。
看看其他一些顶尖模型,在基准测试中的表现也挺优秀。但当你把它们推向极限时,我觉得 Sonnet 是保持性能稳定的最佳选择。
那么,正常的编程体验和基准测试的结果之间有什么差别呢?我们在评估这些模型时,基准测试的不足之处在哪里?
这是个很复杂但重要的问题,它揭示了基准测试和真实编码之间的不同。真实编码并不是面试那种刻板的形式。我们人类有时会说出一些不太标准的英语,有时会说:“就照我之前做的来。”又或者是“加点东西,然后再做点别的,再做个 UI 元素。”很多时候,处理的内容都是依赖于上下文的。而面试问题则相对具体得多,它们往往依赖于严格的规范,而人类的表达则灵活很多。
基准测试能反映的内容和实际编程之间有差距,这让总结变得困难,因为实际编程往往是无序的,什么是正确的、什么是不正确的,有时候也不那么明确。而且公共基准测试的问题也使事情变得更复杂,因为这些测试有时只是走过场,而且从模型中获取公共基准测试的数据非常棘手。
举个例子,像 SWE-Bench 这样受欢迎的基准确实受到了一些基础模型训练数据的影响。如果你让这些基础模型去解答 SWE-Bench 的问题,但是没有给它们提供足够的代码库上下文,它们可能就会出现错误的文件传递和函数名称。
在这种情况下,模型可能会针对文字问题或拉取请求进行训练,实验室有可能会做得越来越好,或者他们在净化数据方面已经取得了进展,但不能忽视存储库本身的训练数据。这些都是一些常见的 Python 存储库,像 SimPy 就是一个例子。我不认为他们会在 SimPy 这些流行的 Python 存储库上特别为基准测试而调整模型,以获得真实的评估分数。
探索提示词的魅力与实用性
说到基准测试的缺陷,使用这些模型来搭建系统的时候,其实有些“拐杖”可以帮我们判断模型是否在向正确的方向发展。很多情况下,人们是通过让真人来体验这些模型,获取一些定性的反馈。你知道吗,一些基础模型的公司也有专人负责这项工作。我们内部也会对这些模型进行评估,除了依靠私人邮件的反馈外,我们也非常重视这些评估的结果。
提示工程的技巧
那么,一个好的提示词能有什么作用呢?你或许已经看过我之前写的关于提示词设计的文章了吧。
其实这还得看你在用哪个模型。每个模型对提示的反应各不相同,像 GPT-4 就对提示词特别敏感。但是,问题来了,当你的空间有限时,如何选择哪些信息放入提示词呢?
针对这个疑问,我们内部有个叫 Preempt 的系统。它类似于网站设计:你希望在手机和电脑上都能正常显示网站页面。这就需要考虑一些动态信息,因为网页设计并不像杂志排版那样一成不变。无论是网站还是提示词的输入,都是动态的,所以你得确保格式适用。当输入量大时,你可能还得删减一些内容。因此,我们从网站设计中汲取了灵感。
我们特别喜欢 React 这样的声明式设计方式,比如在 JavaScript 中使用 JSX,你可以直接声明:“我想要这样的效果,我认为这个部分比其他部分更重要,或者需要更高的优先级。”

在网页设计中,渲染工作是由渲染引擎完成的,而在 Cursor 中,这个任务则交给了 Preempt 渲染器。你只需要说明你想要的效果,渲染器就会自动为你实现,真是非常方便。
这种方法我们发现特别有效,而且它的功能也在不断演变:最开始是为了适应较小的上下文窗口,现在则在提示词数据的拆分和实际生成中起到了重要作用。因此,调试变得更简单了,因为你可以随时修改提示词,并在旧的提示词上进行测试,直接查看你的修改是否提升了整体评估的表现。
你们真在用 JSX 写提示词吗?
其实,答案是肯定的!Preempt 的确看上去很像 React。它还配备了一些组件,比如文件组件,能够获取光标的位置。在代码编辑器中,光标所在的那行往往是最关键的,因为你正盯着它。那么就能根据光标的位置为不同的代码行设置优先级。光标所在的那一行优先级最高,越远的行优先级就越低。最终在展示时,系统会算出能显示多少行代码,并围绕光标所在的行进行呈现。
这实在是太酷了!
你甚至可以实现更复杂的功能,比如当整个代码库中有大量代码块时,可以通过检索、嵌入和根据得分重新排序等方法,给这些组件设定优先权。
那么,人类在提问的时候,是否也应该尝试类似的方式呢?在提示中使用 JSX 有什么好处,还是随便问什么更有效?
我觉得我们的目标是让你可以随意提问,而我们的任务就是找到合适的方式,把与你想法相关的信息给检索出来。
我之前和 Perplexity 的 CEO Aravind Srinivas 聊过这个问题,他认为提问者越懒越好。这种观点很有意思,但我觉得对于程序员来说,应该有更高的要求,对吧?
确实如此。如果你说「随便你怎么问」,人们通常会懒惰。这就带来了一个矛盾:一方面人们可以自由提问,另一方面也在鼓励人们在提示中表达更深入的想法。
我的看法是,即使 AI 已经足够智能,仍然难以传达足够明确的意图来引导模型做出正确的反应。为了解决这种意图不明确的问题,有几种方法。一种是让模型主动问你:「根据你的查询,我不太确定该如何处理这些部分,能不能详细说明一下?」另一种可能是,如果存在五六种生成方式,「考虑到目前查询的模糊性,不如我们把所有可能的结果都给你,然后让你来选择。」
模型主动提问的挑战
你有没有想过,让模型主动发问其实有多难呢?最近,我们为Cursor引入了一个新功能,允许它在你编写代码或输入内容时,试着预测你的意图。如果模型发现某些地方有点模糊,它会猜测你可能在写某个API。在这个过程中,模型还会参考你的历史记录,看看哪些文件和你当前的编辑内容是相关的。
不过,这里有个技术难题,就是如何从众多历史记录中找出最相关的信息,判断在你输入的提示下,哪些文件是最重要的。虽然这个功能现在还在测试阶段,但我们相信会逐步改进。我们想让你感受到这样的想法:“嘿,你是想添加这个文件,还是那个文件,来帮助模型更好地进行编辑呢?”
比如说,当你在编写一个API的时候,可能还需要同时编辑使用这个API的客户端和服务器代码。这样一来,如果API有改动,客户端和服务器的代码也需要相应地调整。
Cursor能够做的就是,帮助你在输入提示或代码时,在你按下“回车”之前,找到那些可能需要一起修改的部分。这样一来,就能提前解决一些不确定性,确保所有相关代码都得到正确的更新,而不必手动去查找和同步这些改动,省时又省力。
关于上下文的思考
说到上下文,当我用Python编写代码时,通常会导入很多东西。自动找出我想在上下文中包含哪些内容,这可真是个挑战!
这确实有些复杂。我觉得未来在自动计算上下文方面,我们能做得更好。不过要注意的是,自动包含上下文是有代价的。
首先,模型包含的上下文越多,它的处理速度就越慢,成本也会变高。这意味着你可能会减少模型的调用次数,后台执行的任务也要简单些。此外,对于很多模型来说,提示中信息过多会让它们感到困惑。因此,对于包含的上下文,准确性和相关性必须要高。
探索模型与代码库的深度连接
其实呢,我们在产品的一些功能上已经尝试了自动化上下文处理,未来我们希望能做得更好。说白了,有很多有趣的想法可以实践,比如研究更高级的检索系统,或者提升嵌入模型和重排序器的效果。
还有一些很酷的理论我们也在内部进行探索。你有没有想过,能否让语言模型自己理解新的信息源?最吸引人的问题是,能否让上下文窗口变得无限?如果真能做到,那么模型是不是就能专注于无限量的上下文呢?再进一步,我们能否让模型在处理这些无限上下文时,缓存一些信息,这样就不必每次都重新计算?此外,还有一些新想法正在试验中,它们更关注如何在模型的权重中直接学习这些信息。如果我们在模型的权重层面上进行更多的操作,而不仅仅是在上下文学习层面,或许能获得一种全新的理解方式。
我们对提升检索系统的能力和挑选最相关代码部分的想法感到非常兴奋。一个有趣的概念是,能否在 VS Code 中直接学习这些知识。我们在 VS Code 的分支和项目中都进行了一些尝试,所有的代码都是公开的。这些预训练模型接触过大量的代码,也可能了解相关问题和答案。通过微调和强化学习,我们希望模型能够解答关于代码的一般性问题。有时候,当你问它 VS Code 的相关问题时,它可能会出现一些错误,但有时也能给出很好的答案。如果我们专门训练一个模型,让它深刻理解特定的代码库,结果会如何呢?
这其实是一个开放的研究问题,我们对此充满了兴趣。同时,我们也在思考一个重要的问题:你希望模型能够端到端地完成所有工作吗?也就是在内部进行检索,再回答问题或生成代码,还是说你希望将检索与最前沿的模型分开,或许几个月后你能看到一些比现在最好的开源模型更强大的模型?这样的话,可能需要单独训练一个优秀的开源模型作为检索器,将上下文输入到这些更大的模型中。
能不能再详细谈谈训练模型如何理解代码库的问题?这意味着什么?这是合成数据的方向吗?
当然,有很多方法可以尝试。想法真的是无穷无尽,关键在于去实践每种方法,然后看看哪些最有效。一个简单的想法是,尝试复刻 VS Code 和前沿模型所做的事情。让我们继续进行预训练,进行一种持续的预训练,涵盖一般代码数据,并加入你关心的特定库的数据。接下来在后训练阶段,我们可以从指令微调入手,建立一个关于代码的标准指令微调数据集,然后针对特定库提出很多关于代码的问题。
这样,你就能得到一些基本的事实数据,虽然这可能有点困难,或者你也可以使用合成数据来进行你提到的操作,让模型询问关于近期代码片段的问题。这意味着你可以获取代码片段,然后让模型针对这些片段提问,最终将这些问题和答案作为指令微调的数据点。理论上,这样做能帮助模型更好地回答关于该代码库的问题。
聊聊OpenAI o1的那些事儿
你们对OpenAI o1有什么看法呢?这个系统在测试的时候能够进行计算,未来在编程方面会起到怎样的作用呢?
说到预训练模型,Scaling law的效果确实让人惊叹,但我们现在却遇到了所谓的“数据壁垒”。不过,提升模型性能的一种有趣方法是增加推理时的flops。以前,我们总是需要训练更大的模型来使用更多的flops,但如今或许可以在相同规模的模型上延长运行时间,以达到大型模型的表现。

让我觉得很有意思的是,有些问题可能需要一个拥有100万亿参数、训练了100万亿tokens的超级模型才能解决,但这类问题可能仅占所有查询的1%甚至0.1%。那么,花费大量资源去训练这样昂贵的模型,只为满足极少数的查询,是否显得有些浪费呢?

所以,更明智的做法是,去训练一个能处理99.9%查询的模型。对于那些要求极高智能的问题,我们可以在推理时延长运行时间,以此来获取更优的答案。
如果你打算构建一个能跟o1对抗的模型,你会怎么着手呢?
首先,肯定得训练一个“过程奖励模型”(process reward model)。
或许我们可以聊聊“奖励模型”、“结果奖励模型”和“过程奖励模型”之间的区别。结果奖励模型是传统的语言建模奖励模型,主要关注最终结果,比如数学问题答对了,模型就能获得相应的奖励。
探索过程奖励模型与OpenAI的思维链
过程奖励模型的亮点在于,它对“思维链”的每一步都进行评分。去年夏天,OpenAI发布了一篇论文,介绍了他们如何利用人工标注员创建了一个包含数十万条“思维链”数据的大型数据集。到目前为止,除了在样本选择上有帮助,过程奖励模型似乎还没有被广泛应用。
说到这里,结合过程奖励模型进行“树搜索”真的是个有趣的方向啊!想象一下,如果能够对“思维链”的每一步进行评分,那就可以进行分支探索,尝试多条路径,并利用过程奖励模型来评估这些路径的好坏,简直太酷了!
OpenAI提到他们决定不公开模型的“思维链”,这其实是个不小的挑战。他们的选择是让模型总结思维链,而不是直接展示给用户。同时,OpenAI会在后台监控这些思维链,确保模型不会误导用户。你觉得隐藏思维链的做法如何呢?
我有个小猜测,可能OpenAI不希望用户轻易提炼出模型的能力。如果能看到那些隐藏的思维链,复制它们的技术就变得简单多了,因为你可以直接观察到模型如何一步步达到最终结果,这可是宝贵的数据啊。
那这些思维链能不能用来训练模型呢?
之前也有类似的情况发生,虽然这只是个人猜测:过去,API能很方便地获取生成 tokens 以及提示 tokens 的对数概率,但后来这个功能被删掉了。我的猜想是,如果你能够获取这些对数概率,就像能够看到隐藏的思维链一样,这会让你更容易从API和大型模型中提取出能力,并将其应用到自己的模型中。
另外,关于整合o1模型的讨论,我想补充一下:现在我们还在摸索这个模型的用法。所以我们把o1整合进Cursor中,因为一拿到这个模型就想试试,估计很多程序员也会对此感兴趣吧。
不过,o1并不是Cursor默认体验的一部分,我们还没找到一种能够在编辑器中每天甚至每小时使用o1的方法。因此,我认为如何最佳使用o1的方式仍在探索中。我们还没有看到明确的实际用例,但有些方向是显而易见的,比如可以让你更容易在后台处理一些任务,或者让模型在循环中运行,赋予它们一些智能能力。我们仍在不断探索中。
其实呢,我们心里有些想法,只是还没准备好跟大家分享。我们希望能确保推出的东西是实实在在有帮助的。
不过,o1确实有一些明显的问题。先不说能力有多强,它不支持流式输出,这就意味着如果你想实时监控输出内容,那可真是麻烦,最后只能等着一整段文本一起出现。说实话,这让我觉得它更像是在测试阶段的初级版本,感觉就像是v0版本,还有不少地方需要改进。我猜在增加预训练数据、扩展模型规模和探索预训练方法的同时,也许会找到其他途径来不断提升搜索能力。
最近听说GitHub Copilot可能会跟o1搞点什么合作,网上也有评论说:“这是不是意味着Cursor要结束了?”你怎么看呢?
我觉得,是时候让Cursor歇一歇了。
没错,Cursor确实该关门大吉了。
所以大家真的认为现在是关闭Cursor的好时机吗?
我个人感觉这个领域和2010年前后的软件行业差别挺大的,因为这次的上限真的是很高。我觉得再过个3到4年,最好的AI编程产品会比现在更加实用。
当然你可以谈论护城河、品牌优势等等,但如果在产品创新上停滞不前,那就会被甩得远远的。这对那些初创公司和想入局的人来说是个好消息,只要你能做出更好的产品,就有机会超越那些已经拥有大量用户的竞争对手。因此,我认为未来几年,关键在于打造最优秀的产品和系统,这不仅包括模型引擎的改进,还要优化编辑体验。
确实如此,我觉得Cursor相比其他产品的附加价值不仅仅在于能够迅速整合像o1这样的新模型。更重要的是,Cursor的定制模型在许多方面提供了深入的支持,而这些功能可能在你不知不觉中就发挥着作用,每一个功能都是为提升用户体验精心设计的。

Cursor的功能确实很强大,但我觉得在用户体验上还可以进一步优化,比如提供更多的教程和使用案例,帮助新手快速上手。
Cursor虽然在AI编程工具中表现突出,但未来面对Github整合o1的挑战,团队是否有足够的应对策略呢?
Cursor的功能确实很吸引人,但在面对Github的竞争时,团队是否准备好应对潜在的技术挑战?
Cursor的技术能力让人印象深刻,但在面对Github整合o1的情况下,团队是否考虑过如何保持竞争优势?
Cursor的技术确实很吸引人,但我认为团队应该加强对用户反馈的重视,尤其是在功能的易用性上。
Cursor的功能确实吸引人,但团队应考虑如何在Github整合o1后保持创新,避免落后于竞争者。
Cursor的功能确实很强大,但在Github整合o1的背景下,团队是否考虑过技术更新的频率和稳定性?