par Vinay Gaba, Ankit Mathur, Rishabh Singh, Patrick Wendell et Matei Zaharia
Chez Databricks, notre manière de concevoir des logiciels évolue rapidement à mesure que nous adoptons massivement l'AI pour l'ingénierie. Le paysage des modèles et des harnais pour la génération de code s'est rapidement développé l'année dernière, offrant aux développeurs plus de choix que jamais. Avec la multiplication des options, il est devenu crucial de comprendre quels agents de codage offrent les meilleures performances sur des tâches de codage réelles, et de saisir comment ces performances varient en fonction du prix.
Cet article présente les résultats et la méthodologie du benchmark de codage interne que nous avons développé chez Databricks, qui évalue les outils sur des tâches de codage réelles réalisées par nos ingénieurs sur la base de code de Databricks. Les tâches comprenaient des modifications sur une base de code de plusieurs millions de lignes couvrant de nombreux langages populaires (Python, Go, Typescript, Scala, etc.), et les tâches comme les solutions ont été minutieusement examinées pour garantir leur exactitude. Cette étude ne se veut pas exhaustive, mais l'exercice a mis en lumière des enseignements qui ont déjà permis à notre équipe d'ingénierie de gagner considérablement en efficacité grâce aux agents de codage. Ci-dessous, vous pouvez voir les scores obtenus par les modèles et les harnais sur l'ensemble du benchmark :

Figure 1 : Coût vs performance sur notre benchmark
Les principales conclusions de notre analyse sont les suivantes :
Examinons chacun de ces points plus en détail.
Des écarts de quelques points dans les résultats spécifiques se lissent souvent dans les tâches réelles. Nous nous sommes plutôt concentrés sur les grandes tendances qui nous aident à déterminer quels modèles utiliser pour différentes tâches. En fait, les résultats ont montré un regroupement clair des modèles et des harnais en 3 niveaux de capacité.

Figure 2 : Trois niveaux de capacité distincts sont ressortis de nos résultats globaux, avec des nuances quant aux modèles efficaces dans chaque groupe
Au sommet des performances, nous constatons que les modèles les plus intelligents sont très efficaces pour résoudre toutes sortes de problèmes, mais ils sont très coûteux. Les modèles d'intelligence moyenne et inférieure restent très efficaces pour les tâches courantes et, dans de nombreux cas, ils sont également nettement moins chers.
Au quotidien, les ingénieurs effectuent de nombreuses tâches de complexité très variable : les tâches opérationnelles courantes, comme l'activation d'un flag ou la mise à jour de configurations, ne nécessitent pas de modèles extrêmement intelligents, contrairement aux explorations de conception plus approfondies. Pourtant, par le passé, nos modèles par défaut étaient toujours les plus coûteux . Sur la base de cette analyse, nous avons déterminé que nous devions confier davantage de travail aux modèles de la catégorie Haiku et GPT 5.4 Mini.
Il y a eu beaucoup d'enthousiasme autour de GLM 5.2, et nos résultats prouvent que GLM peut être un modèle de choix au quotidien pour beaucoup de nos développeurs. Il s'est classé dans le premier niveau de capacité, à égalité statistique avec Opus 4.8 en termes de qualité, mais pour un coût de 1,28 $ par tâche contre 1,94 $ pour Opus.
Les scores de qualité de GLM sont cohérents avec les retours qualitatifs de nos développeurs internes qui testent GLM pour leur développement quotidien. En raison de ses excellentes performances pour les tâches de codage de tous les jours, nous nous sommes concentrés sur servir GLM avec les meilleures performances, et tout indique qu'il est temps de commencer à les déployer comme outils de travail quotidiens pour le codage.
Les développeurs évaluent souvent à l'œil nu le coût des tokens pour estimer ce que coûtera un modèle lors de la réalisation de tâches de codage. Nous avons cependant constaté que le coût des tokens est souvent un mauvais indicateur du coût global de la tâche, en raison des variations d'efficacité de raisonnement entre les modèles. Cela souligne la nécessité d'un benchmark au niveau de la tâche, car la forme et la complexité de la tâche peuvent varier selon les contextes.
À titre d'exemple, Sonnet 5 est environ 1,7 fois moins cher par token qu'Opus 4.8, mais sur nos tâches, nous avons constaté que Sonnet coûtait 2,09 $ par tâche contre 1,94 $ pour Opus, tout en obtenant un score inférieur de six points sur la complétion des tâches (81 % contre 87 %). Cela s'explique principalement par le fait que Sonnet 5 a travaillé plus longtemps et a lu davantage pour y parvenir, consommant 1,9 fois plus de tokens.
Lorsque nous avons exécuté le même modèle avec le même effort de réflexion via deux harnais différents (Claude Code/Codex vs Pi), nous avons constaté que le coût par tâche différait considérablement (parfois de plus du double), tandis que la qualité restait identique. La différence principale résidait dans la quantité de contexte que chaque harnais transmettait au modèle à chaque étape.

Pi a envoyé environ 3 fois moins de contexte par étape. Il a mieux géré le contexte, en conservant un ensemble de travail plus restreint et en terminant les tâches en moins d'exécutions.
La leçon à en tirer n'est pas qu'un harnais est toujours moins cher ou que les harnais natifs sont moins bons. Le choix du modèle n'est qu'une pièce du puzzle. C'est pour instaurer cette flexibilité que nous avons investi dans Omnigent afin de rendre les changements de mode et de harnais totalement fluides.
Les benchmarks publics comme SWE-Bench et TerminalBench sont utiles, mais ils ne pouvaient pas répondre aux questions que nous nous posions. Cela s'explique par plusieurs raisons :
En construisant un benchmark sur nos propres PR, nous pouvons prendre ces décisions avec une plus grande certitude que nous ne gênerons pas nos développeurs en déployant des optimisations.
Nous avons utilisé Unity AI Gateway pour capturer les logs de toutes nos interactions de codage, ce qui nous a permis d'analyser la complexité des tâches que les ingénieurs abordent à l'aide d'agents de codage. La complexité des tâches était très diversifiée : environ un quart d'entre elles ont été qualifiées de tâches à faible complexité, et environ 60 % de complexité moyenne.

Cependant, les modèles coûteux étant ceux utilisés par défaut par les ingénieurs, il y avait clairement une formidable opportunité d'améliorer l'efficacité.
Nos ingénieurs fusionnent des milliers de modifications de code par jour, nous disposons donc déjà d'un excellent jeu de données sur lequel nous appuyer. Une bonne pull request est un artefact riche, avec des commits qui montrent l'itération du développeur, la revue par des humains et des tests qui permettent de vérifier qu'une modification de code est fidèle à son intention. Cependant, nous avons eu besoin de plusieurs contrôles de qualité et filtres pour en tirer un benchmark de haute qualité :

Une fois les PR candidates obtenues, nous nous sommes concentrés sur la construction de tâches bien définies en :
Le résultat de cet exercice a été une tâche unique dans le benchmark. Voici un exemple simplifié :
Bien que nous ayons utilisé des scripts et l'IA pour générer des tâches candidates, nous avons évalué chaque échantillon à la main. Dans certains cas, nous avons constaté que les tests de la PR d'origine devaient être réécrits pour permettre une implémentation alternative ou pour être plus rigoureux, ce que nous avons fait manuellement (sans IA). De même, nous avons également trouvé des cas qui nécessitaient d'améliorer la description de la tâche pour la rendre bien définie.

Figure 3 : Un avant-après de notre suite de tests : le test précédent reposait sur la vérification d'une correspondance exacte de chaîne, ce qui entraînait des échecs lorsque le modèle tentait de résoudre la tâche. Ce n'était pas une bonne méthode pour tester des résultats non déterministes, il a donc été réécrit pour évaluer le comportement à la place.
Nous avons instancié les harnesses d'agents de codage et les modèles en utilisant leurs configurations standard prêtes à l'emploi, avec tous les outils courants auxquels les ingénieurs de Databricks auraient accès.

Lorsque l'agent indiquait explicitement qu'il avait terminé la tâche, nous enregistrions un point de contrôle (checkpoint) de ce code, appliquions les tests mis de côté et évaluions les tests pour déterminer si cette tâche était réussie (« pass ») pour cette combinaison modèle + harness. Nous n'avons pas utilisé de juge LLM pour évaluer l'exactitude, car nous avons constaté que cela valorise le fait d'avoir l'air correct plutôt que de l'être réellement.

Lors de nos premières expériences, certains scores de modèles semblaient trop beaux pour être vrais, nous avons donc inspecté manuellement les traces pour comprendre ce qui s'était passé dans ces trajectoires d'agents. Ce que nous avons constaté, c'est qu'en raison de notre configuration initiale, l'implémentation « correcte » pouvait encore être récupérée dans l'historique Git de l'arbre de travail (worktree) ! Chaque tâche provenant d'un commit fusionné, rien n'empêchait un agent disposant d'un shell de parcourir l'historique Git pour la trouver. Pour résoudre ce problème, nous avons verrouillé l'historique Git : pendant toute la durée de chaque exécution, nous avons complètement coupé la copie de travail du dépôt.
Nous sommes partis d'une question simple : pouvons-nous utiliser les agents de codage plus efficacement ? La réponse est un oui catégorique, et parce que nous pouvons nous appuyer sur les données, nous pouvons commencer à développer des fonctionnalités pour sélectionner automatiquement les bons modèles et suivre l'efficacité.
Toute entreprise peut faire de même. Toute équipe disposant d'un backlog de PR fusionnées dispose déjà d'un benchmark sur lequel aucun modèle ne s'est entraîné, évalué par les tests que votre équipe a écrits. Nous ajoutons activement de nouvelles tâches (en particulier les plus difficiles), et nous prévoyons d'y soumettre chaque nouvel agent/harness pour valider nos choix avec plus d'assurance.
Chez Databricks, nous avons toujours redouté le verrouillage technologique (lock-in), non seulement vis-à-vis des fournisseurs, mais aussi vis-à-vis des certitudes qui rendent les équipes moins flexibles au fil du temps. Ce même instinct a guidé nos premiers choix en faveur des formats et standards ouverts, et il façonne aujourd'hui notre approche de l'IA : mesurer ce qui fonctionne réellement sur le code que nous déployons, donner aux ingénieurs la liberté de passer d'un modèle à l'autre et d'utiliser différents harnesses avec des garde-fous cohérents, et optimiser pour utiliser l'IA efficacement.
Dans un prochain article de blog, nous détaillerons comment nous utilisons les fonctionnalités de routage intelligent dans Unity AI Gateway et dans Omnigent pour aider nos développeurs à utiliser les agents les plus intelligents tout en restant efficaces.
(Cet article de blog a été traduit à l'aide d'outils basés sur l'intelligence artificielle) Article original
Abonnez-vous à notre blog et recevez les derniers articles directement dans votre boîte mail.