← Semua artikel

API Serasi OpenAI sebagai Pengganti Langsung — Migrasi dalam Dua Baris

20 Ogos 2026 · 5 min bacaan · api, migration

unbleep ialah API serasi OpenAI, yang dalam praktiknya bermaksud migrasi hanya melibatkan dua baris dan tiada kebergantungan baharu. Anda mengekalkan SDK rasmi, logik cuba semula anda, gelung penstriman anda, pengiraan token anda dan pengendali ralat anda. Yang berubah hanyalah ke mana permintaan dihantar dan kunci mana yang mengesahkannya. Artikel ini merangkumi pertukaran itu, kemudian empat perkara yang cukup berbeza sehingga boleh merosakkan sesuatu jika anda tidak mengetahuinya.

Migrasi ke API serasi OpenAI dalam dua baris

python
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://unbleep.ai/v1",
    api_key=os.environ["UNBLEEP_API_KEY"],
)

resp = client.chat.completions.create(
    model="unbleep",
    messages=[{"role": "user", "content": "Summarise this incident report."}],
)
print(resp.choices[0].message.content)

Jika anda lebih suka tidak menyentuh kod langsung, SDK membaca kedua-dua nilai daripada persekitaran, jadi perubahan konfigurasi sudah memadai:

bash
export OPENAI_BASE_URL="https://unbleep.ai/v1"
export OPENAI_API_KEY="ub_live_9f2c..."

Pasangan yang sama itu meliputi sebahagian besar ekosistem yang dibina di atas SDK — LangChain, LlamaIndex, Instructor, Vercel AI SDK, apa-apa sahaja yang mendedahkan tetapan base URL. Kunci diberi awalan supaya kebocoran mudah dikesan oleh pengimbas rahsia: ub_live_ dan ub_test_ kedua-duanya mengecaj kredit prabayar yang sama pada kadar per token yang sama. Kunci ujian ialah kelayakan berasingan yang boleh dibatalkan, dengan had yang lebih rendah — 15 permintaan/minit berbanding 60 untuk akaun — bukan peringkat percuma. Simpan kedua-duanya di sisi pelayan.

GET /v1/models berfungsi, jadi alatan yang menyenaraikan model untuk mengisi menu juntai bawah tidak memerlukan pengendalian khas.

Memilih model

Tiga peringkat. Id bertarikh — unbleep-250811, unbleep-high-250811, unbleep-mini-250811 — diterima sebagai alias, tetapi buat masa ini ia merujuk kepada binaan yang sama seperti id tanpa tarikh, dan respons melaporkan semula id tanpa tarikh itu. Anggap ia sebagai ejaan yang serasi ke hadapan, bukan jaminan kebolehulangan; jika sesuatu penilaian mesti boleh diulang, rekodkan outputnya, bukan id modelnya.

| Model | Konteks | Harga masuk / keluar per 1M | Nota | | --- | --- | --- | --- | | unbleep | 256K | $3.00 / $3.00 | Lalai. Peringkat penaakulan. | | unbleep-high | 1M* | $5.00 / $5.00 | Kerja terbesar. Peringkat penaakulan. | | unbleep-mini | 32K | $1.00 / $1.00 | Murah dan pantas. Menjawab terus, tiada jejak penaakulan. |

*Badan permintaan dihadkan pada 2,000,000 bait — lebih kurang 500k token — jadi satu panggilan sebenarnya tidak boleh memenuhi tetingkap 1M; apa-apa yang lebih besar dikembalikan sebagai 413 payload_too_large.

Had 32K pada unbleep-mini ialah perangkap yang paling kerap menangkap mereka yang berhijrah daripada model berkonteks 128K: prompt yang muat sebelum ini kini akan ditolak. Jika anda menghalakan mengikut kos, halakan mengikut panjang juga.

python
def pick_model(prompt_chars: int) -> str:
    """~4 chars/token is a deliberate under-estimate; leave room for the completion."""
    est_tokens = prompt_chars // 4
    if est_tokens < 24_000:
        return "unbleep-mini"
    return "unbleep" if est_tokens < 200_000 else "unbleep-high"

Penstriman

Tetapkan stream=True dan anda mendapat Server-Sent Events yang standard: setiap peristiwa ialah chat.completion.chunk yang membawa delta, dan strim ditamatkan dengan data: [DONE] secara literal. Gelung sedia ada anda berfungsi tanpa perubahan.

bash
curl -N https://unbleep.ai/v1/chat/completions \
  -H "Authorization: Bearer $UNBLEEP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "unbleep",
    "messages": [{"role": "user", "content": "Explain the residual stream."}],
    "stream": true,
    "stream_options": {"include_usage": true}
  }'

Anda mendapat kiraan token sama ada anda memintanya atau tidak: unbleep sentiasa meminta penggunaan daripada backend dan menyampaikannya semula, dan hanya stream_options: {"include_usage": false} yang eksplisit akan membuangnya sebelum dihantar keluar. Dalam kedua-dua kes, strim berakhir dengan satu cebisan terakhir yang mempunyai tatasusunan choices kosong — membawa objek usage yang terisi melainkan anda memilih untuk tidak menerimanya — dan itulah sebabnya gelung di bawah menyemak choices sebelum menyentuhnya.

Medan reasoning_content

Inilah satu-satunya tambahan tulen pada skema. unbleep dan unbleep-high berfikir sebelum menjawab, dan rantaian pemikiran itu dikembalikan dalam reasoning_content, medan yang bersebelahan content pada mesej (tanpa penstriman) atau pada delta (penstriman). Backend huluan tidak sepakat sama ada mahu memanggilnya reasoning atau reasoning_content; API menormalkannya kepada reasoning_content supaya anda hanya perlu mengendalikan satu bentuk sahaja.

Oleh sebab ia bukan sebahagian daripada skema OpenAI, ia tiada dalam stub jenis SDK. Model respons membenarkan medan tambahan, jadi capaian atribut berfungsi pada masa jalan — tetapi bacalah dengan getattr supaya respons mini, yang tiada jejak, tidak menimbulkan ralat:

python
import sys

stream = client.chat.completions.create(
    model="unbleep",
    messages=[{"role": "user", "content": "Why did this detection rule misfire?"}],
    stream=True,
    stream_options={"include_usage": True},
)

usage = None
for chunk in stream:
    if not chunk.choices:          # final usage-only chunk
        usage = chunk.usage
        continue
    delta = chunk.choices[0].delta
    thought = getattr(delta, "reasoning_content", None)
    if thought:                    # trace to stderr, answer to stdout
        sys.stderr.write(thought)
    if delta.content:
        sys.stdout.write(delta.content)

if usage:
    details = usage.completion_tokens_details
    print(f"\nreasoning tokens: {getattr(details, 'reasoning_tokens', 0)}")

Tiga akibat praktikal:

python
resp = client.chat.completions.create(
    model="unbleep",
    messages=[{"role": "user", "content": "phishing or benign?"}],
    max_tokens=4,
    extra_body={"thinking": False},   # spend the budget on the answer, not the trace
)

Jangan sekali-kali suapkan reasoning_content semula ke dalam giliran seterusnya sebagai kandungan pembantu (assistant). Ia output diagnostik, bukan sejarah perbualan, dan memainkannya semula akan merosotkan respons berikutnya.

Ralat dan dua perangkap sebenar

Ralat menggunakan sampul OpenAI — {"error": {"type", "code", "message"}} — jadi blok except sedia ada anda terus berfungsi. Kod status dipetakan seperti yang anda jangkakan: 401 kunci tidak sah, 422 disekat oleh policy: strict, 429 had kadar, 5xx ralat huluan yang boleh dicuba semula.

Status yang mungkin tidak pernah anda kendalikan ialah 402, kredit habis. Akaun adalah prabayar, jadi tiada caj lebihan dan tiada invois — permintaan hanya berhenti sehingga anda menambah nilai. OpenAI mengisyaratkan kehabisan kuota sebagai 429, yang bermaksud laluan migrasi yang naif akan menyebabkan logik backoff anda mencuba semula 402 selama-lamanya. Anggap ia muktamad dan cetuskan amaran untuknya.

Perangkap kedua: system_fingerprint tidak dikembalikan. Ia mengenal pasti backend penyajian, jadi ia dibuang bersama medan vendor yang lain. Jika anda menjadikannya kunci untuk cache atau semakan kebolehulangan, anda memerlukan penanda versi sendiri: id model bertarikh ialah alias untuk binaan semasa, bukan snapshot beku, jadi ia tidak akan memberitahu anda bila backend berubah.

Had kadar dikembalikan sebagai pengepala pada setiap respons — x-ratelimit-limit-requests, x-ratelimit-remaining-requests, x-ratelimit-reset-requests — jadi kerja kelompok boleh mengatur kadar permintaannya sendiri, bukannya menemui had itu dengan melanggarnya. Ada had kedua yang tidak diterangkan oleh pengepala: paling banyak 8 permintaan yang sedang berjalan serentak bagi setiap akaun, dan permintaan kesembilan dikembalikan sebagai 429 dengan kod too_many_concurrent_requests. Panggilan penstriman memegang slotnya sehingga strim tamat, jadi hadkan bilangan worker anda sendiri pada 8.

Apa yang ada di sebalik endpoint ini

Wajar dinyatakan dengan jelas: model di sebalik endpoint ini adalah abliterated, bermaksud tingkah laku penolakannya telah dibuang pada peringkat pemberat. Itulah tujuannya — ini API pembangun yang ditujukan untuk penyelidikan keselamatan, red-teaming dan penilaian, di mana penolakan ialah ralat pengukuran. Ia juga bermaksud pagar keselamatan yang lazim tidak ada untuk menangkap prompt yang buruk, jadi pastikan ada manusia yang bertanggungjawab terhadap output dan baca dasar penggunaan boleh terima. Penggunaan yang sah adalah tanggungjawab anda.

Dapatkan kunci API — migrasinya benar-benar hanya dua baris.