Les limites stderr de MCP permettent aux exécutions d'agents de continuer
Définissez des limites stderr pour MCP afin d'empêcher les assistants trop bavards de consommer la mémoire, retarder les approbations, bloquer l'arrêt et laisser des enregistrements d'action incomplets.

Un assistant trop bavard peut arrêter une exécution d'agent sans casser un seul message JSON-RPC. Il lui suffit de transformer stderr en file d'attente sans limite, puis de faire payer la facture à une autre partie de la pile : un tube se remplit, un lecteur conserve des mégaoctets, un arrêt attend indéfiniment ou une carte d'approbation apparaît après que l'utilisateur a cessé de faire confiance à l'exécution.
Traitez stderr comme une entrée non fiable avec un budget défini. Cela peut sembler tatillon jusqu'au jour où vous voyez une commande parfaitement ordinaire produire un diagnostic à chaque nouvelle tentative, alors que l'action qu'elle devait prendre en charge est déjà terminée et que le processus parent essaie encore de récupérer tout ce bruit. La solution n'est pas « désactiver la journalisation ». Il faut vider le flux en continu, ne conserver qu'une quantité limitée, comptabiliser ce qui a été supprimé et garder l'état de l'action indépendant de la sortie textuelle.
Stderr est un chemin de contre-pression
Stderr peut bloquer un assistant lorsque le parent le relie à un tube sans le lire assez rapidement. Les systèmes d'exploitation donnent aux tubes des tampons de taille finie. Lorsqu'un processus enfant remplit ce tampon, son écriture suivante attend qu'un lecteur se libère. Si cet enfant n'atteint le chemin de réussite qu'après avoir écrit le diagnostic, l'action semble bloquée alors que la requête réseau, la connexion SSH ou le travail local se sont déroulés correctement.
L'échec inverse est plus discret, mais souvent plus coûteux. Un parent peut lire stderr rapidement et ajouter chaque octet à une chaîne, à un tampon d'événements ou au résultat d'un outil MCP. Le tube ne se remplit jamais, mais un processus enfant très bavard peut consommer suffisamment de mémoire pour ralentir l'hôte, déclencher une pression mémoire ou faire échouer les appels suivants. Une limite qui protège uniquement le tube est incomplète. Une limite qui protège uniquement la mémoire l'est aussi.
C'est encore plus important avec les agents, car ils favorisent la multiplication des tâches. Une tâche peut lancer plusieurs assistants, et une boucle de nouvelle tentative peut créer une autre poussée avant que la première ne soit vidée. Un débit de journaux qui semble anodin dans un terminal interactif devient un problème de ressources lorsque plusieurs sessions le capturent en même temps.
Il faut limiter trois éléments distincts :
- Les octets en attente dans le tube du système d'exploitation.
- Les octets que le pont conserve en mémoire pour un appel.
- Les octets que le pont expose à un agent, à une interface utilisateur ou à une projection du journal.
Ne confondez pas une limite de lignes avec une limite d'octets. Une seule ligne peut contenir un corps de réponse volumineux, une chaîne de certificats ou un objet d'erreur réduit au minimum. Ne supposez pas non plus que UTF-8 arrive toujours sous forme de caractères complets. Les lecteurs de flux reçoivent des octets par blocs, et une limite doit continuer à fonctionner lorsqu'un caractère multioctet traverse la frontière entre deux blocs.
Un lecteur pratique conserve un compteur d'octets pour l'ensemble du flux et un tampon circulaire distinct pour la queue conservée. Une fois le total au-dessus de la limite, il continue à vider le flux afin que l'enfant puisse se terminer. Il cesse d'agrandir le tampon conservé et enregistre que la troncature a eu lieu. Tuer immédiatement l'enfant dès le premier dépassement peut être pertinent pour un outil dont la sortie est elle-même abusive, mais ce n'est pas un bon comportement par défaut pour les diagnostics. Vous voulez souvent connaître le véritable statut de sortie ainsi que les dernières lignes qui l'expliquent.
MCP garde stdout hors limites
Un serveur MCP stdio doit traiter stdout comme une zone réservée au protocole. Les recommandations de la spécification du Model Context Protocol sur le transport stdio indiquent qu'un serveur ne doit rien écrire vers stdout à part des messages MCP valides. On pourrait prendre cette règle pour une simple question de mise en forme. En pratique, elle évite une catégorie d'échecs bien plus grave : une ligne de progression anodine d'un assistant peut amener l'hôte à analyser un JSON invalide et à abandonner une session qui fonctionnait correctement.
Placez les diagnostics destinés aux humains sur stderr, mais ne supposez pas que cela les rend inoffensifs. Stderr est un canal hors bande uniquement au sens du protocole. L'hôte du processus décide toujours s'il hérite de ce flux, le relie à un tube, le capture, l'écrit dans un terminal ou le transfère dans un journal structuré. Chaque choix modifie le comportement en cas d'échec.
L'héritage fonctionne pour un développeur local, car le terminal consomme la sortie et le développeur peut la voir. C'est un mauvais choix par défaut pour un pont d'agent. Il diffuse du texte arbitraire dans un endroit qui peut ne pas être conservé, mélanger les sorties d'appels concurrents et contenir des informations que l'agent ne devrait jamais recevoir. La capture complète est préférable pour le diagnostic, mais seulement si elle est limitée.
Gardez la frontière du protocole simple. Le serveur MCP doit envoyer des messages JSON-RPC valides sur stdout, limiter ses propres diagnostics sur stderr et lancer les assistants avec des flux contrôlés explicitement. Un assistant doit renvoyer des résultats structurés par le canal prévu. Il ne doit pas afficher un bloc JSON sur stderr en espérant que le parent le reconnaîtra plus tard.
Cette distinction évite une erreur récurrente : traiter stderr comme un autre canal de réponse. Ce n'en est pas un. Il n'a pas de cadrage fiable, peut être incomplet lors d'une annulation et peut contenir des sorties produites par des bibliothèques qui ne connaissent rien de votre modèle d'action. Si l'appelant a besoin d'un nombre de nouvelles tentatives, d'un code d'erreur distant ou d'une liste de fichiers modifiés, ajoutez ces informations au résultat structuré. Réservez stderr aux éléments dont une personne peut avoir besoin pour diagnostiquer un échec.
La capture de sortie a besoin de son propre budget mémoire
Lire stderr dans une tâche en arrière-plan ne rend pas la capture sûre. Cela déplace simplement le goulot d'étranglement du tube vers le tas. J'ai vu des hôtes résoudre un interblocage en lisant les deux flux en parallèle, puis découvrir qu'un mauvais assistant pouvait les forcer à conserver chaque octet jusqu'à la fin de l'action. Le processus se termine désormais, mais l'hôte en souffre.
Utilisez un tampon circulaire pour les diagnostics conservés. Une fois sa capacité atteinte, il garde les octets les plus récents, qui contiennent généralement l'erreur utile. Conservez également un court préfixe si, dans votre environnement, la première ligne a un sens particulier, par exemple l'appel de commande ou la version d'une bibliothèque. Ne conservez pas les deux indéfiniment.
Le pseudocode suivant décrit le comportement à implémenter. Il ne dépend pas d'un langage particulier.
on_stderr_chunk(bytes):
stderr_seen += length(bytes)
if stderr_seen <= capture_limit:
append_tail(bytes)
else:
append_tail(bytes) # ring buffer evicts older bytes
stderr_truncated = true
continue_reading()
Le commentaire mérite qu'on s'y arrête. capture_limit doit désigner la quantité conservée, pas le point auquel vous arrêtez de lire. Une implémentation stricte peut ignorer append_tail après la limite et conserver les premiers octets. Je préfère une queue, car les messages d'erreur arrivent souvent après des pages de sortie de progression. Quel que soit votre choix, indiquez-le dans l'enregistrement afin qu'un enquêteur ultérieur sache s'il lit le début ou la fin.
Ajoutez une deuxième limite autour de l'objet qui transmet les diagnostics au contexte de l'agent. Un agent n'a pas besoin d'une transcription de plusieurs mégaoctets pour décider s'il doit réessayer. Il lui faut une erreur concise, un statut de sortie et, au plus, une queue sélectionnée. Si le pont transmet la sortie brute de l'assistant parce que « le modèle pourrait en avoir besoin », il donne à chaque assistant un moyen d'étouffer le reste du contexte de la tâche.
Ne décodez pas puis ne réencodez pas un flux volumineux uniquement pour appliquer une limite textuelle. Comptez les octets bruts avant de construire des chaînes. Décodez la portion conservée en remplaçant les séquences non valides, puis indiquez qu'il s'agit de stderr capturé. Vous éviterez ainsi le gaspillage de mémoire et la fausse confiance lorsqu'un assistant produit par erreur des données binaires.
Une action terminée peut encore échouer pendant l'arrêt
C'est lors de l'arrêt du processus que les flots de journaux se transforment en rapports d'incident trompeurs. L'action peut avoir réussi à distance, l'assistant peut avoir affiché son dernier diagnostic et le parent peut malgré tout ne pas produire de résultat parce qu'il attend le mauvais événement dans le mauvais ordre.
Une séquence classique ressemble à ceci :
- Le pont lance un assistant et commence à lire stdout, mais la lecture de stderr prend du retard pendant une poussée de sortie.
- L'assistant termine son action externe, puis écrit suffisamment de diagnostics pour remplir le tube stderr.
- Le parent annule la session ou atteint une échéance et envoie un signal d'arrêt.
- Le parent attend l'enfant avant de fermer ou de vider les lecteurs de flux.
- Un lecteur attend la fin du fichier tandis qu'une autre tâche attend le lecteur, et la session n'atteint jamais son enregistrement final.
L'effet externe peut déjà exister. Une requête HTTP peut avoir été acceptée ou une commande SSH peut avoir modifié un fichier distant. Signaler simplement que l'appel a « expiré » laisse à l'opérateur la pire réponse possible : il ignore si une nouvelle tentative répétera la modification.
Donnez à chaque assistant un propriétaire unique qui gère ensemble quatre éléments : le descripteur de l'enfant, le lecteur stdout, le lecteur stderr et l'annulation. En cas de fin normale, attendez la sortie du processus et videz les lecteurs jusqu'à la fin du fichier avant de construire le résultat final. En cas d'annulation, demandez l'arrêt, continuez à vider les deux flux, attendez pendant une période de grâce limitée, puis forcez l'arrêt si la plateforme l'autorise. Enfin, attendez que les lecteurs terminent et enregistrez l'état de sortie réellement observé.
Ne faites pas des lecteurs de flux de simples enfants du gestionnaire de requête. Un gestionnaire peut disparaître lorsqu'un client se déconnecte. L'assistant et ses lecteurs ont besoin d'un propriétaire qui reste actif assez longtemps pour terminer le nettoyage et écrire l'état final. Sinon, un processus agent peut se terminer, l'hôte peut supprimer les dernières références à ses lecteurs et un enfant peut rester en vie avec des tubes que personne ne consomme.
Les groupes de processus exigent la même attention. Un emballage shell peut lancer des descendants qui héritent de stderr, et tuer uniquement l'emballage peut laisser un descendant garder le tube ouvert. Évitez le shell lorsque c'est possible. Si vous en avez besoin, lancez-le dans un groupe de processus isolé et définissez précisément les descendants concernés par l'annulation. Testez ensuite le cas où l'emballage se termine mais où un petit-enfant continue d'écrire.
Le moment de l'approbation doit ignorer le volume des journaux
Le moment de l'approbation doit suivre l'état de l'action, pas le rythme des diagnostics de l'assistant. Si votre interface ne présente l'approbation qu'après qu'un assistant a produit une transcription préalable, une phase préalable bruyante modifie le moment où l'utilisateur doit décider. L'approbation semble alors aléatoire, et les utilisateurs apprennent à accepter les cartes sans comprendre pourquoi l'une a pris plus de temps.
Définissez les transitions avant d'écrire le code de l'interface. Un appel peut être reçu, validé, en attente d'approbation, autorisé, envoyé, terminé, annulé ou échouer avant son envoi. Stderr peut être associé à un appel, mais il ne doit pas décider de la transition. Le pont doit valider la cible et les paramètres demandés, créer l'enregistrement de l'appel et présenter toute approbation requise avant de lancer une action qui en a besoin.
Il existe une exception utile. Un assistant peut être nécessaire pour découvrir l'action qui va se produire, par exemple pour convertir un nom de configuration local en point de terminaison concret. Dans ce cas, traitez la découverte comme une opération distincte, sans action, avec son propre budget de sortie. Ne dissimulez pas une action dans une « phase préalable » avant de prétendre que l'utilisateur l'a approuvée plus tard.
Donnez à l'approbation une échéance en temps réel qui ne se réinitialise pas à l'arrivée de nouveaux stderr. Continuez à recueillir la queue limitée pendant que la carte est visible, mais ne redessinez jamais la carte pour chaque ligne. Un avertissement de nouvelle tentative ou un résumé d'erreur peut fournir un contexte utile avant l'approbation, mais il doit apparaître comme une explication stable, pas comme une vue de journal qui défile sans fin.
Séparez le consentement de la vivacité dans vos tests. Un test de flot doit mesurer le temps entre une demande d'appel valide et une carte d'approbation, avec stderr produit avant et après ce moment. Un test de lecteur lent doit vérifier que la carte reste utilisable pendant que le pont vide le flux. Un test d'annulation doit vérifier que la fermeture de la carte ne laisse aucun processus assistant en cours et produit un enregistrement final.
La conséquence humaine est simple : une carte d'approbation doit décrire une action précise à un moment précis. Si la sortie des journaux peut retarder, modifier ou dépasser ce moment, l'interface rend compte de la confusion du processus au lieu de donner le contrôle à l'utilisateur.
Les enregistrements d'appel doivent contenir les faits du cycle de vie avant les diagnostics
Un enregistrement d'appel est complet lorsqu'il explique l'état de l'action, pas lorsqu'il contient chaque ligne produite par un assistant. La sortie des journaux est une preuve. Les événements du cycle de vie constituent l'enregistrement.
Écrivez la tentative avant l'envoi. Incluez un identifiant d'appel stable, l'identifiant de session, le type d'action demandé, la décision d'approbation ou de refus et les informations sur la cible présentées à l'utilisateur. Lorsque l'envoi commence, ajoutez ce fait. Lorsqu'il se termine, ajoutez le résultat observé : réussite, échec distant, échec local, annulation, arrêt forcé ou résultat inconnu dû à la perte de la frontière du processus.
Ajoutez ensuite les métadonnées de diagnostic. Enregistrez au minimum le nombre total d'octets stderr reçus, le nombre d'octets conservés, l'indication d'une éventuelle troncature, le statut de sortie de l'assistant s'il est disponible et la fermeture correcte ou non du flux. Ainsi, une queue courte reste honnête. Un lecteur ultérieur peut distinguer « la commande a affiché ceci » de « le pont a conservé la dernière partie de ce que la commande a affiché ».
La structure d'un enregistrement peut rester aussi courte :
{
"call_id": "c_7f2a",
"state": "cancelled_after_dispatch",
"stderr_bytes_seen": 184320,
"stderr_bytes_retained": 16384,
"stderr_truncated": true,
"exit_status": null,
"stream_end": "reader_completed_after_cancel"
}
N'écrivez pas exit_status: 0 parce qu'un parent a reçu un corps de réponse réussi. Un corps de réponse et la fin d'un enfant sont deux observations différentes. N'écrivez pas non plus state: failed lorsqu'une annulation a eu lieu après l'envoi et que le système distant a peut-être agi. Cette distinction semble tatillonne pendant l'implémentation, puis devient la différence entre une enquête sûre et une nouvelle tentative à l'aveugle au milieu de la nuit.
Le NIST SP 800-92 Guide to Computer Security Log Management souligne un point utile : la gestion des journaux comprend leur génération, leur transmission, leur stockage, leur analyse et leur suppression, pas seulement la collecte de texte. Appliquez ce raisonnement aux actions d'agent. Si la collecte peut empêcher la fin d'une action, le chemin de journalisation fait partie de l'exécution. Il a besoin de limites, d'un état et d'une gestion des erreurs comme n'importe quel autre chemin d'exécution.
Sallyport projette ses journaux Sessions et Activity à partir d'un journal d'audit chiffré, chaîné par hachage et inscriptible uniquement. L'appelant peut ainsi distinguer l'exécution de l'agent des enregistrements d'actions individuels, au lieu de prendre la transcription d'un assistant pour l'historique.
Limitez le bruit à trois endroits
Une seule limite au sommet de la pile laisse trop de place aux accidents. Définissez des limites au niveau de l'assistant, du pont et de la destination des diagnostics. Chaque limite protège une frontière différente.
Commencez par rendre les assistants moins bavards par défaut. Placez la progression ordinaire derrière un réglage de débogage explicite, émettez un seul résumé pour une séquence de nouvelles tentatives et évitez d'afficher les corps des requêtes ou des réponses par défaut. Un assistant ne doit jamais écrire des identifiants, des en-têtes d'autorisation ou du contenu de clés privées sur stderr. La suppression des informations sensibles après capture est un filet de sécurité utile, mais elle ne peut pas effacer un secret qui a déjà été affiché dans un terminal, un rapport d'incident ou un tampon sans limite.
Ensuite, faites en sorte que le pont vide continuellement le flux et conserve un préfixe ou une queue limitée. Il doit appliquer une durée maximale et un nombre maximal d'octets conservés pour chaque flux. Il doit également disposer d'un budget de diagnostic à l'échelle du processus. Sans ce dernier contrôle, cinquante appels qui restent chacun sous leur limite individuelle peuvent tout de même provoquer ensemble un pic de mémoire.
Enfin, limitez la destination. Si vous exportez les diagnostics d'un appel vers une interface utilisateur, une réponse d'agent ou un fichier, imposez-y une autre limite. Un journal peut conserver les champs structurés du cycle de vie et une empreinte de la sortie supprimée sans stocker la même trace d'erreur répétée à chaque nouvelle tentative.
Utilisez une structure de configuration explicite. Les noms importent peu. La séparation, elle, est essentielle.
helper_output:
stderr_retained_per_call_bytes: 16384
stderr_retained_process_bytes: 262144
stderr_agent_excerpt_bytes: 4096
shutdown_grace_seconds: 5
retain: tail
Cette configuration évite un échec courant : une équipe définit une limite de réponse de l'agent et suppose que l'hôte est protégé. L'hôte lit et stocke toujours toutes les données avant de réduire la réponse. La limite par appel protège une action. La limite du processus protège les actions concurrentes. La limite de l'extrait transmis à l'agent protège le contexte qu'un modèle doit partager avec le reste de son travail.
N'utilisez pas un interrupteur global unique appelé quiet. Il rend les échecs de production plus difficiles à diagnostiquer et encourage les développeurs à réactiver des journaux illimités lorsqu'ils ont besoin d'éléments de preuve. Gardez la sortie normale concise, proposez un mode de débogage contrôlé pour une courte période et conservez dans l'enregistrement de l'appel le fait que ce mode était actif.
Évitez la recommandation courante qui consiste à rediriger stderr vers /dev/null. On la fait parce qu'elle supprime immédiatement le blocage et garde les réponses de l'agent propres. Elle supprime aussi le premier indice utile lorsqu'un assistant SSH ne peut pas s'authentifier, qu'une vérification de certificat échoue ou qu'une commande distante renvoie une erreur inattendue. Videz, limitez et étiquetez le flux à la place.
La troncature doit être visible, pas spectaculaire
La troncature est sûre lorsqu'elle est explicite et que le système continue à vider le flux. Elle devient dangereuse lorsqu'un lecteur ultérieur ne peut pas savoir si le message d'erreur est complet, lorsque le pont cesse de lire et bloque l'enfant ou lorsque la sortie supprimée peut contenir le seul récit d'une action qui ne possède aucun autre enregistrement.
La queue conservée doit commencer par un marqueur produit par le pont, pas par l'assistant. Par exemple :
[stderr truncated: kept last 16384 of 184320 bytes]
connection retry 18 failed: remote side closed the channel
Ce marqueur fait partie de l'enregistrement, ce n'est pas une décoration. Il explique à l'utilisateur pourquoi la première ligne visible semble abrupte et empêche un agent de traiter une trace d'erreur partielle comme une explication complète. Si vous conservez un préfixe et une queue, indiquez les deux nombres d'octets. Ne les assemblez jamais silencieusement.
Définissez les limites en partant de la concurrence, pas en recopiant un nombre d'un autre projet. Demandez-vous combien d'actions une exécution d'agent peut avoir en cours, combien d'exécutions l'hôte accepte, quelle quantité de mémoire les diagnostics peuvent consommer pendant une mauvaise minute et quelle quantité de texte une personne peut réellement examiner. La dernière réponse est généralement bien plus petite qu'on ne l'imagine.
Gardez le résultat de l'action séparé de l'extrait. Une action HTTP réussie doit renvoyer son résultat structuré prévu même si stderr atteint sa limite, sauf si l'assistant utilise lui-même le dépassement comme signal d'échec. À l'inverse, un flux stderr propre ne prouve pas qu'une action a réussi. Traitez les diagnostics comme un champ parmi plusieurs observations.
Les tests de flot doivent accompagner les tests d'intégration normaux
Un assistant qui écrit trop de stderr n'est pas un cas exotique réservé aux tests de sécurité. C'est un test de fiabilité élémentaire. Les bibliothèques deviennent verbeuses après une mise à jour, les clients distants répètent des avertissements lors des nouvelles tentatives et une entrée mal formée peut déclencher une boucle d'erreur. Si le pont ne rencontre en test que des assistants silencieux et fonctionnels, il n'a aucune preuve que sa gestion des processus fonctionne sous pression.
Commencez par un composant de test qui émet une quantité fixe de stderr, se termine avec un statut choisi et n'effectue aucun travail externe. Sur un système de type Unix, cette commande crée un flot volontaire pour un banc de test local :
yes helper-diagnostic 1>&2
Exécutez-le avec une échéance courte. Le résultat attendu ne consiste pas seulement à constater que l'échéance est atteinte. Vérifiez que le pont ne conserve pas plus que la quantité configurée, marque la troncature, termine l'enfant, vide les flux jusqu'à leur fermeture et écrit un événement de cycle de vie final.
Ajoutez ensuite les cas qui révèlent les erreurs d'ordonnancement :
- Un assistant écrit sur stderr avant d'attendre l'approbation.
- Un assistant écrit pendant l'approbation et se termine immédiatement après celle-ci.
- Un assistant réussit l'action externe, remplit stderr et reçoit une annulation pendant le nettoyage.
- Un emballage se termine tandis qu'un descendant garde stderr ouvert.
- Un assistant écrit des séquences d'octets non valides et une ligne unique plus grande que la limite conservée.
Mesurez quelques faits pour chaque cas : le nombre maximal d'octets de diagnostic conservés, le temps avant approbation, le temps entre l'annulation et la fin du processus, l'état final et la présence de l'enregistrement d'appel attendu. Ne vous contentez pas d'un test qui vérifie seulement qu'une chaîne d'erreur contient « truncated ». Cette chaîne peut apparaître alors qu'une tâche de lecture reste bloquée ou que l'enregistrement final n'est jamais stocké.
Exécutez les mêmes composants de test avec des appels concurrents. Une limite par appel peut sembler correcte isolément et pourtant échouer lorsque tous les appels atteignent leur limite en même temps. Testez également la déconnexion d'un client. Le processus agent peut disparaître, mais l'hôte doit toujours terminer ou annuler l'action d'une manière définie.
La dernière vérification consiste à vérifier hors ligne la chaîne d'audit et à la comparer au cycle de vie attendu par le composant de test. La vérification peut vous dire si les entrées stockées ont été modifiées. La comparaison avec le composant de test vous dit si le pont a écrit les entrées qu'il devait écrire dès le départ. Les deux sont nécessaires.
Garder des journaux utiles sans leur laisser piloter l'action
La règle utile est simple : stdout transporte les messages du protocole MCP, les résultats structurés portent les effets des actions et stderr transporte des diagnostics limités. Une fois que ces canaux ont des rôles différents, le moment de l'approbation, l'arrêt, le suivi de la mémoire et les enregistrements d'audit cessent de se disputer le même texte non structuré.
Commencez par l'assistant qui vous a déjà causé des problèmes : celui qui réessaie trop bruyamment, reste bloqué après une annulation ou affiche toute une réponse distante lorsqu'il échoue. Placez-le derrière un lecteur limité et exécutez le composant de test de flot jusqu'à ce que l'enregistrement de l'action reste fidèle. Des journaux silencieux sont agréables. Des journaux limités sont un véritable contrôle opérationnel.
FAQ
La sortie stderr peut-elle vraiment bloquer un agent MCP ?
Oui. Si le processus parent capture stderr sans limite, un assistant peut transformer les diagnostics en mémoire retenue ou remplir un tube qui bloque l'assistant. Les messages MCP peuvent être sains alors que le processus qui les transporte reste bloqué par ses propres journaux.
Un serveur MCP doit-il écrire ses journaux vers stdout ou stderr ?
N'envoyez pas les journaux vers stdout. Le transport stdio réserve stdout aux messages du protocole, et une seule ligne de diagnostic peut donc corrompre le flux JSON-RPC. Envoyez les diagnostics vers stderr et demandez à l'hôte de vider et de limiter ce flux.
Quelle limite stderr définir pour un assistant agent ?
Un bon point de départ consiste à définir une petite limite en octets par appel, une queue conservée plus petite et une limite stricte à l'échelle du processus. Les valeurs exactes dépendent de la concurrence et de la mémoire disponible, mais la limite doit être explicite et observable, pas un effet secondaire accidentel de l'environnement d'exécution.
Est-il sûr de tronquer stderr d'un assistant ?
Conservez une queue limitée, enregistrez le nombre total d'octets reçus et indiquez que la sortie a été tronquée. Un enregistrement d'audit complet n'exige pas une copie intégrale de chaque ligne de débogage. Il doit rendre compte honnêtement de ce qui a été exécuté, de ce qui s'est produit et des éléments écartés.
Des journaux très verbeux peuvent-ils retarder une demande d'approbation ?
L'approbation doit suivre le cycle de vie de l'action, pas le volume des journaux. Lancez le délai d'approbation lorsque l'action peut être soumise à l'approbation humaine, et continuez à vider stderr pendant l'affichage de la carte.
Dois-je vider stdout et stderr en même temps ?
Lisez toujours les deux flux en parallèle. Vider uniquement stdout peut bloquer un processus qui remplit son tube stderr, et vider uniquement stderr crée le même problème dans l'autre sens pour un assistant qui produit une réponse volumineuse.
Que doit enregistrer un journal d'audit lorsqu'un assistant est arrêté ?
Enregistrez l'action tentée avant son envoi, puis indiquez si l'envoi a commencé, s'il s'est terminé et si la sortie a été tronquée. Si l'assistant survit à la déconnexion du client ou si le client se ferme en premier, le journal doit le préciser au lieu de laisser croire à un résultat propre.
Un délai d'expiration protège-t-il contre un flot excessif de journaux ?
Non. Un délai court limite la durée écoulée, tandis qu'une limite stderr borne les données conservées et la pression sur le tube. Il faut les deux, ainsi qu'un chemin d'annulation qui ferme les flux et attend la fin du processus.
Comment tester des assistants MCP bruyants ?
Utilisez un véritable assistant qui produit une quantité contrôlée de stderr, puis faites-le passer par le même pont et le même parcours d'approbation qu'en production. Mesurez le nombre maximal d'octets conservés, le temps avant approbation, la latence d'annulation, le statut de sortie et la présence de chaque enregistrement du cycle de vie.
Pourquoi une passerelle d'actions doit-elle limiter les journaux des sous-processus ?
Une passerelle qui exécute des actions pour le compte d'un agent doit traiter la sortie de l'assistant comme une entrée non fiable. Elle doit conserver les éléments utiles de la queue et les diagnostics tout en empêchant un agent ou une dépendance défectueuse de consommer la mémoire ou de maintenir une action ouverte indéfiniment.