繁中 ▾

從試用額度開始

電子郵件和密碼,金鑰立即顯示在畫面上。

https://api.uncensoredllmhub.com/v1

LLM 串流輸出未知錯誤:原因與解決方法

如果您持續看到來自 LLM 串流的未知錯誤,該訊息幾乎總是隱藏了特定原因:Base URL 錯誤、速率限制、請求過大或緩衝事件的代理伺服器。本頁將說明如何找出原因並加以修復。

更新於

帶有發光資料包的管線,其中一個區段在放大鏡下斷裂,代表串流錯誤

重點摘要

  • 文字來自客戶端,因此請使用 curl 重現呼叫,以查看真實的錯誤主體和狀態。
  • HTTP 429 錯誤(代碼為 rate_limited 或 concurrency)是繁忙帳戶最常見的原因,且串流會佔用其槽位直到結束。
  • 在進行其他操作之前,先檢查 Base URL、金鑰、模型 ID uncensored、主體大小(8 MB)和總 token 數(100,000)。
  • 僅重試 429 錯誤和網路中斷,等待 Retry-After,並將並行請求保持在金鑰限制之下。

該訊息實際告訴您的內容

如果你搜尋了 來自 LLM 串流的未知錯誤 learn more,你很可能是在聊天前端、編輯器外掛或代理框架中看到彈出訊息或紅線。該用語來自該客戶端。它表示應用程式要求了串流輸出,但在串流之前或期間發生錯誤,而應用程式不知道如何描述該錯誤。API 本身會以 HTTP 狀態碼和 JSON 錯誤主體回報問題,而客戶端已丟棄該詳細資訊。

這是好消息,因為這表示您可以找回詳細資訊。在客戶端之外發送相同的請求,讀取狀態行和主體,原因通常在一次或兩次嘗試後就很明顯。本頁其餘部分將按照該 API 上傾向發生的順序列出原因,然後提供一個小型串流客戶端,它會列印真實錯誤而非隱藏它。

從一開始就要記住的一件事:串流請求有兩個失敗點。它可以在第一個位元組之前失敗,當伺服器拒絕請求時(金鑰錯誤、URL 錯誤、限制)。或者它可以在中間失敗,當連線在已收到一些文字後中斷。修復方法不同,因此請注意您看到的是哪一種。如果答案從未開始,請查看第二到第四節。如果它開始然後停止,請查看關於代理伺服器和超時的部分。

首先檢查 Base URL、金鑰和模型

新設定中的大多數串流錯誤來自三個小失誤。排除這些需要一分鐘。

  1. Base URL。 它必須是 https://api.uncensoredllmhub.com/v1,包含 /v1 且沒有尾隨的 /chat/completions。客戶端會自行附加路徑。如果您將完整端點貼上到期望 Base 的欄位中,客戶端會請求一個不存在的路徑並報告模糊的失敗。
  2. 金鑰。 標頭是 Authorization: Bearer YOUR_KEY。多餘的空格、連同金鑰複製的換行符,或來自其他服務的金鑰都會以相同方式失敗。如果您不確定,請從 API 金鑰頁面 重新建立或複製金鑰。
  3. 模型 ID。 唯一的模型是 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 秒後再重試

並行限制是讓人驚訝的那一個,因為串流的工作方式。串流請求會佔用其槽位直到串流結束,而不僅僅是第一個 token 到達時。如果您的應用程式為每則訊息開啟串流且從未關閉舊的串流(例如,因為使用者導航離開且 UI 忘記取消請求),這些槽位會保持佔用狀態。在限制為 2 的試用金鑰上,兩個被放棄的串流就足以讓第三則訊息失敗。

症狀是一致的。前幾則訊息可以運作,然後開始出現錯誤,然後在短暫等待後一切又恢復正常。如果符合,請中止不再需要的串流(瀏覽器中的 AbortController,伺服器中關閉回應),並在您自己的程式碼中限制並行呼叫的數量。代理程式是常見的肇事者:一次觸發十個函式呼叫的規劃器會立即達到試用金鑰的限制。

回應標頭可幫助您了解目前的狀況。X-RateLimit-Limit-Requests 和 X-RateLimit-Limit-Concurrency 顯示適用於您使用的金鑰的限制,而 X-Request-Id 標識呼叫,如果您需要向 支援 查詢此事。

請求大小與上下文長度

請求也可能因過大而被拒絕。兩個數字很重要。主體最多為 8 MB,提示詞加上補全必須適合 100,000 token 的上下文視窗。每次輪次都重新發送整個對話的聊天前端會緩慢地達到這些限制,然後一次性全部失敗:聊天運作一個小時,然後一個長訊息或貼上的檔案使其超過限制,之後的每個輪次都會失敗,因為歷史記錄仍在請求中。

如果錯誤在長時間會話後開始,請使用新的短對話進行測試。如果這可以運作,則歷史記錄是原因。透過刪除舊輪次、將它們總結為一則訊息或開始新的聊天來縮減它。大型貼上的文件是另一個觸發因素。幾百 KB 的文字檔案沒問題,但 base64 資料塊或非常大的日誌可能比您預期的更快達到 8 MB。

您不必設定 max_tokens,因為補全可以使用視窗中剩餘的任何內容。如果您確實設定了它,請確保提示詞 token 加上 max_tokens 保持在 100,000 以下。在長歷史記錄之上硬編碼大型 max_tokens 的客戶端可能會使總和超過視窗,即使單獨的提示詞看起來沒問題。

代理伺服器、緩衝和超時

串流使用伺服器發送的事件:一個長期的 HTTP 回應,隨著產生的進度交付小區塊。在您和 API 之間的任何等待整個回應再轉發它的東西都會破壞這一點。結果要麼是長時間的沉默後出現爆發,要麼是超時和通用錯誤。

在您自己的設定中尋找這些:

  • 反向代理伺服器。 如果您透過 nginx 或類似的代理伺服器路由 API,請關閉該位置的回應緩衝,並將讀取超時提高到您預期的最長答案之上。來自 100,000 token 視窗的長答案可能需要一些時間。
  • 企業或防毒軟體代理伺服器。 某些代理伺服器會檢查 HTTPS 流量並保留主體。請使用手機熱點進行測試以排除此問題。
  • 無伺服器函式。 許多平台會限制執行時間或緩衝回應,除非您選擇啟用串流。如果串流每次都在相同的秒數死亡,平台時間限制可能是原因。
  • 瀏覽器擴充功能和 VPN。 很少見,但它們可以切斷閒置連線。

指向此處的線索是答案中間的錯誤,每次嘗試都有相同的截斷時間。速率限制會在開始時拒絕請求,因此串流中間的截斷(例如總是發生在 30 秒時)幾乎從來不是限制。

顯示真實錯誤的客戶端

當您想要真相而不是友好的訊息時使用此方法。它會捕獲 OpenAI SDK 異常,列印狀態和錯誤主體,並在存在時讀取重試提示。

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 的訊號量,可為使用相同金鑰的第二個工具保留空間。
  • 如果串流在中途斷裂,請保留部分文字。將該文字作為助手訊息重新發送,並要求模型繼續,而不是從頭開始重新生成。

失敗或遭拒的請求不會計費,因此使用重複的測試呼叫進行除錯不會耗盡你的額度。成功的請求會以每 1M 輸入 token $0.15 和每 1M 輸出 token $0.50 計費,而正常完成的 部分串流 僅是一個簡短的答案。有關請求格式的更多詳細資訊,請參見 API 文件。

如果您已完成上述所有操作但仍看到該訊息,請將失敗呼叫的 X-Request-Id 發送到 支援頁面,附上嘗試時間以及失敗是在第一個 token 之前還是之後發生的。這些資訊足以追蹤發生了什麼。

問答

為什麼我的應用程式在 LLM 串流時顯示未知錯誤且沒有任何詳細資訊?

這些文字來自隱藏底層 HTTP 狀態的客戶端應用程式。使用 curl 並加上 -i 參數重新發送請求,即可看到真實的狀態碼與 JSON 錯誤訊息。

429 錯誤代表服務當機嗎?

通常不是。這表示你已超過每分鐘或並行請求的速率限制,或是服務要求你透過 Retry-After 標頭等待 5 秒。請放慢速度、將請求排入佇列後再重試。

為什麼前幾則訊息正常,之後卻失敗?

串流會佔用並行請求槽位直到結束為止。如果之前的串流從未關閉,或是你的歷史記錄已超出上下文視窗,後續請求就會失敗,直到槽位釋放或歷史記錄被截斷為止。

失敗的串流請求會收費嗎?

失敗或被拒絕的請求不會收費,因此你可以自由測試。已完成的請求則會按正常價格以 token 計費。

只差一張表單,即可取得金鑰

建立帳號、複製金鑰、更改基礎 URL。這就是整個設定過程。

取得 API 金鑰

https://api.uncensoredllmhub.com/v1