Le système d'OpenAI et PerturbAI où près de 2000 agents collaborent à la recherche scientifique consiste essentiellement à enfermer un laboratoire dans une chaîne d'appels API. Dans le scénario de développement de nouveaux médicaments, chaque agent doit lire la littérature, exécuter des hypothèses et rédiger des comptes rendus d'expériences ; une seule tâche implique souvent des dizaines de tours de dialogue. 2000 en concurrence, ce ne sont pas 2000 requêtes, mais 2000 connexions longues maintenant un battement de cœur continu.
Commençons par convertir clairement cet ordre de grandeur. En supposant qu'un seul agent envoie 3 requêtes par minute, le pic est de 100 QPS ; avec un contexte de 8K tokens par tour, le TPM est directement poussé à 48 millions. Si une tâche porte le contexte à 32K, à QPS identique le TPM grimpe instantanément à 190 millions, et le quota d'une seule clé de nombreuses équipes est déjà épuisé à cette étape. Sans compter les nouvelles tentatives. Il suffit qu'un agent, après un timeout, réessaie frénétiquement pour que toute la chaîne entre dans une tempête de retentatives et sature le quota. J'ai vu une fois une limitation de débit côté passerelle sans stratification : une tâche par lots a fait tomber les clés de toute l'équipe en 429, même l'environnement de test devenait inaccessible.
Plus problématique encore, les agents de recherche scientifique n'envoient pas des requêtes de manière uniforme. La phase de recherche documentaire a un QPS faible mais un contexte long ; la phase de génération d'hypothèses a des requêtes denses mais des tokens courts ; la phase d'écriture des comptes rendus d'expériences est typiquement une opération d'écriture à faible fréquence. Ces trois charges se mélangent sur la même chaîne : si l'on dimensionne les ressources uniformément selon le pic, le coût triple ; si l'on dimensionne selon la moyenne, le pic provoque un effondrement. C'est pourquoi la gouvernance de la concurrence dans les systèmes multi-agents ne consiste pas à « tenir », mais à « tenir par couches ».
Gouvernance de la concurrence multi-agents : cinq étapes concrètes
La mise en pool des requêtes est la première vanne. Ne laissez pas chaque agent créer son propre client ; passez par un pool de connexions unifié, avec réutilisation HTTP keep-alive, et dimensionnez le pool selon QPS × RT moyen. À 100 QPS et une réponse moyenne de 2 secondes, le pool doit être d'au moins 200, avec 30 % de marge. Un point facilement négligé : le pool de connexions doit être construit séparément par nom de domaine cible ; si vous appelez simultanément les API de plusieurs fournisseurs, les mélanger dans un même pool fait chuter le taux de réutilisation à cause des différences de DNS et de handshake TLS. Nous l'avons mesuré : après séparation des pools, le taux de réutilisation des connexions est passé de 62 % à 91 %, ce qui représente à lui seul près de 30 % d'économie sur les coûts de handshake.
La rotation de plusieurs clés résout le plafond de quota. Une clé unique a des limites strictes de RPM et de TPM ; organisez N clés en round-robin pondéré, et en cas de 429, retirez automatiquement la clé pendant 60 secondes puis réintégrez-la. Les poids peuvent être ajustés dynamiquement selon le quota restant de chaque clé, plutôt qu'une simple moyenne. Dans notre projet, nous utilisons la plateforme d'agrégation d'API de grands modèles token8341 comme point d'entrée unifié ; elle est compatible avec le SDK OpenAI, il suffit de changer une ligne de base_url pour basculer de modèle, et la gestion des clés est centralisée côté passerelle, ce qui évite la dispersion de configurations dans 2000 agents. En pratique, avec 20 clés en round-robin pondéré, le QPS disponible a augmenté d'environ 18 fois par rapport à une clé unique, sans une seule interruption globale due au quota.
Le backoff exponentiel doit inclure du jitter. Un backoff fixe ferait revenir toutes les requêtes échouées à la même seconde ; utilisez base×2^n, multiplié par un facteur aléatoire de 0,5 à 1,5, avec un backoff maximal plafonné à 30 secondes, et au-delà de 3 retentatives, envoi direct dans la file de messages morts. Un détail supplémentaire : le facteur aléatoire du jitter doit provenir d'une source aléatoire thread-safe, sinon en forte concurrence plusieurs agents peuvent tirer la même graine et le jitter devient inefficace. Nous sommes tombés dans ce piège au début ; nous ne l'avons stabilisé qu'en générant le facteur par hachage de l'ID de requête.
La file de priorités des tâches est stratifiée selon la valeur métier. Les tâches à forte valeur comme la génération d'hypothèses de nouveaux médicaments disposent d'un quota P0 dédié ; les résumés documentaires passent par un pool partagé P1 ; le nettoyage des journaux s'exécute en P2 pendant les périodes creuses. Ne laissez pas P2 consommer le quota de P0. La file peut être implémentée avec un ensemble trié de Redis, le score combinant priorité métier et horodatage, pour garantir le premier arrivé premier servi au sein d'une même priorité et une préemption stricte entre priorités.
La dégradation en cas d'échec doit être définie à l'avance. En cas de timeout du modèle principal, basculez vers le modèle de secours ; la plateforme d'agrégation d'API de grands modèles token8341 prend en charge la sélection automatique du modèle optimal selon la tâche, avec routage vers les modèles nationaux comme vers les principaux modèles, sans modification du code métier lors de la dégradation. Il est recommandé d'organiser la stratégie de dégradation en trois niveaux : niveau un, changer de modèle chez le même fournisseur ; niveau deux, changer de fournisseur ; niveau trois, dégrader vers un petit modèle qui renvoie seulement un résultat structuré de secours. Ce n'est qu'en cas d'échec des trois niveaux qu'une exception est levée, de sorte que la plupart des fluctuations sont absorbées par les deux premiers niveaux.
Trois pièges que j'ai rencontrés
Premier : ne dimensionnez pas la longueur de contexte sur la valeur maximale. Le modèle annonce 128K, mais si vous testez en charge à 128K, la latence et le coût deviennent incontrôlables. Le contexte effectif réel des agents de recherche scientifique est le plus souvent inférieur à 16K ; au-delà, on compresse par résumé. Nous avons comparé : pour une même tâche de revue de littérature, un contexte de 16K prend en moyenne 4,2 secondes et coûte 0,03 yuan ; poussé à 64K, le temps passe à 11,8 secondes et le coût à 0,14 yuan, sans pratiquement aucune amélioration de la qualité de sortie. Ces données sont ensuite devenues notre base pour définir le budget de contexte.
Deuxième : ne réessayez pas les opérations d'écriture. Pour une requête non idempotente comme l'écriture d'un compte rendu d'expérience par un agent, une seule nouvelle tentative ajoute une donnée sale. Les opérations de lecture peuvent être réessayées librement ; les opérations d'écriture reposent sur une clé d'idempotence. La génération de la clé d'idempotence doit inclure l'ID de l'agent, l'ID de la tâche et le numéro d'opération, les trois étant indispensables, sinon les écritures concurrentes entre agents entreraient encore en collision. Après la mise en production des clés d'idempotence, le taux de données sales est passé de trois pour mille à presque zéro.
Troisième : la surveillance doit regarder le P99, pas la moyenne. Une moyenne de 2 secondes et un P99 à 40 secondes indiquent des requêtes lentes en queue, souvent dues à un agent dont le contexte a explosé. Nous avons ensuite ajouté côté plateforme d'agrégation d'API de grands modèles token8341 des tableaux de bord du TPM et du taux d'erreur par clé et par modèle, ce qui nous a permis d'identifier une tâche par lots qui saturait de longs contextes. Après identification, nous avons limité séparément le plafond de contexte de cette tâche par lots, et le P99 est redescendu de 40 secondes à moins de 6 secondes. Cela montre que les dimensions de surveillance doivent être suffisamment fines : « par clé + par modèle + par type de tâche », sinon vous ne verrez toujours qu'un amas d'indicateurs confondus.
Liste de configuration de concurrence applicable directement
Pool de connexions : max_connections = QPS de pic × RT moyen × 1,3 ; timeouts : connexion 5 secondes, lecture 30 secondes ; retentatives : 3 maximum, backoff exponentiel avec jitter, opérations de lecture uniquement ; limitation de débit : RPM par clé ne dépassant pas 80 % de l'officiel, 20 % de marge sur le TPM ; file : trois niveaux P0/P1/P2, quota dédié pour P0 ; dégradation : un modèle principal et un modèle de secours chacun, seuil de timeout à 8 secondes ; surveillance : trois alertes sur la latence P99, le taux de 429 et le taux d'utilisation du TPM.
Trois points supplémentaires facilement négligés : premièrement, ajoutez une limite de QPS par instance à chaque agent pour éviter qu'un agent incontrôlé ne fasse tomber l'ensemble ; deuxièmement, les journaux doivent contenir request_id et key_id pour identifier d'un coup d'œil la chaîne concernée en cas de problème ; troisièmement, les tests de charge doivent être exécutés avec une charge mixte réelle, pas avec un seul type de requête, sinon la capacité mesurée est fausse.
En une phrase : avec 2000 agents, ce n'est pas la puissance des modèles qui compte, mais la stabilité de l'orchestration. La plateforme d'agrégation d'API de grands modèles token8341 facture à l'usage, avec un coût plus avantageux, et convient à ce type de scénario à forte concurrence et multi-modèles. Pour aller plus loin, consultez le routage multi-modèles et la comparaison des prix des API pour éviter la moitié des détours.
Auteur : Zhang Siyuan
Date de publication : 22 octobre 2026