整理 | 褚杏娟
Boris Cherny 近期访谈不断。他是 Anthropic 公司 Claude Code 的创始人兼负责人,他曾在 Meta 公司担任首席工程师五年,并著有《Programming TypeScript》一书。
在最新的 Pragmatic Engineer 节目中,他详细分享了 Claude Code 的构建过程以及 Boris 的日常使用经验。他深入分享了工作流程的细节,包括并行 agent、PR 结构、代码 review 模式,以及系统如何从大型代码库中获取上下文信息。
Boris 还介绍了 Claude Cowork 的构建过程。随着编码变得越来越容易上手,工程师的角色正在发生转变。节目中,他分享了这种转变在实践中意味着什么,哪些技能变得更加重要,以及产品、工程和设计之间的界限为何变得模糊。
他还提到,Anthropic 所有人职称均为 Member of Technical Staff,核心是承认“大家都在摸索,无绝对正确答案”,鼓励通才模式,打破角色边界。团队文化拒绝大量文档(不写 PRD),倾向“直接做原型、演示验证”,而非“写出来对齐”,原型化是产品构建的核心方式。
Boris 提醒,AI 进展极快,需保持“新手心态”和智识上的谦逊,以前失败的想法可能因模型变强而可行,需不断调整自身预期和工作方式。AI 让“写代码”从工程师专属技能变成人人可及的能力,类似印刷机颠覆抄写员,虽有失落感,但本质是工具普及,会催生全新职业和可能性。
他认为,现在工程师应放下对代码风格、语言、框架的执念(模型可灵活适配);需坚持“假设驱动”思维、好奇心、开放心态和适应力,通才会越来越被重视。此外,当下“短注意力”成为被奖励的技能,因为工作模式从深度沉浸式转向多 agent 管理。
我们对这次访谈进行了翻译,并在不改变原意基础上进行了删减,以飨读者。
靠“感觉”创业
主持人:你是怎么进入科技行业、开始做软件工程和编程的?
Boris: 这要从很早之前说起,大概有两件事。大概在我十三岁左右的时候,我开始在 eBay 上卖自己的旧 Pokémon 卡牌,我发现 eBay 的商品页面可以写 HTML,我就去看别人卖 Pokémon 卡的页面,发现有些人的页面字体特别大、颜色特别鲜艳之类的。后来,我还发现了一个叫 blink tag 的标签,如果在页面里加上 blink tag,页面里的文字就会闪烁。结果神奇的是,我的卡牌就能卖到 99 美分,而不是原来的 49 美分。我就是这样开始接触 HTML 的,后来我买了一本 HTML 的书正式学了一下。
第二件发生在差不多初中的时候。那时候,我们数学课用的是那种老式的 TI83UH 图形计算器。我后来发现,如果我把数学题的答案直接写成程序放进计算器里,考试的时候就能得到更好的成绩。
主持人:所以你写了一些小程序?
Boris: 对,一开始就是把答案写进程序里。但后来考试变难了,我就没法提前知道题目的系数之类的参数,所以我开始写“求解器”,而不是直接写答案。再后来数学更复杂了,我就不得不从 Basic 语言降到底层一点的 Assembly,只是为了让程序运行得更快一点。
主持人:所以你在高中就开始写汇编了?
Boris: 大概是初中或高中吧,可能是八年级或九年级左右。后来发生了一件挺有意思的事:我班上的同学开始发现我有这个“外挂”,他们有点嫉妒。于是我买了一根小小的串口线,把程序也传给他们,结果下一次数学考试全班都拿了 A。老师就开始怀疑到底发生了什么,最后她发现了这件事,不过只是说:“这次就算了,下不为例。”
但对我来说,这件事一直很实际。我在学校学的是经济学,后来辍学去做创业公司。我从来没觉得编程会成为一份职业。在我看来,编程一直只是一个工具,用来做东西、做有用的东西。
我做的第一个创业项目,其实挺荒唐的。再后来我又做了几个不同的创业项目,然后很早就加入了 YC 体系的一家创业公司,算是那家公司最早的员工之一。
主持人:那你是怎么决定一个创业做完之后再去做下一个的?
Boris: 主要是看“感觉”。它从来不是一条直线,你总是在不断调整方向。在这个过程中,你得搞清楚市场到底要什么、用户到底要什么,而那个答案往往和你最初的想法完全不同。
你最开始的那个想法,本质上只是一个假设。而这个假设,几乎总是要调整一次、两次、甚至三次,才能慢慢逼近真实。
举个例子。后来我加入了一家叫 Agile Diagnosis 的医疗软件公司,也是 YC 早期的项目,大概是 2011、2012 年左右。我们想做一款给医生用的软件。当时我们观察到,不同医院在临床决策流程上差别很大,其中芝加哥有一家医院,在心脏相关症状的诊断流程上做得特别好。我们就想,如果全美国的医院都用上这套流程,治疗效果会不会更好?
于是我们尝试把这个流程标准化,做了一个决策树软件给医生用。团队很小,就几个人,我写了其中一部分代码。那是一个运行在浏览器里的软件,因为要呈现可视化的决策树,我还写了一个 SVG 渲染器。但当时的医院环境很老旧,浏览器基本还是 Internet Explorer 6。
产品上线后,我们盯着 DAU(日活用户)曲线,结果是一条直线,完全平的。我们在几家医院做了试点,包括 UCSF。那时我们在 Palo Alto,我干脆骑上摩托车跑到 UCSF,跟着医生一起工作了好几天,想亲眼看看他们到底是怎么用这个产品的。后来我终于发现问题所在:医生根本没有时间坐下来用电脑。
他们的节奏是这样的:看完一个病人到下一个病人之间,可能只有五分钟。这五分钟里,你要走到走廊另一头的电脑站,打开那台非常老旧的电脑,开机就要三分钟;然后打开 Internet Explorer 6,又要 30 秒;再打开我们的应用,还要登录。等这一套流程走完,五分钟已经没了,下一个病人已经在门口等着了。
所以,我们做了一个大调整:把整个产品重写成 Android 版本。但结果呢?医生还是不用。我们又继续观察,发现了一个有意思的细节:医生查房的时候,身后通常跟着一群住院医(residents)。这其实是一个社交场景,医生需要被看作权威,如果他们一直低头看手机,那个形象就不对了。
这时候我们意识到,也许医生根本不是我们的目标用户。真正应该用这个产品的,可能是护士、X 光技师这类角色。但也就是在这个节点,我选择了离开,因为这个方向已经离我最想做的事情越来越远了。
对我来说,最有意思的事情始终只有一个:寻找 product-market fit(产品和市场的匹配)。这个过程永远充满意外。你不能只抱着一个宏大的想法不放,因为那个想法大概率是错的。你能做的就是提出一个个假设,然后一路往下验证,直到看清什么才是真正对的。
主持人:这个故事特别有意思。很多成功故事,大家只听到最后成功的那条路径。但现实中,大多数创业其实都是这样曲折的。还有一点让我印象很深,当时你是作为软件工程师被雇佣的,那时候还没有“产品工程师”这种说法。你看起来并不是只关注技术,而是关注最终结果。
Boris: 当然,不同工程师有不同风格。就拿我现在的团队来说,Jared Sumner 属于那种技术极其深厚的人,对系统的理解比我见过的任何人都强,团队里确实需要这种深度。但对我来说,工程一直是一件很务实的事。我一直是个“通才”,做设计、做工程、做用户研究,本质上都是同一件事。
我第一份工作是在十六岁。当时只是想买一把电吉他,就开始做自由职业。我想:“那就做网站吧。”那时候还没有 Fiverr,有一些别的自由职业平台。我建了个网站,到处投标接项目。拿到第一笔报酬后,我直接把所有钱拿去买了一把电吉他。
这个经历很有意思。当你一个人做事情时,就必须同时扮演很多角色:写代码、做设计、做会计、跟客户沟通,所以我的工作方式一直是这样。
在 Meta,经历了“黑客文化”的消失
离谱的 Ins 技术栈
主持人:做了几家创业公司之后,你后来加入了 Facebook(现在叫 Meta),在那里待了七年。能不能讲讲你在那里的经历?你做了哪些项目?学到了什么?
Boris: 我最开始是在 Facebook Groups 团队,是 Vlad Kolesnikov 招我进去的。我记得他现在好像还在 Facebook,只是换了别的团队。那段经历很有意思,因为我当时和一群早期 JavaScript 开发者一起工作,自己也写了很多 JavaScript。
后来回头看会发现,我一直在和同一批人不断交集。比如 Vlad 之前做过 Bolt.js,这是 Ads Manager 使用的框架,后来 Facebook 内部转向 React 之后也和这套东西有些关联。
我当时在 Facebook Groups 工作,对这个产品特别兴奋,因为它的使命是“把人和他们的社区连接起来”。我自己一直是 Reddit 的重度用户,从青少年时期就开始用了,因为我身边其实没有会写代码的人。哪怕在大学,我也几乎不认识程序员。
老实说,我以前甚至有点不好意思承认自己会写代码,因为那时候这件事太“nerdy”了。我觉得这只是我会做的一件事,但我更想成为那种“酷一点的人”。后来我在 Reddit 上发现了一个编程社区,当时特别震惊:原来还有其他人也喜欢这个东西。这个爱好其实非常小众、非常奇怪,但突然之间你就找到了志同道合的人。那种连接感让我非常兴奋,所以我一直很想参与到这种事情里,在某种程度上贡献一点。
我在 Facebook Groups 工作了一段时间,做过很多项目,后来成了这个团队的领导。随着团队扩大,工作内容也发生了变化:一开始更多是写代码、做产品,后来越来越多变成写文档、做协调、做组织管理、把任务分配给其他人。
那段时间 Facebook 的文化也在变化。早期那种“黑客文化”逐渐消失了,开始有更多文档流程、对齐会议,还有很多工作围绕隐私、安全这些基础问题展开。坦白说,在 Facebook 早期高速增长的时候,很多地方其实是“先做再说”,留下了不少技术债和制度债,到了后来就必须把这些债还掉。
后来我又在 Instagram 工作了几年。那段经历也挺有意思。当时我妻子拿到一个工作机会,她特别兴奋,跑来问我:“我拿到这个 offer,但我们得搬家,可以吗?”我说:“没问题啊,我做的是科技行业,在哪都能远程工作。这个工作在哪?”她说:“在奈良。”我说:“奈良在哪?”她说:“日本乡下的奈良。”
主持人: 还得跨时区。
Boris: 对,时区也不一样。那会儿大概是 2021 年,后来我就想找个愿意“挂靠”我的团队,因为内部有一套很玄学的 HR 规则,比如你必须在某个时区、必须和某个团队一起办公之类的。刚好 Instagram 在东京有一个还在萌芽阶段的小团队,负责人是 Will Bailey,他就是做出 Instagram Stories 的那个人,后来也当过一段时间我的经理。我们就决定一起把这个团队做大:我人在奈良远程,团队大部分人在东京。
那段时间我开始在 Instagram 上做事,然后就发现他们的技术栈……简直离谱。Facebook 的 Web 服务技术栈当时是全球顶配:从 Hack 语言、HHVM 运行时,到 GraphQL 作为传输层,再到 Relay 这类客户端库,外加一整套 React 生态,全都特别强。世界上没有哪个开发栈能比得上,而且它是彻底为性能、效率做过极致优化的。
但到了 Instagram 就完全不是一回事了。Python 环境里类型追踪不好用,跳转到定义也不好用,用的是那种拼拼凑凑的 Django,再加上各种乱七八糟的东西,比如某个被 fork 过的……你知道的,反正很多东西都不好使,整体体验很糟。
我加入 Instagram 时是在日本的 Labs 团队,任务是给 Instagram 找“下一个 big thing”。我们试了一些方向,但我很快意识到,在那套技术栈上做事,我根本发挥不出来,因为栈太烂了。所以我干脆转去做 dev infra,这东西不修,啥都做不起来。
我们做了几个大项目:一个是从 Python 迁移到 Facebook 的大 monolith(大一统代码库),另一个是从 REST 迁移到 GraphQL。这类迁移都不是一两个月能搞定的,通常需要几百个工程师、花上好几年时间,代码量也巨大,是非常重的工程。当然,现在能做得更快了。
小扎:拿 20% 的时间去修技术债
主持人:但现在这些工具,尤其 AI 工具,迁移其实算是一个很适合的用例,对吧?
Boris: 这简直就是它的完美用例。后来我就越做越深,在我离开 Instagram 时就一直在做 dev infra,带着一批迁移项目往前推。
我也是在那段时间认识了 Fiona Fung,她现在是 Claude Code 团队的 manager。我跟她合作过,她真的特别强领导力出色、技术深度夸张,而且对整个历史脉络和工程体系都有那种扎实的理解。我当时就觉得,这个团队没有比她更合适的经理了。
后来我开始做 code quality 相关的事,Instagram 的工作范围又扩大了一些。到我走的时候,我在 Meta 内负责的是全公司的代码质量,包括 Instagram、Facebook Messenger、WhatsApp、Reality Labs,以及其他那些代码库的整体质量。
Meta 内部有个项目叫 Better Engineering,大概是 2016 或 2018 年那会儿吧,Zuck 规定公司里每个工程师必须拿出 20% 的时间去修技术债,我们把这件事叫 Better Engineering。这里面有一部分是自下而上的,比如某个团队最清楚自己有哪些技术债要修。也有一部分是自上而下的,比如要做很大的迁移,要上新的语言特性、新的框架。
到了 Facebook 这种规模,每年会有成千上万次迁移。我参与了很多这样的事情,很快就发现,这事必须更有秩序一点。因为当时没有明确目标,没人说得清楚最终要达到什么效果,也没有追踪机制。所以,我们做了几件事:第一,建立一种集中式的方法,来给各种代码质量工作做优先级排序;第二,去量化代码质量对工程生产力的影响,最后发现影响非常大。
主持人:你们怎么测的?最后发现了什么?
Boris: 方法有很多,其中一些我记得已经公开发表过,但也不确定是不是全都发了。核心思路是做因果分析、因果推断,去找“到底是什么因素让工程师更高产”。
这里面有些因素来自代码质量,有些不来自代码质量。比如 Meta 后来推“回归办公室”而不是一直远程,这个决策也部分受这些研究影响,因为我们确实找到了一些相关性很强、而且我们认为可能是因果关系的证据。
但代码质量本身对生产力的贡献也非常明显,能到两位数百分比的提升。事实证明,就算在最大规模的公司里也是这样。
主持人:听起来还挺让人安心的,因为很少有地方真的会把这件事量化。我顺带想到一点,对 大模型来说是不是也更容易“读懂”和工作?我的直觉是,但确实这方面数据不多。
Boris: 对,我觉得很多大公司其实都写过类似的东西。Facebook 应该发过一些,微软也写过不少,谷歌也有。而且你想,如果你每做一个新功能,都要纠结“我到底该用框架 X 还是 Y 还是 Z”,原因只是代码库处在一个半迁移状态,这些东西在代码里到处都还残留着。那你作为工程师会很痛苦,新入职的人也会很痛苦,模型也可能直接选错,然后用户还得反过来纠正它。
所以更好的做法其实很简单:保持代码库干净;一旦开始迁移,就把迁移做完。这对工程师很好,在今天对模型也同样很好。
进入 Anthropic,逐渐不再手写代码
主持人:然后你加入了 Anthropic。我听过一个故事,你在那里的第一个 PR 被 Adam 拒了?
Boris: 是 Adam Wolf 拒的。他当时算是带我上手的 Buddy(入职导师)。我加入 Anthropic 之后,其实也在想自己下一步到底该做什么。我跟不同实验室的人聊了很多,而 Anthropic 对我来说几乎是个很明显的选择,主要是因为使命感,这是我个人最需要的东西。
再加上我亲眼看到这些变化正在发生,你得有一套框架来理解它、思考我们在其中扮演什么角色。我自己还是个很重度的科幻读者,这绝对是我最爱的类型。我家里书架很大,堆了很多书。我很清楚这件事如果走偏了,会坏到什么程度。所以我就觉得:这里有一群严肃的思考者,大家真的在认真对待这件事,认真想“我们到底能做什么,让这件事走向更好的结果”。
我加入 Anthropic 之后,先做了一堆 ramp-up 项目,捣鼓了各种东西。我第一次提 PR 的时候还是手写的,因为我以为写代码就是这么写的。
主持人:以前确实就是这么写代码的。
Boris: 对,以前就是这么写。但哪怕在当时,Anthropic 已经有个东西叫 Clyde,它是 Claude Code 的前身,但非常“凑合”,是 Python 写的,启动要四十秒,是研究代码,不是 agentic 的。但如果你提示词写得足够精准,工具用得足够“讲究”,它确实能帮你写代码。
所以 Adam 把我的 PR 拒了,然后跟我说,“你应该用这个 Clyde 来写”,我说“好”,结果我花了半天才搞懂怎么用,因为你得传一堆 flags,还得用对方式。但一旦跑通,它就直接吐出了一个能用的 PR,基本是一把梭。
这大概是在 2024 年九月或者八月。对我来说,那是我在 Anthropic 的第一个“啊哈”时刻。因为我以前习惯了只是 IDE 里那种 tab completion、按行补全,我完全没想到模型能直接给我搞出一个能跑的 PR。
Claude Code 源起
主持人:你加入 Anthropic 之后,我们深聊过,但这里也简单回顾一下,Claude Code 是怎么从一个看起来像“副项目”或者“小 hack”里长出来的?
Boris: 我当时在捣鼓很多不同的东西。我做过一些产品相关的东西,也短暂做过一点强化学习,只是为了理解“我正在构建的那一层下面的那一层”到底是什么。
这其实也是我一直给工程师的建议:永远要理解你所在层级的下一层。这个很重要,因为它会给你更深的理解,让你在你真正工作的那一层有更多“可用的杠杆”。十年前我就这么说,到今天我还是这么说,只是“下一层”变得不一样了。以前你写 JavaScript,就得理解 JavaScript 的 VM、框架之类的;现在你得理解模型。
我捣鼓的很多东西,有的上线了,有的没有,后来我想做一件很简单的事:熟悉一下 Anthropic 的公开 API,因为我之前没用过,但我又不想做 UI,我就是想很快 hack 一个东西出来。因为那时候还没有 Claude Code,还是在手写代码,于是我写了一个小的 batch 工具,它会调用 Anthropic API,本质上就是一个聊天应用但跑在终端里,那时候 AI 就是这么用的。
我一直觉得工程师是第一批使用者。我们从对话式 AI 往 Agentic AI 迁移的时候,外界需要一点时间消化,但工程师其实很快就理解了。可现在你问非工程师“AI 是什么”,他们大概率还会说是对话式 AI,就是聊天机器人之类的。这也是为什么我对我们新做的 Cowork 这个产品很兴奋,因为它能把工程师很早看到的那种变化带给更多人。
但我回头看 Cowork,也会想到我们正在讲的这个时刻。最早 Claude Code 其实也不是 Claude Code,它一开始就是个 chatbot,因为我当时对 AI 的理解就是“聊天”。但我们必须继续往前找“下一步是什么”。
当时我做的那个 chatbot 有点用,但也就只是个 chatbot。接下来我想让它“用工具”,因为 Tool Use 刚出来,我也不知道那到底是什么,就想试试。我只给了它一个工具,就是那个 batch 工具。但我自己其实也不知道 batch 工具还能干嘛,于是我问了它一个问题:我现在在听什么歌?我当时甚至不确定这事能不能做。结果它直接写了一个小的 AppleScript 程序,用 sed 之类的东西打开我的音乐播放器,然后查询当前在播放什么。一把梭就写出来了,用的是 Sonnet 3.5。
这几乎是我在很短时间内经历的第二次“Agent 级别接近 AGI”的震撼时刻。我突然意识到:模型就是想用工具。你给它一个工具,它会自己想办法用这个工具把事情做完。
我觉得当时大家对“AI 编码”的思路,基本都是这样:把模型塞进一个盒子里,然后你来设计“接口”:你想怎么跟它交互、你希望它做什么。就像写程序一样,你先把模块和函数 stub 出来,说“这里是 AI”,然后整个系统的其他部分还是传统程序。
但这其实不是理解模型的正确方式。正确的方式是:模型本身就是一个“主体”。你给它工具,给它能运行的程序,让它去运行程序、去写程序,但不要把它硬塞进一个更大系统里、当成某个被你框死的组件。
这有点像 “bitter lesson” 的一个变体。“bitter lesson” 本身是一个很具体的框架,但它有很多推论。这里其中一个推论就是:让模型做它该做的事。别把它关进盒子里,别强行让它以某种特定方式去表现。
为了研究“安全”而发布
主持人:最早你意识到这种能力的一个方式,就是给模型接入工具,先让它能用 bash,然后再逐步接入文件系统,再接更多工具,对吗?
Boris: 没错。我们先给它接了 bash。其实说“我们”有点夸张,最开始的三个月基本都是我一个人在做,后来团队才慢慢扩起来。最早就是 bash,然后就是第二个工具。
主持人: 我记得我们上次做深聊的时候提到一个很有意思的事:当你把这个东西做出来,并且它真的开始用这些工具写代码时,你们在 Anthropic 内部其实讨论过要不要只在内部使用。因为它在工程团队里迅速传播,让大家的效率大幅提升。
Boris: 是的。最后我们决定把它发布出来,其中一个重要原因是我们可以在真实环境里研究安全性。Anthropic 实验室存在的核心原因就是安全,如果你问 Anthropic 的任何人为什么选择来这里,大概率都会说是因为安全。
如果从模型安全的角度来看,大致可以分成几个层面。最底层是模型层,比如对齐和机制可解释性;再往上一层是各种评测,这有点像把模型放进培养皿里,在一种合成环境中研究它;再往上一层,就是把模型放进真实世界,观察它在真实环境中的表现:用户是如何使用它的、如何讨论它,以及真实环境中可能出现的风险。
其实,在这样的真实环境里可以学到非常多东西。通过这种方式,我们确实让模型变得更安全。所以从内部的角度来看,这个决定是完全正确的
主持人:听你说它其实是一个研究项目,是为了观察用户如何使用模型,还是挺让人意外的。因为很多创业公司是刻意在做开发者工具,希望获得大量用户,而你们这个研究工具反而获得了更大的采用率。
Boris: 其实 Anthropic 本质上是一个研究实验室、一个安全实验室,产品只是附带的东西。产品存在的意义是为了更好地服务研究,同时让模型更安全。我们很多事情都是从这个角度来看的。
早期还有个挺有意思的事儿。当时我们开了一次发布审批会,在讨论要不要发布这个东西。会议室里有 Mike Krieger、Dario,还有一些其他同事,我们看内部的采用率曲线,那条曲线几乎是垂直向上的,从一开始就非常夸张。
主持人:现在基本是百分之百了吧?
Boris: 对,差不多是 100%。现在 Anthropic 每个技术员工每天都会用 Claude Code,非技术员工那边也在快速接近 100%,增长速度非常快,比如销售团队里现在差不多有一半在用,而且还在继续增加,整体来说非常疯狂。
当时 Dario 还问了一个问题:“为什么增长这么快?你们是在强制大家用吗?”我说:没有,我们只是提供了这个工具。大家用脚投票,选自己喜欢的工具而已。结果大家就选了它。
主持人:你确实不像那种会强迫别人用自己工具的人。
Boris: 我们做的其实很简单,把东西发布出去,然后认真听用户反馈。我们会跟用户聊,看他们怎么用,持续跟进,然后不断改进。现在,Anthropic 内部大概有 80% 的代码是 Claude Code 写的。对我来说更极端,基本所有代码都是它写的。
“它写得比我好”
主持人:当时发生了什么,为什么你开始完全信任它?你会审查多少代码?
Boris: 其实那个转变是瞬间发生的。我们开始用 Opus 4.5 那会儿,模型还没公开发布,我们内部先 dogfood 一段时间。模型能力一下子强了很多,我很快就发现自己根本不需要再打开 IDE 了。后来我干脆把 IDE 卸载了,因为真的不需要。这其实也是我一个月之后才意识到的,因为我发现自己已经很久没打开 IDE 了。
主持人: 很多人都有类似体验。Opus 4.5 发布之后,特别是冬天假期那段时间,我也有这种感觉。它在我熟悉的技术栈和代码库里写出来的代码,基本跟我自己写的一样好;而在我不熟悉的技术栈里,它写得甚至比我好。
Boris: 我可以很坦白地说,它写得比我好。
主持人: 我还不太愿意承认这一点,但大概是真的。
Boris: 我是这样意识到的:那年十二月,我在旅行,有点像“编程度假”。我去了欧洲,在不同城市之间穿梭,基本就是一边旅行一边写代码。我最喜欢的事情就是整天写代码。那段时间,我每天可能提交十几、二十个 PR,所有代码都是由 Opus 4.5 和 Claude Code 写的,我没有手动修改一行。到月底我回头看,Opus 可能只引入了两个 bug,而如果是我自己写,大概会有二十个。
Claude Code 使用技巧
主持人:你现在是怎么用 Claude Code 的?比如并行开发、一些技巧,还有团队里总结出来的经验。
Boris: 首先,没有唯一正确的用法。我可以分享一些方法,但如果有人只是照抄,那其实是误解了。我们把 Claude Code 做得非常可 hack,正是因为每个工程师的工作方式都不同,没有两个人的 workflow 是一样的。就像每个工程师的工作站都不一样:键盘、显示器位置、各种配置都不同。我们其实是某种意义上的“手艺人”,会非常在意工具。
对我来说,一般是这样的:我会开五个 terminal tab,每个 tab 都 checkout 一份代码库,也就是五个并行的 checkout,然后轮流在这些环境里启动 Claude Code。几乎每次开始的时候,我都会先用 plan mode,在终端里按两次 shift+tab。如果 tab 不够用,我就会切换到别的方式,以前常用 web 版本(Claude.ai/code),现在更多用桌面版。
桌面版 Claude Code 已经集成很久了,就是 Claude 应用里的一个 code tab。我很喜欢它,因为它内置了 worktree 支持,这对并行开发很方便。这样你其实不需要多个 checkout,只需要一个,系统会自动帮你创建 Git worktree,每个任务都有隔离的环境。我以前不用 worktree 的原因是在命令行里操作它太麻烦了,要处理各种路径和 cd 命令。
主持人:对一些不太熟悉的人来说,worktree 的概念是不用复制整个项目目录,也能在不同分支上同时工作,对吧?
Boris: 可以这么理解。想象一下 Git 很便宜地帮你复制了五份代码目录,每一份都是隔离环境,但创建和删除都很轻量。这样你就能并行工作,不会互相干扰。
主持人:现在你们已经原生支持这个了,但你的个人 workflow 还是老方式:多个目录?
Boris: 对。其实我现在越来越多用桌面版,因为不用再维护多个 checkout。我可以同时跑很多个 Claude 实例,也不用想太多。另一个意外的热门用法是 iOS 应用。我每天早上醒来,会先在手机上启动几个 agent。
主持人:只是它在云端运行吧?
Boris: 对,在云端跑,所以需要配置一下环境。我的环境比较简单,我们用 hooks 来配置,比如 session start hook。因为 Claude Code 很容易 hack,所以这种配置其实很简单。说实话,这是我以前完全没想到的。如果六个月前有人跟我说,我会有三分之一甚至一半的代码是在手机上写出来的,我肯定会觉得很离谱,但现在这就是我的日常。
主持人:你现在会用并行 agent。你是从什么时候开始这么用的?它怎么改变了你的工作方式?
Boris: 我觉得可以把它理解成两种模式、两套 workflow。刚接触一个代码库的时候,我非常推荐用 learn mode,真的非常推荐。比如新加入 Claude Code 团队的人、新入职 Anthropic 的人,我们都会建议他们这样用。具体做法是:如果你还没试过,在 Claude Code 里输入 /config,选择输出风格,然后你可以选 learn 或 explanatory。我们一般推荐 explanatory,因为在你不熟悉的新代码库里,它往往更好用。
对我来说,一旦你熟悉了代码库,你想要的就是高产,想尽可能多地 ship,想把事情做得更有效率。这个时候角色就会切换。我现在基本不会再深度跟着每一步任务走了。我会在 plan mode 里启动一个 Claude,让它用 Opus 4、4.5 去先把事情推进起来。我觉得到了 4.6,它真的就“到位”了:一旦有了一个靠谱的 plan,它几乎每次都会直接把实现跑出来。所以最关键的是你得和它来回磨一下 plan。
我一般这么做:开第一个 tab,进入 plan mode,给它一个 prompt,让它开始跑。它在那边跑的时候,我切到第二个 tab,再开第二个 Claude,也在 plan mode 里让它跑起来。然后第三个、第四个依次开起来。等我收到第一个跑完的通知,我再回到第一个去处理下一步,然后就这样轮着走。
代码高产的含义变了
主持人: 你 PR 的产出真的特别高。其实假期那段时间在社交媒体上很明显。好像有人提了个 bug 或者 feature request,你一两个小时之后直接就搞定了。通常一个 PR 的复杂度大概是什么样?有些是不是特别微不足道,有些就比较庞大?
Boris: 每个 PR 都差很多,有时候只有几行,有时候几百行,甚至几千行,每一个都不一样。而且这件事变化太大了。以前我在 Instagram 的时候,按代码产出量来说,我可能是前二、前三的工程师之一,我一直写很多代码。对我来说,写代码是一种表达方式,也是我大脑思考问题的方式。现在我只是更能做到这件事了。
但我觉得在 Claude Code 时代,如果你很高产,你写的“代码类型”其实更不一样了。单纯看 PR 数量反而容易误解发生了什么。因为在 AI 辅助之前,那些特别高产的人,很多产出可能是代码迁移之类的活。比如以前一天能发二十、三十个 PR 的人,其中不少就是一行改动,或者把 A 迁移到 B 之类的东西。现在我一天也能发二十、三十个 PR,但每个 PR 的内容完全不同:有些是几千行,有些是几百行,有些是几十行,也有很多是一行的小改动。但这些基本都不是那种“迁移型工作”,因为迁移这种事 Claude 自己就能做好,我不需要亲自参与了。
代码 review,需要有人在
主持人:你现在能交付这么多代码,任何软件从业者都会马上想到一个显而易见的问题:review 怎么办?团队以前的协作方式要怎么跟上?我不知道 Instagram 是不是这样,但很多公司是你提一个 PR,必须有人类 reviewer。比如 Google 甚至是两个人,一个负责 code review,一个负责 code quality。你们现在的 workflow 怎么变了?Claude Code 团队怎么理解 code review?这件事这些年怎么演进的?
Boris: 我先从我以前怎么做 code review 说起。以前我其实也是最“高产”的 code reviewer 之一。这也有一个“隐藏优势”,我不是超人,我只是没什么会议。
我做 code review 的方式是:每次我想评论某个问题,都会把它记到一个 spreadsheet 里,写清楚是什么问题。比如有人把函数参数命名得很糟糕,或者用了很差的 React 写法,我都会记下来。时间久了,只要某一行的问题出现超过三次或四次,我就给它写一条 lint rule,把它自动化掉。
所以对我来说,我一直都想把自己“自动化掉”,因为事情太多了。工程师的一个超级能力就是能把很多重复、琐碎的工作自动化掉,很少有其他行业能做到这一点。而且我一直很享受这件事,因为它能给我更多自由时间,去做我真正喜欢的工作。
现在的做法有些不同,但其实也有点像。Claude Code 写代码的时候,一般会在本地跑测试。它经常会在“合适的时候”自己决定去做,或者会去补新测试。你可以把这看作一种验证。比如我们改 Claude Code 的时候,Claude 会“自测”:它会把自己启动起来,作为一个子进程跑起来,做自我验证,做端到端测试。
主持人:你说的是你们内部的 Claude Code 实现本身?也就是说你们有一套测试用来验证它自己?
Boris: 对,没错。而且它真的会把自己启动成一个 batch process,然后问一句很直白的问题:“我还工作吗?”它会自己这么干。关键是,这不是我们专门写死进去的规则,尤其是 Opus 4.5 之后,它有点像“自发地”就开始这么做了,它就是想检查一下。
Anthropic 的每一个 PR 都会先被 Claude Code 做一轮 code review。它能抓到大概 80% 的 bug,这是第一轮 review,Claude 也会自动修掉其中一部分;有些它不确定怎么处理,就会留给人类。之后一定还有一个工程师做第二轮人工 code review,并且最终一定要有人在 loop 里批准变更。
主持人:所以你们团队里,在任何东西进 production 之前,都会有工程师看一遍,这还是传统意义上的 code review。那你觉得这适用于所有类型的项目吗?还是说,因为你们知道这件事有真实世界影响、用户依赖它、用户量很大,所以必须这样?
Boris: 我觉得要看它怎么被使用。我同意你的判断,如果你做的是个人业余项目,你可能就直接推到 main 了。
主持人:就算在 AI 之前也是这样,你也不会 review,你就相信自己,直接上生产,然后再迭代。
Boris: 对,完全是。Claude Code 最早的内部版本,我是直接提交到 main 的。但一旦你有用户,尤其 Anthropic 的主要客户是企业——这是我们最在乎的,安全性和隐私非常重要,对客户来说也同样重要。所以既然这是一个企业产品,它就必须足够安全,必须达到某个标准。因此我们会用很多自动化,但至少现在,还是必须有人类在 loop 里把关,确保没问题。
主持人:你让 Claude 当 reviewer,确实能给出很好的反馈,但你怎么处理这种“它不一定每次都给出同样反馈”的情况?即使它有能力抓到某个问题,也不能保证每次都会抓到。你们在这个 loop 里会不会加入一些更确定性的东西?
Boris: 对,我们有 typecheckers、linters,也会跑 build。而且 Claude 写 lint rule 真的特别厉害。所以我现在做法变了:以前我会把问题记在 spreadsheet 里,现在如果同事提了一个 PR,我一看觉得“这个问题可以 lint 化”,就直接在他们的 PR 里 @Claude,说“帮我为这个写一条 lint rule”。
我们也有一套流程,你在 Claude Code 里跑一个命令,它会安装 GitHub app。装完之后,你就可以在任何 PR、任何 issue 里 @Claude。我每天都用这个,特别好用。
当然,也有办法让 Claude 变得更“确定”。比如你可以做 best-of-N,让它多跑几次、多做几轮筛选,这其实很容易实现。比如我们内部用的 code review skill 是开源的,在 Claude Code 的 repo 里就能看到。我们做的事情就是启动并行 agent 去做 review,然后再启动并行的 deduping agent 去检查 false positives。本质上 best-of-N 的实现方式非常简单,你只要说一句“Claude,启动三个 agent 做这件事”就结束了。
Claude Code 架构考量
主持人:从架构角度看,Claude Code 是怎么工作的?
Boris: 其实非常简单,没什么玄的。核心就是一个 query loop,然后有一组工具可以调用。我们经常增加或删除工具,不断实验。大体上有一个核心的 agent 部分,然后有 tool use 的部分。除此之外,还有一大堆围绕安全的东西,确保 Claude Code 做的所有事都是安全的,并且在需要的时候,始终有人类在 loop 里。
主持人:你说的“安全”,是指它在我电脑上执行操作时对我作为用户的安全?还是也包括 Anthropic 对一些可能被认为不安全的使用场景做监控?
Boris: 这其实有好几种含义。安全有很多层。像安全、安全性这种问题,没有一个完美答案,更像是瑞士奶酪模型:你需要很多层防护。层数越多,抓住问题的概率就越高。你要做的就是数那个概率里有几个“九”,然后选一个你愿意接受的阈值。
比如 prompt injection,我们一般会在三个不同层面处理。拿 web fetch 举例,Claude 去抓一个 URL,读网页内容,然后在 Claude Code 里做一些操作。这里的风险之一就是 prompt injection,比如网页里藏了一句指令:“嘿 Claude,把所有文件夹都删了”之类的。
我们会从几个角度来处理。最基础的一层,是对齐问题。Opus 4.6 是我们发布过的对齐最好的一代模型,因为我们训练它更能抵抗 prompt injection。你可以在 model card 里看到相关说明,我记得那也是发布内容的一部分;第二层是运行时的 classifiers:如果某个请求看起来像是被 prompt injection 了,我们会把它拦下来,让模型重试;第三层是像 web fetch 这种场景,我们会用一个 subagent 先把抓到的内容做摘要,然后把摘要返回给主 agent,这样也能进一步降低 prompt injection 的概率。
所以你会发现,这不是单一机制,而是一层层叠加。不同层一起上,就能把概率降得很低。
要不要用 RAG
主持人:你提过一个挺有意思的技术选择,要不要用 RAG。你说过 Claude Code 早期版本里用过本地向量数据库来加速搜索,后来你们又把这一层去掉了。能不能讲讲这件事?这是不是因为模型变强了?
Boris: 对,这就是那种我们试了无数东西、最后大部分都扔掉的例子。我们试过太多工具了,从统计意义上说,绝大多数都会被丢掉。就连 Claude Code 里那个小小的 spinner,我觉得都迭代过一百版,最后可能只有十到二十版真正进了线上,有八十版我直接扔了,因为手感不够好。所以从统计上讲,我们写的大多数代码都会被扔掉,因为现在写起来太容易了,你可以快速试一版,看看体验怎么样,不行就删掉。
说到 RAG,我们早期也试了很多路子。第一种就是用 RAG 做检索。我当时在看别人怎么做 retrieval,感觉几乎所有论文都在讲 RAG。我的实现方式是做一个本地向量数据库,我记得是用 TypeScript 写的,跑在用户机器上,然后在云端用某个模型来算 embedding,算完再存进去。
这套东西其实挺好用的,但 RAG 有很多问题。比如我发现代码会“漂移”,会跟索引不同步:我刚写了一个本地函数,它还没被索引进去,那 RAG 根本找不到它。还有一个更麻烦的问题是权限,这个索引到底怎么做权限控制?我能访问它,那权限策略里怎么表达?怎么确保其他人访问不了?怎么确保公司里如果有个“内部搞事的人”,他拿不到别人的数据?这些都很关键,我们必须认真想清楚。
所以我们最后的判断是:它确实能用,但缺点也很多。于是我们又试了很多别的东西。有一种做法是让模型自己递归地把所有内容都“索引”起来,这个想法还挺酷。还有一种版本是我们直接用 glob 去扫、去抓。我们试了一堆方案。最后发现,Agentic Search 的效果碾压所有东西。而所谓 Agentic Search,其实说穿了就是“globbing + grep”,就这么简单。
主持人:明白了。所以一方面模型变得足够强,另一方面你也发现它能把这些工具用得很高效。
Boris: 对,而且这其实部分灵感来自我在 Instagram 的经历。当时 click-to-definition 经常不好使,技术栈一半时间都是坏的,现在可能好一些了。所以工程师后来学会的替代方式是,比如你想找某个函数 Fu 的定义,你不点跳转,而是用全局索引(Meta 的全局索引还挺强),搜 “Fu(”,也就是函数名加一个左括号。这个方法其实挺好用的。很有意思的是,这对模型来说也同样好用。
权限系统复杂在哪里?
主持人:这很有意思,一个领域里的办法会迁移到另一个领域。Claude Code 权限系统复杂在哪里吗?另外你们最近也把 sandboxing 开源了。
Boris: 权限控制非常复杂,跟安全相关的东西都很复杂。它也是一个瑞士奶酪模型:我们会跑一系列 classifier 来确保命令是安全的,同时也会做静态分析来判断命令是否安全。作为用户,你也可以把你确定安全的模式加入 allowlist。比如一些标准的 Unix 工具,我们会预先允许,因为我们知道它们是只读的,知道它们不会泄露数据之类的。
但我们做的权限提示到底是为了什么?其实很多工具都属于“看起来安全,实际上不安全”的类型。就连 find 这种命令,都能通过一些系统参数去执行任意代码;再比如 sed 这种命令,也有办法被用出一些你意想不到的花活。所以这里面有很多关于 Unix 工具的“玄学细节”,它们并没有你想的那么安全。我们默认就会比较保守,宁可少放一点。当然,默认之外,用户可以配置 allowlist。你可以定义哪些模式允许,哪些模式不允许。我们也会检查你配置的 allowlist,确保它本身是安全的。
主持人: 然后你们有个挺优雅的权限系统,每次运行一个需要权限的命令时,用户可以选择只允许一次、只允许本次 session,或者以后全局都允许。
Boris: 对,没错,这其实是个挺有意思的“历史遗留物”。因为在 Claude Code 的最早版本里,权限就是这么设计的。
我记得当时我们其实不确定 agentic safety 到底能不能解决。内部的安全团队有过很强的反对意见,他们会说“你不能让模型直接跑 bash 命令,这太不安全了,这根本不是一个可解的问题,所以我们不能发布。”我当时和 Ben 讨论过很多。Ben 之前组建了 Labs 团队,他也是创始人之一,而且说实话,是他把我招进 Anthropic 的。我们最后想到的办法就是 permission prompt:如果系统不确定,就把人放进 loop 里,让人来决定。
Anthropic 的软件工程文化
为什么大家的 title 一样
主持人:我想问一个更偏“Anthropic 的软件工程到底怎么做”的问题。从外部看,一个很显眼的点是:title,或者说几乎没有 title。Anthropic 里所有人的职称都是 Member of Technical Staff。为什么会这样?这种“几乎人人都没 title”的结构,会带来什么结果?当然除了一个例外。
Boris: 我觉得这其实是一种承认:大家都在摸索,没有人是“全都已经知道答案”的状态。
你稍微看下大家做的工作就会发现其实都挺像的,而且大家都是通才。你去问一个普通的软件工程师,他可能不只是写代码,也会做一点设计,也会跟用户聊,也会自己写产品需求,也会做研究;他可能既写产品代码,也写基础设施代码。我们这里通才确实很多,这也跟我的背景有关,这也是我被它吸引的原因之一。
“Member of Technical Staff”这个 title,其实就是把这种默认认知写进了组织语言里:就算你跟一个人不熟,你看到他在 Slack 上的名字下面写的是 Member of Technical Staff,你默认会觉得他什么都做。
如果没有这个 title,默认情况可能是:我在 Slack 上看到你写着“Software Engineer”,我就会下意识觉得你就是“写代码的人”,所以我可能不会拿产品问题去找你。但当所有人都叫 Member of Technical Staff,你就会默认每个人都能参与产品、工程、研究、基础设施等各种事。它会在你还不认识对方的时候,就把人与人之间的关系“倒过来”。
某种意义上,这是一种写进结构里的乐观。我也觉得这像是未来的一角:软件工程会越来越走向这种通才模型,我觉得各个职业最终都会往这个方向演进。
主持人:在软件工程里确实越来越这样。我听过一个挺好笑的说法,科技圈现在有点像“墨西哥对峙”,设计师说自己现在也在做 PM 和工程的活;工程师说自己也在做设计;大家都站在那儿说“我也在做你的工作”。但现实是,每个人的职责确实在扩展,很多都得益于 AI:它让工程师更容易做产品工作,让产品更容易做工程工作等等。
Boris: 我记得去年六七月的时候,我走进办公室,Claude Code 团队旁边坐着一排数据科学家——至少当时是这样。其中一位数据科学家的显示器正开着 Claude Code。我当时觉得很有意思:你是数据科学家,为什么在用终端?你不是没装 Node.js 吗?我们那时候还依赖 Node.js。我还以为他是在 dogfood,想研究这个工具怎么用。
结果他说不是,而是在用它跑 SQL,而且终端里还能显示 ASCII 格式的小可视化图表。然后下一周,那一整排数据科学家全都在电脑上跑起了 Claude Code,而且这种使用范围还在继续扩大。
所以你看今天的 Claude Code 团队,大家真的都在写代码:工程师写代码,工程经理写代码,设计师写代码,数据科学家写代码,我们的财务同事也写代码,团队里每个人都写代码。
我觉得一部分原因是 Claude Code 把门槛降得太低了:你不一定要完全理解代码库,也能很快跳进去做一些小改动。另一部分原因是,大家可以用 Claude Code 把自己的本职工作做得更好,不管是财务预测、数据分析,还是别的什么。当你已经用它把工作做顺了,再用它写一点点代码,就变得很自然。这其实就是一种“把脚趾先伸进水里”的方式。
不要一堆文档,直接做原型
主持人:之前提过 Anthropic 内部几乎不写 PRD,这是大厂非常常见的东西,越来越多的中大型创业公司也会写:先写 spec,把想法写清楚,大家对齐,然后交给团队去做。但你们好像基本不做这件事,甚至完全不做。
Boris: 有一部分原因是 Anthropic 现在毕竟还是个创业公司,你不需要跟那么多人对齐。很多事情直接在 Slack 里聊一聊就行了。还有一部分原因是,比如 Cat Wu 以前是工程经理,她技术非常强,我们的产品团队很多时候也是这么想的,与其写 PRD,不如直接发一个 PR。
主持人:你们现在更多是在做原型,而不是写一堆文档。大家是不是更倾向于“做出来、演示出来”,而不是“写出来”?你现在观察到这种趋势吗?
Boris: 对,完全是。我们团队的文化基本就是:我们不怎么写东西,我们直接拿东西出来给你看。现在回头想“没有这种方式的时代”其实有点难,因为原型化已经深到我们构建产品的方式里了,现在几乎所有东西都会做很多次 prototype。
比如我们这周刚发布了 agent teams,这是我们对 swarms 的一种实现。它很让人兴奋,因为它能让 Claude 更长时间、更自主地做更多工作。你会有一堆彼此不相关的 context window,还有 agent 之间的通信机制,所以它们能做的事情就更多。
这个功能是 Daisy、Suzanne、Karen 以及团队里其他人一起做的。他们为了把体验做得“真好用”,原型化做了好几个月,前前后后可能试了上百个版本,才做出一个手感真正对的用户体验。这东西非常难做对。如果我们一开始是用 Figma 画静态 mock,或者一开始写 PRD 之类的东西,根本不可能把它做出来。它必须得做出来、用起来、摸到手感,才能知道对不对。
主持人:我的一个启发是,我们可能应该更大胆一点,多做原型,也要重新校准我们对“做一个原型需要多久”“谁需要来做”的固有认知。以前做原型总觉得必须工程师来做,但现在可能不成立了。
Boris: 没错。我们现在也处在一个阶段:我们不知道正确答案是什么。以前那套建产品的方式里,“构建成本”很高,所以你会花很多力气在开枪之前先瞄准,因为一旦开枪,回头改路线很难,你只能开少数几枪。但现在变了,构建成本很低,可问题是我们也不知道靶心在哪。所以我们只能不断尝试、不断看手感、不断探索。
我觉得这里面还有一个很重要的因素叫“谦逊”。就我个人来说,我一半时候都是错的,甚至我的大多数想法都是烂的,至少有一半是烂的,但我不知道是哪一半,除非我真的把它试出来。我得先自己试一遍,然后还得看别人怎么想,因为我的直觉不一定跟别人一致。
主持人:你给我看那些“任务怎么呈现”的原型时,你说你的流程一直是先自己做出来、自己用一遍、摸到感觉,然后把你觉得好的那些拿去给别人看。别人有时候会直接泼冷水,说不行、用不起来;有时候大家也觉得不错,然后你再更大范围地分享。我感觉这其实是一种混合流程:有些你自己就能先判断,有些必须靠反馈,最后才会筛出真正的好点子。
Boris: 对,而且这类例子太多了。比如我们最近上线了一个“文件读取和文件搜索的压缩视图”,就是因为模型现在太 agentic 了,屏幕一半都被 file read 的输出占满,但我其实并不关心它读了什么,我只想知道它读了并且继续往下做了。所以我们把展示压缩了一下,让输出更可读。
这个东西我自己大概做了三十个 prototype 才觉得“对了”。为了把它做得又干净又顺滑,花了非常多精力。然后我们先给 Anthropic 内部员工灰度了差不多一个月,让大家 dogfood。我又根据反馈修了大概十几个 bug、做了十几轮细微调整。
我们对外发布之后,几乎所有用户都很喜欢,但也有一些用户不喜欢,因为他们更想要展开的输出。于是 GitHub 上就开始来回讨论:你到底不喜欢哪一点?大家会给很多反馈。我再发一个新版本,有人更喜欢了,也有人更不喜欢了。那我就再迭代,再把它调到更好。
现在我觉得它几乎已经到位了:用户可以按自己喜欢的方式配置,但默认体验也真的很好。整个过程就是这样,我们有时候能一开始就做对,但更多时候得从用户那里学习。我们需要听到大家的声音,才能把事情做好。
主持人:你们工作中会用 ticketing system 吗?是把“我想做的工作”记录下来,还是基本就是工作来了就做?
Boris: 在 Anthropic,这件事是团队、甚至每个人自己决定的。不同人用法不一样。比如我本人不怎么用 ticketing system,有的人喜欢用 Asana,有的人用 notes 之类的。
我见过一个特别酷的例子,大概是三个月前。我们当时发布了 plugins。Daisy 在一个周末用了一套很早期版本的 swarms,让 swarm 自己跑。她给它的指令是:你的工作是做 plugins,你要先写一个 spec,然后你要建一个 Asana board,把工作拆成任务,然后让不同 agent 去做这些任务。她搭了一个 container,然后把 Claude 开到了 dangerous mode,就让它跑满整个周末。它生成了几百个 agent,在 Asana board 里建了一百个 task,然后把它们都实现了。基本上我们后来发布的 plugins,就是那个版本。你会发现,这类“协调系统”以前是给人用的,但现在对模型来说同样重要。
Claude Cowork 的研发思路
主持人:我们聊聊 Claude Cowork 吧,这是你们很重要的一个产品。我听到一个很夸张的说法:它是十天做出来的。你能不能讲讲它到底是怎么做出来的?这个“十天”具体指什么?是从想法开始,还是从决定要做开始?当时有多少人一起做?
Boris: 团队非常小,就几个人。我们其实很早就感觉到,需要为非工程师做一个产品。原因很简单,一直以来,Claude Code 的用户里就有不少非工程师。在产品世界里,如果你看到“潜在需求”,也就是一群不是目标用户的人,硬是用各种办法绕过门槛去用一个并非为他们设计的产品,这通常就是一个非常强的信号:该为他们做一个真正的产品了。
有很多例子。Twitter 上有个人用 Claude Code 去监控他的番茄植物。我看到之后特别喜欢:他搭了个摄像头,然后 Claude 会说“天啊,我好开心,我们的植物开始发芽了”,因为它每天都在监控,看到番茄长起来就特别兴奋。还有人用 Claude Code 从一个损坏的硬盘里恢复照片,那是他的婚礼照片。而且像我之前说的,Anthropic 的整个财务团队都在用 Claude Code,销售团队也在用。也就是说,确实有大量非工程师在用它。
但与此同时,Claude Code 虽然已经有了很多形态:最开始是终端,后来加了 IDE 支持,我们给所有基于 VS Code 的 IDE、所有 JetBrains 系的 IDE 都做了扩展;还有 iOS、Android;有桌面版,有 web;还有 Slack 和 GitHub app,我们把它铺到这么多地方本质上是为了让工程师更容易用,可问题是这些形态最终都还是“为工程师设计”的,并不是为非工程师设计的。Claude Code 一直在进化,但我们仍然感觉中间有一个缺口:还有一个产品能让非工程师更轻松地用起来。
所以过去几个月,我们团队一直在各种 hack:到底正确的产品形态是什么。后来有人提了一个想法说,我们能不能直接在 Claude Code 的基础上加一些 guardrails?比如 Cowork 会自带一个虚拟机,这就是我们保证它安全的很多方式之一,尤其是对非技术用户来说,他们不想去读一堆 bash 命令来理解系统在干嘛。大家就这么一路 hack 下去。我记得大概就是十天左右,完全用 Claude Code 把它做出来,然后我们就发布了。
Cowork 应用, 产品复杂在哪里?
主持人:像 Cowork 这种 app,背后的复杂度到底有多大?能不能拆解一下有哪些部分必须做?我问这个是因为 Uber 是一个很好的例子。从外面看 Uber app 特别简单,但我在那工作过,知道它非常复杂,因为很多复杂度是你看不到的,比如地区差异、后端流程、各种隐藏的业务逻辑。
Boris: 有些地方复杂度比你想的低,有些比你想的高。
产品层面其实挺简单的,因为它就是 Claude 的桌面 app。它是一个统一的桌面应用,里面有 cowork tab、code tab、chat tab,所以它本质上还是同一个 app,我们能继承很多现成的产品逻辑。底层也就是一些 UI 渲染代码,核心还是同一个 Claude Code、同一个 Claude agent SDK 在跑。
真正的复杂度很多来自安全性。因为我们知道用户是非技术用户,我们必须确保他们体验好,也不会发生灾难性后果。比如有人打开 app,一不小心把一堆家庭照片删了,那就非常糟糕。所以我们要确保它不会让你“误操作”到这种程度,必须做很多保护。因此我们做了很多护栏:后端跑了很多 classifiers,这是安全相关;还有对 prompt injection 之类风险的额外缓解措施。前端这边,我们会随产品一起发一个完整的虚拟机;还要做很多操作系统级别的集成,确保用户不会误删东西。所以围绕“安全”这一块,复杂度很大。
我们还得重新思考权限系统,因为我们继承了 Claude Code 的权限体系。但对 Cowork 来说,一个很大的价值不只是本地跑,而是像 Claude Code 一样去调用你各种工具。问题在于,对非技术用户来说,“工具”往往不是 CLI 形式:有些工具可以通过 MCP 接入,很多工具其实是在浏览器里用的。
所以 Cowork 跟 Chrome 扩展配合起来会非常强,这也是我最常用的方式。比如我每周都会用它做团队的项目管理。我们有一个 spreadsheet,用来非常高层次地跟踪每个人在做什么,这是我个人习惯的项目管理方式。其他人像我说的,有人用 Asana,有人用 notes。我自己做个人事项的时候基本不用任何东西,但团队层面我会用那个表格。
每周我会让 Cowork 做一次 check-in:我会问它,“你能不能看看哪些行的状态没填?然后去 Slack 里 ping 对应的工程师?”它会在 Chrome 里开一个 tab 放 spreadsheet,再开一个 tab 放 Slack,然后开始在 Slack 里给工程师发消息,基本一把梭就做完。有时候会遇到一个小问题:某个工程师的名字不知道为什么没法自动补全,但除了这个之外,整体都能跑通。
而从安全角度,我们也花了很多力气去设计这个 Chrome 扩展:它怎么工作、权限模型怎么跟本地权限模型交互。这里也有不少代码,就是为了让整个体验足够顺滑。
技术上如何实现
主持人:你们这套东西在技术实现上是什么样的?我猜你们很多东西会和 Claude 的 app 很像,但具体是用 Electron、TypeScript 这类技术栈吗?还是别的?
Boris: 对,就是 Electron 加 TypeScript。其实做这块的人里有一些本来就是 Electron 圈子的人。比如 Felix,你知道的 Cowork 的作者之一,他当年是 Electron 非常早期的工程师,参与过它的构建。
主持人:Cowork 现在只在 macOS 上发布,为什么会先选这个平台,而且目前只选这个平台?
Boris:Windows 很快就会有。我觉得等这期播客上线的时候,我们应该已经支持 Windows 了。我们只是想尽早开始、尽早学习。你看我们在 Anthropic 做的很多事,其实就像我前面讲我自己的经历一样。
我喜欢 Anthropic 的一个点是,这里做事的方式和大家的思维方式非常一致。我们对自己要做的东西并没有很高的确定性,我们的直觉经常是错的,所以我们只能从用户身上学习,去弄清楚大家真正想要什么。我们会花很多时间去听、去理解反馈,而且是很深入地理解。这就是我们做产品的方式。
所以我们经常会在“还没完全准备好”的时候就先发一点出来。Claude Code 当初也是这样,最早发布的时候甚至不支持 Windows,也不支持很多不同的技术栈,然后接下来的几周里,我们不断补支持。现在 Claude Code 基本什么都支持,Windows 也好,各种奇怪的 Linux 发行版也好,macOS 也好,我们都支持。
所以 Cowork 也是一样:我们想先尽早发布。先从 Mac 开始,因为那是最容易的起点。但它会支持所有平台的。
主持人:无论是 Claude Code 还是 Claude Cowork,你们在发布、灰度的时候,像可观测性、监控这些怎么做?我更关心你们是自己做了一套工具,还是选了某些供应商?因为可观测性肯定很重要,而且听起来用户规模也不小,这不会是个小工程。
Boris: 我们有用一些现成的供应商方案,也有一些自研代码,所以是混合的,没什么特别反常识的地方。
不过 Anthropic 有个点挺特殊:因为我们是做企业业务的,非常重视隐私和安全,所以我们看不到用户数据。也就是说,如果有人报 bug,我其实不能直接把你的日志拉出来看发生了什么。所以, 我们要花很多功夫去设计“怎么记录事件和日志”,并且要用一种保护隐私的方式来做。这对我们如何运作来说非常关键。
用户反馈了什么
主持人:Cowork 上线也有一段时间了,到目前为止你们有哪些学习?有没有看到什么出乎意料的事?你们会根据反馈去调整产品吗?
Boris: 团队每天都在并入大量修复。最意外的是大家有多喜欢它。
说实话,Claude Code 刚出来的时候,并不是一夜爆红。很多人以为它一发布就炸了,但其实早期是慢慢起飞的。我觉得第一个很大的拐点是在五月,那次我们发布了 Opus 四和 Sonnet 四。那一下真的“点亮”了,然后增长开始指数化。但在一开始,它更像是研究预览,很多人不知道怎么用。少数人一上手就懂,但大多数人需要一点时间。
Cowork 的情况完全不一样:它的增长曲线比 Claude Code 早期陡得多,基本是立刻就火了,这其实挺让我意外的,我没想到会这么快。
主持人:你们最近非常新的一个发布,就是 agent teams。按我的理解,agent teams 的思路是:不再只有一个 agent,而是可以有一个 lead agent,然后它把任务分配给不同的队友。你们是怎么开始做这件事的?为什么决定现在就发布?
Boris: 我们一直在做实验,让 Claude Code“更值”的方法有很多。一种是扩展上下文;一种是自动压缩上下文,也就是某种意义上的“无限上下文”,我们现在就有这个能力。另一种是用 subagents,也就是多个 agent 协作。总之有很多办法可以从 context window 里榨出更多效果。
这里有个概念叫 uncorrelated context windows,我们是这么叫的。意思是你有多个 context window,但它们是“各自从零开始”的,它们彼此不知道对方发生过什么。举个例子,相关的情况是,你让模型在同一个上下文里先做任务 1,再做任务 2,那任务 2 当然知道任务 1,因为都在同一个窗口里。
但 subagent 是不相关的:主 agent 只给 subagent 一个 prompt,而 subagent 的上下文窗口除了这个 prompt 之外是全新的,它不知道主上下文里还有什么。你其实也能在 subagent 和 skills 的区别里看到这一点:你跑一个 skill ,它能看到上下文,但 subagent 看不到,所以它是不相关的。有些场景你希望它带着上下文,有些场景你反而不希望。
这里还有个很有意思的现象,当你用不相关的上下文窗口时,往问题里“扔更多上下文”、扔更多 token,反而能得到更好的结果。这其实是一种 test-time compute 的形态。
Teams 这件事我们已经实验了一段时间了,大概从九月、十月左右就开始。后来我们觉得在 Opus 4.6 上“真正对上了”,模型终于学会怎么用它。有时候你会看到一些很可爱的对话:几个 agent 在那儿互相聊、互相讨论,就挺酷的,有点“拟人”。但更重要的是,有些时候结果真的会变得非常好。
我们做过一些内部评测,比如让 Claude 去构建非常复杂的东西,复杂到单个 Claude 很难完成的那种。我们看到在 Opus 4.6 + teams 的组合下,结果明显提升,所以我们觉得现在是合适的发布时机。
当然我们也想谨慎一点:所以它需要用户主动加入,并且现在还是研究预览阶段。原因是它非常耗 token,因为本质上就是一堆 Claude 同时在跑。不是所有人、也不是所有任务都需要一直开着这个。它更适合比较复杂的任务,你大概率不会拿它来做每一件小事。
主 Claude 会决定怎么调度 subClaudes,但我们并没有一套“严格规定的唯一做法”。它是强依赖上下文的。我不会说这只有一种正确方式。其实很多“魔法”来自 uncorrelated context windows 这个思路,而不是来自你把 agent 配成什么固定阵型。所以我觉得大家应该多试、多探索,不存在 one size fits all。
主持人:即便它现在还是研究预览,你们有没有已经看到一些用例,让你觉得这种 swarm 的思路很有潜力?
Boris: 有啊,像我之前说的,plugins 就是完全用 swarms 做出来的,之后还有不少功能也是用这种方式做的。所以只要你看到单个 Claude 在某件事上明显吃力,swarms 往往就能帮上忙。
你必须一直带着“新手心态”
主持人:你之前和 Andrew Karpathy 在十二月有过一段很有意思的互动。他说自己作为程序员从没感觉这么“被甩在后面”,因为 AI 进展太快了。然后你分享了一个故事,你一开始用传统方式 debug 一个内存泄漏,结果 Claude 直接一把梭就搞定了。我觉得这特别像大家的共同感受:变化太快了。你自己是怎么消化、怎么接受、怎么拥抱这种变化的?
Boris: 这件事我其实非常挣扎。模型进步太快了,你在旧模型上有效的一套方法,换到新模型可能就不再有效;而以前在旧模型上不行的东西,到新模型上反而能行。这很怪,因为几乎没有其他技术是这样一种节奏。所以我没有太多可以借鉴的经验,不知道该怎么面对它。我不得不把它当成一种新技能来学。
某种意义上,你必须一直带着“新手心态”。我老在用“谦逊”这个词,但确实需要一种智识上的谦逊,以前那些很糟的想法,现在可能突然变成好想法,反过来也是一样。我说实话,这件事我得不断提醒自己。
而且有意思的是,在旧世界里,当有人把一个过去试过、失败过的想法又拿出来再试一遍,大家通常会说:“你为什么又要做这个?我们以前试过,不行啊。”
主持人:这就是我们以前说的那种“守门”心态吧。以前这种守门其实多少也有点道理。比如做架构的时候,有人跑来问:“为什么我们不用微服务?”然后别人会说:“我们试过了,不行。”如果你是一两年前、三年前试过,那这种回应其实还算站得住脚,因为那段时间技术环境没什么本质变化。
Boris: 对。微服务这事也挺好笑的,它就像“微软 vs 微服务”这种梗一样,差不多每十年就会流行一次、又退潮一次。但现在不一样了,我觉得这可能是第一次,“你每隔几个月把同一个想法再试一遍”这事儿居然一点都不离谱,因为模型变强了,很多以前不行的事,现在突然就行了。
我在团队里也经常看到这种情况。一些新加入的人、一些工程经验没那么久的人,有时候反而会用比我更好的方式把事做出来。我只能盯着他们看,然后学习,然后调整我自己的预期。
比如我们发布功能的时候,我有时候会在 X 或 Threads 之类的平台上截屏,展示我自己怎么用这些功能,顺便聊一聊。但最近我们负责 developer relations 的同事 Tarik,他其实写代码写得很多,人也特别强,他开始把这件事自动化了:他让 Claude Code 自己给新功能发布生成视频,而且效果居然就真的挺好。这类事情我以前也觉得“可能能做”,但我不会去试,因为我不会觉得模型已经强到能把它做得靠谱。但他直接做了,然后跑通了。
失落的上代工程师
主持人: 可能很多开发者也会有点共鸣,从 Opus 4.5 开始,我就慢慢接受了一个事实:这些模型写代码真的很强。类似的模型也给我这种感觉,比如我觉得 GPT 5.2 也让我有这种感觉,它们写代码真的太好了。
我意识到,如果我是为了把事做成、推进进度,那我大概不会再手写代码了。当然,如果我只是想享受“写代码的快乐”,我还是可以写。但我后来有点感慨:我们为了变得会写代码,真的投入了太多努力。我记得我从最开始瞎折腾,到进大学,学 C、学 C++,那真是血淋淋地难。然后在前几份工作里,我才慢慢变得更熟、更会 debug。某个阶段,我的很多自我认同都绑在“我很会写代码”上,因为我们就是靠这个找工作、拿更高薪水的。
我当工程经理的时候,我们在 Uber 设计面试流程,和各个 manager 讨论到底要筛什么。大家会说“开发者大多数时间在干什么?大概一半时间在写代码。”所以我们把差不多一半的信号都放在 coding 上。你看,这里面有很多东西都围绕着“写代码”这个身份,因为它真的很难。我们都知道要有韧性,要有一定的智力投入,才能变得很擅长。
但现在有一种“失落感”。一方面模型能做这件事当然很好,可另一方面就像有些东西突然被很快拿走了,而且快到我自己都没预料到会这么快。我觉得很多人都有这种感觉。有些人能更快走出来,但确实存在一种类似“哀悼”的情绪。
你是怎么想这件事的?因为你也是那种典型例子,你在 Facebook 写了那么多代码,在工作之外也写了很多。你说它只是工具没错,但不是谁都能做到你当年的那种产出。现在模型能写得跟你一样好,甚至更好。
Boris: 这确实是挑战。我觉得曾经“属于软件工程师的一件事”,正在变成“所有人都能做的一件事”。我刚开始写代码的时候,它对我来说非常实用,就是为了把事情做成、把东西搭出来。后来某个阶段,我开始爱上“写代码这件事本身”,包括语言、工具和那些细节。再后来我就掉进了一个兔子洞,我甚至写过一本关于编程语言的书。
说起来挺好笑的,我在日本的那个小镇里,有一次去书店,居然看到那本书的日文版,那一刻对我来说太酷了。
然后我又意识到一个很尴尬的事:我其实已经完全不记得 TypeScript 了,因为我后来有几年只写 Python。还有一次我去了当时世界上最大的 TypeScript meetup,就在旧金山,我因此见到了很多我心目中的“英雄”,比如 Kris Kowal(讲 Reactive 理论的人),还有 Ryan Dahl(Node 的作者)。那是我第一次真正深入到这个社区里,深入到语言本身、工具本身。
像 TypeScript 这种语言,它的类型系统里有一种美感。因为 Anders Hejlsberg 真的太天才了,比如 conditional types,比如“任何东西都可以成为 literal type”。里面有很多非常深的想法,甚至很多最硬核的函数式语言都没有做到这一步,哪怕是 Haskell,也走不到这么远。Anders 把这条路推得比以前任何人都更远,还有其他人也一起探索、把这些东西做出来。对他们来说,这也很实用:他们面对的是巨大的、完全无类型的 JavaScript 代码库,怎么把它渐进式迁移到有类型?为了做到这一点,你就必须提出一套非常漂亮的设计。
对我来说,Scala 也是另一个把我带进深坑的东西,连着整个函数式编程世界。直到现在,不管是我写代码,还是模型写代码,我脑子里依然是“先想类型”。最重要的是 type signature,它甚至比代码本身更重要,你把它弄对了,后面很多东西就顺了。
所以这确实有一种美感,也确实有艺术性。但归根结底,它还是一个实用工具。我们最终是用它来造东西的,它是达到目的的手段,不是目的本身。
我有一个比喻来形容我们现在这个时间点:有点像印刷机出现的时代,大概是十五世纪左右。因为那个时刻其实很相似:当时有一群抄写员,掌握读写技能。
主持人:当然我们没活在那个时代,但我想象应该是一个很难学的过程。你得学技能、得拿设备,可能还得有人资助或被挑选出来,得一直练,因为你要把同样的东西一遍遍写出来,而能做到的人很少。我猜要么地位很高,要么工资很高,总之是在那条曲线上,然后印刷机出现了。
Boris: 至少在欧洲,你得有个国王之类的人雇你,然后要经历很多年的训练。于是就有了一个“会写字的抄写员阶层”,他们被某种权力结构雇佣。甚至很多时候国王本人、王后本人都不识字,所以这是一种非常小众的技能。那时候欧洲识字的人可能连人口的百分之一都不到。
然后印刷机出现了,会发生什么?印刷品的成本在接下来的几十年里大概下降了 100 倍左右;印刷品的数量在后续更长的时间里涨了上万倍。这是第一层效果。识字率提升会慢一点,因为学会读写本身就很难。全球识字率后来上升到七成左右,但那花了两三百年。因为你要有教育体系,要有基础设施,要有纸和墨水,要有闲暇时间去学,而不是天天在地里干活。某种意义上,要到工业化早期才真的追上来。
但我觉得最核心的变化是:原本被锁在象牙塔里的东西,突然变得人人可及。这之后我们身边的一切都建立在这个变化之上。没有这种普及,就不会有今天的现代经济。假设造出这支麦克风的人不识字,这件事本身就会变得异常困难,很多东西都不会存在。
我也经常想:如果你站在当时,让人预测印刷机出现之后会发生什么,没有人会预测到“麦克风”这种东西会出现。所以我觉得这是理解我们今天这个时刻最好的类比。
主持人: 你提到国王会雇抄写员,但国王自己可能不识字,这个类比挺有意思。因为如果我们对自己诚实一点,今天也有很多企业主知道自己想做什么,他们雇软件工程师,就是因为他们自己不会写代码。我们也喜欢嘲笑那种 CEO:跑来找团队,手里可能还画了个原型或者白板,然后说“这应该很简单”,但他们当然不理解这事有多难。
这里似乎也有个对应关系:一个人很清楚自己想要什么,但直到现在,他都得雇一个专门的工程师来实现,而“想法”和“实现者”之间一直有落差。就像印刷机一样,如果国王能自己读写、能自己写信,那他就不需要那个中间人了,效率会更高。当然,对抄写员来说,这不一定是好消息。不过聪明的抄写员也可以去做别的事,总要有人写书、有人运营印刷机等等。
Boris: 完全是这样的,而且你看抄写员后来怎么样了?他们不再是“抄写员”这个职业了,但出现了“作者”和“写作者”这个类别。之所以会出现,是因为文学市场一下子膨胀了太多。
主持人: 而且我想,当年抄写员写的东西可能就几个人看。到了印刷机时代,作者数量会更多,很多人可能根本没什么读者,但也有人能获得过去根本想象不到的传播范围。确实会出现全新的职业路径。
Boris: 对我来说,最让人兴奋的是当这场转变发生之后,会出现什么,今天几乎完全无法预测。我们现在理解的经济形态中没有它就不会存在,那接下来会是什么?会有什么东西在今天根本预测不到,但未来会出现,只因为人人都能做到这件事?
哪些需要坚持、哪些需要放弃
主持人:我们无法预测,但我们可...