PT ▾

Comece com o crédito de teste

E-mail e senha; a chave aparece na hora na tela.

https://api.uncensoredllmhub.com/v1

Erro desconhecido no streaming da LLM: causas e correções

Se você continua vendo erro desconhecido no streaming da LLM, a mensagem quase sempre esconde uma causa específica: URL base errada, limite de taxa, requisição muito grande ou um proxy que faz buffer dos eventos. Esta página mostra como encontrar qual é e corrigi-la.

Atualizado

Canal transportando pacotes de dados brilhantes com um segmento quebrado sob uma lupa, representando um erro de streaming

Pontos principais

  • A mensagem vem do cliente, então reproduza a chamada com curl para ver o corpo de erro real e o status.
  • HTTP 429 com código rate_limited ou erro de concorrência é a causa mais comum em uma conta ocupada, e um stream mantém sua vaga até o fim.
  • Verifique URL base, chave, ID do modelo uncensored, tamanho do corpo (8 MB) e tokens totais (100,000) antes de qualquer outra coisa.
  • Tente novamente apenas para 429 e quedas de rede, aguarde o Retry-After e mantenha a concorrência abaixo do limite da chave.

O que a mensagem realmente diz

Se você pesquisou por erro desconhecido do stream da LLM, provavelmente está vendo um toast ou uma linha vermelha em um front-end de chat, plugin de editor ou framework de agente. A mensagem vem desse cliente. Significa que o app pediu uma resposta em streaming, algo deu errado antes ou durante o stream, e o app não soube descrevê-lo. A API relata problemas com status HTTP e corpo JSON de erro, e o cliente descartou esse detalhe.

Isso é uma boa notícia, porque significa que você pode recuperar o detalhe. Envie a mesma requisição fora do cliente, leia a linha de status e o corpo, e a causa geralmente é óbvia em uma ou duas tentativas. O restante desta página aborda as causas na ordem em que tendem a ocorrer nesta API, depois oferece um pequeno cliente de streaming que imprime o erro real em vez de escondê-lo.

Uma coisa a ter em mente desde o início: uma requisição de streaming tem dois pontos de falha. Pode falhar antes do primeiro byte, quando o servidor rejeita a requisição (chave ruim, URL ruim, um limite). Ou pode falhar no meio, quando a conexão cai após algum texto já ter chegado. As correções diferem, então note qual dos dois você vê. Se a resposta nunca começar, veja as seções dois a quatro. Se começar e depois parar, veja a seção sobre proxies e timeouts.

Verifique a URL base, a chave e o modelo primeiro

A maioria dos erros de streaming em uma configuração nova vem de três pequenos erros. Leva um minuto para descartá-los.

  1. Base URL. Deve ser https://api.uncensoredllmhub.com/v1, incluindo /v1 e sem /chat/completions no final. Os clientes adicionam o caminho eles mesmos. Se você colar o endpoint completo em um campo que espera uma base, o cliente solicitará um caminho que não existe e reportará uma falha vaga.
  2. Chave. O cabeçalho é Authorization: Bearer YOUR_KEY. Um espaço extra, uma nova linha copiada junto com a chave, ou uma chave de outro serviço falham da mesma forma. Crie ou copie a chave novamente na página da chave de API se tiver dúvidas.
  3. ID do modelo. O único modelo é uncensored. Clientes que oferecem um menu suspenso costumam preencher automaticamente um nome de outro provedor. Digite o ID manualmente e chame GET /v1/models se quiser confirmar o que o servidor lista.

Uma maneira rápida de testar os três de uma vez é a chamada models. Ela não faz streaming, então separa um problema de conexão ou chave de um problema de streaming:

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

Se isso retornar uma lista normal, a URL e a chave estão corretas e você pode parar de suspeitar delas. Se falhar, corrija isso antes de mexer em qualquer coisa sobre streaming. Também verifique se sua conta tem crédito: a API envia seu saldo restante no cabeçalho X-Balance-USD nas respostas, o que é útil quando uma chave para de funcionar repentinamente após uso intenso. A página de preços explica recargas, e novas contas podem reivindicar $0,50 de teste na página da chave.

Limites de requisições e o stream que ocupa sua vaga

A próxima causa mais comum é HTTP 429. Existem três variações, e seu cliente agrupará todas na mesma mensagem pouco útil.

SinalSignificadoO que fazer
429, código rate_limitedMuitas requisições por minuto para a chaveDiminua a velocidade; uma chave completa permite 300 por minuto, uma chave de teste 60
429, código concurrencyMuitas requisições simultâneas em execução ao mesmo tempoColoque-os em fila; uma chave completa permite 8 ao mesmo tempo, uma chave de teste 2
429 com Retry-After: 5Sobrecarga temporária no lado do serviçoAguarde 5 segundos e tente novamente

O limite de concorrência é o que surpreende as pessoas, devido ao funcionamento do streaming. Uma requisição em streaming ocupa sua vaga até o stream terminar, não até o primeiro token chegar. Se seu app abre um stream para cada mensagem e nunca fecha o antigo, por exemplo porque o usuário navegou para outro lugar e a UI esqueceu de cancelar a requisição, essas vagas ficam ocupadas. Em uma chave de teste com limite de 2, dois streams abandonados são suficientes para fazer a terceira mensagem falhar.

Os sintomas são consistentes. As primeiras mensagens funcionam, depois começam os erros, depois tudo funciona novamente após uma breve espera. Se isso se encaixa, aborte streams que você não precisa mais (um AbortController no navegador, fechando a resposta em um servidor) e limite o número de chamadas simultâneas no seu código. Agentes são os principais culpados: um planejador que dispara dez tool_calls de uma vez atingirá o limite de uma chave de teste imediatamente.

Os cabeçalhos de resposta ajudam você a ver onde está. X-RateLimit-Limit-Requests e X-RateLimit-Limit-Concurrency mostram os limites aplicáveis à chave que você usou, e X-Request-Id identifica a chamada se precisar entrar em contato com suporte sobre isso.

Tamanho da requisição e comprimento do contexto

Uma requisição também pode ser recusada por ser muito grande. Dois números importam. O corpo pode ter no máximo 8 MB, e o prompt mais a conclusão devem caber em uma janela de contexto de 100.000 tokens. Front-ends de chat que reenviam toda a conversa a cada turno atingem esses limites lentamente e depois de uma vez só: o chat funciona por uma hora, depois uma longa mensagem ou um arquivo colado ultrapassa o limite, e todo turno posterior falha porque o histórico ainda está na requisição.

Se o erro começar após uma sessão longa, teste com uma nova conversa curta. Se isso funcionar, o histórico é a causa. Reduza-o descartando turnos antigos, resumindo-os em uma mensagem ou iniciando um chat novo. Documentos colados grandes são o outro gatilho. Um arquivo texto de algumas centenas de kilobytes está bem, mas blobs base64 ou logs muito grandes podem atingir 8 MB mais rápido do que você espera.

Você não precisa definir max_tokens, já que a conclusão pode usar o que sobrar da janela. Se você definir, certifique-se de que tokens do prompt mais max_tokens fiquem abaixo de 100.000. Um cliente que define um max_tokens grande fixo em cima de um histórico longo pode empurrar a soma acima da janela mesmo quando o prompt sozinho parece ok.

Proxies, buffer e timeouts

O streaming usa eventos enviados pelo servidor: uma resposta HTTP de longa duração que entrega pequenos blocos conforme são produzidos. Qualquer coisa entre você e a API que aguarde a resposta inteira antes de encaminhar quebrará isso. O resultado é ou um longo silêncio seguido por uma explosão, ou um timeout e o erro genérico.

Procure estes na sua própria configuração:

  • Proxies reversos. Se você rotear a API através de um nginx ou proxy similar, desative o buffer de resposta para esse local e aumente o timeout de leitura acima da resposta mais longa que você espera. Respostas longas de uma janela de 100.000 tokens podem demorar um pouco.
  • Proxies corporativos ou antivírus. Alguns inspecionam o tráfego HTTPS e seguram o corpo. Teste de um hotspot de celular para descartar isso.
  • Funções serverless. Muitas plataformas limitam o tempo de execução ou fazem buffer das respostas a menos que você opte pelo streaming. Se o stream morre no mesmo número de segundos toda vez, um limite de tempo da plataforma é a causa provável.
  • Extensões do navegador e VPNs. Raro, mas elas podem cortar conexões ociosas.

A pista que aponta para aqui é um erro no meio de uma resposta, com o mesmo tempo de corte em todas as tentativas. Um limite de taxa rejeitaria a requisição no início, então um corte no meio do stream que sempre acontece, digamos, aos 30 segundos, quase nunca é um limite.

Um cliente que mostra o erro real

Use isso quando quiser a verdade em vez da mensagem amigável. Ele captura exceções do SDK OpenAI, imprime o status e o corpo de erro, e lê a dica de nova tentativa quando há uma.

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)

A mesma ideia em Node, com um sinal de cancelação para que streams abandonados liberem sua vaga:

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

E uma chamada curl bruta, que remove qualquer cliente da equação. -N desativa o buffer próprio do curl e -i imprime a linha de status e cabeçalhos, incluindo 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."}]}'

Se o curl transmite texto bem e seu app não, a API está saudável e o problema está no app, seu proxy ou suas configurações. Se o curl mostrar um 429 ou outro status, você agora tem a causa exata.

Regras de retry que não pioram as coisas

As novas tentativas ajudam com problemas transitórios e prejudicam com problemas permanentes. Uma política curta mantém você fora de problemas.

  • Tente novamente para 429 e conexões caídas. Aguarde Retry-After quando presente, caso contrário espere alguns segundos e adicione um pouco de jitter aleatório para que trabalhadores paralelos não tentem novamente em sincronia.
  • Não tente novamente para falhas de autenticação ou requisições muito grandes. O resultado não mudará, e cada nova tentativa apenas adiciona ruído.
  • Limite as tentativas a três ou quatro, depois mostre ao usuário o texto de erro real.
  • Limite sua própria paralelização abaixo do limite da chave. Um semáforo de 6 em uma chave completa deixa espaço para uma segunda ferramenta usando a mesma chave.
  • Se um stream quebrar pela metade, mantenha o texto parcial. Reenvie com esse texto como uma mensagem de assistant e peça ao modelo para continuar, em vez de regenerar do zero.

Requisições falhas ou recusadas não são cobradas, então depurar com chamadas de teste repetidas não drena seu crédito. Chamadas bem-sucedidas são cobradas a $0,15 por 1M de tokens de entrada e $0,50 por 1M de tokens de saída, e um stream parcial que termina normalmente é simplesmente uma resposta curta. Mais detalhes sobre o formato da requisição estão na documentação da API.

Se você fez tudo acima e ainda vê a mensagem, envie o X-Request-Id de uma chamada falha para a página de suporte, com o horário da tentativa e se a falha veio antes ou depois do primeiro token. Essas informações são suficientes para rastrear o que aconteceu.

Perguntas e respostas

Por que meu app diz erro desconhecido no stream da LLM sem detalhes?

A mensagem vem do aplicativo cliente, que oculta o status HTTP subjacente. Repita a requisição com curl usando -i para ver o status real e o corpo JSON do erro.

Um erro 429 é um sinal de que o serviço está fora do ar?

Normalmente não. Significa que você ultrapassou um limite por minuto ou de concorrência, ou o serviço pediu para você aguardar 5 segundos via Retry-After. Reduza a velocidade ou faça fila nas requisições e tente novamente.

Por que funciona para algumas mensagens e depois falha?

Os fluxos mantêm sua vaga de concorrência até o fim. Se fluxos anteriores nunca foram fechados, ou seu histórico ultrapassou a janela de contexto, as requisições subsequentes falham até que as vagas sejam liberadas ou o histórico seja reduzido.

Requisições de streaming com falha custam dinheiro?

Requisições falhas ou recusadas não são cobradas, então você pode testar livremente. Requisições concluídas são cobradas por tokens ao preço normal.

Faltando apenas um formulário para sua chave

Crie uma conta, copie a chave e altere a URL base. Essa é toda a configuração.

Obter chave de API

https://api.uncensoredllmhub.com/v1