RU ▾

Начните с пробного баланса

E-mail и пароль — ключ сразу на экране.

https://api.uncensoredllmhub.com/v1

Неизвестная ошибка потока LLM: причины и решения

Если вы продолжаете получать «unknown error from llm stream learn more», сообщение почти всегда скрывает конкретную причину: неверный базовый URL, лимит запросов, запрос большого размера или прокси, буферизующий события. На этой странице показано, как определить, какая именно причина, и исправить её.

Обновлено

Труба, по которой передаются светящиеся пакеты данных, с одним разорванным сегментом под лупой, представляющая ошибку потоковой передачи

Ключевые моменты

  • Текст исходит от клиента, поэтому воспроизведите вызов через curl, чтобы увидеть реальное тело ошибки и статус.
  • HTTP 429 с кодом rate_limited или concurrency — самая частая причина на загруженном аккаунте, а поток сохраняет свой слот до завершения.
  • Проверьте базовый URL, ключ, идентификатор модели uncensored, размер тела (8 МБ) и общее количество токенов (100 000) прежде всего.
  • Повторяйте попытку только при 429 и обрывах сети, ждите Retry-After и держите параллелизм ниже лимита ключа.

Что на самом деле говорит вам сообщение

Если вы искали неизвестная ошибка потока LLM, вы, вероятно, смотрите на всплывающее окно или красную строку в интерфейсе чата, плагине редактора или фреймворке агента. Формулировка исходит от этого клиента. Это означает, что приложение запросило потоковый ответ, что-то пошло не так до или во время потока, и приложение не знало, как это описать. API сам сообщает о проблемах через статус HTTP и тело ошибки JSON, а клиент отбросил эти детали.

Это хорошая новость, потому что это означает, что вы можете вернуть детали. Отправьте тот же запрос вне клиента, прочитайте строку статуса и тело, и причина обычно очевидна за одну-две попытки. Остальная часть этой страницы разбирает причины в порядке их возникновения на этом API, а затем дает небольшой клиент потоковой передачи, который выводит реальную ошибку а не скрывает её.

Одна вещь, которую следует иметь в виду с самого начала: у потокового запроса есть две точки отказа. Он может завершиться ошибкой до первого байта, когда сервер отклоняет запрос (неверный ключ, неверный URL, лимит). Или он может завершиться ошибкой посередине, когда соединение разрывается после того, как уже поступил некоторый текст. Исправления различаются, поэтому обратите внимание, какое из двух вы видите. Если ответ никогда не начинается, смотрите разделы два-четыре. Если он начинается, а затем останавливается, смотрите раздел о прокси и тайм-аутах.

Сначала проверьте базовый URL, ключ и модель

Большинство ошибок потока в новой настройке вызваны тремя небольшими ошибками. Исключить их можно за минуту.

  1. Базовый URL. Он должен быть https://api.uncensoredllmhub.com/v1, включая /v1 и без завершающего /chat/completions. Клиенты добавляют путь самостоятельно. Если вы вставите полный эндпоинт в поле, ожидающее базовый URL, клиент запросит путь, которого не существует, и сообщит о неясной ошибке.
  2. Ключ. Заголовок — Authorization: Bearer YOUR_KEY. Лишний пробел, новая строка, скопированная вместе с ключом, или ключ от другого сервиса приводят к одной и той же ошибке. Создайте или скопируйте ключ заново со страницы API-ключ, если не уверены.
  3. Идентификатор модели. Единственная модель — uncensored. Клиенты, предлагающие выпадающий список, часто предварительно заполняют имя от другого провайдера. Введите ID вручную и вызовите GET /v1/models, если хотите подтвердить, что перечисляет сервер.

Быстрый способ протестировать все три сразу — вызов models. Он не использует потоковую передачу, поэтому он отделяет проблему соединения или ключа от проблемы потоковой передачи:

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

Если возвращается нормальный список, URL и ключ в порядке, и можно перестать их подозревать. Если запрос не выполняется, исправьте это, прежде чем что-либо менять в настройках потоковой передачи. Также проверьте, есть ли на вашем аккаунте кредит: API возвращает оставшийся баланс в заголовке X-Balance-USD в ответах, что удобно, когда ключ внезапно перестает работать после интенсивного использования. На странице цен объясняется, как пополнить баланс, а новые аккаунты могут получить пробный баланс $0.50 на странице ключей.

Лимиты запросов и поток, удерживающий свой слот

Следующая по частоте причина — HTTP 429. Есть три варианта, и ваш клиент объединит все их в одно бесполезное сообщение.

СигналЧто значитЧто делать
429, код rate_limitedСлишком много запросов в минуту для ключаУменьшите частоту запросов: полный ключ позволяет 300 запросов в минуту, пробный — 60
429, код concurrencyСлишком много одновременных запросовПоставьте их в очередь; полный ключ позволяет 8 одновременно, пробный ключ — 2
429 с Retry-After: 5Временная перегрузка на стороне сервисаПодождите 5 секунд, затем повторите попытку

Лимит параллельных запросов удивляет больше всего из-за особенностей потоковой передачи. Запрос в потоке занимает слот до завершения потока, а не до получения первого токена. Если ваше приложение открывает поток для каждого сообщения и никогда не закрывает старые, например, потому что пользователь перешёл на другую страницу, а интерфейс забыл отменить запрос, эти слоты остаются занятыми. На пробном ключе с лимитом 2 два брошенных потока достаточно, чтобы третье сообщение завершилось ошибкой.

Симптомы типичны. Первые несколько сообщений работают, затем начинаются ошибки, а после короткой паузы всё снова работает. Если это так, прерывайте потоки, которые вам больше не нужны (используя AbortController в браузере или закрывая ответ на сервере), и ограничьте количество параллельных вызовов в своём коде. Чаще всего виноваты агенты: планировщик, который одновременно выполняет десять вызовов инструментов, сразу достигнет лимита на пробном ключе.

Заголовки ответа помогают понять текущий статус. X-RateLimit-Limit-Requests и X-RateLimit-Limit-Concurrency показывают лимиты, применимые к использованному ключу, а X-Request-Id идентифицирует запрос, если вам нужно обратиться в поддержку по этому поводу.

Размер запроса и длина контекста

Запрос также может быть отклонён из-за слишком большого размера. Важны два параметра. Тело запроса не должно превышать 8 МБ, а промпт плюс генерация должны помещаться в контекстное окно на 100 000 токенов. Фронтенды чатов, которые пересылают всю историю диалога на каждом шаге, медленно достигают этих лимитов, а затем сразу всё ломается: чат работает час, затем одно длинное сообщение или вставленный файл превышают лимит, и каждый последующий шаг завершается ошибкой, потому что история всё ещё находится в запросе.

Если ошибка начинается после долгой сессии, протестируйте с коротким новым разговором. Если это работает, история — причина. Сократите ее, удалив старые сообщения, сведя их в одно сообщение или начав новый чат. Большие вставленные документы — другой триггер. Текстовый файл размером в несколько сотен килобайт — это нормально, но base64-блоки или очень большие логи могут достичь 8 МБ быстрее, чем вы ожидаете.

Вам не нужно задавать max_tokens, так как генерация может использовать всё оставшееся место в контекстном окне. Если вы всё же задаёте его, убедитесь, что сумма токенов промпта и max_tokens остаётся ниже 100 000. Клиент, который жёстко задаёт большое значение max_tokens поверх длинной истории, может превысить лимит окна, даже если сам промпт выглядит нормально.

Прокси, буферизация и тайм-ауты

Потоковая передача использует серверные события (SSE): долгоживущий HTTP-ответ, который доставляет небольшие фрагменты по мере их создания. Всё, что находится между вами и API и ожидает весь ответ перед его пересылкой, нарушит этот механизм. Результатом будет либо долгое молчание, за которым следует всплеск данных, либо тайм-аут и общая ошибка.

Ищите это в своей настройке:

  • Обратные прокси. Если вы маршрутизируете API через nginx или аналогичный прокси, отключите буферизацию ответов для этого местоположения и увеличьте тайм-аут чтения выше самого длинного ответа, который вы ожидаете. Длинные ответы из окна на 100 000 токенов могут занять время.
  • Корпоративные или антивирусные прокси. Некоторые проверяют HTTPS-трафик и удерживают тело. Протестируйте через мобильный хотспот, чтобы исключить это.
  • Серверлесс-функции. Многие платформы ограничивают время выполнения или буферизуют ответы, если вы не включите потоковую передачу. Если поток обрывается через то же количество секунд каждый раз, вероятной причиной является лимит времени платформы.
  • Расширения браузера и VPN. Редко, но они могут разрывать соединения без активности.

Подсказка, указывающая сюда — ошибка посередине ответа с тем же временем отсечения при каждой попытке. Лимит запросов отклонил бы запрос в начале, поэтому разрыв посередине потока, который всегда происходит, скажем, через 30 секунд, почти никогда не является лимитом.

Клиент, показывающий реальную ошибку

Используйте это, когда вы хотите правду, а не дружелюбное сообщение. Он перехватывает исключения SDK OpenAI, выводит статус и тело ошибки и считывает подсказку о повторной попытке, если она есть.

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)

Та же идея в Node, с сигналом отмены, чтобы брошенные потоки освобождали свой слот:

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

И «голый» вызов curl, который исключает из уравнения все клиентские переменные. -N отключает собственную буферизацию curl, а -i выводит строку статуса и заголовки, включая 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."}]}'

Если curl потоково передает текст нормально, а ваше приложение нет, API здоров, и проблема находится в приложении, его прокси или его настройках. Если curl показывает 429 или другой статус, у вас теперь есть точная причина.

Правила повторной попытки, которые не ухудшают ситуацию

Повторные попытки помогают при временных проблемах и вредят при постоянных. Короткая политика избавит вас от неприятностей.

  • Повторяйте 429 и обрывы. Ждите Retry-After, иначе ждите несколько секунд и добавляйте джиттер, чтобы параллельные воркеры не повторяли запросы синхронно.
  • Не повторяйте запросы при ошибках аутентификации или запросах большого размера. Результат не изменится, а каждое повторение только добавляет шум.
  • Ограничьте попытки тремя или четырьмя, затем покажите пользователю реальный текст ошибки.
  • Ограничьте собственную параллельность ниже лимита ключа. Семафор на 6 для полного ключа оставляет место для второго инструмента, использующего тот же ключ.
  • Если поток прерывается на полпути, сохраните частичный текст. Отправьте его снова, используя этот текст в качестве сообщения ассистента, и попросите модель продолжить, вместо того чтобы генерировать заново с нуля.

Неудачные или отклонённые запросы не оплачиваются, поэтому отладка с помощью повторных тестовых вызовов не расходует ваш предоплаченный баланс. Успешные запросы оплачиваются по цене $0.15 за 1 млн входных токенов и $0.50 за 1 млн выходных токенов, а частичный поток, завершившийся нормально, — это просто короткий ответ. Более подробная информация о формате запроса приведена в документации API.

Если вы выполнили все вышеперечисленные действия, но сообщение всё ещё появляется, отправьте X-Request-Id неудачного вызова на страницу поддержки, указав время попытки и то, произошла ли ошибка до или после первого токена. Эта информация достаточна, чтобы отследить, что произошло.

Вопросы и ответы

Почему моё приложение показывает неизвестную ошибку из потока LLM без каких-либо деталей?

Это формулировка клиентского приложения, которое скрывает исходный код состояния HTTP. Повторите запрос с помощью curl, добавив флаг -i, чтобы увидеть реальный код состояния и тело ошибки в формате JSON.

Является ли ошибка 429 признаком того, что сервис недоступен?

Обычно нет. Это означает, что вы превысили лимит запросов в минуту или лимит параллельных запросов, либо сервис просит подождать 5 секунд, указав заголовок Retry-After. Уменьшите частоту запросов или поставьте их в очередь и повторите попытку.

Почему несколько сообщений обрабатываются успешно, а затем возникает сбой?

Потоки удерживают слот параллельных запросов до завершения. Если предыдущие потоки не были закрыты или история диалога превысила размер контекстного окна, последующие запросы завершаются ошибкой, пока слоты не освободятся или история не будет сокращена.

Оплачиваются ли неудачные запросы потоковой передачи?

Неудачные или отклонённые запросы не тарифицируются, поэтому вы можете свободно проводить тестирование. Успешные запросы тарифицируются по количеству токенов по стандартной цене.

Ваш ключ — всего в одной форме от вас

Создайте аккаунт, скопируйте ключ, измените базовый URL. Это вся настройка.

Получить API-ключ

https://api.uncensoredllmhub.com/v1