Skip to main content
Retour aux billets
Oct. 20268 min de lecture

Lancé avant la sortie d'openai 3.0.0, il a trouvé les 3 paquets que la version brisait. Nemotron a écrit le même verrouillage que le responsable a publié neuf jours plus tard.

openai 3.0.0 a brisé les nouvelles installations de llm, de Simon Willison, et la correction a pris neuf jours. Floodplain exécute les suites de tests des projets dépendants dans des Nebius Sandboxes avant la sortie. Avec le wheel non publié d'OpenAI lui-même, il a trouvé les 3 mêmes cassures que la vraie sortie, avec les mêmes tests brisés, et NVIDIA Nemotron a écrit des correctifs que leurs suites acceptent.

Nebius x NVIDIA HackathonNVIDIA NemotronNebius Token FactoryNebius SandboxesTavilyPythonOpen sourceHackathon
J'ai écrit ce billet pour le Nebius x NVIDIA Global AI Hackathon (octobre 2026, piste Coding and Agentic Engineering), et j'ai bâti Floodplain pour la même soumission. Page de résultats sur jonathansolvesproblems.github.io/floodplain, code source sur github.com/JonathanSolvesProblems/floodplain sous licence MIT, avec chaque exécution et chaque étape de l'agent enregistrées.
La revendication en une phrase : lancé avant le téléversement d'openai 3.0.0, avec le wheel d'OpenAI lui-même comme fichier non publié, Floodplain a donné le même verdict que la vraie sortie sur les 31 projets dépendants dont la suite fonctionnait, avec les mêmes tests brisés, et les 3 qu'il a signalés ont chacun été verrouillés ou corrigés plus tard par leurs propres responsables, corrigés par ce que la sortie a réellement fait et par ce que ces responsables ont publié. Ce qui n'est pas revendiqué : que l'agent corrige toutes les cassures. Sur llm, il ne soumet jamais, alors qu'un seul appel de rédaction l'a corrigé 9 fois sur 10.
La page de résultats de Floodplain : une rivière tracée depuis openai 3.0.0, versé à 1 h 55 UTC, qui passe devant de petits récepteurs pour chaque projet dépendant, avec trois tronçons teints en vert pour vlmrun (3 tests brisés, corrigé après dix-neuf jours), llm (110, corrigé après neuf jours) et openinference-instrumentation-agno (92, corrigé après six jours).
3 des 20 suites de tests fonctionnelles qui ont reçu openai 3.0.0 ont brisé. Chaque tronçon vert en est une, avec le temps que ses responsables ont mis à la corriger.

La cassure n'apparaissait que dans les tests des autres

Simon Willison maintient llm, un outil en ligne de commande pour les modèles de langage. À 1 h 55 UTC le 12 août 2026, openai 3.0.0 a été publié sur PyPI. Il a remplacé son client HTTP, httpx, par httpx2 et a cessé d'installer httpx. Six heures plus tard, un utilisateur a ouvert l'issue #1608 de llm : les nouvelles installations étaient brisées, et la suite de tests échappait à ses simulations pour appeler la vraie API. Neuf jours plus tard, Simon a publié un verrouillage sous la version 3. OpenAI ne pouvait pas le voir venir avec ses propres tests, parce que la preuve se trouvait dans les dépôts des autres. openai publie trois ou quatre versions par semaine, alors ses responsables se posent cette question une quinzaine de fois par mois. Je voulais qu'ils puissent y répondre avant de publier.

L'issue GitHub #1608 de simonw/llm, intitulée « Fresh install broken and test suite escapes to live API since openai 3.0.0 (httpx → httpx2) », qui montre une trace se terminant par ModuleNotFoundError: No module named 'httpx'.
Le problème, en public : l'issue #1608 de llm, ouverte six heures après la sortie. La correction a pris neuf jours.

Comment on lit un récepteur

Les hydrogéologues découvrent où l'eau va sous terre en versant un colorant fluorescent à un point et en suspendant des sachets de charbon à chaque source en aval. Floodplain fait la même chose avec une version de paquet. J'ai pris chaque paquet des 15 000 plus populaires de PyPI qui déclarait openai comme dépendance le jour de la sortie, 220 en tout, j'ai mis de côté les 63 qui le verrouillaient sous 3.0.0, et j'ai exécuté les 157 autres partout où une copie du code source était disponible. Chaque copie devient trois embranchements identiques sur Nebius Sandboxes, parce que les images sont adressées par contenu : le monde une minute avant la sortie, la même chose comme échantillon de fond pour repérer les tests instables, et une minute après. uv résout chaque embranchement avec l'index figé selon l'heure de téléversement. Une suite qui passait avant et échoue après, avec un fond inchangé, est un positif, et chaque cassure est réexécutée deux autres fois avant de compter.

Un diagramme d'une copie divisée en trois embranchements à partir d'openai 3.0.0 : before (le monde à 1 h 54 UTC), background (le même monde une deuxième fois) et after (le monde à 1 h 56 UTC), à côté du texte qui explique comment chaque embranchement se lit.
Trois embranchements d'une même copie : avant, la même chose une deuxième fois pour repérer les tests instables, et après.

Avant la sortie, la même réponse que la sortie

Rejouer une sortie qui a déjà eu lieu, c'est facile à corriger, mais le but est de l'exécuter avant la publication. Je l'ai donc exécuté comme il est censé l'être : le wheel 3.0.0 d'OpenAI lui-même comme fichier non publié, offert au résolveur par l'option --find-links d'uv dans un embranchement du monde à 1 h 54 UTC, une minute avant le téléversement. Les 31 projets dépendants dont la suite fonctionnait ont donné le même verdict que la reprise de la vraie sortie, avec les mêmes tests brisés. Les trois qu'il a trouvés étaient llm (110 tests réussis sur 1 069), openinference-instrumentation-agno (les 92, perdus à cause d'erreurs d'importation) et vlmrun (3 sur 231). Chacun a ensuite été verrouillé ou corrigé par ses propres responsables, 6, 9 et 19 jours après la sortie.

La section de la page de résultats sur l'exécution avant la sortie : le wheel 3.0.0 d'OpenAI utilisé comme fichier non publié à 1 h 54 UTC, et les 31 suites fonctionnelles donnant le même verdict que la reprise, avec les mêmes tests brisés.
Avec le wheel d'OpenAI lui-même avant son téléversement, les 31 suites fonctionnelles ont donné le même verdict que la vraie sortie.

Nemotron lit le journal, puis écrit le correctif

NVIDIA Nemotron 3 Nano lit chaque journal d'échec et dit pourquoi ça a brisé, et la ligne qu'il cite est vérifiée mot pour mot contre le vrai journal; une citation qui n'est pas dans le journal est rejetée. Ensuite, un appel à Nemotron 3 Ultra rédige un correctif, et un agent Ultra décide étape par étape quoi en faire : lire du code, chercher, exécuter une commande ou des tests choisis dans un nouvel embranchement, réviser, rédiger de nouveau ou soumettre. Un correctif ne compte que si toute la suite du projet brisé l'accepte dans un autre embranchement. Pour llm, le correctif de Nemotron est le même verrouillage que Simon Willison a publié neuf jours plus tard. Tavily cherche des guides de migration, avec deux garde-fous : seulement des pages datées d'avant l'intervention des responsables du projet, et rien qui vient du dépôt du projet lui-même ou qui le nomme, parce que sans eux le premier résultat de Tavily était l'issue même de llm, où la correction est discutée.

La section Why it broke pour llm, attribuée à NVIDIA Nemotron 3 Nano : une explication d'une phrase selon laquelle openai 3.0.0 est passé à HTTPX2 et a changé la façon dont les requêtes simulées sont reconnues, au-dessus du journal pytest d'échec avec la ligne citée en évidence.
Nemotron 3 Nano explique pourquoi llm a brisé. La ligne qu'il cite est vérifiée mot pour mot contre le vrai journal.
La section du correctif pour llm : un diff dans pyproject.toml qui change l'exigence openai en openai>=2.32.0,<3.0, marqué comme accepté par la suite dans un nouvel embranchement, à côté de What the maintainer shipped : « openai>=2.32.0,<3 » dans simonw/llm 0.32.1, neuf jours et quinze heures après la sortie.
Le correctif de Nemotron a été accepté par la suite de llm dans un autre embranchement. C'est le même verrouillage que son responsable a publié neuf jours plus tard.

Huit révisions de l'agent, toutes conservées

L'agent a demandé huit révisions, chacune mesurée sur cinq essais par paquet et conservée dans le dépôt avec chacune de ses étapes. En enquêteur ouvert, Nemotron a exploré le module de 3 000 lignes de llm pendant 40 étapes sans jamais soumettre. Avec une première ébauche comme point de départ, l'agent final a corrigé agno et vlmrun dans 5 essais sur 5 chacun, en environ 16 et 29 étapes par essai. Sur llm, il ne soumet toujours pas, alors qu'un seul appel de rédaction sans outils l'a corrigé 9 fois sur 10, et la page le dit. Le reste du travail a surtout consisté à refuser des résultats qui avaient l'air bons : un embranchement qui ne renvoyait rien rapporté comme « rien n'a brisé », un correctif déclaré vérifié dans une suite qui ne pouvait pas importer, et 11 projets dépendants comptés comme réussis alors qu'openai 3.0.0 ne les avait jamais atteints, ce qui a fait passer le chiffre principal de 3 sur 31 à 3 sur 20. Un script fait échouer la compilation si un chiffre de la page ne concorde pas avec les résultats enregistrés.

Une exécution enregistrée de l'agent : une première ébauche de correctif, puis les 15 étapes que l'agent a choisies (lister des fichiers, lire pyproject.toml et des fichiers d'exigences, exécuter des tests), qui se termine par submit et la note que toute la suite passe dans un nouvel embranchement.
L'agent Nemotron 3 Ultra choisit chaque étape selon ce que la précédente a renvoyé, puis soumet. Son correctif passe dans un nouveau bac à sable.

Toujours aux aguets

Une tâche GitHub Actions quotidienne vérifie PyPI pour les versions d'openai qu'elle n'a pas encore vues et les exécute contre les projets dépendants dont les suites ont donné une lecture sur 3.0.0, puis écrit le résultat dans une issue GitHub, ou dans un commentaire sur la demande de tirage de la version quand on l'exécute avant la publication. Elle n'ouvre jamais de demandes de tirage dans les dépôts des autres; elle remet le correctif. Sa première vraie surveillance a été openai 3.37.0, sortie depuis deux jours : aucune des 21 suites fonctionnelles n'a brisé. Un test semblait brisé, est repassé deux fois sans erreur dans le même embranchement, et le rapport le dit au lieu de le compter.

L'issue GitHub #1 du dépôt floodplain, ouverte par la surveillance : « openai 3.37.0: none of the 21 working test suites broke », qui liste les paquets restés propres, un test instable non compté et les paquets retenus.
La vérification quotidienne sur openai 3.37.0 : aucune des 21 suites fonctionnelles n'a brisé, et un test instable mis de côté.

Ce qui n'est pas revendiqué

Le chiffre principal est corrigé par des choses que je ne contrôlais pas : ce qu'openai 3.0.0 a réellement brisé, et ce que trois groupes de responsables ont publié ensuite. Ça reste une seule version d'un seul paquet. Seulement 20 des 157 projets dépendants exposés avaient une suite de tests qui fonctionnait avant la sortie et qui a réellement installé 3.0.0 dans l'embranchement d'après, alors 3 sur 20 est le dénominateur honnête, pas 3 sur 220. Chaque correctif est un échantillon, pas un comportement, alors les correctifs sont rapportés en K essais sur N par révision du correcteur, et sur llm l'agent final ne soumet pas du tout. La surveillance n'a tourné que sur openai, et la recette devrait s'appliquer à d'autres paquets, mais je ne l'ai mesurée qu'ici.

Projet associé

Floodplain: run before openai 3.0.0 shipped, it finds the 3 packages the release breaks, and NVIDIA Nemotron writes fixes their own test suites pass

Voir le projet