Le backoff de retry de Codex est vraiment abusé : après un 403, plus on réessaie, plus ça ressemble à du botting

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. »