〈X〉-EP-here's how i shipped 2,500 PRs last month to production

https://x.com/poteto/status/2102050467505430555

Lauren(@poteto)上個月把 2,500 個 PR 送進 production。標題寫 2,500,她在台上講 2,000,兩個數字指的是同一個月。她開場自己就說,這是有點瘋狂的一個月。但她想講的不是產能,是信任。

她在 xAI 做 Cursor 相關的產品工作。六個月前她剛加入 Cursor 團隊,那時 Cursor 還不屬於 xAI。回頭看,她做的每個 skill、每件工具、每一次 codebase 的改動,疊起來都是同一件事:她在學著信任她的 agent。

米其林廚房,不是軟體工廠

她不喜歡「軟體工廠」這個詞,講到後半段索性把它從投影片上劃掉。在她眼裡,技術人不是在組裝線上量產同一個東西,蓋產品這件事有創作的成分,某種程度上是藝術。她更喜歡的比喻是米其林廚房。

在廚房裡,你不再親手處理每一個進到成品裡的零件,可是端出去的那道菜還是你負責。所以重點移到廚房怎麼設:line cook 跟 sous chef 怎麼站、設備到什麼等級、受過什麼訓練,連洗碗的人跟煮菜的人要配幾個都要算。這些都會決定最後那道菜長什麼樣。

瓶頸是她自己

六個月前,Cursor 正在做 IDE 的替代品,也就是新的 agent window。在她加入之前,它有不少效能問題,她的主管問她能不能幫忙。她之前在 React 團隊待過一段時間,看起來正合適。

真的跳下去才發現整個流程有多手工。她本來就做過效能工作,但 PR 進來的速度讓她覺得那是一道永遠在長高的牆,她根本不知道 app 的效能是不是正在退步。她大半時間掛在 Chrome DevTools 前面,錄 performance trace、抓 heap snapshot,手工到她自己都受不了。有一天她忍不住想:我們明明有 agent,我在幹嘛?

於是她開始想 verification skill。能不能讓 agent 自己把 app 跑起來、自己收 trace、自己看懂 trace、自己找出 hotspot,然後自己往效能更好的方向爬?六個月下來,她的產出跟剛開始完全是兩回事。她說她從來沒有立志一個月要送兩千個 PR,那完全不是她的目標;是那些 skill、那些工具、那些 codebase 的改動,一層一層疊出同一件事:信任。

她說她心裡一直有一句話:「我才是瓶頸。」所以她要做的,是把當工程師累積下來的知識盡量倒進她那隊 agent,讓她不必是每一件事的關卡。

從顧 1 到 5 個 agent,到想開 100 個

一開始她在最低的那一格:一次顧 1 到 5 個 agent。每一段對話都要盯,agent 走偏就拉回來;人不在旁邊,基本上什麼都不會發生,或者發生錯的事。她說這一格其實最難離開,因為你不太看得出要怎麼離開。

真正卡住的是信任。你還沒信任 agent 做出來的東西,就想一次 spawn 一百個 subagent,下場會是一堆品質很差的 PR、一堆 regression、一堆 bug,然後沒有人會開心。

verification 有光譜,最低的那一端就能走很遠

在她口中,verification 是有層次的。低的那一端就是 verification skill:教 agent 怎麼把 app 跑起來,用 Chrome DevTools protocol,或你手邊任何一套除錯協定,教它 debug、收 performance trace、抓 heap snapshot。

光譜的另一端硬得多,也還是個開放問題:formal verification。靠 formal methods,或用 Lean、TLA+ 這類語言,去確認商業邏輯的 invariant 永遠成立、app 永遠停在正確的狀態。她說得很直白,真有能力走 formal methods 的人非常少;但就算沒有,光靠 verification skill,能走的路已經很遠。

ControlGlass:一支 CLI,加一張功能地圖

她在 Cursor 做的第一個 skill 叫 ControlGlass,內容就是上面那套:用 Chrome DevTools protocol 教 agent 跑 app、收 trace。

這個 skill 後來長成兩個零件。第一個是 CLI。理由很實際:要 agent 每次都能重現地跑起 app、收到 trace、收到「這段 code 真的有用」的實證,就不能讓它每個 session 自己現寫一份腳本,那代表每個 session 拿到的東西都不一樣。CLI 放進 skill 目錄,agent 每次用同一支;而且你得真的投資把它做好,讓它撐得住各種使用情境。

第二個零件是 feature map,這個詞是她自己取的。起點是很日常的場景:Slack 上有人丟一張截圖,只拍到 UI 的一小角,後面掛三個問號。agent 有 control skill,app 跑得起來,但它只能猜使用者到底在講什麼。feature map 有點像網站的 sitemap,她說這是一種 materialized memory:這個 app 怎麼運作、有哪些功能、使用者靠鍵盤快捷鍵還是點哪個 DOM 元素走到那個功能、每個功能在做什麼。它放在 skill 目錄裡,跟 codebase 一起,另外有自動化在維護。

CLI 加上 feature map 之後,agent 除了能重現地控制 app、收 trace,還聽得懂內部和外部使用者丟過來的需求。這個組合後來變成團隊的關鍵基礎設施,他們持續花力氣保養。她說讓 agent 能驗證自己的工作,力量非常大,對建立信任來說也是。

寫得對,不等於寫得好

verification 管的是正確性。結帳按鈕按下去會不會真的結帳、這段 code 有沒有做到你要它做的事,verification 給你實證。但它不會告訴你效能如何、code 品質如何。

所以她把腦筋動到另一邊:教 agent 像真的軟體工程師那樣工作。她做了一個 plugin 叫 PStack,裡面是一組 skill,靈感來自她做工程時真正在用的工作流。debug、做功能、prototype,各種任務各有自己的 playbook,教 agent 用你想要的方式寫 code。她說這一塊正是團隊裡資深工程師最能貢獻的地方:把做法收進 team repo 的 skill,agent 就跟著變聰明。verification skill 加上這些 playbook,agent 可以自己確認做對了,也可以確認做得好;也因為有 verification,效能數字、統計、telemetry 都是量出來的,不是感覺。

建立信任的順序,從硬到軟

她說這些東西排起來是一條線,一端最硬、最不容易被繞過,另一端最軟。

硬的那端是 codebase,她認為那是最好的記憶體。agent 喜歡沿著它看到的 pattern 往外長,它讀進來、開起來的檔案就在 context window 裡;你不會看到它每個 PR 都順手幫你重構,它只會把眼前看到的東西接下去。

往中間走是 static analysis:linter、compiler diagnostic、CI。用法很具體。每次你糾正 agent,糾正完它還是犯同一個錯,那就把那個錯寫成一條 lint rule;更好的做法是改 codebase,讓那個錯在結構上根本做不到。

再往軟的那邊是 rules、BugBot 跟 skills。這一層的約束力弱一點,主要靠引導。agent 大部分時候會用,但它可能因為各種原因忘了讀某一條 rule,也可能是操縱它的人選擇不理。

最軟的一端是 style guide,只靠人在 code review 裡擋。以現在 PR 進來的速度,要人記得每一條慣例、看過每一行改動,就是不可能。她不建議只靠這一層;但人審時發現的洞,正好指出前面幾層還缺什麼。

codebase 是 agent 的記憶體,壞 pattern 會像病毒一樣長

同一個記憶體,反過來的事也成立:裡面只要有一個 anti-pattern,它會像病毒一樣擴散。一個小小的 workaround,旁邊配一行解釋這個 workaround 的註解,agent 很愛照抄;幾天、幾週之後你會發現那個 workaround 長滿整個 codebase,變成所有 agent 的預設做法。她說那是一個非常糟的位置。

她還有一個比喻是花園。看起來無害的 workaround 一開始只有一棵,因為 agent 的天性,它會被複製再複製,很快你就得到一座 vibe code 出來、maintain 起來很痛、效能問題一堆的 codebase。所以她主張每個團隊都需要一個角色,她叫它 gardener:有人要一直盯著這座花園,在雜草跟害蟲剛冒頭的時候就處理掉,不要等它們長滿。

她舉的例子小到有點意外:agent 在 code 裡留註解。她一開始看到也不太喜歡這些東西,覺得多半是 slop,但也幫 agent 想過理由,人本來就會在棘手的地方留幾個字給自己或同事,應該還好吧。後來她發現,agent 是把旁邊那行註解當成「所以這裡不用真的解掉問題」的正當理由,拿 OK 繃把問題貼過去。所以在 Dune 裡,他們選擇直接禁止註解。

Dune:讓簡單的路就是對的路

Dune 是團隊自己蓋的 client framework,撐起他們的桌面 app,一部分靈感來自 Cursor agent window 那些效能問題。他們得到的關鍵原則是:agent 很愛走捷徑,那就設計一個框架,讓捷徑本身就是正路。

這樣的 codebase 對人來說可能不太好待,能寫什麼、不能寫什麼鎖得很死;對 agent 來說卻接近完美,尤其是手上 context 很少的那種。她提醒,現在會進 codebase 貢獻的人已經不全是工程師,可能有設計師、PM,甚至 CEO;你要讓一個很忙、幾乎沒有 context 的人操縱的 agent,預設就做出對的事。

Dune 的規矩繞著三件事。已經欠下的技術債要刪。大多數受祝福的寫法只留一條 paved path,讓 agent 不用猜,而且 codebase、CI、lint rule 裡都要有足夠引導,把它導上那條路。看到技術債或壞 pattern,直覺反應是「我要寫一條 lint rule 擋它」;你不一定要馬上清乾淨,但 lint rule 至少先止血,擋住它繼續長,清潔另外找時間做。目標是讓 codebase 一直停在「如果下一個 agent 照抄這裡,你會很開心」的狀態。

架構上,Dune 把邊界畫得很硬。功能全部收在同一個資料夾;React 那側有一個 entry point,可以想成 route;有出現在 app 裡的 transcript 區塊,有跑在 VM 上的 host,還有撐起整個 app 的 client。跑在 Electron main process 的東西不准跑到 renderer thread,這是從 Cursor agent window 學來的教訓:偶爾會有 code 不小心被 import 進 renderer thread,把 UI 拖慢。renderer 要一直保持順,不能有 long task,60 fps 的預算是 16 毫秒,120 fps 只剩 8 毫秒。這條邊界是用 import dependency graph 擋下來的,不是靠大家記得。

最後她說,Dune 本身沒那麼重要;重要的是自己家有一個 agent-friendly framework 這件事。你可以把團隊最強工程師身上的 tribal knowledge,從 style guide 和 code review 的留言裡挖出來,寫進框架、寫進 codebase,讓下一個進來的 agent 自然而然沿著它走。

外圈交給 bot,內圈交給 Cursor

前面都做完,就可以往外接自動化。她的分法是外圈跟內圈。

外圈是那隻接了一堆 connector 的 bot:Slack、Datadog、Sentry、PlanetScale,你手上在用的服務都接進去,讓它把資訊聚在一起,替自己做出好決定。有人把這種東西叫 company brain,她覺得不需要做到那麼複雜;agent 本來就很會用工具,connector 接上去,讓 bot 自己去踢 cloud agent 起來做事,其實不用投資太多基礎設施。routines 可以訂閱 Slack thread,也可以訂閱 Sentry alert,事件一進來就自動起動。

內圈是 Cursor:automations 加上它們的 SDK,可以再長出別的 bot,重複使用你已經建好的 agent infra,去做更複雜的任務。

這些東西會互相複利。codebase、rules、skills 疊得夠厚,外圈的事件進來、bot 起 cloud agent、cloud agent 用同一套 skill 驗證自己的工作,跑出來的結果是自動重現 bug report、自動開 PR。她說對整個團隊來說,這是實實在在的加分。

下次你伸手去修 agent 的時候

收尾她回到那張圖,說如果整場只帶走一件事,就是這個。

每次你發現自己又在糾正 agent、又在插手,先停下來問:這一下修在哪一層最有效。而且要照順序問。先問能不能用 codebase、架構、資料結構讓這件事結構上做不到;做不到,再看 static analysis;還不夠,才往上疊 rules、BugBot、skills。

照這個順序做久了,你會走到一個狀態:你信任這個環境到某個程度,agent 就可以自由了。她說這裡沒有什麼秘密,就是很多苦工。你每次伸手去修正 agent,其實都是環境在告訴你它還缺哪一層;把那一層補上,下一次你才不用再修同一個東西。如果你還在全程盯著對話,先懷疑環境,不要先懷疑 agent 的智力。