L'ingegnere lineare Mufeez Amjad ha pubblicato un resoconto dettagliato di come l'azienda ha rielaborato la sua pipeline di integrazione continua dopo che gli agenti di codifica AI hanno trasformato la CI nel suo peggior collo di bottiglia, riducendo il tempo di attesa delle richieste pull da più di sei minuti a poco più di cinque mentre le sue suite di test sono quasi quadruplicate dall'inizio dell'anno.
Il post, pubblicato sul blog di ingegneria di Linear il 21 settembre, iniziava, come spesso accade, con un messaggio conciso dall'alto. All'inizio di quest'anno, Amjad ha aperto Linear per scoprire che Tuomas, il CTO dell'azienda, gli aveva assegnato un problema intitolato "I costi della CI sono alti" - e gli aveva chiesto di rendere la CI più veloce già che c'era. Per ulteriori informazioni su questa storia, consulta la nostra copertura del settore dell'intelligenza artificiale in corso.
Quando gli agenti superano la convalida
Il problema è strutturale, non incidentale. "Gli agenti hanno reso esponenzialmente più veloce la spedizione del codice", ha scritto Amjad, "ma la convalida di tali modifiche non ha mantenuto lo stesso ritmo". Ogni richiesta pull deve ancora passare attraverso la CI, quindi con l'accelerazione dello sviluppo, la CI diventa il punto di strozzatura, facendo aumentare i costi dell'infrastruttura e lasciando gli sviluppatori e i loro agenti in attesa di feedback più a lungo.
Lineare ottimizzato per due parametri: quanto tempo un PR attende su CI e quanto tempo runner consuma. I risultati dopo mesi di lavoro: nonostante le suite di test siano quasi quadruplicate da gennaio, il tempo di attesa delle richieste pull è sceso da più di sei minuti a poco più di cinque, e il tempo di esecuzione per test è stato ridotto all'incirca della metà.
Il lavoro rientrava sostanzialmente in quattro categorie: infrastruttura e strumenti migliorati, ottimizzazione dei lavori che vincolano altri lavori, riduzione delle configurazioni ripetute e maggiore efficienza nell'esecuzione dei test. La base di codice di Linear è principalmente TypeScript, ma molte delle ottimizzazioni si applicano a linguaggi e toolchain diversi.
Macchine più veloci e compilatore nativo
Alcuni dei primi miglioramenti non richiedevano quasi alcuna ottimizzazione dell'IC stesso. Lo spostamento dei carichi di lavoro da GitHub Actions a runner di terze parti con CPU più veloci, storage con prestazioni più elevate e una migliore infrastruttura cache ha dato i suoi frutti immediatamente: in un confronto comparabile dei due giorni su entrambi i lati del passaggio, i lavori sono stati eseguiti in media il 34% più velocemente, con alcuni carichi di lavoro come "tsc" in calo del 52%.
La modernizzazione della toolchain ha contribuito alla vittoria. Passando a `tsgo`, il compilatore nativo di TypeScript, si è ridotta la mediana settimanale del controllo di tipografia del 73%, abbastanza grande da eliminare completamente il collo di bottiglia del controllo di tipografia.
Linting senza il grafico del tipo
La lanugine è stata un altro dei primi obiettivi. Una manciata di regole ESLint personalizzate di Linear dipendevano dalle informazioni sul tipo TypeScript, che costringevano ogni esecuzione di lint a costruire l'intero grafico di tipo prima di valutarle, rendendo l'linting uno dei lavori CI che richiedono più memoria.
Il team ha riscritto le regole per utilizzare l'analisi statica sull'albero della sintassi astratta, identificando costrutti simili a funzioni e modelli di guardia senza alcuna informazione sul tipo. Ciò ha consentito a ESLint di eliminare completamente TypeScript, riducendo il tempo di lint dell'API del 68% e il tempo di lint dell'intero repository del 55%, con un sostanziale calo dell'utilizzo della memoria. Ha inoltre facilitato la successiva migrazione a Oxlint, riducendo ulteriormente i minuti dei corridori CI spesi per la formazione di pelucchi.
Restringimento del percorso critico
Con i controlli individuali più rapidi, Linear ha ridotto lo zoom e ha trattato la CI come un sistema. Ciò ha attirato l'attenzione sui piccoli lavori che si trovano davanti a tutto il resto: il rilevamento del cambiamento di percorso e i controlli della cache dei risultati dei test che si verificano a livello di lavoro, il che significa che nessuno degli otto frammenti di test API può iniziare fino al termine.
Le correzioni erano granulari ma aggiuntive. Il limite della profondità di recupero ha portato il gate più lento da 94 secondi a 20. La rimozione completa del checkout dai lavori che non avevano mai avuto bisogno di un albero di lavoro li ha ridotti da 27 secondi a 7. Un checkout scarno e senza blocchi con cronologia limitata ha risparmiato altri 11 secondi e passa per eventi push e merge-queue. Nel complesso, la durata media del processo di rilevamento delle modifiche è scesa da 26 secondi a 8, il suo p90 da 31 a 12 e la sua esecuzione più lenta da 138 secondi a 37.
Anche l'affidabilità del checkout necessitava di miglioramenti: poiché i corridori di terze parti si trovano all'esterno della rete di GitHub e si affidano a un collegamento IP diretto, il degrado intermittente del collegamento occasionalmente bloccava i recuperi. Linear ha sostituito `actions/checkout` con la propria azione composita che riprova con il backoff, imposta `GIT_HTTP_LOW_SPEED_LIMIT` e `GIT_HTTP_LOW_SPEED_TIME` in modo che una connessione bloccata si interrompa dopo circa 30 secondi invece di bloccarsi e utilizza una cache di checkout che mantiene un mirror git persistente su un disco fisso.
Una soluzione sottile ha eliminato il tempo sprecato nella coda di unione: i marcatori di cache venivano scritti come parte del controllo finale prima della fusione, quindi un PR poteva restare in coda anche dopo aver superato i test. Lo spostamento di quella scrittura in un processo senza gating ha ridotto di 42 secondi il percorso di unione per ogni richiesta pull API e voce della coda di unione. Insieme, queste modifiche hanno richiesto circa un minuto di riduzione dei controlli richiesti per le PR API sugli errori di cache, riducendo al contempo gli avvii dei corridori.
Meno secondi sprecati per lavoro
L'ultima categoria ha attaccato i costi di installazione ripetuti in ogni lavoro. Ciascun frammento di test API ha impiegato dai 7 agli 8 secondi per installare lo stesso client Postgres con apt ad ogni esecuzione; spostandolo in una piccola immagine base CI accanto a Node significava che gli shard potevano essere pronti per essere eseguiti. Il team ha successivamente aggiunto intestazioni di build native all'immagine dopo aver scoperto che il loro download durante la configurazione poteva occasionalmente bloccarsi.
Perché ha avuto risonanza
Il post ha colpito gli sviluppatori: è arrivato sulla prima pagina di Hacker News, raccogliendo circa 250 punti e circa 280 commenti in un giorno. La reazione è facile da spiegare: l'esperienza di Linear menziona un costo dello sviluppo assistito dall'intelligenza artificiale che la maggior parte delle organizzazioni ingegneristiche sta affrontando solo ora. Gli agenti che generano richieste pull in pochi minuti attendono ancora su pipeline di convalida progettate per la cadenza umana e ogni minuto di tale attesa viene moltiplicato per ogni agente che lavora in parallelo.
La lezione dalla rielaborazione di Linear è che il collo di bottiglia è mobile, ma solo attraverso l'accumulo poco affascinante di molte piccole correzioni - corridori più veloci, controlli di tipografia più economici, regole di lanugine a livello di sintassi, fetch limitati, checkout resilienti, immagini precostruite - piuttosto che qualsiasi singolo proiettile d'argento.
---
Stai al passo con l'intelligenza artificialeRicevi le ultime notizie, analisi e scoperte sull'intelligenza artificiale, tutto in un unico posto.
Leggi altre notizie sull'AI →