主要ポイント
- ラベルは URL パス、JSON リクエストおよびレスポンスの形式、Bearer 認証、SSE ストリーミングをカバーします。
- どのモデルが回答するか、その動作、またはコストについては何も示しません。
- 切り替えは通常、2 つの値の変更を意味します:base URL と API キー。
- プロバイダを信頼する前に、ストリーミング、ツール、JSON モード、エラーコードをテストしてください。
短い答え
プロバイダがその API が openai-compatible であると言う場合、それは OpenAI クライアントライブラリが送信するのと同じ HTTP リクエストを受け入れ、同じ形状のレスポンスを返すことを意味します。コードはそのまま維持し、base URL とキーを変更するだけで、呼び出しは異なるサーバーに行われます。
これがすべての約束です。これはインターフェースに関する声明であり、2 つの充電器が同じプラグを使用していると言うようなものです。ケーブルの向こう側に何があるかは示しません。モデル、その安全ルール、価格、制限はすべてプロバイダによって決定され、大きく異なります。
ラベルが実際にカバーする内容
実際には、OpenAI 互換性は具体的な項目の短いリストです。プロバイダがそれらすべてをサポートする場合、ほとんどのクライアントコードは変更なしで実行されます。
- パス。 チャットリクエストは
POST /v1/chat/completionsに送信され、モデルリストはGET /v1/modelsから取得されます。 - 認証。 キーは
Authorization: Bearerヘッダーに含まれます。 - リクエストボディ。
model文字列、roleとcontentを持つオブジェクトのmessages配列、およびtemperature、top_p、stop、seedなどのオプションのサンプリングフィールド。 - レスポンスボディ。 アシスタントメッセージを含む
choices配列、finish_reason、およびトークン数を含むusageオブジェクト。 - ストリーミング。
stream: trueで、サーバーはサーバー送信イベントを送信し、それぞれが小さな JSON デルタを運び、最終マーカーで終了します。 - オプション機能。 ツール呼び出し、JSON モード、およびプロバイダがサポートする類似フィールド。
このフォーマットに対して多くのツールが書かれたため、それは共通のターゲットになりました。エディタ、エージェントフレームワーク、ロールプレイフロントエンド、およびプレーンスクリプトはすべてカスタム base URL を入力できるため、それが必要とするものはそれだけです。
なぜ 1 つのフォーマットが共通のターゲットになったか
チャット完了フォーマットはシンプルで早期に導入されたために広まりました。1 回これに対応するツール著者は多くのバックエンドに到達でき、1 回これに対応するバックエンド著者は多くのツールに到達できます。これは両側に良い取引なので、このフォーマットは定着しました。これはそれが設計された会社とは無関係なサービスの中でも同様です。
開発者としてあなたにとって、これは実用的な意味を持ちます。あなたのコードは、各プロバイダ用に異なる統合を必要としません。午後中にエンドポイント間でプロトタイプを移動し、同じプロンプトで 2 つのモデルを比較するか、最初のものが遅い場合に 2 番目のプロバイダをフォールバックとして維持できます。考えを変えるコストは低く、それが新しいサービスにコミットせずに試すことを容易にします。
裏面は、共有された表面が実際の違いを隠すことです。切り替えが非常に簡単であるため、URL の背後にあるすべてが同等であると想定したくなります。そうではなく、以下のセクションでギャップが通常どこに現れるかを示します。
ラベルが伝えないもの
ここで人々は驚きます。ラベルは、API があなたの仕事に有用かどうかを決定するすべてのものを省略します。
その背後のモデル
互換性のあるエンドポイントはいかなるモデルでも提供できます。オープンウェイトモデルを提供するものもあれば、複数のベンダーにルーティングするもの、独自モデルをラップするものもあります。互換性があるからといって、サービスが OpenAI によって運営されているわけでも、モデルが OpenAI のモデルのように動作するわけでもありません。model に渡すモデル名は、プロバイダが定義する単なる文字列です。
拒否動作
コンテンツルールはモデルとプロバイダに属し、プロトコルには属しません。2 つの互換 API は、同じプロンプトに反対の答えを与えることができます。あなたのユースケースがフィクション、ロールプレイ、または他の合法的な成人向けコンテンツである場合、何かを接続する前にプロバイダが拒否について何と言っているかを確認してください。
機能の深さ
一部のプロバイダはチャットのみを実装します。他のプロバイダはツール、JSON モード、ログ確率、または追加エンドポイントを追加します。サーバーが無視するフィールドを送信するクライアントは、必ずしも大きく失敗しないため、サイレントミスマッチが可能になります。
制限、価格、エラー
レート制限、コンテキストの長さ、最大ボディサイズ、トークンあたりの価格はすべてプロバイダの選択です。エラーボディもHTTPステータスコードが一致する場合でも詳細が異なるため、リトライロジックはメッセージテキストではなくステータスコードとヘッダーに基づいて動作すべきです。
簡単な互換性テスト
3 つのリクエストで数分でプロバイダを検証できます。キーを自分のものに変更してください。この例では、このサイトの 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 をリストします。2 番目はチャットの形状をチェックします。次に、アプリケーションが依存する部分をテストします:"stream": true を追加して増分チャンクの出現を確認し、関数呼び出しを使用する場合は tools 配列を渡し、解析可能な出力が必要な場合は response_format を {"type":"json_object"} に設定します。
また、意図的にエラーをトリガーします。例えば、無効なキーなど。クリーンな HTTP ステータスとクライアントが処理できる JSON エラーボディを見たいのです。
Nodeでの同じ呼び出し
JavaScript SDK は同じ 2 つの値を取ります。以下は、ほとんどのチャットインターフェースが使用する形状のストリーミング呼び出しです。
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 では、変更は 2 つのコンストラクタ引数です。プログラムの残りの部分は以前と同じままです。
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 です。独立したプロバイダによって運営され、合法的な成人用途に対してコンテンツ拒否なしで答えるように調整された 1 つのオープンウェイトモデルを実行します。それは任意のモデルベンダの公式 API ではなく、ベンダ間でルーティングしません。モデル ID は uncensored です。
SSEを介したストリーミングに対応し、使用量は最後に報告されます。関数呼び出し、JSON モードをサポートし、temperature、top_p、stop、seed、ペナルティを透過的に転送します。コンテキストウィンドウはプロンプトと補完を合わせて100,000トークンです。画像や音声は生成せず、埋め込みやファインチューニングも提供しません。固定ルールは1つ:未成年者を含む性的コンテンツは禁止です。
課金は前払いでメーター方式です:入力トークン1Mあたり$0.15、出力トークン1Mあたり$0.50で、サブスクリプションはありません。数字は価格ページで確認でき、ドキュメントで初回リクエストの手順を確認できます。無料で試したい場合は、新しいアカウントでAPI キーページからワンクリックで$0.50の試用クレジットを受け取ることができます。
よくある互換性の落とし穴
- ベースURLの誤り。 URLは
/v1で終わる必要があります。クライアントは/chat/completionsを自身で付加するため、ベースURLに追加すると404エラーになります。 - サポートされていないパラメータ。 ライブラリがサーバーが認識しないフィールドを送信する場合、それが拒否されるか黙って破棄されるかを確認し、その後でそれを削除してください。
- ストリーミングと同時実行数。 ストリーミングリクエストはストリームが終了するまで同時実行数のスロットを占有します。アプリで複数のストリームを開くと、1分あたりのカウントが低くても、コード
concurrencyの429エラーに達する可能性があります。 - 429時のリトライ。 429は待機するシグナルとして扱ってください。
Retry-Afterヘッダーが存在する場合は、その意図を尊重してください。 - トークンカウント。 他のプロバイダのトークナイザーが一致すると想定しないでください。課金対象となる数字は、レスポンス内の
usageオブジェクトで確認してください。
これらは、どこを探すべきかを知っていれば修正は難しくなく、大半は最初のエラーメッセージを注意深く読むことに尽きます。
