FR ▾

Commencez avec le crédit d'essai

E-mail et mot de passe, la clé s'affiche tout de suite à l'écran.

https://api.uncensoredllmhub.com/v1

Erreur inconnue du flux LLM : causes et solutions

Si vous voyez encore une erreur inconnue dans le flux LLM, En savoir plus, le message cache presque toujours une cause précise : une URL de base incorrecte, une limite de débit, une requête trop volumineuse ou un proxy qui tamponne les événements. Cette page explique comment identifier laquelle et la corriger.

Mis à jour le

Tuyau transportant des paquets de données lumineux avec un segment brisé sous une loupe, représentant une erreur de streaming

Points clés

  • Le texte provient du client, donc reproduisez l'appel avec curl pour voir le corps d'erreur et le statut réels.
  • HTTP 429 avec le code rate_limited ou concurrency est la cause la plus courante sur un compte occupé, et un flux conserve son slot jusqu'à sa fin.
  • Vérifiez l'URL de base, la clé, l'ID de modèle uncensored, la taille du corps (8 Mo) et le nombre total de tokens (100 000) avant toute autre chose.
  • Ne réessayez que les erreurs 429 et les coupures réseau, attendez Retry-After, et maintenez la concurrence sous la limite de la clé.

Ce que le message vous indique réellement

Si vous avez recherché erreur inconnue dans le flux LLM, En savoir plus, vous consultez probablement une notification toast, une ligne rouge dans un front-end de chat, un plugin d'éditeur ou un framework agent. Ce libellé provient de ce client. Il signifie que l'application a demandé une réponse en streaming, qu'une erreur est survenue avant ou pendant le streaming, et que l'application n'a pas su la décrire. L'API signale les problèmes avec un statut HTTP et un corps d'erreur JSON, et le client a ignoré ces détails.

C'est une bonne nouvelle, car cela signifie que vous pouvez récupérer les détails. Envoyez la même requête en dehors du client, lisez la ligne de statut et le corps, et la cause est généralement évidente en une ou deux tentatives. Le reste de cette page passe en revue les causes dans l'ordre où elles se produisent généralement sur cette API, puis vous donne un petit client de streaming qui affiche la vraie erreur au lieu de la masquer.

Une chose à garder à l'esprit dès le départ : une requête de streaming a deux points de défaillance. Elle peut échouer avant le premier octet, lorsque le serveur rejette la requête (mauvaise clé, mauvaise URL, une limite). Ou elle peut échouer au milieu, lorsque la connexion tombe après que du texte est déjà arrivé. Les correctifs diffèrent, alors notez lequel des deux vous observez. Si la réponse ne commence jamais, consultez les sections deux à quatre. Si elle commence puis s'arrête, consultez la section sur les proxys et les délais d'attente.

Vérifiez d'abord l'URL de base, la clé et le modèle

La plupart des erreurs de streaming sur une configuration fraîche proviennent de trois petites erreurs. Elles prennent une minute à écarter.

  1. URL de base. Elle doit être https://api.uncensoredllmhub.com/v1, incluant /v1 et sans /chat/completions à la fin. Les clients ajoutent le chemin eux-mêmes. Si vous collez l'endpoint complet dans un champ qui attend une URL de base, le client demande un chemin qui n'existe pas et signale une erreur vague.
  2. Clé. L'en-tête est Authorization: Bearer YOUR_KEY. Un espace parasite, une nouvelle ligne copiée avec la clé, ou une clé d'un autre service échouent de la même manière. Créez ou copiez à nouveau la clé depuis la page des clés API si vous n'êtes pas sûr.
  3. ID de modèle. Le seul modèle est uncensored. Les clients qui proposent une liste déroulante remplissent souvent un nom d'un autre fournisseur. Saisissez l'ID à la main, et appelez GET /v1/models si vous voulez confirmer ce que le serveur liste.

Un moyen rapide de tester les trois à la fois est l'appel models. Il ne fait pas de streaming, donc il sépare un problème de connexion ou de clé d'un problème de streaming :

curl -i https://api.uncensoredllmhub.com/v1/models   -H "Authorization: Bearer $API_KEY"

Si cela renvoie une liste normale, l'URL et la clé sont correctes et vous pouvez cesser de les suspecter. En cas d'échec, corrigez cela avant de toucher au streaming. Vérifiez aussi que votre compte dispose de crédit : l'API renvoie le solde restant dans l'en-tête X-Balance-USD des réponses, ce qui est utile quand une clé cesse soudainement de fonctionner après une utilisation intensive. La page tarifs explique les recharges, et les nouveaux comptes peuvent obtenir un crédit d'essai de 0,50 $ depuis la page des clés.

Limites de débit et flux qui conserve son slot

La cause la plus courante suivante est HTTP 429. Il existe trois variantes, et votre client les regroupera toutes dans le même message peu utile.

SignalSignificationQue faire
429, code rate_limitedTrop de requêtes par minute pour la cléRalentissez ; une clé standard permet 300 par minute, une clé d'essai 60
429, code concurrencyTrop de requêtes exécutées simultanémentMettez-les en file d'attente ; une clé complète permet 8 à la fois, une clé d'essai 2
429 avec Retry-After: 5Surcharge temporaire du côté du serviceAttendez 5 secondes, puis réessayez

La limite de concurrence est celle qui surprend, à cause du fonctionnement du streaming. Une requête en streaming occupe son créneau jusqu'à la fin du flux, et non jusqu'à l'arrivée du premier token. Si votre application ouvre un streaming pour chaque message sans jamais fermer l'ancien, par exemple parce que l'utilisateur a navigué ailleurs et que l'interface a oublié d'annuler la requête, ces créneaux restent occupés. Sur une clé d'essai avec une limite de 2, deux flux abandonnés suffisent à faire échouer le troisième message.

Les symptômes sont cohérents. Les premiers messages fonctionnent, puis des erreurs commencent, puis tout fonctionne à nouveau après une courte attente. Si cela correspond, annulez les flux dont vous n'avez plus besoin (un AbortController dans le navigateur, fermer la réponse sur un serveur), et plafonnez le nombre d'appels parallèles dans votre propre code. Les agents sont les principaux coupables : un planificateur qui déclenche dix appels de fonctions à la fois atteindra la limite sur une clé d'essai immédiatement.

Les en-têtes de réponse vous aident à savoir où vous en êtes. X-RateLimit-Limit-Requests et X-RateLimit-Limit-Concurrency indiquent les limites qui s'appliquent à la clé que vous avez utilisée, et X-Request-Id identifie l'appel si vous devez contacter le support à ce sujet.

Taille de la requête et longueur du contexte

Une requête peut également être refusée pour être trop volumineuse. Deux nombres comptent. Le corps peut faire au maximum 8 MB, et le prompt plus la complétion doivent tenir dans une fenêtre de contexte de 100 000 tokens. Les front-ends de chat qui renvoient toute la conversation à chaque tour atteignent ces limites lentement puis tous en même temps : le chat fonctionne pendant une heure, puis un long message ou un fichier collé le fait basculer, et chaque tour suivant échoue parce que l'historique est toujours dans la requête.

Si l'erreur commence après une longue session, testez avec une nouvelle conversation courte. Si cela fonctionne, l'historique est la cause. Réduisez-le en supprimant les anciens tours, en les résumant en un seul message, ou en démarrant un nouveau chat. Les gros documents collés sont l'autre déclencheur. Un fichier texte de quelques centaines de kilo-octets est correct, mais les blobs base64 ou les logs très volumineux peuvent atteindre 8 Mo plus vite que prévu.

Vous n'avez pas besoin de définir max_tokens, car la complétion peut utiliser tout l'espace restant de la fenêtre. Si vous le définissez, assurez-vous que le nombre de tokens du prompt plus max_tokens reste inférieur à 100 000. Un client qui code en dur une valeur élevée de max_tokens sur une longue histoire peut dépasser la limite de la fenêtre de contexte, même si le prompt seul semble correct.

Proxys, mise en tampon et délais d'attente

Le streaming utilise les événements envoyés par le serveur : une réponse HTTP de longue durée qui délivre de petits blocs au fur et à mesure de leur production. Tout élément entre vous et l'API qui attend la réponse complète avant de la transmettre brisera ce mécanisme. Le résultat est soit un long silence suivi d'une rafale, soit un timeout et l'erreur générique.

Recherchez ces éléments dans votre propre configuration :

  • Proxys inverses. Si vous acheminez l'API via nginx ou un proxy similaire, désactivez la mise en tampon des réponses pour cet emplacement, et augmentez le délai de lecture au-delà de la réponse la plus longue que vous attendez. Les réponses longues depuis une fenêtre de 100 000 tokens peuvent prendre un certain temps.
  • Proxys d'entreprise ou antivirus. Certains inspectent le trafic HTTPS et retiennent le corps. Testez depuis un point d'accès mobile pour écarter cette hypothèse.
  • Fonctions sans serveur. De nombreuses plateformes limitent la durée d'exécution ou tamponnent les réponses à moins que vous n'activiez le streaming. Si le flux meurt au bout du même nombre de secondes à chaque fois, une limite de durée de la plateforme en est probablement la cause.
  • Extensions de navigateur et VPN. Rare, mais ils peuvent couper les connexions inactives.

L'indice qui pointe ici est une erreur au milieu d'une réponse, avec le même temps de coupure à chaque tentative. Une limite de débit rejetterait la requête au début, donc une coupure en milieu de flux qui se produit toujours, disons, à 30 secondes n'est presque jamais une limite.

Un client qui affiche la vraie erreur

Utilisez ceci lorsque vous préférez la vérité au message convivial. Il intercepte les exceptions du SDK OpenAI, affiche le statut et le corps d'erreur, et lit l'indication de nouvelle tentative lorsqu'elle est présente.

import time
from openai import OpenAI, APIConnectionError, APIStatusError, RateLimitError

client = OpenAI(
    base_url="https://api.uncensoredllmhub.com/v1",
    api_key="YOUR_API_KEY",
)

def stream_once(messages):
    stream = client.chat.completions.create(
        model="uncensored",
        messages=messages,
        stream=True,
    )
    for chunk in stream:
        if chunk.choices and chunk.choices[0].delta.content:
            print(chunk.choices[0].delta.content, end="", flush=True)
        if getattr(chunk, "usage", None):
            print("\n[usage]", chunk.usage)

messages = [{"role": "user", "content": "Write two sentences about harbours."}]

for attempt in range(4):
    try:
        stream_once(messages)
        break
    except RateLimitError as e:
        wait = int(e.response.headers.get("retry-after", 5))
        print("429:", e.body, "- waiting", wait, "s")
        time.sleep(wait)
    except APIStatusError as e:
        print("status", e.status_code, e.body)
        print("request id:", e.response.headers.get("x-request-id"))
        break
    except APIConnectionError as e:
        print("connection problem:", e)
        time.sleep(2)

La même idée en Node, avec un signal d'annulation pour libérer le créneau des flux abandonnés :

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.uncensoredllmhub.com/v1",
  apiKey: process.env.API_KEY,
});

const controller = new AbortController();

try {
  const stream = await client.chat.completions.create(
    {
      model: "uncensored",
      messages: [{ role: "user", content: "Write two sentences about harbours." }],
      stream: true,
    },
    { signal: controller.signal }
  );
  for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
  }
} catch (err) {
  console.error("status:", err.status, "body:", err.error);
}
// call controller.abort() when the user leaves the page

Et un appel curl brut, qui retire tout client de l'équation. -N désactive la mise en mémoire tampon interne de curl et -i affiche la ligne de statut et les en-têtes, y compris X-Request-Id :

curl -N -i https://api.uncensoredllmhub.com/v1/chat/completions   -H "Authorization: Bearer $API_KEY"   -H "Content-Type: application/json"   -d '{"model":"uncensored","stream":true,"messages":[{"role":"user","content":"Say hello."}]}'

Si curl diffuse du texte correctement et que votre application ne le fait pas, l'API est saine et le problème se trouve dans l'application, son proxy ou ses paramètres. Si curl affiche un 429 ou un autre statut, vous avez maintenant la cause exacte.

Règles de retry qui n'empirent pas les choses

Les nouvelles tentatives aident en cas de problèmes temporaires et nuisent en cas de problèmes permanents. Une politique courte vous évite les ennuis.

  • Nouvelle tentative sur les 429 et les connexions interrompues. Attendez Retry-After lorsqu'il est présent, sinon attendez quelques secondes en augmentant le délai, et ajoutez un jitter aléatoire pour éviter que les workers parallèles ne réessayent en même temps.
  • Ne relancez pas les échecs d'authentification ou les requêtes trop volumineuses. Le résultat ne changera pas, et chaque relance n'ajoute que du bruit.
  • Limitez les tentatives à trois ou quatre, puis affichez le texte d'erreur réel à l'utilisateur.
  • Plafonnez votre propre parallélisme en dessous de la limite de clé. Un sémaphore de 6 sur une clé complète laisse de la place pour un deuxième outil utilisant la même clé.
  • Si un flux se casse à mi-chemin, gardez le texte partiel. Renvoyez-le avec ce texte comme message assistant et demandez au modèle de continuer, plutôt que de régénérer depuis zéro.

Les requêtes échouées ou refusées ne sont pas facturées, donc déboguer avec des appels de test répétés ne vide pas votre crédit. Les appels réussis sont facturés à 0,15 $ par 1M de tokens d'entrée et 0,50 $ par 1M de tokens de sortie, et un flux partiel qui se termine normalement est simplement une réponse courte. Plus de détails sur le format de la requête se trouvent dans la documentation API.

Si vous avez effectué toutes les opérations ci-dessus et voyez toujours le message, envoyez l'ID de requête X-Request-Id d'un appel défaillant à la page support, avec l'heure de la tentative et si l'échec est survenu avant ou après le premier token. Ces informations suffisent pour retracer ce qui s'est passé.

Questions et réponses

Pourquoi mon application indique-t-elle une erreur inconnue du flux LLM sans aucun détail ?

Le message provient de l’application cliente, qui masque le statut HTTP sous-jacent. Répétez la requête avec curl en utilisant l’option -i pour afficher le statut réel et le corps de l’erreur JSON.

Une erreur 429 signifie-t-elle que le service est indisponible ?

Généralement non. Cela signifie que vous avez dépassé une limite par minute ou de concurrence, ou que le service vous a demandé d’attendre 5 secondes via l’en-tête Retry-After. Ralentissez ou mettez les requêtes en file d’attente, puis réessayez.

Pourquoi cela fonctionne-t-il pour quelques messages, puis échoue-t-il ?

Les flux maintiennent leur place de concurrence jusqu’à ce qu’ils soient terminés. Si des flux précédents n’ont jamais été fermés, ou si votre historique a dépassé la fenêtre de contexte, les requêtes suivantes échouent jusqu’à ce que les places se libèrent ou que l’historique soit réduit.

Les requêtes de flux échouées sont-elles facturées ?

Les requêtes échouées ou refusées ne sont pas facturées, vous pouvez donc tester librement. Les requêtes terminées sont facturées par token au tarif normal.

Il ne vous reste qu'un formulaire pour obtenir votre clé

Créez un compte, copiez la clé, modifiez l'URL de base. C'est toute la configuration.

Obtenir une clé API

https://api.uncensoredllmhub.com/v1