L'API Responses de llama-server signale à tort les sorties tronquées comme terminées
Un bug dans la build b11753 de llama.cpp fait que le point d'accès /v1/responses marque les réponses coupées et les appels d'outils invalides comme terminés, risquant de corrompre les données des agents IA auto-hébergés.
Traduit automatiquement depuis l’original en anglais.
Un important problème de compatibilité a été identifié sur le point d'accès /v1/responses compatible OpenAI de llama-server, affectant les déploiements auto-hébergés de grands modèles de langage. Au 20 octobre 2026, le problème persiste dans la build b11753 de llama.cpp, où le serveur indique incorrectement que les réponses tronquées et les appels d'outils incomplets ont été correctement exécutés. Cette divergence représente un risque pour les développeurs qui créent des agents autonomes s'appuyant sur des signaux d'état précis pour exécuter des tâches en aval.
Ce qui s'est passé
Le problème fondamental réside dans la manière dont llama-server traduit les états internes de génération vers le format de l'API Responses. Lorsqu'une requête atteint la limite de jetons définie par max_output_tokens, le moteur sous-jacent de complétion de chat identifie correctement la raison d'arrêt comme étant "length" (longueur). Cependant, lorsque ce résultat est converti en objet API Responses, le serveur force le champ de statut à "completed" (terminé), que la sortie ait été finalisée ou coupée court. Ce comportement affecte à la fois la génération de texte standard et les scénarios d'appels de fonctions.
Lors de tests avec des modèles tels que Gemma-3-1b-it et Qwen3-0.6B, des requêtes limitées à huit jetons renvoyaient un statut "completed" avec des détails d'incomplétude nuls, même si le texte se terminait au milieu d'une phrase. Plus critique encore, les appels d'outils tronqués par les limites de jetons retournaient des arguments JSON invalides—tels que {"path": "/—tout en étant marqués comme éléments terminés. Les clients faisant confiance à cet indicateur de statut pourraient tenter d'analyser du JSON cassé ou d'exécuter des commandes partielles, entraînant des échecs silencieux ou des erreurs inattendues dans les environnements de production.
Détails clés
- Le bug affecte la build b11753 de llama.cpp et impacte spécifiquement le point d'accès
/v1/responses, tandis que/v1/chat/completionsrapporte correctementfinish_reason: "length". - Les arguments d'appel d'outil tronqués sont retournés comme des éléments
function_callvalides avec un statut "completed", malgré la présence de JSON malformé impossible à analyser. - Les réponses en streaming ne parviennent pas non plus à émettre un événement
response.incomplete, se terminant plutôt parresponse.completedet omettant le signal attendufunction_call_arguments.done. - Le seul indicateur fiable de troncature dans l'API Responses consiste à vérifier si
usage.output_tokensest égal auxmax_output_tokensdemandés, bien qu'il s'agisse d'une heuristique plutôt que d'un statut définitif. - Le code source dans
tools/server/server-task.cppcontient sept instances où le statut est forcé à "completed", sans logique permettant de lire la raison d'arrêt sous-jacente ou de définir le statut sur "incomplete". - Aucun correctif amont ni pull request n'avait été fusionné pour le problème ggml-org/llama.cpp#30773 au 20 octobre 2026.
Contexte
L'API Responses est une spécification plus récente conçue pour les interactions de type agent, permettant aux modèles de retourner des sorties structurées incluant des étapes de raisonnement et des appels d'outils. Llama-server implémente cela en convertissant les requêtes Responses entrantes en requêtes Chat Completions standard en interne. Bien que le processus de génération fonctionne correctement, la couche de traduction ne parvient pas à mapper le finish_reason de la complétion de chat vers les champs status et incomplete_details de l'API Responses. Cette conversion unidirectionnelle perd des signaux d'échec critiques, laissant les clients ignorer que le modèle n'a pas terminé sa réflexion ou sa commande.
Pour les développeurs, cela met en évidence un piège courant dans les couches de compatibilité : s'assurer que les états d'erreur et les conditions limites sont préservés lors des traductions d'API. Un champ de statut n'est utile que s'il peut refléter avec précision les résultats négatifs. Dans ce cas, le serveur privilégie le retour de contenu plutôt que la communication de l'intégrité, supposant que la plupart des réponses tiendront dans les limites. Cette hypothèse s'effondre pour les tâches complexes nécessitant de longs contextes ou une exécution précise d'outils.
Pourquoi c'est important
Pour les équipes exécutant des agents IA auto-hébergés, ce bug introduit une faille de fiabilité subtile mais dangereuse. Les systèmes autonomes comptent souvent sur le champ status pour décider s'ils doivent poursuivre une tâche. Si un agent reçoit un statut "completed" pour un chemin de fichier ou un extrait de code tronqué, il pourrait tenter d'exécuter une commande partielle. Cela peut entraîner une corruption de données, des échecs de déploiement ou des vulnérabilités de sécurité si l'entrée partielle est mal interprétée par les systèmes en aval. Le risque est maximal pour les petits modèles ou les prompts complexes où les limites de jetons sont fréquemment atteintes.
De plus, ce problème complique le débogage. Comme le serveur ne rapporte pas d'erreur, les journaux peuvent afficher des complétions réussies même lorsque la sortie est inutilisable. Les développeurs pourraient attribuer à tort l'échec aux capacités de raisonnement du modèle ou à ses compétences en formatage JSON, plutôt que d'identifier la troncature au niveau de l'infrastructure. Cette fausse piste gaspille du temps d'ingénierie et peut conduire à des changements de modèle ou des ajustements de prompt inutiles qui ne traitent pas la cause racine.
Que pouvez-vous faire
- Implémentez une validation côté client pour traiter toute réponse où
usage.output_tokenségalemax_output_tokenscomme potentiellement tronquée et vérifiez l'intégrité de la sortie avant utilisation. - Validez strictement tous les arguments d'appel d'outil comme JSON avant l'exécution ; rejetez tout élément
function_calldont l'analyse échoue, quel que soit son statut rapporté. - Préférez utiliser le point d'accès
/v1/chat/completionspour les tâches critiques si votre architecture applicative le permet, car il rapporte correctementfinish_reason: "length"pour les sorties tronquées. - Augmentez les limites de
max_output_tokenspour les flux de travail des agents afin de réduire la fréquence des troncatures, assurant ainsi que le modèle dispose d'espace suffisant pour compléter des raisonnements complexes ou des définitions d'outils. - Exécutez des scripts de diagnostic tels que
check-llama-responses-status.shcontre votre déploiement pour confirmer si votre version et configuration spécifiques sont affectées par ce comportement de statut forcé. - Surveillez les dépôts amont pour les correctifs apportés au problème #30773 de llama.cpp, et envisagez de contribuer à un correctif qui mappe la raison d'arrêt de la complétion de chat vers le champ de statut de l'API Responses si vous en avez la capacité.



