花叔专栏 / AI工具实测

「闪电.skill」发布!用Anthropic的方法论把你的产品提速3倍!

⚠️注:这篇内容非常非常非常长...11718字,建议收藏再看。或者,你也可以不看,把链接丢给你的agent,让它自己安装文中的skill,以及自主学习进化就好了~

前几天,Anthropic的三位工程师在自家开发者博客claude.dev上发了一篇复盘,讲他们8月怎么用两周时间,把claude.ai网页版和Claude桌面端的核心体验整体提速了3倍左右。

具体的数是这样的:打开claude.ai到页面能打字,从3.1秒降到0.55秒;在桌面端新开一个Claude Code会话,从0.8秒降到0.3秒;加载一个Claude Cowork云端会话,从2.6秒降到0.73秒(都按第75百分位算,也就是四分之三的用户比这个数快),四类核心操作一共13项指标,几何平均快了3.1倍,他们估算每天能帮用户省下几万小时的等待。

干活的主力是Claude,整个冲刺都跑在一个Slack频道里,每个讨论串里都有Claude(用的是Claude Tag,背后是一个跟Opus 5.5水平差不多的内部研究模型),它找瓶颈、搭benchmark、写代码提PR、盯每一次部署,人负责定目标、做取舍、审批每一个改动,两周合进去3000多个改动,一次线上事故和回滚都没有。

我觉得这篇特别值得细读,倒不在3倍这个数本身,而在于它大概是我见过把让AI在一个真实产品上大规模干活这件事写得最细的一篇:方法、踩过的坑、跟Claude的原始对话、人怎么和AI协作,全都摊开写了。他们的结论就一句话,只要Claude能把一件事衡量出来,它就能把这件事变快(Once Claude can measure something, it can make it faster)。

这套东西其实不挑规模,你在Claude Code里做自己的小项目,同样可以照着用:先找能数的东西,证明这个数跟你真正在乎的事挂钩,让Claude去爬,再把成果锁住。里面有两条,我自己之前搭写作系统和做skill的时候正好摔过跤。我也让agent照着这套方法,给我自己的4个网站提了一遍速,其中公众号排版器在实验室里打开到能打字的耗时少了九成,方法整理成了一个skill(闪电.skill),实测数据和skill都放在文末。

原文链接:https://claude.dev/blog/how-we-made-claude-ai-faster/

一、核心方法

以前做性能优化,测量是第零步:你先加埋点,等线上数据一点点攒起来,然后才开始理解问题出在哪。

原文说有了Claude之后,测量变成了爬山的第一步,Claude手里只要有一个能比较的数,它就能开始改代码、跑benchmark、看这个数有没有往下走,而且它能异步干好几个小时,一晚上自己试很多轮。所以在他们看来,杠杆最高的事变成了一件:找到更多可衡量的数据指标。

「爬山」(hill climbing)是原文反复用的词,意思就是给一个数,让Claude一步一步把它往更好的方向挪。但能数的东西不一定是对的东西,所以这套方法里有三样配套:

1、每个benchmark先证明自己。一个新指标要先证明,把它压下去,用户真实感受到的耗时也会跟着降,证明不了就下线,免得Claude爬错山。

2、棘轮(ratchet)。赢下来的成果要锁住:benchmark写进CI,数字只许降不许升,哪个PR让它变差,CI就不让合并,每天还有个任务,数字降了就自动把上限往下调。

3、护栏和掌舵。每个改动至少一个人审批,用户看得见的改动全放在功能开关后面,高风险的先给员工用、再放1%的用户、最后全量。人负责三件事:给Claude胆子,替它做品味上的取舍,决定往哪爬、什么时候停。

具体到每一个问题,跑的都是同一个循环:

二、实施过程

1、设定目标与基线

冲刺开始前,他们建了一个Slack频道,给Claude留了一段常驻指令,原文是这样的:

@Claude 你的工作是负责claude.ai网站和桌面App性能相关的一切事务。你的职责包括:监控每次部署有没有带来性能退化;评估现有遥测数据是否准确、全面;维护一套整理得当的可观测性看板;针对发现的问题和唾手可得的改进,主动去实现方案;提出值得做的性能项目;以及和你的人类同事沟通。\[……]

这个频道的终极目标,是让你尽可能自主,但我们知道今天还做不到。

然后他们让Claude通过Datadog的MCP去分析使用数据,Claude从里面找出了影响最大的四类用户操作:打开App、开始一段对话、加载一段已有的对话、发送一条消息,这四类占了用户全部活动的95%。算上网页端和桌面端,再乘上几个不同的产品(Chat、Claude Code、Cowork),一共是13项不同的测量。为了让这13个数能互相比,他们又补了一轮埋点,统一口径:每项都从用户的一次操作开始计时,到结果渲染出来为止,并且把客户端和服务端各自花的时间分开。

冲刺开局手上有一份大约二十个项目的清单,都是人挑的,每个项目对准一类操作。Claude给每个项目估了能省多少毫秒,他们把这些估算加起来,定了这次冲刺的目标。有几个项目挺大的,他们当时的判断是两周内大概能做完大部分。

结果第三天,13个目标就达成了12个。

计划里的项目都提前落地了。让App打开得更快的,有两个:一是把一个静态的输入框直接烘进HTML里,这样React还在初始化的时候,用户就已经可以打字;二是给桌面端外壳的主进程预编译好V8的代码缓存,不用每次从头编译。让切换得更快的,有三个:切换对话时输入框不再卸载重建,鼠标悬停在某个会话上就提前把它预取下来,侧边栏的重复渲染砍掉了90%。

开局他们特意给Claude留了自己找机会、自己提新方向的空间,结果Claude提出来的这些方向很快就长成了完整的项目,效果远远超过了一开始定的目标。于是他们重新定目标,接着去找更多能数的东西,频道里发的是这样一段话:

@Claude 原始清单里的项目我们差不多都立项了,还多做了一些。我们来刷新一下\[……]还有什么没探索过的,还有什么能爬山的,现在最大的机会在哪?\[……]「疯狂」的点子我也欢迎

2、寻找确定性指标

从一开始他们就想好了,迭代速度要比部署节奏更快。Claude可以异步干好几个小时,甚至通宵,他们希望它验证自己原型的时候,不用等线上数据回来,所以得在实验室里另找测性能的办法。

第一条线索是Sam找到的(原文这几段对话都注明是按真实对话复原的):

Sam(12:34):除了掐表计时,我们还能用什么?比如能不能数JS的指令数?

Claude(12:42):可以。纯JS的热路径,可以直接数指令:用Valgrind跑benchmark,加上node --predictable,跟仓库里存好的基线比,跑一次就行,不需要统计。浏览器里的路径,Chromium下没法数指令,但有一串别的确定性计数可以用:每次交互的React提交次数、V8精确覆盖率给出的函数调用次数、布局和样式重算的次数、DOM变更次数。你想先做哪个?

Sam(12:49):valgrind+Ir+--predictable开一个线程去探索,浏览器和React的每个bench各开一个新线程。每个线程都@我。你知道我们要什么。开干。

十一分钟后,五个线程已经跑起来了,每个盯一种测量:指令数、V8调用次数、React提交次数、样式重算次数、DOM变更次数。

对每一个新benchmark,他们都带着几分怀疑。每个benchmark要干两份活:一是做Claude在实验室里能压的那个指标,二是在CI里当护栏,数字只能往下拧。如果一个benchmark结果不稳定,或者跟用户真实感受到的延迟其实不相关,他们就直接扔掉,不让Claude去爬一座错的山。频道里的原话是:

@Claude 请证明,对每一个候选指标爬山,都能换来可以测量的真实耗时提升。证明不了的,我们就把它的bench下线

真实耗时(wall-clock time)是用户能感觉到的,但它噪音很大,毫秒级的数字太不稳定,没法当CI的闸门。指令数的好处是确定,同样的代码跑多少次都是同一个数,但他们仍然要Claude证明,指令数降了,真实耗时也会跟着降。

于是他们让Claude在两条热路径上把指令数往下压:一条是组装一段对话消息树的例程,一条是在Claude Code输出里扫描状态行的扫描器。Claude用Valgrind把两条都分析了一遍,发现第一条路径里有四分之一的指令,花在同一种很慢的字典查找上(megamorphic dictionary lookup),同一个消息ID被分三次各查了一遍。

一个小时后,两条路径的指令数分别降了48%和31%,真实耗时分别降了78%和44%。他们在CI里加了两个新棘轮:从那以后,任何让这两条路径指令数变多的PR都过不了CI,每天还有个任务,只要数字降了,就把上限跟着往下调。

这就引出了整个冲刺最核心的一条:有了Claude,只要能量出来,问题就能解。测量以前是第零步,现在是爬山的第一步,Claude一拿到要打败的数就能开始优化。

3、建立优化循环

所有这些都在同一个Slack频道里跑,好几个工程师和Claude一起在每个讨论串里干活。冲刺慢慢稳定成了一个循环:

1、有人针对某类操作里慢的一截,开一个讨论串,常常附一张截图或者一段录屏;

2、Claude追踪这段流程,找一个或者自己搭一个benchmark,把问题复现出来;

3、在实验室里拿到有希望的结果后,Claude带着PR回来,常常是好几个,按风险和审查难度拆好,用户看得见的改动都放在功能开关后面;

4、上线后,Claude盯着部署,读线上数据;

5、变快了,Claude就把benchmark的棘轮拧紧,把战果锁住,没变快,就把开关关掉,接着迭代;

6、然后它去找同一类操作里下一个慢的地方。

举个例子。有人发了一段录屏:页面加载完之后,侧边栏的一行行会话才陆续蹦出来,Chat和Cowork的会话各自在不同的时间到位,整个页面看着一抖一抖的。他们现有的监控一个都没发现这个问题,最接近的指标是累积布局偏移(CLS),但每次偏移只算0.008分左右,离「良好」的门槛0.1还远得很。

Issac想到可以直接去调底层的Layout Instability API。Claude建了一个遥测事件,把每一次布局偏移的来源,对应到一个有名字的区域(比如侧边栏、对话区)和一个阶段(比如首次绘制之前、可以打字之后)。它还加了一个集成测试:打开一个侧边栏里有会话的页面,故意把侧边栏的数据压到首次绘制之后才给,只要任何一个有名字的区域发生偏移,测试就失败。Claude拿这个测试当benchmark来证明修复有效:在主分支上跑20次,红了20次,在修复的PR上跑20次,绿了20次。

这个遥测事件上线之后,Claude去读线上数据,发现网页端31%的页面加载,在页面已经能用、用户什么都没动的情况下,有东西在挪位置。然后Claude按名字一个个去处理原因:一个来晚了的标题行,一个在用户名加载出来后往旁边滑了一下的光标,一个在滚动条冒出来时跟着挪动的列表。它把排在最前面的几个一批修掉,修完了,再去找下一批。

这只是一个线程。冲刺期间,他们同时跑着150多个这样的线程。

4、并行扩展线程

一个线程上跑通了这个循环,在更多线程上跑就只是多开几个的事。一个讨论串里最初的需求做完之后,Claude不会就此收工,而是接着往下做,单个线程能提出50个优化PR,有时候到100个。而且越来越多的时候,是Claude自己在开新线程,去追它在另一次排查或者每晚的定时任务里发现的机会。频道里的工程师Shelley说了一句:「(这个模型)是个数字狂魔。」

每一种测量都能找到可以改进的地方:

  • Claude做了一次React hook普查,发现输入框的打字路径上挂着6900个hook和900个状态订阅,用户每按一个键,它们都要重新渲染一遍;
  • Claude数了样式重算,发现一个:root:has()选择器,让每一次DOM变更都多花24毫秒;
  • Claude追踪首次绘制之后的代码路径,发现一个遗留的location.reload(),每天造成大约50万次隐藏的页面重载,他们所有的加载指标都看不到它;
  • Claude读了闲置标签页的性能采样,发现一模一样的缓存快照,每分钟要往IndexedDB里复制两次,而且全在主线程上。

一个线程最后会通向哪,他们很少事先知道。有一次Claude在全面排查CPU卡顿,注意到给一个已经输出完的代码块做语法高亮,能把页面冻住大约一秒钟。它在实验室里挖下去,找到了元凶:破折号。只要一条回复的markdown里有任何一个非Latin-1字符,比如破折号(—)或者弯引号,V8就会把整段字符串按UTF-16双字节存储,于是每一条语法高亮的正则都被赶到了更慢的双字节路径上。Claude的修法是一个20行的改动:高亮之前,先把每个代码块复制成一个单字节字符串。

到第二周,他们的产出已经多到很难在每日更新里总结清楚了,最忙的几天,一天合进去200多个改动。Claude一直在提新的benchmark,大约三分之一的PR里都带着新增的遥测或者护栏,而每多一个测量工具,就会冒出更多的线程和更多的机会。

所有事情都在一个频道里公开进行,他们在彼此的线程里进进出出,争论决策,也庆祝战果。消息慢慢传开了:别的团队开始把自己的改动拿到这个频道里,请它帮忙做性能审查。因为冲刺里加上的那些护栏和Claude skill,新项目在写的时候,就不知不觉按更高性能的方式写了。

5、搭建安全护栏

这个速度他们事先是有准备的。他们动的几乎每一处都是热路径(首次绘制、输入框、对话区),所以安全机制是一开始就定好的:每个PR都要过自动审查,外加至少一个人批准;单元测试永远先于优化;任何可能造成用户可见问题的改动,都放在一个短期的功能开关后面。

开关越攒越多,他们就专门开了一个线程来协调这些开关的放量和清理。Claude把每个开关分成两类,急停开关(kill switch)或者逐步放量开关(ramp),只要安全了就立刻下线。两周里他们一共加了将近200个功能开关,冲刺结束时,一半以上已经清理掉了。

他们也清楚,在一个变化很快的代码库里,性能上的战果是会慢慢流失的,而Anthropic的代码上线速度又特别快。所以一个项目只要证明有效,他们就会投入力气去保护它。拿那个静态输入框来说,它的设计本身就很脆弱:用户几乎一打开页面,看到的就是一份HTML做的页面副本,然后React直接在它上面绘制真正的页面。

只要React渲染出来的结果差了哪怕一个像素,这个效果就破了。所以Claude给它搭了几十道护栏,比如:

  • 静态的HTML,是在jsdom里渲染真正的React组件生成出来的,有一个测试保证两者永远不会走样;
  • 一套集成测试在14种视口尺寸下,把静态页和React渲染的页面逐一比对,要求对齐误差在1像素以内;
  • 一个按键测试,会在两者交接的那一刻持续打字,只要丢了一个键或者顺序乱了,测试就失败;
  • 在线上,每一次交接都会上报偏移量,精确到十分之一像素,只要有一次偏移不是零,Claude就开一个线程去查。

实验室里不可能什么都抓得到,所以他们也用上了最老的那道护栏:逐步放量。高风险的改动先给员工用,再放给1%的用户,最后才是所有人。静态输入框在内部上线4个小时之后,一个同事发了一段录屏,里面有一次布局偏移,他们所有的指标都没看见。他在新标签页里打开claude.ai时,输入框会往下掉一截,但那不是他们的代码造成的:

Marius(18:15):偶尔会看到一次不大不小(大概15到20像素)的纵向布局偏移(把输入框往下推),在新标签页里打开claude.ai时出现(刷新页面时不太会)。我说不清到底是什么导致的,但它确实存在。(附录屏,2秒)

Claude(19:05):在你的录屏里找到了,是Chrome在调整页面大小,不是静态输入框交接给真实输入框这一步的问题(交接这一步在你今天的49次加载里都是0像素)。

  • 在新标签页上,Chrome会在页面下方画一个自己的56像素高的页脚(「由anthropic.com管理 · 自定义Chrome」)。标签页跳转到claude.ai时,这个页脚消失,页面高了56像素,但这件事发生在我们首次绘制之后大约100毫秒。
  • /new页面把问候语和输入框放在页面高度18%的位置,所以它们会往下掉0.18×56≈10像素(你的视频量出来正好是10)。刷新页面时没有页脚可以收起,所以只有新标签页会出现;「偶尔」取决于我们的首次绘制是不是抢在了尺寸调整之前。
  • 它之所以只是「偶尔」,是因为需要Chrome在你还停在新标签页上的时候,就从地址栏开始预渲染这个页面:隐藏的页面按较矮的高度布局,等显示出来之后才调整大小。
  • 这个问题一直都潜伏着,只是页面以前从没这么早画出来过。我们的布局测试看不到它,因为无头Chrome没有浏览器界面可以收起,而且占位页和应用是一起移动的。

原文用的词是「不知怎么地」,Claude就把问题追到了Chrome预测性加载里的一个边缘情况:用户还在地址栏里输入网址的时候,Chrome就已经在后台按当前标签页的高度预渲染页面了;而在被组织统一管理的浏览器上,新标签页因为多了那个页脚,会稍微矮一点。用户按下回车,claude.ai的第一帧显示的就是这个稍矮的布局,大约十分之一秒之后,Chrome再把它调整回正常大小。Claude把布局在这次尺寸调整前后固定住,他们又加了一个测试来模拟这套预渲染流程。

6、人类掌舵

这个循环产出很高,但它不是自主运行的。让它保持快、保持安全、不跑偏,是人的活,原文分成了三部分。

野心。Claude默认对范围很谨慎:发现了问题先记成工单,对可行性总是留余地,估时也往宽了报。但他们对自己的护栏有信心,所以他们做的很多事(尤其在前期),是鼓励Claude更大胆一点:

Claude(15:32):好,一个小PR,让Code也有Chat和Cowork已经有的那些计时标记。我这周内提上去;现实一点说,Code的数据要等几天,得先合并、部署,再攒出一个基线窗口。

Raymond(15:32):你现在就提的话,我马上给你合并、部署。我们有能力做任何事。请勇敢一点

Claude(15:33):马上,PR一小时内提上来。

目标开始一个个达成之后,他们发现线程会慢下来。Sam就挨个线程去发同一句话:「继续往下压,目标不是终点。下一个是什么?野心大一点。」

品味。每个线程都有一个具名的人负责,任何用户能感知到的变化,Claude都会附上改动前后的截图或者录屏,交给这个人来拍板。表格是一格一格填出来,还是等一整行齐了再显示?加载时的骨架屏是立刻出现,还是半秒之后才出?流式输出的文字逐词淡入,值不值得花掉五分之一的帧预算?Claude负责想办法抠毫秒,取舍由人来权衡。

方向。他们刻意让每个线程保持很窄,只盯一个benchmark或者一类操作,也要求Claude只在这个范围里找改进,用他们自己的话说,这些线程是150把在找钉子的锤子。人做的大部分决定是关于先后顺序和用户影响的:先做哪些界面,互相踩脚的线程怎么合并,一个线程已经边际收益递减了什么时候关掉。有一个900行的PR,得到的回复只有一行:「我拍板:每次发送省2毫秒,不值得维护这个构建插件的复杂度。」

7、挑战8毫秒帧预算

有一个支线任务,能把上面这些东西全串起来。为了演示对实时语法高亮里一条正则的优化,Claude附上了一段在实验室里录的长回复流式输出的录屏,还在角落里加了一个帧率读数,是在页面里用动画帧的时间戳算出来的。

Raymond(14:33):这个bench其实挺酷的。我们是被卡在60fps了吗?你能不能把滚动和流式输出的流畅度冲到120?如果我没理解错,你的测试台可能不支持

Claude(14:34):对,现在的测试台是60Hz,因为无头Chromium默认就是这样。我认为它可以跑到120(解除垂直同步,或者用DevTools控制帧),我先确认这一点,然后按8.3毫秒的帧预算重跑一遍评估。

Claude(14:59):120Hz测试台的进展:成了。用DevTools的begin-frame控制,在无头Chrome里做确定性的120Hz逐帧步进,每帧8.33毫秒,发240个begin-frame正好出240帧,所以「这一帧有没有塞进120Hz的预算」变成了一个精确的读数,不再是一个有噪音的读数。

Raymond(15:05):太强了。开干

机制和野心都到位之后,Claude就开工了。每一帧画面只有8.33毫秒的预算,Claude一帧一帧地步进一条长回复,给每一帧计时,找出慢的部分。它把已经输出完的块缓存起来,去掉了每来一段内容都要按整条消息长度重算一遍的工作;把还在增长的代码块的分词逻辑挪到了worker里;表格改成一格一格地显示出来。

光这一个线程,就合进去将近60个PR。长回复以前一共会阻塞主线程大约750毫秒,现在大约200毫秒,CPU占用降到原来的三分之一左右,在120Hz的MacBook上从头到尾都能稳在120fps。这个120Hz测试台后来成了每晚跑的定时任务,Claude盯着它有没有退化。冲刺结束前,Claude官方开发者账号@ClaudeDevs专门发推说了这件事:

网页端和桌面端的Claude,长回答的流式输出现在流畅了大约4倍。我们重写了流式渲染器,只去动还在变化的部分,所以在一台慢一些的笔记本上,长回复的卡顿少了9倍,最严重的一次冻结短了4.5倍,在120Hz的MacBook上从头到尾都稳在120fps。

原文这一节最后一句是:冲刺开始的时候,他们没打算去爬流式输出时帧与帧之间的那几毫秒,结果发现这个也能数,而任何能数的东西,Claude都能爬。

8、后续计划

现在的claude.ai和桌面App,比8月初快了3倍左右,那些棘轮应该能把它们稳在这个水平。但他们说还没做完:第95百分位(也就是最慢的那5%的用户)、其他类型的操作、特别长的对话,都还有改进空间。他们还预告了另一篇,讲冲刺期间顺着问题追到上游去的那些支线,有些贡献已经落进了Electron、Chromium、Node.js等项目里。

在内部分享结果的时候,Issac的一句话说得最到位:「哪怕是六个月前,你也没法说服我这是可能的。」他们说打算以后一直这样干下去,一次一个线程,不管规模多大。原文最后一句是,那个频道现在还在跑。

(原文末尾还特别感谢了Boris Cherny,理由是他鼓励他们把野心放得更大一点。)

三、经验提炼

1、提出量化目标

对我这种不会写代码的人来说,这条可能是最直接能用的。你跟Claude Code说把这个页面优化得快一点,它会改,改完了到底快没快,你大概也说不清。换成先让它把快这件事变成一个数,比如页面从打开到能点击用了多少毫秒、打包出来的文件有多大、打一个字触发了多少次重新渲染,这件事就从凭感觉变成了能爬山。原文说测量以前是第零步,现在是爬山的第一步,这句放到我们自己的项目里也成立。

2、验证指标有效性

这条我自己摔过两次。

第一次是写作。我给自己的写作流程做过一个「表达指纹」系统,用一个距离指标衡量AI写出来的稿子离我手写的文章有多远,数越小越像我。有一组稿子让AI对着这个指标自检、迭代了4轮,距离压到了0.32;另一组只是写之前读了三篇我的手写文章,一遍写完,距离1.71。按指标算,前一组的距离只有后一组的五分之一,我读下来的感受正好反过来:迭代了4轮的那篇明显更差,一遍写完的那篇好太多。后来这个指标就从目标里撤掉了,只留着查明显问题。

第二次是达尔文.skill。它是我借鉴Karpathy的autoresearch做的skill自动优化器,让一组judge给skill打分,分数涨了就保留改动,跌了就回滚(其实也是一个棘轮)。跑了一段时间发现,同一份一个字都没改的skill,换一个judge来打分,总分能上下摆8分,真实的改进全被这个噪音淹掉了。最后把判断方式改成了让同一个judge拿改前、改后两版对比着看。

回头看Anthropic放弃拿毫秒当CI闸门、改数CPU指令这一步,其实是同一个动作:真实的量太吵,就换一个稳定的量,前提是先证明这两个量挂钩。原文写得很直白,证明不了的benchmark一律下线。

3、锁定已有成果

每次让Claude优化完,顺手让它写一个检查(一个测试、一个脚本都行),把现在的数记下来,以后任何改动让这个数变差就报错。Anthropic那边还多做了一步,每天有个任务,数字降了就把上限自动往下调。这样一来,赢下来的东西就不会在后面的改动里悄悄流失。

4、先建护栏,再扩并发

今年2月Anthropic发Opus 4.6的时候提到了一个蜂群模式(官方叫Agent Teams),我学着开了一个,让它帮我开发一个测试性的复杂产品,然后下楼吃烤鱼去了。一个多小时后回来,8个不停执行的agent不光把我200美元会员的用量烧光了,还额外烧了65美元,我赶紧把它们的电源拔了。

Anthropic同时开着150多个线程,两周3000多个改动没出一次事,靠的就是前面那一整套护栏:每个改动至少一个人审批,单元测试先于优化,用户看得见的改动全放在功能开关后面,高风险的先员工、再1%、再全量,每个线程有一个具名的人负责。我那次的8个agent,一条护栏都没有。

5、明确人的三项职责

Claude默认是保守的,所以工程师要做的第一件事,居然是鼓励它胆子大一点,Raymond那句「请勇敢一点」,还有原文最后专门感谢Boris Cherny「鼓励我们野心更大一点」,说的都是这件事。我给自己所有agent共用的那份规则文件里,也写过意思很像的一句:限制通常不在能力,在于有没有先认定自己要做到那个水准。

品味和方向,则一直留在人手里。表格一格一格出还是一行一行出,由人拍板;900行代码换每次发送省2毫秒,一句话就毙掉。Claude负责把每一个能抠的毫秒都找出来,要不要抠、先抠哪个,是人定的。

6、中文场景的额外收益

破折号那个bug,AI写东西最爱用的就是破折号,这次卡住的正好是Claude自己的页面。不过说起来,汉字也都不在Latin-1里,按原文讲的这个机制,一条中文回复天然就会让整段按双字节存储,所以在这次修复之前,我们用中文跟Claude聊代码,高亮大概一直走的是慢路径,中文用户可能是这次修复受益最大的一批人之一。

7、认清三点局限

也有几件事得说清楚。

一是起点。这篇在Hacker News上最刺耳的一条评论是:先做一个3秒才加载出空白页的网站,再把它优化到1秒,然后给自己鼓掌。这个说法有它的道理,Google给网页定的「良好」线,是最大内容绘制(LCP)在2.5秒以内(同样按第75百分位算),claude.ai冲刺前从打开到能打字要3.1秒,口径不完全一样,但放在这把尺子上,大概是「需要改进」那一档(超过4秒才算差),冲刺后的0.55秒则远在「良好」线以内。

二是工具。Claude Tag目前只对Team和Enterprise客户开放,还是beta,个人订阅用户(包括我)用不上。不过这套方法本身不依赖Slack,Claude Code就够用。

三是它不是全自动的。原文自己也说了,这个循环不是自主运行的,每个线程都有人在管,冲刺前的项目清单和安全机制也都是人提前准备好的,最慢那5%用户的体验、特别长的对话,也还没解决。

四、实战验证

我让agent照着这套方法,给自己的网站提了一遍速。

1、算清慢的代价

网页慢一点到底有多大代价,其实有不少一手研究。

2009年谷歌做过一个实验,故意把一部分用户的搜索结果页拖慢100到400毫秒,这些人每天的搜索次数少了0.2%到0.6%,而且拖得越久少得越多;慢400毫秒那组,延迟撤掉之后的五周里,搜索量平均还比对照组低0.21%。微软必应2013年发表过一次减速实验,结论是每快100毫秒,收入多0.6%,他们内部的说法是,一个工程师把服务器响应提速10毫秒,多带来的收入就够付他一年的全部成本。谷歌2017年还用SOASTA的数据训练过一个模型来估算,移动页面的加载时间从1秒变成3秒,用户跳出的概率会高出32%,到5秒高出90%(这是模型估算,不是对照实验)。

搜索引擎这边也在拿速度给网页排队。百度2017年上线过「闪电算法」,官方公告说,移动页面首屏在2秒之内打开的,给流量倾斜,3秒及以上的会被打压。谷歌从2021年起也把Core Web Vitals这些体验指标用在了排名里,不过官方文档每次都会补一句,相关性永远排第一,体验只在内容差不多的时候起作用。

2、定好测量规矩

我挑了自己4个在线上跑着的网站:公众号排版器(editor.huasheng.ai)、个人主页huasheng.ai、图片工具站img2046.com、教程站bookai.top,每个站派一个agent。规矩参照原文:先定义什么叫打开到能用,先建棘轮和护栏再动代码,目标定成打开到能用的p75少九成。前后两个版本都在我电脑上起服务,按Fast 4G给所有请求限速、清空缓存,交替各测10到25次,取第75百分位;改完确认没引入新问题、确实变快了,才上线。

3、照搬静态输入框

效果最好的是排版器:在实验室里,打开到能打字的耗时从2238毫秒降到209毫秒,少了九成(快了10倍多)。它之前慢,是因为首屏要先从jsdelivr同步下载5个外部脚本,下完之前页面一直是白的。agent用了三招:导出图片、粘贴富文本才用得到的两个库,改成用到的时候再加载;Vue和markdown-it放回自己的域名;还有一招直接照搬了原文的静态输入框,把一个能用的编辑框写进HTML,页面框架还没启动就能打字,启动之后再把已经打的字接过去。

预览区要等框架启动完才出来,这一项从2238毫秒降到1037毫秒,少了53.7%。线上从我自己电脑实测,能打字的时间从3.25秒降到1.52秒,这1.5秒里大约1.4秒是我电脑走代理建连接花掉的,后面细说。

静态编辑框刚出现时是空的,要等框架启动后才把用户上次存的草稿填进去,老用户要是看到空框,以为是新页面,直接粘贴了一篇新文章,旧草稿随后就会被自动保存覆盖。执行的agent只测了持续打字会不会丢字,没测到这一层,是负责复核的agent发现的。修法是编辑框一出现就先把草稿填进去,也补了一个专门的测试,修之前有草稿的场景5次全挂,修之后10次全过。

4、判断优化空间

另外三个站就没这么夸张了。

bookai.top搜索点击最多的那篇ChatGPT合租教程,首屏那张图是两三千像素宽的手机截图,实际只显示753像素,压到合适的尺寸之后,在1440宽的桌面屏幕上,打开到能用从7776毫秒降到1588毫秒,少了79.6%;手机屏幕上那张图不在首屏,前后没差别。顺手还把全站一个400KB、其实只用到6个图标的图标库换成了内联SVG,标题、描述、结构化数据这些SEO字段上线前后逐项比对,一个没变。

img2046的压缩工具页,把只有批量下载才用得到的两个库改成按需加载,打开到能用少了11%,脚本执行时间少了29%。这一步agent自己还踩了个坑,按需加载之后批量下载会报错,是它补测多文件下载时发现的,修完再测,打出来的压缩包跟优化前逐字节一致。

我的个人主页,打开到能用基本没动(少了1.6%,在测量误差以内),头像那张图换成WebP之后,最大内容渲染快了13.4%。修这张图最省事的办法是打开Vercel自带的图片优化,本地一测,头像从55KB压到了15KB,但复核时查了Vercel的文档,免费的Hobby套餐每月只有5000次图片转换,超了之后新图片直接报错,页面上只剩替代文字,最后改成提前把图压好,当静态文件发出去。这个站剩下的空间在字体上(三个字体文件加起来126KB,比那张图大得多),还有域名跳转和Cloudflare这些配置,这次都没动。

四个站里到九成的只有排版器,它的首屏被5个同步脚本整个卡住了。

5、避开测量陷阱

测量这一步踩了三个坑。

一是测量机自己的网络。从我自己电脑量线上,所有网站的首字节时间都在1.4秒上下,一开始agent把这当成了个人主页的主要瓶颈,差点把力气花到服务器上。拿vercel.com当对照站一量,它也是1.4秒,问题出在我电脑走的代理,跟网站无关。

二是屏幕宽度。bookai那张大图,在1440宽的桌面屏幕上正好落在首屏里,是最大内容渲染的那个元素,压缩它就能省下一大截;换成手机屏幕,它掉到了首屏外面,同样的改动测不出任何变化。用哪种屏幕宽度测,结论可以完全不一样。

三是同时开工。4个agent在同一台电脑上跑测速和构建,互相抢CPU。个人主页第一次配对测量用的是固定顺序,每轮都先测旧版再测新版,结果测出来新版反而慢了1.4%,后来改成每轮轮换先后顺序,才拿到可信的数字。

6、领取闪电.skill

这套方法我整理成了一个skill,叫闪电.skill(名字来自《疯狂动物城》车管所里那只叫「闪电」的树懒),8个步骤、测速和棘轮两个脚本都在里面,每一招都标了出处,上面4个站踩过的坑也都写进去了:

https://github.com/alchaincyf/huashu-flash

在终端运行 npx skills add alchaincyf/huashu-flash 就能装上,或者直接把仓库链接丢给你在用的agent,让它帮你装,然后跟它说一句「帮我给某某网站提提速」。

如果你手上有一个自己在做的项目,其实可以不读我这篇,直接把原文链接和这个skill一起丢给你的Claude Code。

原文:https://claude.dev/blog/how-we-made-claude-ai-faster/

这篇读完了,下次实践再见。

花叔的插画头像

AI Native Coder · 独立开发者 · 作者

《一本书玩转DeepSeek》作者,小猫补光灯、女娲Skill生态创作者。不会写代码,用AI做产品,分享独立开发、AI工具与内容创作的实践。

本文收录自微信公众号。在原平台阅读 ↗

返回花叔专栏