Cursor 团队:AI 时代的编程未来
Cursor Team: Future of Programming with AI
AI 编程工具 Cursor 的团队谈代码模型的训练思路、开发者工作流的变化与编程的未来。
Cursor 内部有个说法,来自联合创始人 Sualeh 后来的一次复盘:2022 年 6 月,团队里有人打了个赌,赌 2024 年 6 月或 7 月,大模型能不能在 IMO(国际数学奥林匹克)上拿到金牌。Sualeh 本人是竞赛选手,清楚这道题的分量,他当时的第一反应是「Aman 疯了」。两年后 DeepMind 的系统离金牌线只差一分。
这个赌局被当成了饭后谈资,它几乎定义了 Cursor 存在的前提。如果模型能力能这样陡峭地爬升,那所有围绕「程序员怎么工作」的产品设计,都得在一个更激进的时间尺度上重做。
这期播客是 Cursor 四位创始人 Michael Truell、Aman Sanger、Sualeh Asif、Arvid Lunnemark 第一次集体出镜,聊了将近两个半小时。表面上是聊一个代码编辑器,往下挖,聊的是编程这件事本身会长成什么形状。
代码编辑器到底是什么
Lex 开场问了一个看起来很傻的问题:代码编辑器的意义是什么?
Michael 的回答是,传统上编辑器是程序员「用正式编程语言做文本编辑」的地方。对不写代码的人,可以理解成一个为程序员做的、超级强化版的 Word。强化的理由很单纯:代码有结构。正因为有结构,编辑器能替人做的事远比普通文字处理器多。
从关键词的语法高亮让你能快速扫读,到像浏览网页超链接一样在代码库里跳转定义,再到错误检查抓一些低级 bug,这些都是编辑器在「结构」上做文章。Michael 补了一句关键的话:未来十年,代码编辑器是什么,会发生很大变化,因为「造软件」这件事本身会变得不太一样。
Arvid 补了一个常被低估的维度:编辑器得好玩。
很多我们做出来的东西,试完就扔了,因为它不好玩。而好玩很大一部分来自快。快就是好玩。(Arvid Lunnemark)
这句「Fast is fun」后来几乎成了 Cursor 所有工程决策的隐形指挥棒。后面聊到的 KV cache、投机解码、影子工作区,本质上都在服务这一条。
从 Vim 到 VS Code,再到一个疯狂的念头
Cursor 四个人早期全是 Vim 用户,纯 Vim 加终端,连 Neovim 都不碰。转折发生在 2021 年 Copilot 出来的时候。Aman 说他想试试 Copilot,而当时唯一能用的编辑器是 VS Code,结果一进去就再没出来。
Lex 给 Copilot 的体验做了个精妙类比:像一段亲密友谊里,朋友能替你把话说完。说得准的时候,那种「他懂我」的感觉会上瘾;说得不准的时候,你就得手动删掉重打。Arvid 补充了一个被忽略的细节:Copilot 即使错了也不致命,因为你只要再敲一个字符,提示就会重新生成,错一次的代价几乎为零。
Sualeh 说,Copilot 真正的历史意义在于,它是第一个真正意义上的 AI 消费级产品。在它之前,语言模型一直待在论文和 demo 里。
但团队的野心不止于自动补全。2020 年 OpenAI 的 scaling law 论文出来后,Michael 说那是一个「即使没有新想法,只要加算力和数据就能变好」的时刻。真正让所有事情闭合的,是 2022 年底拿到 GPT-4 的早期权限。之前他们做过一些很具体的工具,比如给金融从业者在 Jupyter Notebook 里用的小工具,也试过用模型做静态分析。
GPT-4 的能力跃升让他们看清了两件事。第一,之前理论上预测的收益变成了现实。第二,整个编程流程都要穿过这些模型,给某一步加个 AI 助手不够用。他们的判断是要重做一个编程环境,给老环境打补丁这条路走不通。
为什么非要 fork VS Code
这个问题很多人问过。市面上已经有 Copilot 这样的插件,为什么 Cursor 要重做一个编辑器?
Michael 的回答很直接:如果你只是现有编辑器的一个插件,你能控制的就非常有限。而 Cursor 团队的判断是,模型会持续变强,编程方式会被彻底改写,这时候被插件的框架限制住,等于自断手脚。他们想要的是「能做出最有用的东西」的自由度。
Aman 补了一个更深的行业观察,这也能解释为什么 Cursor 敢和微软正面竞争:
过去的技术浪潮,往往是一个大东西出现,解锁一批公司。但 AI 编程不一样,每一年、每一次模型能力的跃迁,都会解锁一批新特性。在 AI 编程里,领先几个月,甚至领先一年,产品就会好用得多。(Aman Sanger)
他把这个讲得更狠:一年后的 Cursor,必须让今天的 Cursor 显得过时。一家创业公司如果不能自我作废,就会被别人作废。他评价微软做了很多了不起的事,但不认为他们处在一个能持续做研究和实验、把天花板往上顶的位置。
Sualeh 从另一个角度解释了这个决策:「我们其实是做给自己用的。」当年用 Copilot 时,他能看到模型在变强,但 Copilot 的体验几个月都没什么变化。他当时的感受是:天花板在往上抬,你们为什么不做新东西?alpha 功能在哪里?一个卖得很好、却没有新东西的产品,对想要探索的人来说很难受。
Arvid 补了一个组织层面的关键点:Cursor 把「做 UI 的人」和「训模型的人」放在同一间屋子里,有时候干脆是同一个人。「这样你能做出一些,如果大家不交流、不做实验就根本做不出来的东西。」
Tab:把「下一步」整个预测出来
Cursor 目前最被称道的能力,圈内人叫它 Tab。Michael 把 Cursor 现在做得好归纳成两件事:
第一,像同事一样从你肩膀后面探头,比你更快一步地猜出你下一步要做什么。字符级别的补全只是这个想法的低配版,Cursor 预测的粒度是整个下一次改动,是你下一处要跳过去的地方。
第二,反过来,让你跳到 AI 前面去,用指令驱动代码生成。
Sualeh 讲了 Tab 这个想法怎么来的。他们最初只是想让模型能替人改代码,试了很多次才等到一个真正会改代码的模型。后来发现,一旦接受了一处改动,下一步该去哪儿其实是「明摆着的」。如果你是个 Vim 用户,按 18JJ 就能往下走 18 行,但为什么要人自己数?
所以想法是:你按一下 Tab,它跳到 18 行下面,给你看下一处改动,你再按 Tab。内部当时有个竞赛,看我们能让人按多少次 Tab。(Sualeh Asif)
他接着把这套想法抽象成一个更漂亮的概念:「零熵编辑」。当你已经表达了意图,剩下的操作里其实没有新信息了,但你还是得敲一堆字符让电脑「理解」你在想什么。那模型就应该直接读懂你的心思,把所有零熵的操作都 tab 掉。
Aman 从模型角度补了数据依据:代码的 bits per byte(按字节归一化的损失)比自然语言更低,意思是代码里大量 token 是高度可预测的。而当你预测的对象从「补全代码」换成「人在编辑已有代码时下一步做什么」,可预测性还会再被放大一个量级。Cursor Tab 的目标,就是消灭编辑器里所有低熵的动作,在意图已经确定的地方,把你直接推到未来。
这套东西技术上怎么做?Aman 讲了两个关键点。
第一,这类任务需要极低延迟,所以得用专门训练的小模型。它的特征是「prefill token 消耗巨大,生成长度极小」,也就是要吃进大量上下文却没几个输出。这种负载形态跟稀疏模型天然契合,所以他们用了 MoE(Mixture of Experts)架构,在长上下文下性能提升明显。
第二,他们做了一个叫 speculative edits(投机编辑)的东西,是投机解码(speculative decoding)的变体。区别在于,投机解码通常用小模型去起草、大模型来验证;而代码编辑有一个天然的先验:你正在编辑的那段代码,本身就是最准的「草稿」。
做法很朴素也很聪明:把原始代码块直接喂回模型,模型绝大部分时候会同意「这段我照抄回去」。于是这些行可以并行处理。一直走到某一行模型开始不同意,真的生成新 token,再等匹配了足够多之后重新投机。
Sualeh 提了一个 UI 上的额外好处:因为是流式输出,人可以边看边审,不用盯着一个加载动画干等。
那个被所有人低估的验证问题
聊到一半,Lex 提到 Cursor 体验里的 diff 界面:红绿对比,接受改动。他感叹这背后的 UX 设计工程问题相当大。
Sualeh 讲了他们为了这个界面推翻了多少版。最早是类似 Google Docs 的删除线加上新代码并排显示,太乱。后来试过「按住 Option 键才展示 AI 建议」的交互,蓝色高亮提示这里有建议,你按住 Option 才看到新代码,松开回到原文。这个设计思路本身是合理的,但 Lex 一针见血:你首先得知道要按 Option。
Arvid 把这背后的本质挑了出来,叫它「验证问题」:
这些 diff 对小改动很好用。但一旦改动很大,或者涉及多个文件,逐行审 diff 就变得很不人道了。(Arvid Lunnemark)
他提了两个方向。一是把 diff 拆成「高信息」和「低熵」两类,重要的高亮出来,重复的灰掉。二是让模型先看 diff,预判哪里有 bug,用红色波浪线标出来,告诉你「这段重点看」。他补了一句关键判断:当前的 diff 算法只是普通算法,设计里有人类智慧,但运行时没有智能。
Aman 从产品层面说得更狠:代码审查这个交互,本来就是为「人给人 review」设计的。当代码的生产者是模型,你不需要照顾「作者」的体验,可以完全围绕审阅者重新设计。而现在这种「把 AI 产出硬套成 PR」的做法,恰恰是想象力不足。
Arvid 还提了一个被忽略的细节:顺序。真实的代码审查里,你从上往下翻文件列表,但逻辑上的正确阅读顺序其实不一样。让模型来告诉你该先读哪块、再读哪块,这才是模型应该做的事。
Sualeh 把这个问题推到了更远处:
模型会变强,能提出的改动会越来越大。改动越大,人要做验证的工作就越多,你就越得帮人减负。我不想把时间全花在审代码上。(Sualeh Asif)
一堆自研模型叠起来的东西
Lex 聊到这儿说了一句很准的话:这个编辑器里跑着一堆机器学习。
Aman 讲了其中的结构。Cursor 的工作方式是一套自研模型和前沿模型的「合奏」。前沿模型负责推理密集的部分,自研模型补它做不好的部分。有两个典型例子。
第一是 Cursor Tab,前面讲过,在特定任务上,专门的模型可以打赢前沿模型。
第二是 Apply。这个功能很少被外行注意,但它撑起了 Cursor 体验的关键一环。前沿模型很擅长勾画代码改动的草图,但一到「生成精确的 diff」就开始翻车。Aman 说得很直白:
你拿 Sonnet、o1,任何前沿模型去干这事,它都会在特别蠢的地方搞砸,比如在大文件里数错行号。(Aman Sanger)
Sualeh 补刀:「跟很多人想的不一样,靠确定性算法根本解不了这个问题。」
听到这里能感到那个反差:把「建议」和「原文」合成一份精确的 diff,对人来说是几乎不费吹灰之力的动作,对模型却是硬骨头。Cursor 的解法是让模型先画一个很粗的草图,再训练专门模型去把草图落到文件里。Aman 说外面有些粗糙的模仿品,想用确定性匹配硬解,结果至少 40% 的时候会崩,产品体验直接毁掉。
更妙的是,Apply 还带来了省钱和提速的副产品。因为它让最贵的推理模型只需要输出极小规模的草图,后面的实现交给更轻的模型去落地。Aman 判断这个趋势会继续:越来越聪明的模型做规划,实现细节交给次要的模型去做。o1 这种级别的模型只出一个高层计划,被下级模型递归应用。
到底哪个模型写代码最好
Lex 问出了那个所有人都在争的问题:GPT 还是 Claude?
Aman 的回答很干:没有一个模型在所有维度上 Pareto 最优。维度包括速度、改代码能力、处理超长上下文的能力、代码能力。就当下综合最优而言,他认为答案是 Sonnet,并说这是社区共识。
o1 很有意思,推理能力确实强,做编程面试题、LeetCode 难题表现很好。但它对你「粗糙意图」的理解,明显不如 Sonnet。Aman 还提了一个更含蓄的批评:一些前沿模型在基准上的表现,跟它们在中间地带的真实能力,是有落差的。在训练分布附近跑基准,分数很好看;一旦稍微出界,Sonnet 是那种「能力能保持住」的模型。
这引出了另一个问题:基准和真实编程到底差在哪里?
Sualeh 说得最直接:真实编程里,人是半句半句说话的,有时候是「照我刚才那样做」,有时候是「加这个,再做那个,顺便把那个 UI 改一下」。所有这些都高度依赖上下文。面试题的规格极其明确,而人的诉求极其不明确。
Michael 补了第二层难度:公开基准本身就被污染了。他举了 SWE-Bench 的例子,这是最流行的 agent 基准之一,但在基础模型的训练数据里污染严重。一个证据是,如果你让模型做 SWE-Bench 的题,但不给它任何代码库上下文,它能直接幻觉出正确的文件路径和函数名。
Aman 接了句更狠的话:这些题目涉及的代码库,大多是最流行的 Python 仓库之一,比如 sympy。基础模型公司不会为了保护这些基准的干净度,而把这些主流代码库从训练集里剔除。
那怎么办?Michael 说,很多做系统或做模型的团队用了一种土办法:找人来玩,做定性反馈。有些基础模型公司,专门有人干这个。Cursor 内部也做大量定性评估,再加上一些私有评测集。
Arvid 给这件事起了个名字:「vibe」测评。Lex 马上接话说,他自己也是这么做的,读论坛、读 Reddit、读 X,但用户经常说「我觉得 Claude 变蠢了」,他自己有时候也这么觉得,只是不确定是模型的问题还是他自己的问题。
Aman 提了一个有意思的猜测:AWS 用的是自家芯片,数值精度和 Nvidia 的 GPU 可能不一样,有人猜 Claude 在 AWS 上表现变差,可能跟 Bedrock 上跑的是量化版本有关。Sualeh 补了一句:芯片是脏的,bug 是极难避免的,这个难度怎么高估都不为过。
把 prompt 当成 React 组件来写
Arvid 写过一篇博客,讲 Cursor 内部的 prompt 系统,叫 Preempt。
他的思路起点是:早期模型(2023 年那批 GPT-4)上下文窗口只有 8K,而编辑器里可用的上下文信息一大堆:文档、加进来的文件、对话历史。你怎么决定哪些塞进 prompt、哪些不塞?空间有限,怎么排?
他借了一个看似完全不相关的领域的思路:网页设计。
做杂志印刷,你确切知道内容放在哪。但做网页的时候,输入是动态的,你得让它永远能工作,输入太大就得裁掉点东西。(Arvid Lunnemark)
于是他借鉴了 React 的声明式写法。Cursor 内部确实是用 JSX 来写 prompt 的。有组件,有一个组件叫 File,输入是光标位置。光标所在的那一行优先级最高,往外每远一行减一,渲染引擎(Preempt renderer)自动算能装多少行,以光标为中心适配。
更妙的是,这个抽象让 prompt 变得「可调试」。因为原始输入和渲染是分离的,你可以改渲染逻辑,然后在老 prompt 上回放,看这个改动在整套 eval 上到底有没有提升。Arvid 说这个能力现在比当初更重要:早期 Preempt 是为了适配小窗口,现在更多是为了把数据切分和渲染解耦,让调试变得可能。
Lex 顺着问:那用户是不是也应该写 JSX 来提问?Arvid 的回答很干净:
我们的目标是你做你觉得最自然的事,我们的工作是想办法把相关内容找出来,让你的表达能被理解。(Arvid Lunnemark)
这跟 Lex 之前采访 Perplexity 的 Aravind 聊过的观点相通:让用户尽可能懒。但 Lex 也抛出了一个张力:对程序员,你是可以要求更多的。那到底是让用户懒,还是让系统去「启发」用户思考得更深?
Aman 的回答是另一种思路:当意图传达不够时,可以有几种解法。最朴素的是让模型直接问,「这部分我不确定,你能说清楚吗?」另一种是,如果搜索空间不大,那干脆生成五六个选项让你挑。
Sualeh 提了一个 Cursor 最近做的功能:在你打字时,系统会猜你在做什么,主动建议你该加哪些文件。比如你在改 API,系统能根据你在同一文件里的历史提交猜出 client 和 server 都很重要,主动建议你加进来。这个能力还在很早期,但方向是把「提示词的构建」这件事从用户手里接过去一部分。
Agent 能干什么,这四个人怎么判断
Lex 问 agent 的实用程度。Arvid 先说了一句很坦诚的话:
Agent 很像人,看 demo 的时候会觉得自己离 AGI 更近了,非常酷。但对很多事情,agent 现在还不够有用。我们正在接近它们真正有用的那个点。(Arvid Lunnemark)
他举了一个具体的例子:Cursor 的聊天输入框里,有一个 bug 是 Command+C、Command+V 有时候不管用。这种任务规格极其明确:「这里坏了,帮我修」,两句话就能说清楚。他很想要一个 agent,自动找到相关文件、复现 bug、修掉、验证一遍,一天后他回来看结果。
接下来他讲了 Cursor 团队对 agent 最不主流的判断:
很多人相信 agent 会接管所有编程。我们不这么看。因为编程里很大一部分价值在迭代,你没法事先把需求说清楚,因为你看到第一版之前根本不知道自己想要什么。(Arvid Lunnemark)
大部分编程场景里,人真正想要的是那种即时的东西:一秒钟给一版初稿,立刻能改,改完再看下一版。派一个 agent 出门办差,那是另一类需求,适合规格清楚、步骤固定的活儿。
他还补充了一个「背景 agent」的产品形态:在一个前后端都改的 PR 里,你在前端工作时,后台可以跑一个 agent 先摸后端,等你切到后端时,已经有一份初稿可以迭代。这个想法后来变成了 Cursor 的 Shadow Workspace。
速度是产品的一部分,拆开讲都是硬核工程
Lex 提了一个很妙的观察:在 Cursor 里,Apply 是唯一让他觉得慢的功能,一两秒而已。这个「一两秒都觉得慢」本身,说明其他部分快到什么程度。Arvid 听到这句时脸上的痛苦,Lex 专门描述了。
Aman 系统讲了几个加速设计。
一是 cache warming(缓存预热)。用户在打字时,系统能预测他大概会用到哪些上下文,提前把当前文件内容预热进 KV cache。等用户按下回车,真正需要 prefill 的 token 已经很少,TTFT(time to first token)明显下降。
二是 KV cache 本身的机制。Aman 解释得很清楚:Transformer 能做上下文依赖,靠的是 attention 里的 key 和 value。默认情况下,模型每生成一个 token,都要把所有历史 token 的 key/value 重新算一遍。但如果把它们存在 GPU 上,生成第 N+1 个 token 时只需要跑最后一个 token 的前向,attention 时复用之前的 KV。这是 Transformer 里唯一的串行依赖部分,复用 KV 等于把这块串行的代价砍掉大半。
三是投机加缓存的组合。Cursor Tab 会在用户按下 Tab 前,先假设他已经接受了当前建议,提前发起下一个请求。如果用户真的按了,下一个建议已经在缓存里等着他了。Aman 说这是个混合了投机与缓存的 trick,能达到「看起来很快」的体感,哪怕模型本身没变过。
Sualeh 接了一句更理论的话:如果把 KV cache 做小,你就能更激进地投机。比如预测接下来 10 个可能动作,用户只要命中其中一个就赚了。他管这个叫 power K 曲线现象,单次采样可能不好,但采样多次,命中好答案的概率会高得多。而 RL 本质上就是在利用这条曲线。
Aman 从模型架构上补了另一条线:老一代主要用 multi-head attention,现在往 group-query、multi-query 迁移,本质是压缩 KV cache 的大小。这么做的直接好处是生成 token 阶段(memory bound)更快,而且 batch size 能做得更大。更小的 KV cache 意味着你能同时处理更多请求,或者让 prompt 更长,而不牺牲生成延迟。
Sualeh 还讲了一个非常有意思的算法:DeepSeek 的 MLA(multi-latent attention)。思路是把所有 head 的 KV 压成一个共享的低秩向量(latent vector),再在需要时展开回去。省下的是内存带宽,用算力换带宽。他顺带给了一个判断:多 query 注意力这类压缩方案,本质都在牺牲 KV 的表达丰富度换效率,MLA 想把损失补回来一部分。
影子工作区:让 AI 在另一个宇宙里跑代码
Arvid 写过另一篇博客,讲 Shadow Workspace。
他先讲了动机:如果你能在后台烧算力,就能帮用户做到超出「预测下面几行」的事情,比如「未来 10 分钟你会做什么」,这需要更多算力和更长的思考窗口。但要让后台计算真的有用,你必须给模型一个反馈信号。纯靠模型多想一会儿这条路,o1 已经证明有效;另一种同样成立的方式是让模型迭代、拿到反馈。
对程序员来说,最重要的反馈信号就是语言服务器(language server)。每种语言各有一个,能做类型检查、判断你写错了什么类型、能不能跳到定义、能不能找到引用。它们在 VS Code 里通过 LSP(language server protocol)接入,好处是 VS Code 本身不用内置所有语言的编译器,直接复用现成的编译器基础设施。
Shadow Workspace 的想法是:开一个隐藏的 Cursor 窗口,把 flag 一挂,它就隐形了。AI agent 可以随便改这个窗口里的代码,只要不保存,就不会污染源文件(因为文件夹是同一个)。在隐藏窗口里,agent 可以拿到 lint 反馈、跳定义、反复迭代自己的代码。
Arvid 提到一个技术坑:Linux 上可以做文件系统的内存镜像,把 AI 的改动挡在内存层,它以为自己在改文件,其实全在内存里。Mac 和 Windows 上更难,但这也是他觉得有意思的原因。
Aman 提了一个「hack 但有趣」的替代方案:让语言模型直接对保存加个锁。于是你编辑的其实是「未保存的、只存在于内存里的影子版本」,但仍然能收到 linter 报错。你要跑代码时,会收到一个小警告说锁被占着,然后可以把控制权协商过来。
Lex 说,这个未来既激动人心又有点吓人。让模型直接改文件,让 agent 跑一整夜,第二天回来像看同事的作品一样看结果。Aman 补了一个更细的判断:几分钟级别的、嵌在用户工作流里的任务,本地跑合适;时间更长、改动更大的任务,应该放到远程沙箱,但怎么让沙箱复现用户环境到「等价」的程度,本身就是极难的问题。
为什么这些模型这么不会找 bug
Lex 说他设想的 agent 不止在编程里,还在视频剪辑里。他做播客的很多后期工作通过代码驱动 Premiere,包括上传、翻译、配音,他希望这些都能被 agent 自动化。回到编程,他最想要的 agent 能力是 bug 发现,尤其是逻辑层面的大方向。
Aman 接得很直接:
这些模型在找 bug 上出奇地差。就算是最聪明的模型,甚至 o1,只要朴素地提示它们去找 bug,校准差得可怕。(Aman Sanger)
为什么?Aman 的解释有信息量。这类模型是预训练分布的强烈反映,而预训练里最多的代码相关数据是「代码生成」和「问答」:GitHub 上的代码是万亿 token 量级,Stack Overflow、GitHub issues 上的问答也海量。但「在现有代码里检测真实 bug」,这件事在网上几乎不存在。所以当你让模型去做 Cursor Tab 那种「预测下一处改动」的任务,或者去做 bug 检测,脆弱性就露出来了。
Sualeh 补了一层更微妙的观察:模型其实在内部「知道」某段代码有点可疑,但难点是校准「有多可疑」。同一段代码,你在做实验时几个 bug 无所谓,你在写数据库时一个边界情况都不能错。这中间的判断需要「用户有多偏执」的上下文,而这恰恰是模型最不擅长的。他还提了一个词:资深工程师的价值一部分来自文化记忆,知道三年前有人写过一段很可疑的代码把服务器搞挂了,这种知识模型没有。
他讲了 Arvid 一个极端的实践:如果一段代码能造成巨大破坏,就在函数里每一行都写上全大写的「DANGEROUS」,重复十遍。这套做法在今天的 AI 模型上确实有效,模型会对这种区域更警觉,更容易发现 bug。Sualeh 自己承认,从美学上他很难接受,但从实用上,人太容易遗忘,一个小失误就能搞挂服务器。
Arvid 顺着这条线想到更远的地方:在形式化验证(formal verification)普及之前,你永远需要担心「这里会不会悄悄引入 bug」。他设想的未来是,人不再写测试,模型根据你的函数生成一份 spec,你审 spec,然后一个强力推理模型去证明实现符合 spec。Michael 追问:如果意图本身很难被精确表达呢?Arvid 承认这确实是个真问题,spec 语言也需要演进。
但 Arvid 觉得整库级别的形式化验证也可行。他举了一个很硬的例子:现在已经有工作做到把 C 代码形式化验证到 GCC 编译器、再到 Verilog、再到硬件。如果这么大的系统都能拆解验证,大型代码库原则上也可以。Aman 追问了更难的问题:外部依赖怎么办?调用 Stripe API 怎么证明?如果模型本身成了程序里的原语,怎么证明它?Arvid 说,他甚至觉得「证明一个语言模型对齐」在原则上也是可能的。Lex 说这就是他的「I have a dream」演说。
基础设施:Merkle 树、分支数据库、为什么 AWS 还赢
聊到基础设施,Lex 提了一个怪问题:为什么 AWS 依旧赢,尽管它的界面那么糟?Arvid 说,AWS 就是好,任何时候你用 AWS 产品,你就知道它能跑通,虽然走通配置流程的过程可能是地狱。Sualeh 一句「这就是赢家该有的样子」把大家逗笑了。
Michael 讲了一个更有价值的细节:每加一个数量级的 QPS,都会撞上新的坑。现在到了「表开始溢出」的规模。Cursor 自研的检索系统(对代码库做语义索引、回答问题)是其中最难扩的。
Sualeh 展开讲了这套系统,这是整期播客里信息密度最高的一段。
Cursor 把用户的代码分块(chunk)上传做 embedding,然后只在数据库里存向量,不存代码本身,所有细节加密在服务端,客户端 bug 是他们的心腹大患。技术上最难的是保证「本地索引」和「服务端状态」一致。每改一个文件、删一个文件、切一个分支,都得同步。
朴素做法是每分钟拉一次全量哈希,但这样会「砸爆用户的 WiFi」,也会让接近 20TB 的数据库每秒被读一遍。Cursor 的解法是分层哈希:每个文件一个哈希,每个文件夹存它所有子节点哈希的哈希,一层层往上,直到项目根节点一个哈希。绝大多数情况下根哈希对上就结束。一旦不对,才逐层下钻,去找不一致的地方。这套结构有个大名鼎鼎的名字:Merkle 树。
Aman 补了一个很妙的经济学细节:索引系统的成本瓶颈不在向量数据库,而在embedding 本身。一个公司里 N 个程序员用同一份代码,你没理由给每个人都重新 embed 一遍。他们的做法是,对某个 chunk 算出的向量做缓存,缓存的 key 是这个 chunk 内容的哈希。这样公司里第 N 个人做 embedding 时几乎瞬间完成,切分支时也不用重算,还不用在服务端存原始代码。
Sualeh 提到一个未来的方向:Turbopuffer 这类数据库正在给 write-ahead log 加分支(branch)能力,让 AI agent 直接在数据库分支上测试,而不用污染主库。他很喜欢这个隐喻:「所有东西都需要分支。」Aman 顺着开脑洞:如果文件系统也能分支呢?Sualeh 回了一句关于多重宇宙的玩笑收尾,说已经有极其聪明的算法能保证不会真的占掉太多空间和 CPU。
为什么不做本地模型
Lex 问一个反复被提及的问题:为什么 Cursor 不把 embedding 之类的计算放到本地?
Arvid 的回答很现实:Cursor 的用户 80% 以上用 Windows 机器,很多性能一般。本地模型基本只在最新款 MacBook Pro 上可行,光是维护这些分支就要吃掉大量工程资源。更关键的是,当模型越来越大,本地能做的事越来越少。
Sualeh 补了一个常被忽略的角度:这跟「用户电脑弱」关系没那么大。哪怕你是大公司里最强的程序员,在一台顶级 MacBook Pro 上处理公司那种二十年积累的庞大代码库,做近似最近邻搜索也会把内存和 CPU 榨干。就算能勉强跑通,也不「好玩」了。
Aman 从模型侧补了另一重困难:趋势是 MOE 化,这对本地推理其实有利,因为 MOE 更受内存带宽约束,而消费级硬件在内存带宽上的劣势比在算力上小。但坏消息是,总参数量越来越大,经常单台机器放不下,得上多节点,更别提塞进 MacBook。
接下来 Arvid 讲了一段可能是整期里最哲学也最动人的话。他说他有一个替代方案,还在研究阶段,但特别令人期待:用同态加密做语言模型推理。你在本地加密输入,传到服务器,服务器在密文上跑你本地根本跑不动的模型,但服务器看不到数据是什么。结果传回来,你解密,只有你能看到答案。他说这个技术现在还处在研究阶段,瓶颈全在开销,如果能把这个开销压下去,意义会非常大。
他接着讲了为什么这件事重要:
当这些模型越来越好,它们会越来越有经济价值,世界上越来越多的信息和数据会流向一两个中心化的玩家。如果全世界的明文数据都流经一个节点,那就有可能被以很坏的方式监控。一开始往往是好的理由,防止坏人恶意使用 AI,于是加上一些监控代码。然后换一个人进来,你就滑下去了,然后开始用全世界的海量数据做坏事。(Arvid Lunnemark)
他还顺手做了一个和云计算的对比。今天你用云服务,大多数时候可以自己管密钥,云厂商其实看不到多少东西。但模型推理这一层不一样,服务商看到的就是完整的明文。
Sualeh 补了一个他真正担心的画面:随着模型能力到 ASL-3、ASL-4,出于合理的安全考虑,你会想监控所有 prompt。这个出发点能理解,但如果全世界的信息都要在这种监控下流动,那太集权了。他描述这种状态是一条极细的线:一边是不想让模型失控,一边是不放心让所有人的所有信息流经三家模型公司。
上下文这件事,为什么自动算不干净
Lex 说这是他自己的痛点:写 Python 时导入了一堆库,Cursor 大概能猜出你想放进上下文的东西,但猜得不够好。
Michael 的回答里有一个容易被忽略的取舍:自动塞上下文不是免费的。塞得越多,请求越慢越贵,你能做的模型调用次数就越少,后台能跑的漂亮功能也就越少。更麻烦的是,很多模型在 prompt 塞满时会犯糊涂。所以「自动上下文」的门槛其实很高,相关性不够的宁可不放。
他提了几条可能的路。一条是更工程化的:更好的检索、更好的 embedding、更好的 reranker。另一条更学术:能不能让模型自己理解一个新语料库。这条路上有几个层层递进的问题。先问能不能让上下文窗口无限长;如果能,再问模型是否真的会注意无限长的上下文;如果会,再问能不能对这种无限上下文做缓存,不用每次都重算。还有一类思路更像微调,把信息学进权重,而非靠 in-context learning 临时装进来。Michael 说,在权重层面学到的理解,可能和在上下文里「临时读懂」的理解有质的不同,但这个问题目前还没有定论。
Aman 给了一个现成的验证案例:VS Code 的代码全公开,这些模型在预训练时都见过,可能也见过围绕着它的问答,然后再经过指令微调和 RLHF,所以你问它 VS Code 的问题,它有时候能答得挺好,当然也会幻觉。他追问:那如果你专门去 post-train 一个模型,让它真的「懂」某个代码库呢?
他讲了具体做法,很朴素。做持续的预训练,把通用代码数据和某个特定仓库的数据混在一起喂进去。然后做指令微调,标准代码数据集之外,加上大量「关于这个仓库」的问答。这些问答可以是真的人工标注,也可以用合成的方式造:拿最近改动过的代码片段,让模型自己针对它提问,然后把问题和代码配对,做成训练样本。
这里还有一个更深的分岔,Aman 说这仍是个开放问题:你希望模型端到端地把检索也做进内部,还是希望把检索和前沿模型分开?后一种情况下,几个月后会出现一批远超最好的开源模型的前沿模型,同时你可以专门训一个很强的开源模型来当检索器,负责给大模型喂上下文。
o1 出来了,然后呢
Aman 把训练分成三段:预训练、后训练、测试时计算。他说测试时计算这条路有意思的地方在于,预训练那边大家开始撞到数据墙,靠加数据加参数继续变好会越来越难,而在推理时多花算力、换来对应幅度的性能提升,是一条新的增长曲线。
他讲了一个很实在的经济学视角:有些问题可能需要万亿参数级、万亿 token 训练的模型才能解,但这类请求可能只占全部请求的 1% 甚至 0.1%。为了这种罕见需求去训练一个超大模型,然后极低频地调用,纯属浪费。更合理的做法是训练一个能覆盖 99.9% 请求的模型,然后在遇到真正硬的问题时,让它多跑一会儿。
o1 到底在内部怎么工作,这事连圈内人都只能猜。Aman 说得很坦率:出了 OpenAI,甚至可能只有 OpenAI 内部少数人知道。他提了几个公开研究里露出的线索,比如用过程奖励模型配合树搜索,或者大规模人工标注的思维链数据集。但这些都是推测。
他顺带把奖励模型分了两类。结果奖励模型(outcome reward model)只看最后答案,给那个最终输出打分。过程奖励模型(process reward model)试图给思维链的每一步打分。他提到一个关键判断:现在公开文献里,过程奖励模型最主流的用法是采样一批候选答案,然后用它来排序挑最好的那个。真正让人兴奋、但还没有被验证成功的方向,是用过程奖励模型去做树搜索,就是说如果每一步能被准确打分,你就可以在思维链里分叉、探索多条路径、再判断哪条分支值得走下去。
Lex 追问这个过程里有个隐含前提:分支的短期质量和最终结果的长期质量要高度相关。Aman 认可,这也正是难点所在。
关于 OpenAI 隐藏 o1 的思维链这件事,Michael 给了一个很有信息量的猜测。他说一个可能的动机是防止能力被蒸馏:如果能看到模型走到答案的每一步,那么复现这套技术的难度会显著下降。他还联系了一个历史细节,某些大模型 API 曾经开放 log probability 的访问,后来又收回去了,理由可能类似,那些概率分布同样能给出大量蒸馏用得上的信息。
Michael 也澄清了 Cursor 集成 o1 的实际状态:o1 不参与任何默认体验,团队至今没找到一种让人每小时、甚至每天都想用的集成方式。原因之一是 o1 不流式输出,对需要边看边监督的任务来说,盯着空白等一大段文字掉下来,体验很糟。Sualeh 补了一句:想法是有的,只是要先做出真正有用的东西才放出去。
Aman 补了另一层难度:模型路由。什么任务该用 4o、什么该用 Sonnet、什么才值得上 o1,这件事没人真正解好。Cursor Tab 那边有初步实现,但要在 4o、Sonnet、o1 之间切换就麻烦得多。他抛了一个很尖锐的自问:判断「这题对 4o 来说太难了」需要什么级别的智能?不确定。
Lex 顺势问了一个互联网上流传的说法:GitHub Copilot 开始集成 o1 了,有人评论「Cursor 是不是完了」。Michael 的回答里有这期最重要的一个判断:
这个领域的天花板高得离谱。三四年后最好的产品,会比今天最好的产品有用得多。你可以把护城河、品牌讲得天花乱坠,但如果你停止在产品上创新,你就会输。(Michael Truell)
他把这当成对创业公司利好的消息:这意味着你永远有机会靠做出更好的东西,去打败那些已经有很多用户的对手。Aman 补充,Cursor 相对其他工具的价值,大部分不来自「最快接上新模型」,而来自那些你意识不到自己在用的自研模型,以及每一个功能背后被反复推敲过的交互。
合成数据的三个种类
聊到这里 Lex 让 Aman 展开了他在内部讲过的一套合成数据分类。这段对做模型的人最有用。
先定义清楚:非合成的自然数据,是人类在真实过程里产生的数据。合成数据分三类。
第一类是蒸馏。让一个语言模型输出 token 或者 token 上的概率分布,然后拿它去训一个能力更弱的模型。这条路不会让你得到比原模型更强的模型,但它能把一个昂贵、高延迟的模型能力,压到一个小的专用模型里。对产品来说,这就是延迟和成本的解药。
第二类靠的是「一个方向比反方向容易」。最典型的例子是 bug 检测:制造一个看起来合理的 bug,比找出 bug 容易得多。所以你可以让一个不太聪明、没训多少数据的模型去制造 bug,用这些合成数据去训一个擅长抓 bug 的模型。Aman 说这对人大概也成立。
第三类是用语言模型生成「可以被轻易验证」的文本。他打了个极端的比方:如果有一个验证器能判断一段文字是不是莎士比亚水平,那你让一群猴子在打字机上乱敲,敲足够久也能凑出足以训练出莎士比亚级模型的数据。数学是这一类最好的场景,因为形式化语言的验证极其便宜。代码里的 LeetCode 型题目也一样,只要有测试集,跑通了就说明解对了。
Aman 的判断是,第三类最有可能带来巨大收益,但它也最难推广。对开放式任务、长周期任务,「完美的验证器」这个前提就很难满足。Michael 补了一种中间状态:让模型去「运行」代码并真的理解输出,相当于把人类的手工验证交给模型做。Aman 认可这一点,说那大概是最有希望的一条路。
顺带聊到 RLHF 和 RLAIF。Aman 的解释是:RLHF 的奖励模型来自人类反馈标注,前提是你能拿到海量的人类反馈。RLAIF 的价值建立在一个前提上,即验证确实比生成容易得多。他说 Cursor 的实际做法是两者混合:模型本身往往已经相当正确,只需要 50 到 100 个样本量级的人类偏好,把它原本的先验校准到你想要的分布上。这和传统上花海量样本训奖励模型的做法很不一样。
Lex 顺着「P 是否等于 NP」这个比喻往下问。Aman 说,如果你相信 P 不等于 NP,那有一大类问题,验证比生成容易太多,这个直觉应该成立。Lex 打趣问:那 AI 会不会顺手证明 P≠NP,然后顺手拿个菲尔兹奖?谁来领这个奖?Michael 说,谁写的那条 prompt 谁领。Sualeh 认真猜了个年份:2028 到 2030。
Arvid 认为菲尔兹奖会比诺贝尔奖更早被 AI 攻下,理由是数学可以被验证,是一个封闭系统,容易设计奖励。Aman 说他自己的直觉是:我们可能会在 AGI 之前先拿到菲尔兹奖。他还补了一句自我修正:当年他赌 IMO 金牌,是因为那时看得清路径,已经能解几道题,文献里也有一堆现成的 tactic 可以捡。但对真正开放的数学难题,他现在的直觉要弱得多,「我们连一条通往解法的路都看不清」。他专门提了 BSD 猜想(Birch and Swinnerton-Dyer conjecture)这类题目做例子,说明难点不在验证,而在于连探索的方向都没有。
Scaling law 比最初那篇论文复杂得多
Aman 讲了一段对 scaling law 的修正史。OpenAI 最初那篇论文有点偏差,主要是学习率调度的问题。Chinchilla 给了一个更准确的版本,核心是在参数量和 token 数之间找到算力最优比例。但后来大家又开始偏离「算力最优」,转而按推理预算做优化,宁可训练时多花算力,换取部署时更便宜更快。
他说今天的曲线维度远比当年多。推理时的算力是一个维度,上下文长度是另一个。他举了一个漂亮的推论:如果你的核心诉求是「推理时延低 + 上下文超长」,那你可能该训一个 SSM 架构,因为它在超长上下文的推理上便宜得多、快得多。哪怕训练时要多花 10 倍算力才能达到同样的能力水平,也值,因为你最在乎的是推理那一端。
对「更大是不是一定更好」这个问题,Aman 的回答很直接:对原始能力而言,更大确实更好。Sualeh 补了「原始智力」这个词。Aman 接着说,他自己特别看好蒸馏:花极其昂贵的算力,训练一个最强的教师模型,然后把它的能力压进一个便宜的学生模型。他举了 Gemma 的做法,训练目标本来就是去最小化学生和 27B 教师之间的 KL 散度。这就是「用训练教师的全部算力,换一个更小的模型」。这也部分缓解了数据墙:同样的 token,你能从中榨出更多信号。
Lex 抛出一个假设性的问题:给你 10 万亿美元,投在接下来五年,怎么分?
Sualeh 说答案可能很简单,全买 GPU,研究人员自己去调。Aman 追问:那你到底是被算力和钱限制,还是被别的东西限制?Sualeh 说他更认同 Arvid 的判断:这个领域是被想法限制的。Arvid 补了一句:但如果你有大量算力,你就能跑大量实验。
Aman 想得更细。他说就算有全世界的资本,你也凑不齐人。全世界真正能在这件事上做出差别的人本来就不多,而且研究里有大量工作是纯粹极其艰苦的工程。他拿 Transformer 论文举例:把文献里那些有趣概念拼起来是一回事,写出能真正把 GPU 性能打满的代码、可能包括 CUDA kernel,是另一回事。再往前一步,让模型并行在几千甚至几万张 V100 上跑通,本身就是一个巨大的工程壮举。他说如果能把这种工程成本降低 10 倍,让一个有好想法的人立刻拿到他设想的架构、且能跑到 40% 到 50% 的 GPU 利用率,那研究的整体速度会快一大截。
Sualeh 最后给了一个很务实的次序判断:如果你看见一条清晰的改进路径,就应该先捡低垂的果实。当一路加规模就能变好时,没有理由停下来做实验。直到你必须靠新想法才能继续,那时才回头重新审视。Aman 说,他们四个人大概都相信,要走到 AGI 一定需要新想法,也都相信这些想法可以在小规模上先验证出来。难的是,对现在的大实验室来说,一边有一个「再加规模大概率还能涨」的核心路径,一边要分出极稀缺的研究和工程人力去探别的路,这个取舍非常难做。
人坐在驾驶座上
Lex 把话题拉到最远处:编程这件事,未来几个月、一年、两年、五年、十年会怎么变。
Michael 讲得最完整。他说 Cursor 押注的是一个「程序员长期坐在驾驶座上」的未来,关键词是三个:速度、主动权、控制权。能改任何你想改的东西,能以极快的速度迭代你在做的东西。
他明确地和另一种流行想象划了界:有一种画面很吸引人,你对着电脑说话,它像一个工程师或者一个工程部门一样替你把软件造出来,一个孤零零的输入框就搞定一切。他们不兴奋于这个画面,一部分原因是延迟,但更重要的是那意味着放弃大量控制权。
如果你只能像对一个工程部门说话那样跟一个东西沟通,你就会把大量极其重要的决策让给这个机器人。但工程里最好的那部分,恰恰是无数个关于「到底要造什么」的微小决定,以及速度、成本和其他一切之间的艰难取舍。(Michael Truell)
他还顺带纠正了一个关于工程的误解。不在工程里的人容易以为,规格已经写得清清楚楚,工程师只负责把它落到代码里。但真正好的工程,恰恰是那些关于系统该怎么权衡的微小判断,速度、成本、复杂度、可维护性,这些东西事先根本写不进规格。
他提了一个有点怪但很有意思的想法:让你能控制自己看代码库的抽象层级。你可以用伪代码的形式消化一整个代码库,甚至可以编辑那段伪代码,然后让改动落到真正的编程语言层面。你在任何一层抽象上都能对逻辑做手势,同时保留文本编辑、保留钻进代码里的能力。他说这个想法目前还很模糊,细节要一项项填,成不成得看时间。
Lex 把这个问题落到最现实的地方:现在有很多年轻人害怕,他们喜欢编程,但怕这条路没有未来。编程这门手艺会不会被根本性地改写?
Michael 的回答很乐观,理由具体:编程今天比 2012、2013 年那会儿好玩太多了,那时候的杂事、样板代码、查各种刁钻问题的比重高得多。今天的编程「越来越接近纯粹的愉悦」。那些把人吸引到编程里的东西,快速造东西的能力、个人的掌控感,都正在被放大。技能会变,人的品味和创意会被放大,样板代码的文本编辑会变少,现在很重要的「小心翼翼」也会变得没那么重要。
Arvid 举了一个他自己的经历:他们决定把代码库里用的 AsyncLocalStorage 迁移到 context object,因为前者性能不好。这是影响整个代码库的大迁移,他和搭档花了五天,用着今天最强的 AI 工具。他很期待未来只需要展示两三个例子,AI 就能把改动铺到所有位置,遇到新情况就高亮出来问他,他示范一次,整件事十分钟搞定。这样你就不用事先站在黑板前反复推演「成本太高了,必须一次做对」,可以先试一个方向,发现不对立刻改。
Aman 把这种心态讲成两种编程方式的对比:一种是先想清楚最优解,再用有限的工程时间去实现;另一种是先动手写,看它长成什么样,然后快速迭代。他说后一种更好玩。
至于该怎么学,Aman 说不同的人因为不同理由写代码,但真正最好的程序员,是那种纯粹热爱编程本身的人。他讲团队里有人下班回家,打开 Cursor 写自己的项目写到凌晨三点,难过的时候说「我就是需要写代码」。这种痴迷会让人钻进细节里,去搞清楚事情到底是怎么跑的。
Lex 追问:那这个人,当超级 Tab 成功、他只需要一直按 Tab 的时候,会变成什么样?
Sualeh 和 Arvid 几乎同时回答:这个人会是团队里最爱 Cursor Tab 的人。Arvid 补了一层更细的理解:按 Tab 是被动接受。你一直在往里注入意图。有时候你拒绝,有时候你多敲几个字符,这就是你在塑造正在被造出来的东西。Sualeh 用一个词概括:带宽。人对电脑的沟通带宽,从「一个字一个字敲」变成「持续注入意图」,这是好几个数量级的提升。
这期节目最后,Lex 读了 Cursor 团队那份叫 Engineering Genius 的内部宣言。宣言里写,他们要造的是「未来的工程师」,一个比任何单个工程师有效十倍的「人机混合程序员」,这个混合体会对代码库有毫不费力的掌控,没有一次低熵按键,即使在最复杂的系统里,也能以判断力的速度迭代。宣言的最后一句是:在这条路上,至少我们会让编程变得更有趣。
把整期听完,最有意思的地方在于这四个人的判断和行业主流叙事之间持续的张力。别人在说「agent 会接管一切」,他们说大部分编程的价值在迭代,而迭代需要人坐在驾驶座上。别人在比谁的模型参数更大,他们在比谁的 KV cache 更小、谁能在用户按下回车前就把 cache 预热好。别人在谈护城河,Michael 说的是「停止创新你就会输」。
Cursor 的差异不在某个单点。让一家公司站住的是整套东西:一堆自研模型、一层被反复推翻重做的 diff 界面、一套用 JSX 写的 prompt 渲染引擎、一棵可以逐层下钻的 Merkle 树,以及一个敢把「快就是好玩」当产品原则的团队。这些东西单拎出来都不性感,叠在一起才有那种「用过就回不去」的体感。
如果你现在就想用起来
把这一期的信息翻译成能立刻动手做的事,大概是下面这些:
- 把 Tab 当成主要输入方式,而非补全按钮。多按几次,看它能不能把你接下来几步都带过去。被拒绝了不要紧,那正是你在注入意图的地方,顺手多敲两个字符往往就校准了。
- 给危险代码加显式标记。如果某段逻辑出错能搞挂服务,就在函数里写清楚,必要时用全大写的警告重复几遍。这不是给同事看的,是给模型看的,今天的模型确实会对这类区域更警觉。
- 不要指望模型替你找 bug。它对「这段代码有多可疑」的校准很差。让它找 bug 时必须给它足够的上下文:运行日志、调用链、类型定义,以及这段代码有多关键。
- 写 prompt 时把「意图」和「上下文」分开想。先把你要什么说清楚,再想它需要看到哪些文件。如果它答非所问,先怀疑上下文没给够,别急着换措辞。
- 大改动别一次做完。展示两三个例子让 AI 铺开,遇到它不确定的地方你示范一次。这比事先在黑板上推演三天更划算,因为迭代成本已经被压下来了。
- 把重复性、规格明确的活儿攒起来交给 agent。比如「这个快捷键在某些情况下失效了,帮我修」,这类任务说清楚就能派出去。设计层面的取舍,留在自己手里。
- 审 AI 产出时先要一份导读。多文件大改动的话,与其从头翻 diff,不如先让模型告诉你该按什么顺序读、哪几块最值得细看。
- 如果模型突然「变笨」,先怀疑部署。同一家厂商不同云上的芯片、量化版本、数值精度都可能不一样,这类问题有真实的工程根源,不必先怀疑自己的判断。
- 给自己留一个「跑实验」的习惯。这次访谈里反复出现的一个判断是,这个领域仍然被想法限制。想到一个可能性就小规模跑一下,比在心里推演三小时更值。
最后留一句 Lex 在节目末尾念的、来自 Reddit 的段子:世界上没有比一个能用的临时方案更永恒的东西。这句话放在 AI 编程这个领域,意外的贴切。
本集资源与出处
- 视频在 YouTube 收看
- 音频官方 MP3 直链来自 lexfridman.com 官方播客 RSS
- 官网Lex Fridman 官网本集页面
- 文稿官方 Transcript(lexfridman.com)