di Vinay Gaba, Ankit Mathur, Rishabh Singh, Patrick Wendell e Matei Zaharia
In Databricks, il modo in cui sviluppiamo software sta cambiando rapidamente, poiché adottiamo l'AI in modo deciso per l'ingegneria del software. Il panorama dei modelli e degli harness per la scrittura di codice si è espanso rapidamente nell'ultimo anno, offrendo agli sviluppatori più scelta che mai. Con un numero maggiore di opzioni, è diventato sempre più importante capire quali coding agent offrano le migliori prestazioni su task di programmazione reali, oltre a comprendere come le prestazioni sui task varino in base al prezzo.
Questo articolo condivide i risultati e la metodologia del benchmark di coding interno che abbiamo creato in Databricks, che valuta gli strumenti su task di programmazione reali eseguiti dai nostri ingegneri sulla codebase di Databricks. I task includevano modifiche a una codebase di svariati milioni di righe che copre molti linguaggi popolari (Python, Go, Typescript, Scala, ecc.), e sia i task che le soluzioni sono stati attentamente esaminati per garantirne l'accuratezza. Questo non vuole essere un report esaustivo, ma l'esercizio ha fatto emergere insight che hanno già reso il nostro team di ingegneria significativamente più efficiente con i coding agent. Di seguito, puoi vedere i punteggi ottenuti da modelli e harness nel benchmark complessivo:

Figura 1: Costo vs. Prestazioni nel nostro benchmark
Le principali conclusioni della nostra analisi sono state:
Esaminiamo ciascun punto più nel dettaglio.
Piccole differenze di pochi punti nei risultati specifici spesso si compensano nei task del mondo reale. Ci siamo concentrati maggiormente sui pattern tematici che ci aiutano a valutare quali modelli utilizzare per i vari task. Infatti, i risultati hanno mostrato un chiaro raggruppamento dei modelli e degli harness in 3 livelli di capacità.

Figura 2: Dai nostri risultati complessivi sono emersi tre distinti livelli di capacità, con sfumature su quali modelli si sono rivelati efficaci in ciascun gruppo
Nella fascia più alta di prestazioni, vediamo che i modelli più intelligenti sono molto efficaci nel risolvere ogni tipo di problema, ma sono molto costosi. I modelli con intelligenza media e inferiore sono comunque altamente efficaci nei task comuni e, in molti casi, sono anche significativamente più economici.
Giorno dopo giorno, gli ingegneri svolgono molte attività diverse che variano notevolmente in complessità: i task operativi comuni, come l'attivazione di un flag o l'aggiornamento delle configurazioni, non richiedono modelli estremamente intelligenti, a differenza di esplorazioni di progettazione più approfondite. Tuttavia, in passato, i nostri modelli predefiniti erano sempre quelli più costosi. Sulla base di questa analisi, abbiamo stabilito che dovremmo affidare più lavoro alla classe di modelli Haiku e GPT 5.4 Mini.
C'è stato molto entusiasmo intorno a GLM 5.2, e i nostri risultati hanno dimostrato che GLM può essere un modello di riferimento quotidiano per molti dei nostri sviluppatori. Si è posizionato nel livello di capacità più alto, statisticamente alla pari con Opus 4.8 in termini di qualità, ma con un costo di 1,28 $ per task rispetto ai 1,94 $ di Opus.
I punteggi di qualità di GLM sono coerenti con i feedback qualitativi che abbiamo ricevuto dagli sviluppatori interni che hanno testato GLM per lo sviluppo quotidiano. Date le sue ottime prestazioni nei task di programmazione di tutti i giorni, ci siamo concentrati sul servire GLM con le migliori prestazioni, e l'evidenza dimostra che è giunto il momento di iniziare a distribuirli come strumenti di riferimento quotidiani per il coding.
Gli sviluppatori spesso valutano a occhio i costi dei token per determinare quanto sarà costoso un modello nel completare i task di coding. Abbiamo scoperto, tuttavia, che i costi dei token sono spesso un indicatore scarso dei costi complessivi dei task, a causa della variazione nell'efficienza di ragionamento tra i modelli. Ciò sottolinea la necessità di un benchmarking a livello di task, poiché la forma e la complessità dei task possono variare in contesti diversi.
Ad esempio, Sonnet 5 è circa 1,7 volte più economico per token rispetto a Opus 4.8, ma, sui nostri task, abbiamo riscontrato che Sonnet è costato 2,09 $ per task contro gli 1,94 $ di Opus, ottenendo un punteggio inferiore di sei punti nel completamento dei task (81% contro 87%). Ciò è dovuto principalmente al fatto che Sonnet 5 ha lavorato più a lungo e ha letto di più per raggiungere l'obiettivo, consumando 1,9 volte più token.
Quando abbiamo eseguito lo stesso modello con lo stesso sforzo di elaborazione attraverso due diversi harness (Claude Code/Codex vs Pi), abbiamo osservato che il costo per task differiva in modo significativo (più del doppio in alcuni casi), mentre la qualità rimaneva invariata. La differenza principale risiedeva nella quantità di contesto che ciascun harness forniva al modello a ogni turno.

Pi ha inviato circa 3 volte meno contesto per turno. Ha gestito meglio il contesto, mantenendo un working set più ristretto e completando i task in meno passaggi.
La lezione qui non è che un harness sia sempre più economico o che gli harness nativi siano peggiori. Al contrario, la scelta del modello è solo un pezzo del puzzle. Stabilire questa flessibilità è il motivo per cui abbiamo investito in Omnigent per rendere immediati gli scambi tra modalità e harness.
I benchmark pubblici come SWE-Bench e TerminalBench sono utili, ma non possono rispondere alle domande che avevamo. Ci sono diversi motivi per questo:
Creando un benchmark sulle nostre PR, possiamo prendere queste decisioni con maggiore sicurezza di non ostacolare i nostri sviluppatori introducendo ottimizzazioni.
Abbiamo utilizzato Unity AI Gateway per acquisire i log di tutte le nostre interazioni di coding, il che ci ha permesso di analizzare la complessità dei task affrontati dagli ingegneri che utilizzano i coding agent. C'era una notevole diversità nella complessità dei task: circa un quarto è stato classificato come lavoro a bassa complessità e circa il 60% a media complessità.

Tuttavia, i modelli costosi sono quelli predefiniti utilizzati dagli ingegneri, quindi c'era chiaramente un'enorme opportunità per migliorare l'efficienza.
I nostri ingegneri integrano migliaia di modifiche al codice ogni giorno, quindi disponiamo già di un ottimo dataset di partenza. Una buona pull request è un elemento ricco di informazioni, con commit che mostrano l'iterazione dello sviluppatore, la revisione da parte di persone e test che aiutano a verificare che una modifica al codice sia fedele al suo intento. Tuttavia, abbiamo avuto bisogno di diversi controlli di qualità e filtri per ricavarne un benchmark di alta qualità:

Una volta ottenute le PR candidate, ci siamo concentrati sulla creazione di attività ben specificate:
Il risultato di questo esercizio è stato una singola attività nel benchmark. Ecco un esempio semplificato:
Anche se abbiamo utilizzato script e AI per generare le attività candidate, abbiamo valutato ogni campione manualmente. In alcuni casi, abbiamo riscontrato che i test nella PR originale dovevano essere riscritti per consentire un'implementazione alternativa o per essere più rigorosi, cosa che abbiamo fatto manualmente (senza AI). Allo stesso modo, abbiamo riscontrato casi che richiedevano il miglioramento della descrizione dell'attività per renderla ben specificata.

Figura 3: Un prima e dopo della nostra suite di test: il test precedente si basava sulla verifica della corrispondenza esatta della stringa, il che ha causato alcuni fallimenti quando il modello ha cercato di risolvere l'attività. Questo non era un buon modo per testare l'output non deterministico, quindi è stato riscritto per valutare invece il comportamento.
Abbiamo istanziato gli harness e i modelli degli agenti di codifica utilizzando le loro configurazioni standard pronte all'uso, con tutti gli strumenti comuni che gli ingegneri di Databricks avrebbero a disposizione.

Quando l'agente indicava esplicitamente di aver completato l'attività, creavamo un checkpoint di quel codice, applicavamo le patch ai test che erano stati esclusi e valutavamo i test per determinare se l'attività fosse superata ("pass") per quella combinazione di modello + harness. Non abbiamo affatto utilizzato un giudice LLM per valutare la correttezza, poiché abbiamo riscontrato che questo premia il sembrare corretti rispetto all'esserlo davvero.

Nei nostri primi esperimenti, i punteggi di alcuni modelli sembravano troppo belli per essere veri, quindi abbiamo ispezionato manualmente le tracce per capire cosa fosse successo in queste traiettorie degli agenti. Abbiamo scoperto che, a causa della nostra configurazione originale, l'implementazione "corretta" era ancora recuperabile nella cronologia Git del worktree! Ogni attività aveva origine da un commit unito (merged), quindi nulla impediva a un agente dotato di shell di scorrere in avanti la cronologia di Git per trovarla. Per risolvere questo problema, abbiamo sigillato la cronologia di Git: per la durata di ogni esecuzione, abbiamo isolato completamente la copia di lavoro dal repository.
Siamo partiti da una domanda semplice: possiamo utilizzare gli agenti di codifica in modo più efficiente? La risposta è un sì definitivo e, poiché possiamo basarci sui dati, possiamo iniziare a sviluppare funzionalità per selezionare automaticamente i modelli giusti e monitorare l'efficienza.
Qualsiasi azienda può fare lo stesso. Qualsiasi team con un backlog di PR unite ha già a disposizione un benchmark su cui nessun modello è stato addestrato, valutato in base ai test scritti dal proprio team. Stiamo aggiungendo attivamente altre attività (soprattutto quelle più difficili) e prevediamo di testarvi ogni nuovo agente/harness per essere più sicuri delle nostre scelte.
In Databricks siamo sempre stati diffidenti nei confronti del lock-in, non solo verso i fornitori, ma anche verso i presupposti che rendono i team meno flessibili nel tempo. Questo stesso istinto ha guidato le nostre prime scommesse su formati e standard aperti, e influenza il modo in cui stiamo approcciando l'AI ora: misurare ciò che funziona effettivamente sul codice che rilasciamo, dare agli ingegneri lo spazio per passare da un modello all'altro e harness con misure di sicurezza coerenti, ed effettuare ottimizzazioni per utilizzare l'AI in modo efficace.
In un prossimo post del blog, parleremo più approfonditamente di come stiamo utilizzando le funzionalità di routing intelligente in Unity AI Gateway e in Omnigent per aiutare i nostri sviluppatori a utilizzare gli agenti più intelligenti mantenendo l'efficienza.
(Questo post sul blog è stato tradotto utilizzando strumenti basati sull'intelligenza artificiale) Post originale
Iscriviti al nostro blog e ricevi gli ultimi articoli direttamente nella tua casella di posta.