Poin utama
- Teks tersebut berasal dari klien, jadi reproduksi panggilan dengan curl untuk melihat badan error dan status yang sebenarnya.
- HTTP 429 dengan kode rate_limited atau concurrency adalah penyebab paling umum pada akun yang sibuk, dan stream memegang slotnya hingga berakhir.
- Periksa URL dasar, kunci, ID model uncensored, ukuran badan (8 MB), dan total token (100,000) sebelum melakukan apa pun.
- Coba lagi hanya untuk 429 dan drop jaringan, tunggu Retry-After, dan pertahankan konkurensi di bawah batas kunci.
Apa yang sebenarnya disampaikan pesan ini kepada Anda
Jika Anda mencari error tidak diketahui dari streaming LLM, kemungkinan besar Anda melihat notifikasi (toast) atau baris merah di antarmuka klien, plugin editor, atau kerangka kerja agen. Penulisan ini berasal dari klien tersebut. Ini berarti aplikasi meminta jawaban yang di-stream, terjadi kesalahan sebelum atau selama proses streaming, dan aplikasi tidak tahu cara menggambarkannya. API itu sendiri melaporkan masalah dengan status HTTP dan badan error JSON, sementara klien telah membuang detail tersebut.
Itu kabar baik, karena itu berarti Anda dapat mendapatkan kembali detailnya. Kirim permintaan yang sama di luar klien, baca baris status dan badannya, dan penyebabnya biasanya jelas dalam satu atau dua percobaan. Sisa halaman ini membahas penyebabnya sesuai urutan kemunculannya pada API ini, lalu memberikan klien streaming kecil yang mencetak error asli alih-alih menyembunyikannya.
Satu hal yang perlu diingat sejak awal: permintaan streaming memiliki dua titik kegagalan. Permintaan dapat gagal sebelum byte pertama, saat server menolak permintaan (kunci salah, URL salah, batas). Atau dapat gagal di tengah, saat koneksi terputus setelah beberapa teks telah tiba. Perbaikannya berbeda, jadi perhatikan mana dari dua yang Anda lihat. Jika jawaban tidak pernah dimulai, lihat bagian dua hingga empat. Jika dimulai lalu berhenti, lihat bagian tentang proxy dan timeout.
Periksa URL dasar, kunci, dan model terlebih dahulu
Sebagian besar error streaming pada konfigurasi baru berasal dari tiga kesalahan kecil. Anda hanya perlu beberapa menit untuk menyingkirkan kemungkinan tersebut.
- Base URL. Haruslah
https://api.uncensoredllmhub.com/v1, termasuk/v1dan tanpa/chat/completionsdi akhir. Klien menambahkan jalur sendiri. Jika Anda menempelkan endpoint lengkap ke dalam bidang yang mengharapkan base, klien meminta jalur yang tidak ada dan melaporkan kegagalan yang samar. - Kunci. Header adalah
Authorization: Bearer YOUR_KEY. Spasi yang tersesat, newline yang disalin bersama kunci, atau kunci dari layanan lain akan gagal dengan cara yang sama. Buat atau salin kunci lagi dari halaman kunci API jika Anda ragu. - ID Model. Satu-satunya model adalah
uncensored. Klien yang menawarkan dropdown sering kali mengisi nama dari penyedia lain. Ketik ID secara manual, dan panggilGET /v1/modelsjika Anda ingin mengonfirmasi apa yang terdaftar di server.
Cara cepat untuk menguji ketiganya sekaligus adalah panggilan models. Ini tidak melakukan streaming, sehingga memisahkan masalah koneksi atau kunci dari masalah streaming:
curl -i https://api.uncensoredllmhub.com/v1/models -H "Authorization: Bearer $API_KEY"
Jika ini mengembalikan daftar normal, URL dan kunci Anda baik-baik saja dan Anda bisa berhenti mencurigai keduanya. Jika gagal, perbaiki itu sebelum menyentuh apa pun tentang streaming. Juga periksa bahwa akun Anda memiliki kredit: API mengirimkan sisa saldo Anda di header X-Balance-USD pada respons, yang berguna ketika kunci tiba-tiba berhenti bekerja setelah penggunaan berat. Halaman harga menjelaskan pengisian ulang, dan akun baru dapat mengklaim kredit uji coba $0.50 dari halaman kunci.
Batas laju dan stream yang memegang slotnya
Penyebab paling umum berikutnya adalah HTTP 429. Ada tiga variasi, dan klien Anda akan menggabungkan semuanya menjadi pesan yang sama-sama tidak membantu.
| Sinyal | Arti | Apa yang harus dilakukan |
|---|---|---|
429, kode rate_limited | Terlalu banyak permintaan per menit untuk kunci | Turunkan kecepatan; kunci penuh memungkinkan 300 per menit, kunci uji coba 60 |
429, kode concurrency | Terlalu banyak permintaan yang berjalan bersamaan | Antrikan; kunci penuh memungkinkan 8 sekaligus, kunci uji coba 2 |
429 dengan Retry-After: 5 | Kelebihan beban sementara di sisi layanan | Tunggu 5 detik, lalu coba lagi |
Batas konkurensi adalah yang mengejutkan orang, karena cara kerja streaming. Permintaan streaming memegang slotnya hingga streaming berakhir, bukan hingga token pertama tiba. Jika aplikasi Anda membuka stream untuk setiap pesan dan tidak pernah menutup stream lama, misalnya karena pengguna berpindah halaman dan UI lupa membatalkan permintaan, slot tersebut tetap terisi. Pada kunci uji coba dengan batas 2, dua stream yang dibiarkan saja sudah cukup untuk membuat pesan ketiga gagal.
Gejalanya konsisten. Beberapa pesan awal berfungsi, kemudian error mulai muncul, lalu semuanya berfungsi kembali setelah jeda singkat. Jika itu sesuai, hentikan streaming yang tidak lagi Anda butuhkan (menggunakan AbortController di browser, atau menutup respons di sisi server), dan batasi jumlah panggilan paralel dalam kode Anda sendiri. Agen adalah penyebab umum: perencana yang memicu sepuluh panggilan fungsi sekaligus akan langsung mencapai batas pada kunci uji coba.
Header respons membantu Anda melihat status Anda. X-RateLimit-Limit-Requests dan X-RateLimit-Limit-Concurrency menunjukkan batas yang berlaku untuk kunci yang Anda gunakan, dan X-Request-Id mengidentifikasi panggilan jika Anda perlu menghubungi dukungan tentang hal tersebut.
Ukuran permintaan dan panjang konteks
Permintaan juga dapat ditolak karena terlalu besar. Dua angka penting. Badan permintaan maksimal 8 MB, dan prompt plus penyelesaian harus muat dalam jendela konteks 100.000 token. Antarmuka obrolan yang mengirim ulang seluruh percakapan pada setiap giliran mencapai batas ini secara bertahap lalu sekaligus: obrolan berfungsi selama satu jam, lalu satu pesan panjang atau dokumen yang ditempelkan membuatnya melebihi batas, dan setiap giliran berikutnya gagal karena riwayat masih ada dalam permintaan.
Jika error dimulai setelah sesi panjang, uji dengan percakapan baru yang pendek. Jika itu berhasil, riwayat adalah penyebabnya. Potong dengan membuang giliran lama, meringkasnya menjadi satu pesan, atau memulai obrolan baru. Dokumen yang ditempelkan besar adalah pemicu lainnya. File teks beberapa ratus kilobyte tidak masalah, tetapi blob base64 atau log yang sangat besar dapat mencapai 8 MB lebih cepat dari yang Anda harapkan.
Anda tidak perlu mengatur max_tokens, karena penyelesaian dapat menggunakan apa pun yang tersisa dari jendela konteks. Jika Anda mengaturnya, pastikan token prompt ditambah max_tokens tetap di bawah 100.000. Klien yang mengkodekan besar max_tokens di atas riwayat panjang dapat mendorong jumlah melebihi jendela konteks bahkan ketika prompt saja terlihat baik.
Proxy, buffering, dan timeout
Streaming menggunakan event yang dikirim server: respons HTTP berumur panjang yang mengirimkan potongan kecil saat diproduksi. Apa pun di antara Anda dan API yang menunggu respons lengkap sebelum meneruskannya akan merusak itu. Hasilnya adalah keheningan panjang diikuti oleh ledakan, atau timeout dan error generik.
Cari ini dalam pengaturan Anda sendiri:
- Proxy terbalik. Jika Anda mengarahkan API melalui nginx atau proxy serupa, matikan buffering respons untuk lokasi tersebut, dan tingkatkan timeout baca di atas jawaban terpanjang yang Anda harapkan. Jawaban panjang dari jendela 100.000 token dapat memakan waktu.
- Proxy perusahaan atau antivirus. Beberapa memeriksa lalu lintas HTTPS dan menahan badan. Uji dari hotspot ponsel untuk menyingkirkan ini.
- Fungsi serverless. Banyak platform membatasi waktu eksekusi atau melakukan buffering respons kecuali Anda mengaktifkan streaming. Jika stream mati pada jumlah detik yang sama setiap kali, batas waktu platform adalah penyebab yang mungkin.
- Ekstensi browser dan VPN. Jarang, tetapi mereka dapat memutus koneksi idle.
Petunjuk yang mengarah ke sini adalah error di tengah jawaban, dengan waktu pemotongan yang sama pada setiap percobaan. Batas laju akan menolak permintaan di awal, sehingga pemotongan di tengah stream yang selalu terjadi, misalnya pada 30 detik, hampir pasti bukan batas.
Klien yang menampilkan error asli
Gunakan ini ketika Anda menginginkan kebenaran daripada pesan ramah. Ini menangkap pengecualian SDK OpenAI, mencetak status dan badan error, dan membaca petunjuk retry jika ada.
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)
Ide yang sama di Node, dengan sinyal abort agar stream yang ditinggalkan melepaskan slotnya:
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
Dan panggilan curl mentah, yang menghilangkan setiap klien dari gambaran. -N mematikan buffering bawaan curl dan -i mencetak baris status dan header, termasuk 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."}]}'
Jika curl meng-stream teks dengan baik dan aplikasi Anda tidak, API sehat dan masalah ada di aplikasi, proxy, atau pengaturannya. Jika curl menampilkan 429 atau status lain, Anda sekarang memiliki penyebab pastinya.
Aturan retry yang tidak memperburuk keadaan
Percobaan ulang membantu dengan masalah sementara dan merugikan dengan masalah permanen. Kebijakan singkat menjaga Anda dari masalah.
- Coba ulang 429 dan koneksi terputus. Tunggu
Retry-Afterjika ada, jika tidak tunggu beberapa detik dan tambahkan jitter acak agar worker paralel tidak mencoba ulang serentak. - Jangan coba lagi kegagalan autentikasi atau permintaan yang terlalu besar. Hasilnya tidak akan berubah, dan setiap retry hanya menambah kebisingan.
- Batasi upaya menjadi tiga atau empat, lalu tampilkan teks error asli kepada pengguna.
- Batasi paralelisme Anda di bawah batas kunci. Semaphore 6 pada kunci penuh menyisakan ruang untuk alat kedua yang menggunakan kunci yang sama.
- Jika stream terputus di tengah jalan, pertahankan teks parsial. Kirim ulang dengan teks itu sebagai pesan asisten dan minta model melanjutkan, alih-alih melakukan regenerasi dari awal.
Permintaan yang gagal atau ditolak tidak dibebankan biaya, sehingga debugging dengan panggilan tes berulang tidak menguras kredit Anda. Panggilan yang berhasil ditagih sebesar $0.15 per 1M token input dan $0.50 per 1M token output, dan aliran parsial yang selesai secara normal hanyalah jawaban singkat. Detail lebih lanjut tentang format permintaan ada di dokumentasi API.
Jika Anda sudah melakukan semua di atas dan masih melihat pesan, kirim X-Request-Id panggilan gagal ke halaman dukungan, dengan waktu percobaan dan apakah kegagalan terjadi sebelum atau setelah token pertama.
