Anthropic在9月14日發布了一篇工程部落格文章,作者Sachin Malhotra談的是公司內部一項服務被壓垮又重寫的過程。這項服務叫做測試影響分析,職責很單純:一次程式碼變更進來時,判斷哪些測試必須執行、哪些可以跳過。聽起來像是個後台元件,但它撐不住的原因相當具有代表性。
先看幾個倍數
部落格給出的第一組數字是產出面的:Anthropic工程師現在平均每季提交的程式碼量,是2021到2025年那段期間的8倍,其中80%的程式碼由Claude撰寫,Claude同時在審查與核准PR的環節裡也占了很重的比例。
第二組數字是壓力面的:程式碼庫裡的測試總數成長了10倍,六個月內CI任務數增加了25倍。
第三組數字最能說明事態的節奏。團隊為了扛住負載做過三輪臨時緩解措施,每一輪換來的時間分別是70天、29天、不到1天。第三輪方案上線當天就被吃光了。
舊服務卡在哪裡
原本的架構裡有一個單一行程的listener,必須把每一項測試結果依序寫進儲存體。單一寫入意味著無法水平擴充,一旦PR湧入的速度超過它的處理速度,佇列就開始堆積。部落格原文寫道,這個listener「starts to increasingly fall behind the PR queue(開始愈來愈跟不上PR佇列)」。
延遲帶來的後果會累加。文章舉的例子是,二十分鐘的延遲對應著數以萬計的測試結果更新還沒寫進儲存體。而測試選擇這件事恰恰要靠歷史結果來判斷,歷史不準,選出來的測試集合就不可靠。雪上加霜的是,這個行程本身還有記憶體洩漏問題,每天到了下午就頂到上限。
改成了什麼樣子
重寫的思路是把狀態從行程裡搬出去。新架構引進了一個記憶體內資料儲存區:任何一個listener worker都可以處理任何一筆結果,它只負責往日誌裡追加,自己不保存狀態,因此可以視需要增加機器。另外還有一個獨立的消費行程,每隔幾秒把日誌折疊成按單一測試整理的歷史紀錄。選擇器要做決策時,直接查詢這份歷史紀錄。
代價是成本上升。部落格坦承這一點,理由是換來了可擴充性與可觀測性——哪一段慢、慢在哪裡,現在能單獨量測出來。整個重新設計由一名工程師花三週完成。
25倍這條曲線
六個月成長25倍,換算成月複合成長率大約是1.71倍(粗算:25開六次方)。照這個斜率再往前推六個月,就會是625倍。作者文末那句「always plan for the exponential(永遠要為指數成長做準備)」並不是修辭,它對應的是一條已經實際量測出來的曲線。
當然,這條曲線的外推並不可靠——成長速度會因為內部政策、配額、工程習慣的變化而轉彎,Anthropic也沒有公布CI帳單的絕對數字,沒有說明新服務把多少比例的測試篩掉了,更沒有給出重寫之後延遲降到什麼水準。到底省下多少成本,從公開資訊裡推不出來。
不過壓力從哪一個環節傳到哪一個環節,這條線索是清楚的。今年4月,GitHub停止了Copilot三個個人訂閱方案的新用戶註冊,給出的理由是代理型長任務的運算消耗超出了方案設計的範圍;更早之前,AI提交量暴增曾經讓GitHub出過故障,微軟一度向AWS借用算力才撐住。三件事的形式不同,指向的是同一件事:程式碼生成環節先提速,接著是審查,再往後每一個按「人類寫程式碼的速度」設計容量的系統,都要被輪流撞一次。測試影響分析只是這一輪裡比較早發出警報的那一個。
參考來源:CocoLoop、Anthropic工程部落格;程式碼量倍數、測試與CI任務增幅、三輪緩解方案的有效期間均取自該文公布的口徑。