Récemment, en utilisant Codex CLI avec un upstream pas très stable, je suis tombé sur un problème à la fois assez drôle… et très concret.
Codex a actuellement la reconnexion en streaming implémentée comme un backoff exponentiel codé en dur. Les premières tentatives ont l’air normales, mais ensuite ça enfle de manière complètement excessive :
- La 1ʳᵉ fois : environ 0,2 s
- La 5ᵉ fois : environ 3,2 s
- La 10ᵉ fois : déjà plus d’1 minute
- Ensuite, ça peut même monter à des tentatives toutes les dizaines de minutes, voire plus
Le problème, c’est que ce design part de l’hypothèse implicite que « plus l’échec dure, plus il faut réessayer lentement ». Mais dans la réalité, beaucoup d’upstreams ne se comportent pas comme ça :
- une passerelle qui “déconne” ponctuellement
- du routage backend instable
- certains relais compatibles OpenAI qui renvoient brièvement 403 / état de quota non rafraîchi
- en pratique, en réessayant quelques fois, ça revient vite
Autrement dit, ce dont on a réellement besoin, c’est :
- que l’utilisateur décide lui-même de la fréquence de retry
- au minimum, permettre un retry à intervalle fixe, par exemple une fois toutes les 500 ms
- et ne pas être pris en otage par un backoff exponentiel imposé
Ce qui est encore plus absurde, c’est que Codex donne à l’utilisateur stream_max_retries, mais ne lui donne pas la main sur l’intervalle de retry ni sur la stratégie de backoff. Résultat :
tu peux monter le nombre de tentatives à 100, mais après la 10ᵉ, chaque attente commence à devenir déraisonnablement longue, ce qui va totalement à l’encontre des scénarios « en retentant plusieurs fois ça passe ».
J’ai déjà remonté le problème à l’upstream :
J’ai l’impression que le fond du problème n’est pas seulement un mauvais choix de paramètres, mais une conception trop paternaliste, qui ne laisse pas à l’utilisateur la liberté de choisir.
Si on pouvait, dans le TOML, supporter explicitement une config comme ci-dessous, on rendrait au moins le contrôle à l’utilisateur :
[model_providers.custom]
stream_max_retries = 100
stream_retry_delay_ms = 500
stream_retry_backoff = "fixed"
Ce besoin est en réalité très courant :
« cet upstream déconne souvent, mais en réessayant rapidement plusieurs fois d’affilée, ça revient généralement ; ne me forcez pas à passer automatiquement à une tentative toutes les dizaines de minutes. »