重點摘要
- 標籤涵蓋 URL 路徑、JSON 請求與回應格式、Bearer 驗證與 SSE 串流輸出。
- 它未說明哪個模型回答、行為方式或價格。
- 切換通常意味著更改兩個值:Base URL 與 API 金鑰。
- 在依賴供應商之前,請測試串流輸出、工具、JSON 模式與錯誤代碼。
簡短答案
當供應商表示其 API 為 openai-compatible 時,意味著它接受 OpenAI 客戶端程式庫發送的相同 HTTP 請求,並以相同格式返回回應。你保留程式碼,僅更改端點與金鑰,請求便會發送到不同的伺服器。
這就是全部承諾。這是關於介面的聲明,就像說兩個充電器使用相同的插頭。它未說明電纜另一端是什麼。模型、安全規則、價格與限制均由供應商決定,且差異很大。
標籤實際涵蓋的內容
實際上,OpenAI 相容性是一系列具體事項的清單。如果供應商支援所有事項,大部分客戶端程式碼即可無縫運行。
- 路徑。 聊天請求發送至
POST /v1/chat/completions,模型列表來自GET /v1/models。 - 驗證。金鑰會出現在
Authorization: Bearer標頭中。 - 請求主體。
model字串、包含role與content的物件陣列messages,以及可選的取樣欄位如temperature、top_p、stop與seed。 - 回應主體。 包含助手訊息的
choices陣列、finish_reason,以及包含 token 計數的usage物件。 - 串流輸出。 透過
stream: true,伺服器發送 Server-Sent Events,每個事件攜帶小型 JSON delta,並以最終標記結束。 - 可選功能。 函式呼叫、JSON 模式與類似欄位,由供應商選擇是否支援。
由於許多工具是針對此格式編寫的,它成為共同目標。編輯器、代理框架、角色扮演前端與純腳本都允許你輸入自訂 Base URL,這就足夠了。
為何一種格式成為共同目標
聊天完成格式因其簡單且早期出現而擴散。支援此格式的工具作者一次即可接觸許多後端,支援此格式的後端作者一次即可接觸許多工具。這對雙方都是好交易,因此該格式得以保留,即使在與設計該格式的公司無關的服務中也是如此。
對你作為開發者而言,這具有實際意義。你的程式碼不需要為每個供應商進行不同的整合。你可以在下午內在不同端點之間移動原型,在同一提示詞下比較兩個模型,或在第一個供應商變慢時保留第二個供應商作為後備。改變主意的成本很低,這使得更容易嘗試新服務而無需承諾。
另一方面,共享介面隱藏了實際差異。由於切換非常容易,很容易假設 URL 後面的內容是等效的。事實並非如此,以下章節顯示差距通常出現在哪裡。
它未告知的內容
人們常在這裡感到驚訝。該標籤省略了決定 API 是否對你的工作有用的所有內容。
後面的模型
相容端點可以服務任何模型。有些服務開放權重模型,有些路由到多個供應商,有些包裝專有模型。相容性不代表服務由 OpenAI 運行,也不代表模型行為像他們的模型。你在 model 中傳遞的模型名稱只是供應商定義的字串。
拒絕行為
內容規則屬於模型與供應商,而非協定。兩個相容 API 可以以相反方式回答相同的提示詞。如果你的用例是小說、角色扮演或其他合法成人內容,請在連接之前檢查供應商關於拒絕的說明。
功能深度
有些供應商僅實作聊天。其他供應商添加工具、JSON 模式、對數機率或額外端點。發送伺服器忽略欄位的客戶端不一定會明確失敗,因此可能出現靜默不匹配。
限制、定價與錯誤
速率限制、上下文長度、最大主體大小與每 token 價格都是供應商選擇。錯誤主體即使在 HTTP 狀態碼匹配時也有所不同,因此重試邏輯應基於狀態碼與標頭,而非訊息文本。
快速相容性測試
你可以在幾分鐘內透過三個請求驗證供應商。將金鑰替換為你自己的。此範例使用此網站的 Base URL。
curl https://api.kimicode.top/v1/models \
-H "Authorization: Bearer YOUR_API_KEY"
curl https://api.kimicode.top/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"messages": [{"role": "user", "content": "Reply with the word ready."}]
}'
第一次呼叫確認金鑰並列出模型 ID。第二次檢查聊天格式。然後測試應用程式依賴的部分:添加 "stream": true 並觀察增量區塊,如果使用函式呼叫則傳遞 tools 陣列,如果需要可解析輸出則將 response_format 設為 {"type":"json_object"}。
也請故意觸發錯誤,例如錯誤的金鑰。你希望看到清晰的 HTTP 狀態與客戶端可處理的 JSON 錯誤主體。
Node 中的相同呼叫
JavaScript SDK 需要相同的兩個值。以下是串流呼叫,這是大多數聊天介面使用的格式。
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.kimicode.top/v1",
apiKey: process.env.API_KEY,
});
const stream = await client.chat.completions.create({
model: "uncensored",
stream: true,
messages: [{ role: "user", content: "Name three uses of SSE." }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
如果這逐字列印文字,則串流路徑端到端運作。相同的迴圈適用於任何相容供應商,這是該格式的整個要點。
程式碼中的切換樣貌
使用官方 Python SDK,更改僅需兩個建構子參數。程式碼的其餘部分保持原樣。
from openai import OpenAI
client = OpenAI(
base_url="https://api.kimicode.top/v1",
api_key="YOUR_API_KEY",
)
resp = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Summarize SSE in one sentence."}],
)
print(resp.choices[0].message.content)
Node SDK 的概念相同,只需設定baseURL與apiKey選項。許多工具會從環境變數讀取OPENAI_BASE_URL與OPENAI_API_KEY,因此有時甚至無需修改程式碼即可切換。
記得也要更改模型字串。命名新伺服器未託管模型的請求將失敗,這是最常見的初始錯誤。
此網站 API 的定位
此服務是遵循 OpenAI 格式的託管純文字 API。它運行一個開放權重模型,由獨立供應商運營,並針對無內容拒絕的合法成人用途進行調整。它不是任何模型供應商的官方 API,也不在供應商之間路由。模型 ID 為 uncensored。
它支援透過 SSE 的串流輸出,並在末尾報告用量,支援函式呼叫、JSON 模式,並傳遞 temperature、top_p、stop、seed 與懲罰。上下文視窗為 100,000 token,包含提示詞與完成。它不生成圖片或音訊,也不提供嵌入或微調。一條規則固定:禁止涉及未成年人的性內容。
計費為預付且計量:每 1M 輸入 token $0.15,每 1M 輸出 token $0.50,無訂閱。你可以在 定價頁面 看到數字,文件 將引導你完成第一次請求。如果你想免費試用,新帳戶可以在 API 金鑰頁面 一鍵領取 $0.50 免費試用額度。
常見相容性陷阱
- 基礎 URL 錯誤。 URL 應以
/v1結尾。用戶端會自行附加/chat/completions,因此若基礎 URL 已包含該路徑,將導致 404 錯誤。 - 不支援的參數。若程式庫傳送了伺服器不識別的欄位,請檢查該欄位是被拒絕還是被靜默忽略,然後將其移除。
- 串流輸出與並行請求。串流請求會佔用一個並行請求槽位,直到串流結束為止。如果你的應用程式開啟了許多串流,即使每分鐘請求數較低,仍可能觸發 429 錯誤並顯示程式碼
concurrency。 - 429 錯誤重試。將 429 視為等待的信號。若存在
Retry-After標頭,請予以遵守。 - Token 計數。不要假設其他供應商的 tokenizer 與你的一致。請從回應的
usage物件中讀取計費的數字。
一旦你知道要檢查這些地方,修復這些問題並不困難,大多數情況都取決於仔細閱讀第一個錯誤訊息。
