智东西10月10日消息,当地时间10月7日,知名播客主持人Lex Fridman和Cursor团队4名创始成员Michael Truell、Sualeh Asif、Arvid Lunnemark和Aman Sanger进行了一场长达两个半小时的对话。
Cursor是一个基于VS Code的代码编辑器,它为AI辅助编程添加了许多强大的功能,它引起了编程和AI社区的关注和兴奋,风头正盛。那么Cursor这样一个初创团队,如何能够与科技巨头微软的Github Copilot一战呢?
在播客中,几人深度讨论了Cursor团队目前的发展以及未来的探索方向,还广泛谈论了编程的未来,以及人类与AI在设计和构建复杂而强大的系统方面达成合作的各种可能。
团队成员在博客中详细分享了Cursor如何理解你的代码库并以此为依据预测你下一步要做什么,然后以惊人的速度生成代码,从而有效提升了编程效率。
他们还介绍了Cursor更多功能,不仅擅长自动补全代码,它还引入了影子工作区辅助编写代码,并能通过简单的描述来命令AI编写更复杂的代码,完成更多的任务。
此外,团队成员还对AI编程的技术要领进行了深入分析,并对人与AI编程之间的伦理问题展开探讨,提到了希望将OpenAI o1模型集成的愿景。
值得一提的是,团队成员认为,快速就是有趣(Fast is Fun)。吸引人们在电脑上创造新内容的原因之一就是惊人的迭代速度,而在其他领域,你可能会受到资源或能力的限制,但在编程的世界,只要有你和计算机,你就能非常快速地构建出非常酷的东西。
创始团队中,Aman Sanger担任Cursor的CEO,是一位工程师和企业家,此前他曾在Instagram和Facebook担任领导职位。Arvid Lunnemark是公司的CTO,是一位工程师,曾在Spotify和Google工作。Michael Truell担任设计主管,Sualeh Asif担任公司COO。
▲播客现场,介绍团队成员(来源:YouTube)
以下是对该播客内容的完整编译(为提高可读性,智东西调整了部分问答的顺序,并在不违背原意的前提下进行了一定的增删修改)。
01.
类似增强版文字处理器,
代码编辑器可处理更多任务
Lex:代码编辑器有什么用?
Michael:代码编辑器主要是构建软件的地方,长期以来,而在今天或很长一段时间里,代码编辑器是指对正式编程语言进行文本编辑的地方。对于非程序员来说,可以将代码编辑器理解为程序员专用的增强版文字处理器。之所以说它是增强版,是因为代码有很多结构。因此,这个“文字处理器”即代码编辑器,实际上可以为你做很多事情,而这些是传统的文字处理器在文本编辑方面做不到的。
这包括给代码中不同的元素提供视觉区分,以便快速浏览;可以在代码库中导航,直接跳转到用户正在使用的内容的定义,就像在互联网上使用超链接;还有进行错误检查以捕获基本错误等。传统上,这就是代码编辑器的定义。我认为在未来十年内,随着构建软件的方式有所变化,代码编辑器的定义也将发生很大变化。
Lex:我认为代码编辑器也应该很有趣。
Arvid:是的,这非常重要。这实际上是我们决定构建什么的一个被低估的方面。我们构建的很多东西,通过试用它们,再进行实验,然后因为它们不有趣而把它们扔掉。所以,有趣的很大一部分在于很多时候要快。快速就是有趣。
Michael:基本上,我认为吸引很多人在电脑上构建东西的原因之一是这种惊人的迭代速度,而在其他领域,你可能会受到资源或能力的限制……甚至将一大群人聚在一起编程也是一件令人惊奇的事情,只有你和计算机,你才能可以非常快速地构建出非常酷的东西。
02.
从Copilot的粉丝到开发Cursor,
Cursor起源的两个重要时刻
Lex:对于不知道的人来说,Cursor是一个超级酷的新编辑器,它是VS Code的一个分支。听听你们对自己编辑器之旅的讲述会很有趣。我想你们所有人都是VS Code和Copilot的忠实粉丝。你们是如何接触到VS Code的,以及这如何引导你们走向Cursor?
Aman:我们最初都是纯Vim用户。没有Neovim,只有纯Vim和终端。至少对我自己来说,当Copilot出来的时候,大约是2021年,我真的很想试试它。所以我进入了VS Code,这是唯一可以使用Copilot的代码编辑器,尽管我真的很喜欢使用Vim,但VS Code和Copilot的体验足以说服我发生转变。所以,这基本上成了默认设置,直到我们开始开发Cursor。
Lex:也许应该解释一下Copilot的功能。它是一个非常不错的自动补全工具。当你开始写东西时,它会建议一到三行代码来完成它,这是一种有趣的体验。你知道当你有亲密的朋友时,你的朋友会帮你补全你的话一样。当它做得很好时,会有一种亲密的感觉。可能“亲密”这个词不太准确,但有一种很酷的感觉,就像“哇,它懂我”。然而当它不懂你时,就会有一种不愉快的感觉。所以会有这种摩擦。但我想说,对于很多人来说,那种“它懂我”的感觉压倒了“它不懂我”的感觉。
Arvid:我认为GitHub Copilot被低估的一点是,即使它出错了也有点烦人,但并没有那么糟糕,因为你只需再输入一个字符,也许它就能理解你了,或者你再输入一个字符,它就能理解你了。所以即使它错了,也不会那么糟糕。
Sualeh:你可以进行迭代和修复。我的意思是,对我来说,Copilot的另一个被低估的部分是,它是第一个真正的AI产品,第一个面向消费者的语言模型产品。
Lex:所以Copilot有点像语言模型的第一个杀手级应用。
Michael:是的,它的beta版在2021年发布。
Lex:那么Cursor的起源故事是什么样的?
Michael:大约在2020年,OpenAI发布了scaling laws论文,这是一个关键时刻,这个领域似乎取得了清晰可预测的进展,即使我们没有任何新想法,看起来只要有更多的计算能力和更多的数据,就可以让这些模型变得更好。
Lex:顺便说一下,我们可能需要花三到四个小时来讨论scaling laws这个话题。但简而言之,这是一系列论文中的一篇,这些论文提出了一系列观点,认为在机器学习领域,模型的大小和数据的大小,越大越好。
Michael:所以在那段时间,我们中的一些人有很多关于这会是什么样子的概念性讨论。对于所有这些不同知识领域的工作者来说,这项技术的发展将如何让他们变得更好?然后我认为有几个时刻,那篇论文中预测的理论进展开始变得非常具体,开始觉得你可以在AI领域做实际上有用的工作,而不需要去攻读博士。感觉现在可以构建一整套真正有用的系统。我认为第一个时刻是玩转Copilot的早期测试版,那种感觉很棒,很神奇。
我认为第二个重要时刻是提前获得了GPT-4的早期访问权限。大约在2022年底,我们开始修改这个模型,能力的升级感觉非常巨大。在此之前,我们一直在研究一些不同的项目。因为Copilot,因为scaling laws,因为我们之前对这项技术的兴趣,我们一直在修改程序员使用的工具,但这些都是非常具体的工具。所以我们正在为必须在Jupyter Notebook上工作的金融专业人士构建工具,或者尝试使用这些模型进行静态分析。
而GPT-4的升级让我们感觉这确实证实了我们之前预测的理论进展。感觉就像在那个时间点你可以立即构建很多东西。而且,如果我们保持一致,这真的感觉不仅仅是一个点解决方案,这将涉及整个编程领域,所有编程都将通过这些模型进行,而且感觉这需要一种不同类型的编程环境,一种不同的编程方式,所以我们开始构建那种更大的愿景。
Sualeh:有一件事我印象非常深刻,我的室友是IMO金牌得主,美国有一个叫PUTNAM的比赛,这有点像是大学生的IMO,也是一个数学竞赛,它非常精彩。我记得Shengtong和Aman在2022年6月左右打赌,赌能否在2024年6月或7月的IMO中获得金牌。
Lex:IMO是国际数学奥林匹克竞赛。
Sualeh:Arvid和我也参加了,尽管我在某种程度上相信进步,但我认为想拿下IMO金牌,Aman是在异想天开。但老实说我完全错了,但这可能是团队中最有先见之明的赌注。
Aman:我清楚地记得我和Michael有一次对话,在那之前我还没有非常深入和批判性地思考过scaling laws,他提出了一个问题,为什么scaling laws就是你需要的一切,或者为什么scaling laws不会带来巨大的进步?我想我经历了悲伤的五个阶段,最后终于接受了。
我想从那以后我一直对进步充满希望和乐观。我想要补充的一点是,这也取决于你将在哪些领域看到进步。数学是一个伟大的领域,尤其是形式化定理证明,因为你可以得到一个很好的信号来实际验证事物是否正确。所以这意味着像强化学习这样的东西可以工作得非常好,我认为你可能会拥有在数学上非常超人的系统,但从技术上讲仍然没有AGI。
03.
Cursor预测你的下一步,
或将改变构建软件的方式
Lex:好的,那么我们谈谈Cursor。
Michael:对我们来说,决定做一个编辑器似乎是显而易见的,至少对于我们想要做的事情和实现的目标来说是这样的,因为当我们开始开发编辑器时,想法是这些模型会变得更好,它们的能力会提高,这将彻底改变你构建软件的方式,这不仅会让你获得巨大的生产力提升,而且会带来根本性的改变,构建软件的方式也会发生很大的变化。所以,如果你是现有编程环境的一个插件,那么你对代码编辑器的控制会非常有限,我们不想被这些限制所束缚。我们希望能够构建最有用的东西。
Lex:Cursor与Copilot在某种程度上是竞争对手,你们如何取胜?靠速度和功能质量吗?
Aman:是的,我想这是一个相当有趣,也许非常独特的领域,如果你看看以前的技术浪潮,也许只有一种主要的事情发生,它解锁了一波新的公司,但每年,每一个模型能力的跳跃,你就解锁了一波新的功能,尤其是编程中可能实现的事情。
所以我认为在AI编程中,即使只是领先几个月,更不用说一年了,也会让你的产品变得有用得多。我认为一年后的Cursor将需要让今天的Cursor看起来过时。我认为微软已经做了很多很棒的事情,但我认为他们不像一个初创公司那样有很大的空间真正继续创新和推动这方面的发展。
Sualeh:我不知道我是否从功能的角度来考虑它,还是从程序员的能力的角度来考虑它。随着新的o1模型发布,我相信会有更多不同类型的模型,比如更长上下文的,也许更快,所有这些疯狂的想法你都可以去尝试,希望其中10%的疯狂想法能够变成某种很酷且有用的东西,我们希望人们能更快地拥有它。换句话说,一个被低估的事实是,我们正在为自己创造它。
当我们开始构建Cursor时,你真的会感到沮丧,你可以看到模型变得更好,但Copilot的体验没有改变。就像,这些家伙天花板越来越高,为什么他们不创造新东西?他们应该创造新东西。那些Alpha功能在哪里?但没有那些功能。如果做了新东西,我确信它是一门好生意。我敢肯定这是一项伟大的事业,我是那种真的想尝试和使用新东西的人,但很长一段时间都没有做出新东西。
Lex:当你比较Cursor和Copilot时,Copilot很快就开始因为某种原因而给人一种过时了的感觉。
Arvid:是的,我认为对我们有帮助的一件事是,我们把所有事情都做成了,我们在开发用户体验和与模型交互的方式的同时,也在开发如何让模型给出更好的答案。所以你如何构建提示,或者你如何找到上下文,对于Cursor Tab来说,你如何训练模型?所以我认为这有助于我们让同一批人来负责整个体验。
Sualeh:是的,就像制作UI的人和训练模型的人坐在一起,相距18英尺远,甚至经常是同一个人。你可以创造出一些如果不交谈、不实验就不可能实现的东西。
Lex:你们用Cursor来写Cursor?
Arvid:当然。
Lex:我们聊聊无所不能的Tab,堪称加强版自动补全的功能。Tab是怎么工作的?它是什么?
Michael:概括来说,我认为Cursor目前在两个方面表现不错。当然,它还有其他功能,但这两项功能对程序员来说非常有帮助。一是它就像在你身后观察,是一个速度很快、可以抢在你前面输入并预测你下一步要做什么的同事。这也是一个好的自动补全功能的初衷,预测你下一步要做什么,但我们可以更进一步,不仅预测Cursor后面的字符,还能预测你要进行的下一个整体更改、下一个差异、接下来要跳转的位置。
第二个是,能帮助你有时领先于AI,告诉它该做什么,实现从指令到代码的转换。为了做好这两件事,我们在提高编辑体验上下了很多功夫,让它们既符合人体工程学,又足够智能和快速。
04.
加强版自动补全功能Cursor Tab,
消除编辑器中的低熵操作
Sualeh:我们真正想要实现的是,让模型能够为我们编辑代码。这是我们的愿望,在拥有能够编辑代码的优质模型之前,我们进行了多次尝试。有了优质模型后,为了让使用体验更加流畅,我们付出了很多努力来加快推理速度,并已经开始整合。
Michael刚才也提到了这种跳转到不同位置的能力,我认为这种跳转源于一种感觉,即一旦你接受了编辑,下一步要去哪里应该非常明显。比如,我做了这个更改,模型应该直接知道下一步要跳转到第18行。如果你是WIM用户,你可能会按18JJ之类的快捷键,但为什么我要这么做呢?模型应该直接知道。
所以,你只需要按Tab键,它就会跳到第18行,然后显示下一个编辑,你再按Tab键,你只需一直按Tab键,就能一直这样操作下去。所以内部竞争就变成了,我们能让人按多少次Tab键?一旦你有了这个想法,更抽象地说,要考虑的是如何使编辑达到零熵状态。
也就是说,一旦你表达了意图并且编辑,没有新的信息片段来完成你的想法,但你仍然需要输入一些字符来让计算机理解你真正的想法,那么模型或许应该“读懂”你的心思,所有零熵位都应该只是被Tab键消除,这就是比较抽象的说法。
Aman:一个有趣的现象是,如果你看不同领域的language model loss,我相信每字节的比特数,这是一种对代码字符标准化损失的衡量,比语言低,这意味着代码中有很多token是非常可预测的,很多字符也是非常可预测的。而且,当你不仅仅是试图自动补全代码,而是预测用户在编辑现有代码时的下一步操作时,这种可预测性会被进一步放大。因此,Cursor Tab的目标是消除编辑器中所有低熵操作。一旦意图得到有效确定,就让我们直接跳转到未来的某个时间点,向前跳过。
Lex:那么,Tab在近期内应该能够做什么?
Aman:我可以讲讲让这些功能发挥作用的一些细节。它们的延迟极低,所以你需要在这个任务上训练小型模型。特别是,它们非常需要预填充token。这意味着它们有非常长的提示,能看到很多代码,但实际上生成的token并不多。因此,使用MOE模型是最合适的。这是我们取得的一项突破,极大地提高了模型在长上下文中的性能。另一个突破是我们构建的投机解码的变体,称为投机编辑。我认为,这两点是使其质量高、速度快的重要因素。
Lex:那么缓存起作用了吗?
Aman:缓存起到了巨大的作用。因为你要处理这么多输入token,如果你在给定行中输入的每个按键都要针对所有传入的token重新运行模型,那么一是会大大降低延迟,二是会让GPU负载过高。因此,你需要设计用于模型的实际提示,使其具有缓存意识。然后,你需要跨请求重用KV缓存,以减少计算量。
Sualeh:希望能跳转到不同的文件。所以,如果你在一个文件中进行了编辑,可能需要转到另一个文件来完成你的想法,它也应该转到第二个文件。
Arvid:完整的泛化是下一步行动预测。有时你需要在终端中运行命令,它应该能够根据你编写的代码来建议命令,或者有时它会给出建议,但你很难判断它是否正确,因为你需要更多信息来学习。你需要知道类型才能验证其是否正确。所以它或许应该先带你到某个定义的地方,然后再带你回来,这样你就有了接受下一个补全所需的所有必要知识。
Michael:编程是一门奇特的学科,有时你接下来五分钟要做什么,实际上是可以根据你最近所做的事情预测出来的。那么,我们能否创造一个世界,让这接下来的五分钟要么在你放手的情况下自动完成,要么在你看到下一步要做什么并确认无误后,通过轻触Tab键就能快速实现。
05.
增加显示框提示代码差异,
围绕审查者体验做设计
Lex:Cursor有一个非常酷且引人注目的功能,那就是整个diff界面情况。所以,模型用红色和绿色显示我们将如何修改代码,然后可以在聊天窗口中应用它,它会向你显示diff,你可以接受diff。那么,你能讲讲这方面的发展方向吗?
Sualeh:我们可能会有四五种不同的diff。我们为自动补全功能优化了diff,因此它具有与审查大块代码时不同的diff接口。然后,我们正在尝试优化另一个diff功能,以适应处理多个不同文件的情况。从高层次来看,差异在于,当你进行自动补全时,读取速度应该非常快。实际上,在所有情况下它的读取速度都应该非常快,但在自动补全功能中,你的注意力会集中在一个区域,人类无法同时关注太多不同的地方。
在界面方面,我们有当前框,如果你试图在某个地方删除代码并尝试添加其他代码,它会尝试在侧面显示一个框。
我们尝试了三四种不同的方法来实现这个功能。最初的方法是在旁边显示一个带有蓝色删除线的框。它过去会以Google Docs的风格显示要删除的代码,你会看到一条线穿过,然后看到新代码,这非常分散注意力。然后我们尝试了很多不同的方法……有删除、红色高亮等。
之后的迭代版本有点有趣,你会按住Mac上的option键。所以它会高亮显示一段代码,以显示AI有建议给你。在这个例子中,输入和值都会变成蓝色,蓝色是用来高亮显示AI对你有一个建议。它不会直接显示建议的内容,而只是提示你AI有一个建议。如果你真的想看到它,就按住option键,然后你会看到新的建议,松开option键后,你又会看到原始代码。
Arvid:我个人非常期待在这个领域做出很多改进。我们经常把它称为验证问题,这些差异对于小范围修改来说很好用。但如果是大范围修改,或者涉及多个文件等情况,审查这些差异就有点费力了。所以这里有几个不同的想法。一个想法是,差异中的某些部分很重要,包含了很多信息。而有些部分的信息熵很低,就是重复的内容。
所以,或许可以高亮显示重要的部分,而将不那么重要的部分灰度显示。或者,你可以有一个模型,它查看差异并发现,“哦,这里可能有个漏洞。”我会用红色波浪线标记出来,并提示你,“你应该重点审查这部分差异。”我觉得这类想法很令人兴奋。
而且,你希望用一个智能模型来完成这项工作。目前的算法只是普通算法,没有智能性。算法的设计需要智能,但你并不关心它是关于这个还是那个,你只希望模型能做到这一点。
Sualeh:所以我认为一个普遍的问题是,随着这些模型变得越来越智能,它们能够提出的更改也会越来越大。而随着更改越来越大,人类需要做的验证工作也越来越多。这变得越来越……你需要帮助他们。我可不想把所有的时间都花在代码审查上。
Aman:GitHub试图通过代码审查来解决这个问题。当你进行代码审查时,你正在审查多个文件中的多个差异。但就像Arvid之前说的,我认为你可以做得比代码审查更好。代码审查有点糟糕。你花了很多时间去理解那些通常对你来说很陌生的代码,而且它甚至并不能真正捕捉到很多漏洞。
我认为,使用语言模型可以显著改善审查体验,例如,使用Arvid之前描述的那种技巧,即可能指向实际重要的区域。我还认为,如果代码是由这些语言模型生成的,而不是由其他人生成的……代码审查体验是同时为审查者和代码编写者设计的。
在代码编写者是语言模型的情况下,你就不必那么关心他们的体验了,你可以完全围绕审查者来设计整个体验,让审查者的工作尽可能有趣、轻松、高效。我觉得,如果只是天真地试图让这些东西看起来像代码审查,那就会出现问题。我认为你可以更有创造力,并推动可能性的边界。
Arvid:还有一个想法是,我认为顺序很重要。通常,当你审查一个拉取请求(Pull Request)时,你会看到一个文件列表,并且从上到下依次审查,但实际上,你可能需要先理解这个部分,因为这部分在逻辑上是先发生的,然后你再理解下一部分,而你不希望自己弄清楚这一点,你希望有一个模型来引导你。
我认为,并不是所有的编程都会变成自然语言。如果我正在和Sualeh结对编程,Sualeh在电脑前和键盘上,有时如果我来主导,我会对Sualeh说,嘿,实现这个功能,这样就行了。但有时,向Sualeh解释我想让他做什么太麻烦了,所以我会接过键盘,给他展示一下。
我写一部分示例,然后他就明白了,这是最容易的沟通方式。所以我认为,对AI来说也是这样。有时,与AI沟通的最简单方式就是展示一个示例,然后它就会在其他地方执行这个操作。
或者,有时如果你在做网站,例如,向AI展示你想要什么最容易的方式不是告诉它要做什么,而是拖动或绘制东西,也许最终我们会实现脑机接口之类的,你就可以让它理解你在想什么。所以我认为自然语言会有一席之地。但我肯定地认为,它不会是大多数人大部分时间编程的方式。
▲播客现场(来源:YouTube)
06.
Apply定制模型创建差异,
更少的token使用更智能的模型
Lex:我在使用这个编辑器时,真的感受到了通用AI(AGI)的存在。感觉它背后有很多机器学习在起作用。能告诉我一些让它正常工作的机器学习内容吗?
Aman:Cursor真正发挥作用的地方在于,我们通过这组自定义模型与前沿模型一起训练,这些模型在推理密集型任务中表现非常出色。Cursor Tab就是一个很好的例子,你可以将这个模型专门化,使其甚至比前沿模型还要好。另一个领域是Apply,令人惊讶的是它需要定制模型,但这是必要的,而且在应用方面效果很好。
这些前沿模型在草拟代码计划和生成变化的粗略草图方面相当出色,但实际上,为训练模型创建差异对于前沿模型来说是非常困难的。如果你尝试用Sonnet、o1或任何其他前沿模型来做这件事,它会在一些愚蠢的事情上出错,比如计算行数,尤其是在非常大的文件中。为了解决这个问题,我们让模型勾勒出这个粗略的代码块,表明将发生哪些变化,然后我们训练一个模型,将该变化应用到文件中。
Lex:我们应该说,Apply模型会查看你的代码,并给你一个非常好的新操作建议。而看似对人类来说微不足道的将两者结合起来的步骤,并不容易。
Sualeh:与普遍认知相反,这不是一个确定性算法。
Aman:是的,你会发现其他地方有Apply的浅拷贝,但大多数情况下它都会失效,因为你觉得可以尝试进行一些确定性匹配,但它至少会有40%的时间失败了,这会导致产品体验非常糟糕。我认为,随着模型变得越来越智能,这种趋势将继续下去。所以,Apply还能让你做另一件事,那就是你可以用更少的token来使用最智能的模型。这在生成所有这些token的延迟和成本方面都很昂贵。
所以,你可以给出一个非常粗略的草图,然后让你的模型去实现它,因为实现这个非常粗略的代码是一个更容易的任务。我认为这种趋势将继续下去,你可以使用越来越智能的模型来进行计划,然后也许可以由不那么智能的模型来处理实现细节。也许你可以使用o1,也许它会有更强大的模型,给出更高级别的计划,该计划由sauna递归应用,然后是apply模型。
Sualeh:也许应该谈谈如何让它变快。
Aman:让它变快的一个主要组成部分是投机编辑。投机编辑是投机解码的一种变体,也许简要描述一下投机解码会很有帮助。在投机解码中,你可以利用这样一个事实,大多数情况下,我会加上一个限定,那就是当你在语言模型生成中受到内存限制时,如果你一次处理多个token,这比一次生成一个token要快。
所以我们做的是,不是使用投机解码通常所做的,即使用一个小模型来预测这些草稿token,然后你的大模型会进去验证,在代码编辑中,我们对现有代码的外观有非常强的先验,并且该先验实际上是完全相同的代码。所以,你可以做的是,将原始代码的部分反馈回模型,然后模型大多数情况下都会同意,“好吧,我只是要把这段代码原样输出。”
所以,你可以并行处理所有这些行,只要使用足够多块即可。然后最终你会达到一个分歧点,模型现在将预测与原始代码不同的文本。它会生成这些token,然后,在足够多的token与原始代码匹配后,我们会重新开始以代码块为单位进行预测。
这实际上看起来就像是正常编辑代码的一个更快版本。所以它看起来就像是模型重写所有代码的一个更快版本。因此,我们可以使用与diff相同的接口,但它的流式传输速度会快得多。
07.
GPT和Claude在编程上哪个更胜一筹?
Lex:哪个大语言模型更擅长编程?GPT和Claude,在编程方面,哪个更胜一筹?
Aman:我认为没有哪个模型能在所有我们认为重要的类别中都优于其他模型,这些类别包括速度、编辑代码的能力、处理大量代码的能力、长文本上下文,以及其他几个因素和编程能力。我现在会说总体上最好的是Sonnet。我认为这是大家的共识。
o1也非常有趣,它非常擅长推理。所以,如果你给它一些很难的编程面试风格的问题或者领导代码问题,它能做得很好,但它似乎不如Sonnet那样能理解你的大致意图。如果你看看其他很多前沿模型,我有一个疑虑,那就是感觉它们不一定好……我不是说它们在基准测试上训练,但它们在基准测试中的表现确实非常好,相对于所有中间的东西。
所以如果你尝试所有这些基准测试和它们评估的分布中的东西,它们会做得很好。但是,当你把它们稍微推离这个范围时,Sonnet是我认为在保持相同能力方面做得最好的。你在基准测试中拥有的能力与尝试指示它执行任何与编程相关的事情时拥有的能力相同。
Sualeh:顺便说一下,这是一个非常困难且至关重要的细节,基准测试与真正的编程之间的区别在于,真正的编程并不是面试风格的编程。人类有时会说半吊子的英语,有时你会说,“哦,按照我之前做的那样做。”有时你会说,“添加这个东西,然后为我做这个其他事情,然后制作这个UI元素。”但很多事情都是依赖于上下文的。你真的想要理解人类,然后按照人类的意愿去做,而不是……也许抽象地说,面试问题是非常明确具体的。它们在很大程度上依赖于明确说明,而人类的东西则不那么明确。
Aman:关于Claude,我听到过一个有趣的观点,我认为AWS有不同的芯片,我怀疑它们与Nvidia GPU的数值略有不同,有人推测Claude性能下降可能与在AWS Bedrock上使用的量化版本与Anthropics GPU上运行的版本不同有关。
08.
Preempt系统可自动实现预想效果
Lex:在这一切中,一个好的提示(Prompt)扮演着什么角色?
Arvid:我认为这取决于你使用的是哪个模型,它们都有细微的差别,对不同的提示反应也不同。但我认为,最初的GPT-4和去年的某些模型,它们对提示相当敏感,而且它们的上下文窗口也很小。所以我们有很多与代码库相关的信息,这些信息可能在提示中会很有用。
你有文档、你添加的文件、你有对话历史,然后问题就来了,你如何决定实际上要把什么放进提示里,特别是当你的空间有限时?对于今天的模型,即使你有长上下文,填满整个上下文窗口就意味着它会变慢。这意味着有时模型实际上会感到困惑,而且有些模型比其他模型更容易困惑。
我们内部有一个系统叫做Preempt,它在这方面对我们有一些帮助。我认为它是为我们有8000个token上下文窗口的时代建立的,它有点类似于当你在制作一个网站时。你希望它在手机上能正常工作,你希望它在桌面上也能正常工作,而你有这些动态信息,但你没有固定的布局。
例如,如果你设计一本印刷杂志,你知道你可以把东西放在哪里,但是当你有一个网站或者一个提示时,你有这些输入,然后你需要格式化它们,以便它们能总是正常工作,即使输入非常大,你可能必须削减一些内容。所以我们的想法是,好吧,让我们从中获得一些启发。
设计网站的最佳方式是什么?我们非常喜欢的是React以及它的声明式方法,你在JavaScript中使用JSX,然后直接声明:这就是我想要的,我认为这个部分比其他部分具有更高的优先级或更高的Z轴顺序。在网页设计中,你有一个渲染引擎,就像Chrome一样,在Cursor中它是一个preempt渲染器,它会将所有内容都放在页面上。你只需说明你想要的效果,渲染器会自动帮你实现。我们发现这钟方法非常有帮助,而且它的作用随着时间的推移已经发生了变化。
最初它是为了适应较小的上下文窗口,而现在它在拆分进入提示词的数据和实际生成方面发挥了很大作用。因此,它更容易调试,因为你可以修改提示词,然后在旧的提示上进行测试,直接查看你的修改是否真的提升了整个评估集的表现。
Lex:所以你们是真的用JSX来提示吗?
Arvid:是的。我们有一个文件组件,它接收光标。通常在你的文件中有一行光标所在的位置,那可能是最重要的一行,因为那是你正在查看的一行。然后你可以给出优先级。而且,如果你有很多来自整个代码库的代码块,你可以使用检索和嵌入等重新排序分数来为这些组件添加优先级。
Lex:那么当人类提问时,也应该尝试使用那样的东西吗?这是否意味着问题会变得松散和混乱,还是这样的系统应该鼓励人们更清晰地表达?
Arvid:我认为我们的目标是,你应该只做对你来说最自然的事情,然后我们的工作就是弄清楚如何实际检索到相对重要的事情,以便你的思考是有意义的。
Lex:模型选择回应与一般回应有多难?这很难,如何处理不确定性。我是否选择询问更多信息以减少歧义?
Sualeh:我们最近为Cursor添加了一个加入文件的功能。当你在编辑代码或输入内容时,模型会尝试预测你正在做什么,如果模型发现有不确定的地方,它会猜测你可能在编写某种API。然后,模型会查看你的历史记录,推测哪些文件与当前的编辑内容相关。
这里有一个技术上的难题,就是如何在所有历史记录中找到相关的信息,判断在当前的提示词下哪些文件最重要。虽然这个功能还处于试验阶段,但相信我们会逐步完善它,但我们想展示出这个想法:你是否想添加这个文件、那个文件,以便模型帮你编辑?
也许你在编写一个API,你也应该需要编辑使用这个API的客户端和服务器代码,那么API发生变化时,客户端和服务器代码也需要相应更新。
Cursor可以做的是,当你在编写提示或代码时,在你按下回车之前,模型可以帮你找到这些可能需要一起修改的部分。这样做的好处是,可以提前解决一些不确定性,确保所有相关的代码都被正确更新,而不需要手动去查找和同步这些改动。
09.
我们正在接近AGI时代,
但AI Agent还不实用
Lex:你们怎么看Agent?Agent有多有用?
Arvid:我觉得Agent就像是人类,你能感觉到你正在接近AGI,因为你能看到一个演示,它表现得就像一个真人,这真的很酷。我认为Agent在很多事情上还不是特别有用,但我们已经越来越接近它们真正变得有用的阶段了。
所以我觉得有些类型的任务,有Agent的话会更好。例如,如果我们有一个bug,有时你不能在聊天输入框中使用Command+C和Command+V,这是一个非常明确的任务,我只需要用两句话来说:“这个不能用,请修复它。”然后我会很乐意有一个Agent,它会自动去处理,修复这个bug,然后我回来检查修复情况。
它会找到正确的文件,尝试重现bug,修复它,然后验证它是否正确。这可能是一个需要很长时间的过程。所以我觉得我会很喜欢这样。而且我觉得在编程中,经常有人认为Agent会取代所有的编程工作。我不认为我们这么认为,因为很多编程工作,很多价值在于迭代,或者说你其实不想一开始就明确指定什么,因为你真的不知道你想要什么,直到你看到了初始版本,然后你想在此基础上进行迭代,然后提供更多的信息。
所以在很多编程工作中,我认为你实际上想要的是一个即时的系统,它能立即给你一个初始版本,然后你可以非常快速地进行迭代。
Lex:比如最近推出的Replica Agent,它可以设置开发环境,解决软件包问题,配置一切,包括配置数据库和部署应用。这也是你梦想中的一部分吗?
Arvid:我觉得是的,对于某些类型的编程工作,这真的很酷。
Lex:这在Cursor的范围内吗?
Arvid:是的,我们目前并没有积极地在做这件事,但可以肯定的是我们想让程序员的生活更轻松、更有趣,有些事情真的很乏味,你需要经过一系列步骤,你想把这些事情交给Agent去做。然后有些事情,你可以让一个Agent在后台工作,同时你也在工作。比如说,你有一个同时涉及后端和前端的PR(Pull Request),你在前端工作,然后你可以让一个后台Agent去处理后端部分,当你开始处理后端部分的PR时,你就已经有了一些初始代码可以迭代了。所以这也会很酷。
10.
影子工作区,在后台运行代码
Arvid:首先,我们要明确的是,我们希望在后台进行大量的操作,并且我们正在尝试很多内容。目前,除了缓存预热或找出命令键提示所需的正确上下文之外,我们并没有太多其他后台操作。但我们的想法是,如果能真的在后台进行计算,那么就可以帮助你预测更长时间范围内的操作,而不仅仅是预测你接下来要写的几行代码。
而是预测在接下来的10分钟里,你可能会做什么。通过在后台进行计算,我们可以花更多的计算资源来做这件事。所以我们实施的影子工作区(Shadow Workspace)的概念,并在内部进行实验,是为了真正利用后台计算的优势,我们需要给模型提供某种反馈信号,不然可以通过让模型思考更长时间来获得更高的性能,比如o1就是一个很好的例子。
但另一种提高性能的方法是让模型进行迭代并获得反馈。对于程序员来说,一个非常重要的反馈来源是语言服务器。它存在于大多数不同的语言中,并且每种语言都有一个单独的语言服务器。它可以告诉你“你在这里使用了错误的类型”,并给出错误提示,或者它还可以跳转到定义,并理解你的代码结构。TypeScript语言服务器是由TypeScript团队开发的,Rust语言服务器是由Rust团队开发的,它们都通过语言服务器协议与VS Code进行交互。这样,VS Code就不需要内置所有不同的语言,而是可以使用现有的编译器基础结构。
这是为了代码检查、跳转到定义以及查看你正在使用的正确类型。当你在处理一个大型项目时,类型检查和引用查找功能都是必不可少的。如果没有这些功能,就很难在大型项目中编写代码。
Lex:在Cursor中是如何使用语言服务器协议进行通信的吗?
Arvid:在Cursor中,我们使用语言服务器协议向程序员展示信息,就像在VS Code中一样,但我们的想法是,我们还想将这些信息展示给智能模型,并且我们想在不影响用户的情况下做到这一点,也就是说,我们想在后台进行这些操作。
影子工作区的想法是,我们可以创建一个隐藏的Cursor窗口这样你就可以在它里面设置这个标志,然后把它隐藏起来。虽然你看不到它,但它确实存在。在这个窗口中,AI Agent可以随意修改代码,只要它们不保存修改,因为这仍然是同一个文件夹。然后,它们可以从linters(代码检查工具)中获得反馈,跳转到定义,并对代码进行迭代。
这是我们最终想要实现的目标,也是我们博客文章主要讨论的内容,因为实现这一点有点棘手。我们希望它在用户的机器上运行,以便完全模拟用户的环境。在Linux上,我们可以做一些很酷的事情,比如镜像文件系统,并让AI在文件级别上进行操作,但实际上,这些操作是存储在内存中的。我们可以创建一个类似于内核的扩展来实现这一点。而在Mac和Windows上,这有点难,但这是一个有趣的技术问题,所以我们在进行这项研究。
Aman:一个可能有些粗糙但很有趣的想法是,对保存操作进行锁定。这样,你可以让语言模型在保存到磁盘时锁定,然后你就不必在保存到磁盘的文件的真实版本上操作,而是在操作影子工作区中的那些未保存的内容。你仍然可以获得错误提示,并可以在其中编写代码。然后,当你尝试运行代码时,会出现一个小警告,提示有锁存在,这时你可以从语言服务器或影子工作区中释放锁,以便并发地执行其他操作。
11.
模型查询bug仍有困难,
Open o1也不例外
Lex:允许模型修改文件是一个令人兴奋的未来,虽然这听起来也有些吓人。设想AI agent可以自动执行一系列任务,用户第二天只需对结果进行审查,AI就好像你的同事一样。
Aman:我认为,模型在可运行性方面会有不同情况。执行一些简单任务时,用户可以在几分钟内顺利完成,在本地机器上运行也是合理的。而执行一些需要更长时间以及更大变动的任务时,则需要在远程的沙盒环境中完成。如何精准将用户环境重现在远程沙盒中,并能确保代码运行结果的一致性是极具挑战的。
Sualeh:我很好奇,你们(用户)想要什么样的编码agent?帮助你们找到漏洞?还是实现一些新的功能?
Lex:编码方面,我认为应该去关注查找各种级别的bug,尤其是逻辑错误,以及实现方向上的错误。
Aman:这些模型在简单地提示下并不善于寻找和发现错误。它们的校准非常差,即便是最聪明的模型o1也是如此。
Lex:您能解释一下吗?
Aman:我认为这些模型都能够很好地反映预训练数据的分布,随着损失函数的降低,模型的泛化能力也在增强。但现在损失函数的降低已足够多,以至于模型能够实现全面的泛化。我们主要在前沿领域使用模型,用他们进行代码生成并对问题进行回答。在预训练阶段,GitHub上的大量代码,数量高达数万亿个token,Stack Overflow和GitHub Issues等平台上也有大量问题和答案,都为任务提供了丰富的数据。
但当你尝试推动其中一些在网络上并不常见的事情时,比如根据已有的编辑来预测下一个编辑的Cursor Tab目标,模型的脆弱性就会显现出来。
另一个很好的例子是bug检测,因为实际上并没有太多真实的检测bug并提出修复建议的例子,所以模型在这方面会遇到很大的困难。
但我认为,这同样是一个模型迁移的问题,我们需要将其他模型迁移到Cursor Tab上,在将非常擅长代码的通用模型迁移到bug检测任务时,效果应该也不错,只是需要我们稍做引导。
Sualeh:很明显,我认为模型非常了解代码。当它们在预训练过程中,或许已经能够粗略地察觉到代码的问题所在。这是因为有些人已经对这些错误进行了严格的校准。
但当用模型编程的时候,比如编写数据库,这是很庞大的数据信息,即便设置了很多严格的校准程序,可能错误也还是很难被修正。
12.
危险代码标注存争议,
开发团队并不看好赏金制度
Lex:人类也很难判断代码的重要性。如果某行代码可能造成严重后果,应该添加“这行代码是危险的”这一注释。
Arvid:全部大写,重复十次
Lex:是的,即使是同一个人也可能会忘记单个代码的危险性。
Arvid:我认为在一定程度上这也适用于今天的AI模型,如果你真的在每一行中都标注dangerous,dangerment,dangerous的话,模型也会更加关注这些,并且更有可能在该区域发现错误。
Lex:明确标注代码的潜在危害程度是一种良好的实践。
Arvid:但这种做法存在争议,例如Sualeh就不太喜欢。
Sualeh:虽然从美学角度来看我不喜欢这种做法,但它确实对模型和容易遗忘代码危险性的人们很有帮助,可以避免一些小的错误导致严重的情况,例如服务器宕机。
Aman:即使是普通的文档字符中,人们在修改代码时也经常会忽略,因此需要明确指出潜在风险。
Lex:人们在修改代码时往往只考虑如何改进功能,而忽略了潜在的风险。
Arvid:如果能够对所有代码进行形式化验证,就可以确保不会引入bug。
Aman:这个设想中的未来具体会是什么样子?
Arvid:我认为人们可能不再需要编写测试了,模型会根据代码自动生成规范,用户只需审查规范。同时,智能推理模型会计算出代码是否符合规范。这种方式适用于大多数函数。
Michael:规范的生成真的容易吗?为软件明确人类的意图是具有难度的,毕竟有些想法很难指定,也很难证明它是否真的能够符合你的想法去执行。
Arvid:您认为规范很难生成?
Michael:对于难以用规范语言描述的需求,形式验证并不可靠。
Arvid:即使有大量的规范文档也难以达成?
Michael:规范可以取代单元测试。
Arvid:但规范语言可以不断发展,以涵盖更多需求。
Lex:这一设想是否适用于整个代码库,而不仅仅是单个函数?
Arvid:的确,对整个代码库进行形式化验证更难,但这是值得追求的目标,并且从理论上是可行的。例如,最近有一些研究可以对硬件进行形式化验证,包括C代码、GCC编译器和Verilog硬件描述语言。大型代码库也类似于多层系统,如果可以分解并分别验证每个部分,那么形式化验证整个代码库应该是可能的。不过,规范问题确实是个挑战。
Aman:如何处理副作用和外部依赖?例如调用Stripe API?
Sualeh:Stripe为其API编写了一个规范。
Aman:是否所有外部依赖都可以提供规范?例如,如果程序中使用了语言模型作为原语,如何将其纳入形式化验证?
Arvid:这也是可能的。
Aman:如何证明语言模型效果?
Arvid:可以证明语言模型的对齐性,或者证明它能够给出正确的答案。
Sualeh:这是最终的梦想。
Lex:如果这能够实现,将有助于确保代码的正确性和AI的安全性。
Lex:既然模型在bug查找方面存在困难,那么未来的希望在哪里?
Sualeh:希望模型首先能够帮助发现一些简单的bug,例如off-by-one错误或注释与代码不一致的情况。最终,模型应该能够发现更复杂的bug。
Michael:强大的bug查找模型对于实现AI编程至关重要。如果AI能够自动生成代码,那么也需要能够验证代码的正确性。这不仅是为了帮助人类程序员,也是为了验证AI生成的代码。
Arvid:是的,但实际上是怎么做到的呢?有一个流行的想法是这样的,引入bug比找到bug更容易,因此可以训练一个模型并引入一些错误代码,然后就可以训练一个反向错误的模型,并用其中的合成数据去寻找错误。这是一个不错的例子。
Michael:还可以利用大型模型和代码之外的信息来辅助查找bug,例如通过代码执行轨迹和调试器信息。bug查找工具可能会有两种不同的产品形态,其一是在后台运行的快速模型,用于发现常见的bug。其二是用于解决特定bug的高计算量模型,用户可以支付一定的费用去使用。
Lex:是否考虑过用资金将这些整合起来?如果模型能够找到bug或生成高质量的代码,我愿意付费。前几天,我用Cursor模型生成了三个完美的函数,主要用于与YouTube API交互,为我提供多语言字幕更新功能。
API文档不是很好,而且有代码交叉现象,我用谷歌搜索得不到确切信息,只有一些令人困惑的内容,而Cursor生成得则非常完美。我想,真希望能有一个“打赏”按钮,写着“5美元”既可以支持公司发展,也可以向模型发送积极反馈信号比如“Good Job”。在bug查找中,也可以引入类似的赏金机制。你们有考虑吗?
Arvid:公司内部对此存在争议。我认为在某种程度上,这取决于你对人性的信仰程度。我认为,如果你不花任何钱就找到一个bug那非常棒。如果没发现错误,你就不用花钱,而如果你花钱并找到了一个bug,并且你要点击的“接受”,那么它会显示在括号中,比如1美元。
这会存在一种担忧,比如,我们在计算中投入了很多,也许人们会复制粘贴代码,或者付费机制会影响用户的体验。我认为,可以考虑把付费机制与产品进行分离,如果用户每月支付一定的费用,就可以免费获得所有的功能。
Lex:可以添加一个“打赏”功能,而不是强制收费。
Arvid:即使是打赏也涉及到金钱,可能会影响用户体验。
Aman:用户在分享模型时,人们就已经在表达对模型的认可了。
Michael:如果能够开发出一种技术手段来验证bug是否已被修复,那么就可以不必依赖那些依赖于荣誉系统的赏金机制了。
13.
AWS基础设施非常可靠,
出现问题的概率微乎其微
Lex:终端和代码之间有多少交互?在终端中运行代码可以获得多少信息?是否可以实现一个循环,让模型运行代码并建议如何对代码进行更改?目前代码及其实际运行是完全分离的吗?目前,据我所知是可以在终端中使用“Ctrl+K”来辅助进行代码编写。
Aman:可以在Check命令和Ctrl+K中使用终端上下文信息。但目前还没有实现循环功能,不过这很有意义。关键问题在于,这个循环是在前台进行还是像之前那样在后台进行。
Lex:后台运行的确很酷,因为它可以支持不同的方式运行代码。此外,还需要考虑数据库方面的问题,例如如何防止模型修改数据库。
Sualeh:有一个不错的解决方案。即正在开发一个新的API,我认为PlanetScale和Turbopuffer数据库都会支持这种功能。当你正在开发一个功能并对数据库进行测试时,实际上你并不想针对广泛的数据库进行测试,你可以向数据库添加一个分支,而不是去修改主数据库。
这种技术的实现方式是为数据库的预写日志添加分支。数据库公司需要不断开发新功能,而分支功能可能成为未来的一个趋势,AI agent也可以利用数据库分支进行测试。
Lex:在此可以对基础设施相关信息提出一些问题,Cursor团队目前是主要使用AWS(亚马逊云科技)吗?在使用AWS的过程中,都遇到了什么挑战?
Arvid:AWS非常出色,无论在何时使用它的产品总是能够正常工作,虽然完成其设置过程可能超级麻烦。实话说,AWS确实值得信赖,如果出现问题,那很可能是你自己的问题。
14.
扩展问题是公司发展难关,
隐私保护也亟待突破
Lex:Cursor作为一家初创公司,在发展中遇到了哪些挑战?
Michael:随着请求量级的不断提升,缓存和数据库等通用组件都会遇到瓶颈。例如,我们现在已经遇到遇到了数据表溢出等问题。此外,我们构建的一些定制系统,例如用于代码语义索引和问答的检索系统回答有关代码库的一些问题,我也一直认为这是比较棘手的扩展问题之一。
Sualeh:我的超级高级工程师朋友们说,在扩展过程中很难预测系统会在哪里崩溃。您可以提前尝试预测,但是在添加这些额外的内容时,总会发生一些奇怪的事情。具体而言,Cursor将所有的代码进行分块,然后发送代码进行嵌入,然后将嵌入代码储存在数据库中,但实际上,并不储存任何代码。此后就是我们要确保不引入客户端bug,因为我们对这些bug非常严格,服务器上存储了许多细节,一切都是加密的。
因此,技术挑战之一就是如何确保本地代码库状态与服务器端状态保持一致。技术层面上来说,我们的做法是将对服务器端的哈希值进行下载,并对比本地的哈希值,计算差额,来确定缺少的文件是什么。但这会增加网络开销。如果您使用了Cursor,没有人希望有人一直对WiFi施加操作。
而且,这也会对数据库造成巨大开销。它将读取数十TB的数据库,每秒钟接近20TB或者更早的数据库。这太疯狂。为此,我们采用了Merkle树结构,只需要协调单个哈希,即项目的根节点,去查看哈希值不匹配的子项,并以此类推,可以极大地降低开销。
但随着使用人数的增多,代码库也变得格外庞大。最初,我们对暗代码库进行了重新排列,但如今其规模已经远不如一些拥有庞大文件的公司的规模了。建构一个东西很简单,但扩展到更多人、更多公司,这是个难题。我们也在努力解决这些问题。
Aman:的确,索引系统有很多需要琢磨的东西。实际上嵌入代码才是瓶颈。为了避免重复嵌入同样的代码块,我们采用了一种缓存机制,即将代码块的哈希值与对应的向量缓存起来,这会使得一些公司,在使用Cursor时,代码嵌入的速度会大大提升,用户不需要储存代码数据,只存储向量数即可。
Lex:目前,您认为代码库索引带来的最大受益是什么?短期来看,代码库有什么用呢?
Arvid:最明显的一点是,当你向找出大型代码库中特定的一些东西时,你可以通过模糊性的提问来进行搜索。比如“我想找到执行X功能的地方。”但是你并不知道在文本搜索中要输出什么语言。你只需要请求聊天,按照enter命令来询问代码库进行聊天。很多时候,模型通常都能够给你提供正确位置。
Lex:为什么Cursor不考虑在本地进行代码嵌入等操作?
Arvid:我们也考虑过这种方案,但实现起来很困难。一些用户使用的是最新的MacBook Pro,但超过80%的用户用的是Windows机器,其中许多机器功能并不是非常强大,实际上,本地模型实际仅适用于最新的计算机,并且构建过程也会出现很大的开销。因此,即使我们向这样做,但也还是很难做得到。
Aman:是的,庞大的数据库只会消耗大量的内存与CPU。此外,正如Arvid所说的那样,本地模型建设存在着巨大阻力,其中似乎都在朝着MOE架构发展,虽然MOE模型对内存带宽的要求更高,并且有利于本地运行,但整体模型的规模也会变得更大,需要更多台机器才能运行。我认为,对于编码生成而言,用户希望能够用到最好、最聪明、最有能力的模型,但在本地实现却很困难。
Arvid:实际上我很喜欢本地模式的替代方案。我认为,它仍然处于研究阶段,可以把它想象成,为语言模型推理进行同态加密。用户可以在本地加密输入的数据,然后发送给服务器进行推理。服务器可以可以对加密数据进行处理,但无法读取数据的具体内容,此后服务器会把答案发回给用户并进行加密处理,用户只能通过解密查看返还的内容。目前同态加密的成本依然很大,如果能够降低成本,我相信这会非常值得期待。
世界上有越来越多的信息和数据将流经两个中心化的参与者,但这会有些令人担忧,比如传统黑客的入侵,这是非常可怕的。用户可能会被黑客监控。人们努力防止不良入侵者使用AI模型,继而引入一些监控机制,但这些监控机制又可能被滥用,比如用户的数据可能会被监控。所以我们希望,我们可以解决同态加密问题。
Lex:我想说,这是所有软件都面临的挑战。就像云可以提供很多便利的功能,人们就越来越依赖它,但是它也存在缺点,这就是为什么需要依靠强大的安全措施来抵御一些攻击。但是也又一些具有影响力的公司控制着这些数据,这就是我们存在着的现实生活。
Sualeh:是的,我非常担心。例如Anthropic公司有这种负责任的扩展政策,其中我们是低级别的,当我们进入高级别时,任何模型都会出于合理的安全原因,都会希望对监控有所提示。我认为这是合理的,但也存在一些弊端,如果所有信息都被见监控,那会非常可怕。
Aman:您认为它(AI模型监控)与云服务供应商有何不同?
Arvid:我认为很多数据一开始并不会流向云供应商,而通常你会把更多的数据提供给AI。一开始用户并不会把自己的数据都放在网络上,给那些公司或者模型。但现在AI模型的监控更加集中,云服务中的用户都可以使用加密密钥,而AWS对此却无能为力,但在这里只有中心化AI模型提供商才能够看到确切的文本内容。
15.
关于上下文训练中关于上下文和模型训练的探讨
Lex:在使用Cursor时遇到的一个问题,当我在Python中写代码的时候,会导入一些内容,模型怎么知道我想在上下文中提到哪些内容,弄清楚这一点有多困难?
Michael:我认为我们将来可以在自动计算上下文方面做的更好。需要注意的是,包含自动上下文需要权衡取舍。因此,你为这些模型包含的上下文愈多,其速度就越慢,这些请求的成本的就越高,这意味着,你可以调用的模型就会越来越少。此外,对于这类模型来说,如果提示中包含了太多信息,它们会觉得困惑。因此,在上下文中呈现出的信息准确性和相关性的标准要十分高,我们也希望能够做得更好。
我们在内部也尝试过一些改进措施,但目前该领域还存在一些问题。让语言模型真正达到理解新信息语料库?上下文窗口能否无限扩展?模型能够真正做到关注无限的上下文吗?能够对这些上下文进行缓存而不必重复计算吗?还有很多想法都在尝试中,这些想法类似于在模型权重学习过程中进行微调。同事作为一家公司,我们很高兴可以拥有更好的检索系统,也希望可以做的更好。
Aman:一个有趣证明是VS Code(跨平台源代码编辑器)。
我们处于一个分叉节点。VS Code的代码是开源的,大型语言模型在预训练过程中已经见过这些代码,并且经过微调和RLHF(人类反馈)训练,能够回答与代码相关的问题。因此,当用户询问关于VS Code的问题时,模型有时能够给出正确的答案,尽管有时也会出现误差。如果能够训练一个专门的模型并成立一个理解这些问题的代码库,这会很有研究价值。
另外,我们对于一个开放性的研究问题充满兴趣,同时也存在着不确定性,即用户是希望模型在前端执行完所有任务,还是将检索与代码生成进行分离?未来的几个月,可能会出现一些真正有能力的模型,此后用户可以单独训练一个非常优秀的开源模型并将其作为检索器,在上下文中为这些更大的模型提供信息。
Lex:如何针对特定代码库进行模型训练?
Aman:有很多方法可以尝试,需要通过尝试确定效果。一件非常幼稚的事情,是尝试复制VS Code和一些前沿模型做过的事情。所以我们应该继续进行预训练。某种持续的预训练,在继续预训练阶段加入特定代码库的数据,并在指令微调阶段加入关于该代码库的问题。我们从指令微调开始,建立一个关于代码的常规指令微调数据集,继而抛出更多关于该存储库中的代码问题。
你可以获取更多难以获得的真实数据,或者可以使用合成数据来执行一些操作,让模型对代码各种新构成部分提出问题。因此,获取代码片段,并让模型对此提出问题,再将其添加到指令中对数据点进行微调,从理论上讲,这一过程可能会解锁模型理解该代码库问题的能力。
▲播客现场(来源:YouTube)
16.
与OpenAI o1竞争靠什么?
Lex:想问一些关于OpenAI o1的问题,您认为测试计算系统在编程中的作用是什么?
Aman:我认为测试时间计算非常有趣。因此,随着数据量和模型大小的扩张,预训练制度将使损失函数和下游任务中的表现越来越好。但是,我们正在面临一些数据壁垒。这意味着,继续扩大数据规模变得更加困难。
因此,扩大测试时间计算是一种有趣的方法,如果现在增加我们使用推理时间的flop计算数量,使用Infer Time时,这些模型总是会有更多的flop,但现在,我们也许可以使用相同大小的模型并运行更长时间,并获得与更大模型规模相当的回报。
某些查询可能需要100万亿参数规模的模型才能处理,但这类查询可能只占所有查询的0.1%。在这种情况下,也许有些浪费精力。而训练一个能够处理99.9%查询的模型,然后可以采用一种方法为那些真正想要更高智能查询的人延长推理时间。
Lex:如何判断哪些问题需要更高水平的智能?是否能够动态地在GPT-4与o1使用之间进行切换?
Aman:确实这是一个问题,也没有人真正很好地解决它。团队在Cursor Tab功能中实现了简单的模型路由,但在GPT-4和o1之间的切换还比较困难。另外,需要什么级别的AI来确定对于司机模型是否太难,可能需要o1模型,但这很难说得清楚。
此外,还需要考虑如何判断某个问题对GPT-4来说是否过难,这可能需要o1级别的模型才能判断。
测试时间计算需要一个完整的训练策略才能正常执行。此外,在大型实验室之外,可能只有OpenAI,但没人知道它是如何工作的,有一些非常有趣的论文显示了它们可能提供了怎样的暗示。因此测试时计算可以归类为后训练阶段,但未来用于训练支持测试时计算的模型的算力可能会超过预训练阶段。
Lex:如果要构建一个与o1竞争的模型,应该怎么做?
Aman:也许我们可以训练一个流程奖励模型。其中有结果奖励模型和过程奖励模型的区分,结果奖励模型是人们接受语言建模训练的传统奖励模型,它更重视最终结果。过程奖励模型则需要对思维链进行层层划分。OpenAI去年发表了一篇关于过程奖励模型的论文,他们使用人工标注的数据集训练了一个过程奖励模型。
目前,过程奖励模型主要用于从多个模型输出中选择最佳答案,但还看不出什么特别优秀的地方。众多的学术成果中,人们要做的是从语言模型中抽取一些输出数据,然后使用过程奖励模型对这些进行赋分,继而选出最佳答案。未来,人们就是使用流程奖励模型及其树状结构,探索思维链的多个分支,继而评估分支的质量。
Lex:当分支质量与结果质量密切相关时,就能够帮助模型选择用哪个分支更好?
Aman:是的,我认为也许人们讨论开源模型训练流程奖励模型时,采用的是更自动化的方式。但目前我并未看到任何东西能够创造性地使用流程奖励模型来进行树状结构搜索和编码。
Lex:有一个AI安全问题,它更像是哲学问题。OpenAI曾说,他们向用户隐藏了思维链,这是个艰难的决定,他们会在后台对思维链进行监控,以此确保模型不会试图对用户产生干扰,这确实令人震撼。但你们对于隐藏思维链这件事有何看法呢?
Michael:我推测,OpenAI可能是为了防止别人从他们的模型中窃取他们的技术。如果你能够详细看到思维链的每个步骤,那这个技术就更容易呗获取。
Lex:所以你也可以用这个来训练吗?
Michael:可能大语言模型供应商之间会存在这样的情况,其中一切API曾经提供了他们的所有记录概率的访问权限,但后来又取消了。其中的原因可能就在于,那些访问了记录概率的人,可以窃取到模型的技术信息。
同时我们也集成o1到Cursor之中,对于o1我们也有浓厚的兴趣,并且我觉得很多程序员也都对此充满期待。但无论如何,o1都不是Cursor默认体验的一部分,目前我们还没有找到将其集成到编辑器中的有效方式。所以我认为,如何和使用这个模型(o1),还是个未知数。
Sualeh:我们有一些美好想法,但需要找在发布之前获得一些适用的场景。
Aman:o1模型还存在很多限制,比如不支持流式输出,这意味着用户无法对输出过程进行监督,只能等待文本的出现。另外,它技术发展还处于早期阶段,有很多需要改进的地方,未来会在增加预训练数据量,扩大模型体量的同时,让搜索工作也变得越来越好。
Lex:GitHub Copilot似乎正在以某种方式集成o1模型,有人认为这意味着Cursor要完了?
Michael:我认为这个领域与2010年代的软件领域有所不同,此处天花板真的非常非常高,所以我认为,三到四年内最好的产品很快就会比今天最好的产品更优秀。我认为即便拥有一个很好的品牌,但不去创新未来还是会失败。接下来几年我认为,关键在于建构最好的产品与系统,这需要归结于建模引擎与编辑体验。
Aman:是的,我认为Cursor的优势在于其不仅仅是快速集成新模型就像o1那样,同时它也是深度定制的模型,并且很重视用户体验。
17.
详刨三类合成数据分类法
Lex:您能解释一下,合成数据分类法是什么吗?
Aman:合成数据是可以从AI中获得的一些数据,我认为合成数据主要有三种。第一类是蒸馏,包括语言模型、输出token或token的概率分布,可以用来训练能力较弱的模型。这种方法无法生成比原始模型更强大的模型,但可以将昂贵的高延迟模型的能力提取到较小或执行特定任务的模型中。
第二类是合成数据利用了某些问题中一个方向比另一个方向更容易的特点。例如,在bug检测问题中,引入bug比检测bug更容易。我们需要做的是,在一个未经充分训练的模型中引入一些bug,然后用这些合成数据训练一个擅长检测bug的模型。
最后一类,是使用语言模型生成可以轻松验证的文本。比如,想对系统进行验证,检测语言是否能够达到莎士比亚的水平,你可以让猴子或者打字机去打字,最终就能够获得充分的训练数据来培养一个莎士比亚级别的语言模型。
对于具体的引导代码的代码,可以通过测试结果来判断这个测试代码是否合格,我们也可以使用模型生成、通过测试的代码来对模型进行训练。但我认为这种方法很难产生实际效用,在开放式任务或者发杂任务中,很难找到完美的验证器。
18.
人类反馈联动AI反馈,
共同提升模型训练效果
Lex:人类反馈的强化学习(RLHF)和AI反馈的强化学习(RLAIF)相比而言如何?对AI模型性能提升都有什么作用?
Aman:RLHF是根据人类反馈信息来进行训练的,我认为,如果能够为专注的任务提供充分的人类反馈那么效果会非常不错。
RLAIF则比较有趣,它根据约束条件执行工作,比如使用语言模型来验证解决方案比生成一个解决方案要容易,它更容易奏效,因为RLAIF可以实现一种递归循环。
我们可以将二者进行结合,在两者之间选择一个平衡点,比如在某型生成的正确代码中,加入少量的人工反馈,大概50-100个示例,就能够让模型的先验内容与我们的构想实现一致。
这看起来与普通的RLHF不同,普通的RLHF通常需要大量的示例对奖励模型进行训练。
19.
AI会在实现AGI前获菲尔茨奖?
Lex:根据你的直觉,生成与验证或者生成与排序哪个更容易呢?
Aman:根据直觉而言...可能是这样的...既定情况下验证更容易,而非找到证明。
Sualeh:AI获得菲尔兹奖的可能性有多大?
Sualeh和Arvid:AI更容易获得菲尔茨奖。
Aman:虽然AI已经解决了许多难题,但现在还不确定定理证明领域中AI效用如何。其次,对于我们距离解决这些非常非常难的开放性问题还有多远,我的直觉也不那么准确了。
Lex:你认为AI会先获得菲尔兹奖吗?而不是物理学或其他的什么。
Sualeh:我认为百分之一百是会获得菲尔茨奖的。我觉得,一些奥数难题,比如伯奇和斯温纳顿-戴德(Birch and Swinnerton-Dyer conjecture)猜想对于AI而言还是非常难的,现在还并不知道如何去解决这些问题。
Aman:AI可能会在实现AGI之前就获得菲尔茨奖。
Sualeh:如果能获得,我会非常开心的,我觉得,可能在2028或者2030年就会实现吧。
20.
谈缩放规律的未来,
“模型越大越好”观念已失效
Lex:谈到缩放规律(scaling laws)的话题,大家可以就此谈一下自己看法,对于现状以及未来的发展有何看法?
Aman:最初OpenAI关于缩放规律的论文存在一些错误。他们提到了关于优化学习效率的问题。后来,Chinchilla的论题提到了一个更准确的版本。自那时起,人们开始不再专注于计算优化,而是更加关注在有限的推理预算下获得更优异的效果。
Aman:我认为,这些缩放规律曲线的维度远比我们最初仅用于计算参数数量和数据的维度要丰富得多。比如,推理计算就是一个显而易见的维度。我认为,上下文长度是另一个明显的维度。假设我们关注推理计算和上下文窗口这两个方面,也许我们想要训练的是某种状态空间模型(SSM)。
它们在处理超长上下文时,成本要低得多,速度也要快得多。即使训练时的扩展属性可能需要10倍的计算量,也就是说,需要花费10倍的计算资源来训练模型,以达到相同的能力水平,但这也是值得的。因为我们最关心的是超长上下文窗口下的推理成本预算。因此,人们未来将会这些维度上进行探索。
Lex:你觉得大家是否还在相信“越大越好”这一理念?
Aman:对于原始性能和原始AI来说,更大的模型肯定更好。我认为,人们还是会更看好蒸馏技术。如果我们投入大量、大量的资金进行训练,以获得最具性价比的模型,那么我们可以调整多少个参数呢?
这一点确实值得关注。因为仅仅在推理时间上尽可能多地投入计算,这种天真的做法,人们已经在Llama模型上尝试过了。或者,仅仅是对7B(70亿参数)模型进行过度训练,使用的token数量也远远超过了最优需求。
但是,如果你真的在意这件事,也许我们可以像Gamma所做的那样,不仅仅是在token上进行训练,而是实实在在地通过最小化与Gemma 27B分布的KL散度来进行训练,这就涉及到了知识蒸馏。实际上是在所有这些token上,花费计算资源来训练这个拥有270亿参数的模型,然后将其中的内容蒸馏到一个更小的模型中。
Lex:蒸馏只给你一个更快的模型,越小意味着越快?
Aman:我认为,蒸馏在理论上是从你正在训练的数据中提取更多的信号。这可能是另一种方法,不是完全克服数据墙,而是部分地帮助我们克服数据墙。可以训练的数据有限,让我们用所有这些token来训练这个非常大的模型,然后我们将它蒸馏成这个较小的模型。相比于我们自己去训练模型,蒸馏能够让模型获得更多的信号。
Lex:如果给你们10万亿美元的预算,你们会如何做?
Aman:我认为有很多关于训练这些大型模型的秘密和细节,只有大型实验室才知道。即使我努力去做,也会浪费很多钱。
Lex:假设获得所有信息,包括训练参数以及方式方法,未来五年中你会如何投资才能使你们所说的原始AI实现最大化?
Sualeh:我觉得,答案很简单。你只需尽可能地购买足够多的计算机,此后每一天所要做的就是购买GPU,研究人员就可以根据目标来选择去训练大模型还是小模型了。
Aman:这涉及到一个问题,我们是真的受到计算和金钱的限制,还是受到其他什么制约?
Sualeh:更多是受限于自身观念吧,但也存在其他一些限制因素。
Lex:你们会选择进行大量的实验还是选择使用这些计算资源来训练一个巨大的模型?
Arvid:可能会选择通过实验,我觉得现在我们仍受限于我们目前所持有的观念。
Aman:我认为是这样的,因为即便拥有了世界上所有的计算能力和可收集的数据,最终还是会受到限制,而且限制的不仅仅是想法,是受制于更卓越的工程技术。即便拥有世界上所有的资金,真正能在这里有所作为的人并不多。
研究工作中包含大量纯粹的、极其艰难的工程技术工作。举个例子来说,如果你看看原始的Transformer论文,将文献中嵌入的许多非常有趣的概念融合在一起,而且还需要编码,这些过程,都需要杰出的工程师来完成,就像GNOME Azure。
进一步说,让下一代模型进行并行化工作,这需要庞大的工程量,我认为要让所有这些事情都奏效,需要投入大量的工程技术工作。比如,能够将工程投入成本降低10倍,让那些拥有美好想法的人真地实现那些结构,提升40%到50%的GPU的利用率,那研究工作的效率可能会大幅提升。
Sualeh:如果能够看到一个清晰的改进路线,那么结果就会唾手可得。我认为,可能OpenAI和其他一些实验室的做法是对的,它们抓住了这些成果。比如,GPT-4.25。现有方法是有效的,那就不需要考虑创新,只有当现在遇到瓶颈时,才需要创新。我认为,如果拥有10万亿美元的预算,也许实际上会先去扩大规模,然后再对自身的观念进行更新。
只要现有的方法有效,就没有必要尝试新的想法。只有当现有方法遇到瓶颈时,才需要新的想法。如果拥有10万亿美元的预算,那么可以先尝试扩大规模,然后重新评估想法。
Aman:我们都相信,去实现AGI需要全新的观念。我们也相信,可以在更小的规模内去测试一些新的观念,而且我们有信心这会奏效。对于当前的实验室而言,将有限的研究和开发人才投注到开发其他的新想法之中是十分困难的,毕竟现存方案在未来较长时间都有效。
21.
谈编程未来,仍需程序员领航
Lex:你们现在处于编程世界的中心。你们认为编程,编程的本质在未来几个月,在未来几年,甚至十年会发生什么变化?
Michael:我认为,我们对未来充满期待,因为程序员在很长一段时间内都坐在“历史的驾驶座”上。我们曾谈到过这个问题,这需要程序员有着高效、代理能力与控制能力,他们可以修改任何你想修改的东西,并且对你构建的内容进行快速迭代优化。
此处,与“同计算机对话形的编程”有差别,与计算机对话,就好比你在Slack上与工程部门或工程师进行交谈一样,输入需求到一个独立的文本框,AI就会自动为你完成这些工作。但这也有些问题,首先会有延迟性,其次这也意味着放弃了一些控制力。
从根本上说,工程实际的执行情况,是根据你构建的细微决策来进行的,其中人的关键作用是不能被AI取代的,要让人类坐在“驾驶位”来掌舵。
而未来编程的情况,很可能是程序员可以控制代码库的抽象级别,可以通过观察伪代码的形式对代码库进行编辑。而且程序员也可对编程软件的逻辑进行修改,保留其控制权,这样可以大幅度提升生产力。
但这只是一个模糊的想法,还需要很多细节需要解决,最终能否实现还有待观察。但是人本身的控制力、效率以及以人为中心观念是非常重要的。我们认为,对于一些像Arvid之前提到一样,某些编程,可以把它交给聊天机器人。但大多数编程任务人需要人深度参与。
Lex:编程的基本技能是否会发生根本性的变化?
Michael:实际上,我认为现在是开发软件非常令人兴奋的时刻。不管什么时候,很多代码依然还是需要查阅很多难以理解的信息。但今天的编程比过去有趣多了,人们开始享受编程。现在的编程让人具备快速构建事物的能力,人们的控制力也被极大提升了。
对于那些编程人员来说,这也是个充满意义的时期,人们的创意和趣味会被放大,如果你是程序员,那今天应该更加注意这部分的特殊性。
Arvid:我也同意,最近我们正对代码库进行一次比较大的迁移,将Node.js中的Async Local Storage替换为 Context对象。即使可以借助AI,这个工作也依然需要我与另一个工程师耗费大概五天的时间。不过未来,我们可能只需要给AI展示几个例子,然后这个迁移任务,就可以在10分钟内完成。程序员可以借助AI更快的工作,而不需要在事先就考虑太多,而且任何事情,其实都可以先去尝试新方法,尝试的成本并不高。
Aman:我觉得在编程中有两种方式,其一是努力思考,仔细寻找解决问题的最佳方法然后用有限时间来验证。其二是直接执行代码,看是如何执行的并就此进行更新。我也更认同后一个方案。
Lex:那对于现在想要学习编程的人而言,你们有什么建议呢?应该学习什么?比如Java亦或者PHP?
Aman:我认为,每个人都有学习编程的自身原因。但我觉得,实际上那些真的热爱编程的人,会是最好的程序员。在我们团队内部,很多人在工作后依然会用Cursor编写自己的编程,有的人甚至会熬到凌晨三点去做这件事。当他们难过的的时候,还会说“我需要写点代码。”来宽慰自己。
这种对编码的热爱,趋势他们成为了最好的程序员,我也认为这些人将会认真投入到那些他们研究的事物之中。我认为,未来的编程者们需要会更多地关注“你想要创造什么”。
Sualeh:程序员可以通过更丰富的方式表达自己的意图。
22.
结语:共建人机协同体系,
改善程序员生活
Lex最后运用Cursor团队的宣言为本次谈话做出总结,在《工程天才》中他们说“我们是一个应用研究实验室,构建不可思议的生产性人机协同系统。”
宣言中写道:“首先,我们正在培养未来的工程师,即人类AI程序员这比任何一个工程师的效率都高出一个数量级。这种混合型工程师可以轻松地控制代码库,并且无需进行低熵键盘操作。即使在最复杂的系统中,他们也会以判断的速度迭代。通过结合AI和人类智慧,他们将比最好的纯AI系统更聪明、更工程化。我们是一群研究人员和工程师。我们构建软件和模型,在有效性和可能性基础上进行发明。我们的工作已经改善了成千上万程序员的生活。”
Lex称,在这个谈话中,至少让编程更有趣了。