JA ▾
API キーを取得

そのまま置き換え可能な無検閲API、ロックインゼロ。

入力トークン1Mあたり
$0.15
出力トークン / 1M
$0.50
トークンコンテキスト
100,000
トライアルクレジット
$0.50
1分あたりのリクエスト
300
https://api.openaigatewayapi.com/v1

開発者向けOpenAI API: 互換エンドポイントを使用

コードがOpenAIワイヤーフォーマットに対応している場合、ベースURLとキーの2つの値を変更するだけで、このホストエンドポイントで実行できます。このページには貼り付け可能なコード付きで手順を示します。

更新

光るケーブルで接続された2つのサーバーブロック。1つの設定変更でエンドポイントが切り替わる様子

主要ポイント

  1. ベースURLをhttps://api.openaigatewayapi.com/v1に、モデルをuncensoredに設定します。OpenAIクライアントコードの他の部分は変更不要です。
  2. チャット完了、ストリーミング、ツール呼び出し、JSONモードはすべて通常のSDK呼び出しで動作します。
  3. 制限は、フルキーで同時8リクエスト、1分あたり300リクエストです。429エラーのリトライを実装してください。
  4. ワンクリックの$0.50トライアルにはカード不要です。支払い前に統合をテストできます。

簡易版

多くのOpenAI 開発者向け APIに関するガイドは、ベンダーが1つで請求書も1つであることを前提としています。しかし、ワイヤーフォーマットは単なる HTTPS 上の JSON であり、実装している任意のサーバーと通信できるクライアントコード、フレームワーク、ツールが多数あります。このサイトはそのようなサーバーの1つをホストしています。SDK をそのまま使い、ベース URL を変更し、このサイトのキーに置き換え、モデルを uncensored に設定します。

これが一般的なアプリの移行全体です。チェックリストを示し、ページの残りで各ステップの詳細を補足します。

  1. アカウントを作成し、API キーページでトライアルクレジットを受け取ってください。
  2. ベースURLをhttps://api.openaigatewayapi.com/v1に設定します。
  3. キーをAuthorization: Bearer <key>として送信します。SDKはapi_keyを渡すとこれを処理します。
  4. すべてのリクエストでモデルIDにuncensoredを使用します。
  5. 末尾付近に示すように、短いリトライでHTTP 429を処理します。

エンドポイントは2つあります:POST /v1/chat/completionsとGET /v1/models。サービスはテキストのみです。画像や音声の生成、埋め込み、ファインチューニングはなく、アプリがそれらを呼び出す場合は別のプロバイダーが必要です。

curlで接続を確認する

アプリケーションに触れる前に、キーが動作することを確認します。モデルエンドポイントはトークンを生成しないため、最も安いテストです。

export API_KEY="paste-your-key-here"

curl https://api.openaigatewayapi.com/v1/models \
  -H "Authorization: Bearer $API_KEY" | grep -o uncensored

grepはリストにモデルIDuncensoredが含まれている場合にそれを出力します。grepを削除すると完全なJSONリストが表示されます。401の場合、キーが間違っているかBearerプレフィックスが不足しています。次に実際のリクエストを送信します:

curl https://api.openaigatewayapi.com/v1/chat/completions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "uncensored",
    "messages": [
      {"role": "system", "content": "You are a concise technical assistant."},
      {"role": "user", "content": "Explain idempotency keys in two sentences."}
    ],
    "temperature": 0.4
  }'

レスポンスには通常のchoicesとusageオブジェクトが含まれます。ログに記録する価値のあるヘッダーもあります:サポート質問用のX-Request-Id、残高クレジット用のX-Balance-USD、およびリクエストと同時実行数の上限を示す2つのX-RateLimit-Limit-*ヘッダー。

公式openaiパッケージを使用したPython

Pythonではクライアントコンストラクタのみをいじります。その後は既存のコードです。

from openai import OpenAI

client = OpenAI(
    base_url="https://api.openaigatewayapi.com/v1",
    api_key="paste-your-key-here",
)

resp = client.chat.completions.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": "You write short, accurate release notes."},
        {"role": "user", "content": "Summarise: added retry logic, fixed timeout bug."},
    ],
    temperature=0.5,
    max_tokens=200,
)

print(resp.choices[0].message.content)
print(resp.usage.prompt_tokens, resp.usage.completion_tokens)

実際のコードでは環境変数からキーを読み取ってください。サンプルではコードスニペットを短く保つためにハードコードしています。max_tokens はここではオプションです。指定しない場合、完了テキストは 100,000 トークンのウィンドウ(プロンプトと完了テキストの合計)の残りをすべて使用できます。あえて設定するのは、制御不能な生成によるコストを制限する安価な方法です。

ストリーミング

ストリーミングはServer-Sent Eventsを使用し、よく知っているstream=Trueフラグを使います。使用量はストリームの最後に届くため、最後のチャンクには空のchoicesリストが含まれる場合があります。

from openai import OpenAI

client = OpenAI(base_url="https://api.openaigatewayapi.com/v1", api_key="paste-your-key-here")

stream = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "List five edge cases for a date parser."}],
    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("\ntokens:", chunk.usage.total_tokens)

キャパシティプランニングにおいて重要な点があります。ストリーミングリクエストは最初のトークンではなく、ストリームが終了するまで同時実行数のスロットを保持します。クライアントがストリームを閉じずに放棄すると、そのスロットは予想より長く占有されます。

Node.js の例

Node SDKは異なる名前で同じ2つの設定を受け取ります。

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.openaigatewayapi.com/v1",
  apiKey: process.env.GATEWAY_KEY,
});

const completion = await client.chat.completions.create({
  model: "uncensored",
  messages: [
    { role: "user", content: "Write a regex that matches ISO 8601 dates, and explain it." },
  ],
  temperature: 0.3,
});

console.log(completion.choices[0].message.content);

独自のOpenAI統合を持つフレームワークを使用する場合、設定にbase URL、API base、またはendpointというフィールドを探してください。そこに同じURLを貼り付けるだけで通常は十分です。チャットフロントエンド、エージェントフレームワーク、エディタープラグインは主にこのパターンに従います。temperature、top_p、stop、seedなどのサンプリングパラメータや頻度・存在ペナルティはモデルに渡されます。

ツール呼び出しとJSONモード

モデルが実アプリケーションに適しているかどうかを決定する2つの機能:関数の呼び出しと解析可能なデータの返却。どちらもサポートされています。

関数呼び出し

toolsでツールを宣言し、オプションでtool_choiceで選択を強制し、role: "tool"でメッセージとして結果を送信します。ストリーミングレスポンスは標準フォーマットと同様にtool_callsを分割して配信します。

import json
from openai import OpenAI

client = OpenAI(base_url="https://api.openaigatewayapi.com/v1", api_key="paste-your-key-here")

tools = [{
    "type": "function",
    "function": {
        "name": "get_order_status",
        "description": "Look up the status of an order by its ID.",
        "parameters": {
            "type": "object",
            "properties": {"order_id": {"type": "string"}},
            "required": ["order_id"],
        },
    },
}]

messages = [{"role": "user", "content": "Where is order A-1042?"}]
first = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
msg = first.choices[0].message

if msg.tool_calls:
    call = msg.tool_calls[0]
    args = json.loads(call.function.arguments)
    result = {"order_id": args["order_id"], "status": "shipped"}  # your real lookup here
    messages.append(msg)
    messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
    final = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
    print(final.choices[0].message.content)

アクションを起こす前に引数を常に検証してください。モデルはスキーマに一致するJSONを生成しますが、常にではありません。call.function.argumentsを他の信頼できない入力と同様に扱ってください。

JSON モード

抽出や分類のジョブでは、JSONオブジェクトを要求し、プロンプトでもそれを明記してください。指示にJSONを言及すると、フラグのみを頼るよりも良い結果が得られます。

from openai import OpenAI
import json

client = OpenAI(base_url="https://api.openaigatewayapi.com/v1", api_key="paste-your-key-here")

resp = client.chat.completions.create(
    model="uncensored",
    response_format={"type": "json_object"},
    messages=[
        {"role": "system", "content": "Reply with JSON only: {\"sentiment\": string, \"topics\": [string]}."},
        {"role": "user", "content": "The docs are clear but the rate limits caught me off guard."},
    ],
)
data = json.loads(resp.choices[0].message.content)
print(data)

制限、エラー、リトライ

フルキーは、同時に8リクエスト、1分あたり300リクエストを許可します。トライアルキーは、同時に2リクエスト、1分あたり60リクエストです。最大リクエストボディは8 MBです。制限を超えるとHTTP 429が返され、エラーコードでどの制限を超えたかがわかります。

エラーコード意味取るべき行動
rate_limited1分あたりのリクエスト数が多すぎるプロデューサーを遅くするか、1分間で作業を分散させる
concurrency一度にリクエストが多すぎるワーカー数を8以下、またはトライアルキーの場合は2に下げる
429 と Retry-After: 5一時的な過負荷指定された秒数待ち、再試行する

SDKは一部の失敗をすでに再試行します。バーストがバッチジョブをクラッシュしないように、429エラーの独自の処理を追加してください。

import time
from openai import OpenAI, RateLimitError

client = OpenAI(
    base_url="https://api.openaigatewayapi.com/v1",
    api_key="paste-your-key-here",
    max_retries=0,
)

def ask(prompt, attempts=5):
    for i in range(attempts):
        try:
            r = client.chat.completions.create(
                model="uncensored",
                messages=[{"role": "user", "content": prompt}],
            )
            return r.choices[0].message.content
        except RateLimitError as e:
            wait = float(e.response.headers.get("retry-after", 2 ** i))
            time.sleep(wait)
    raise RuntimeError("still rate limited after retries")

失敗または拒否されたリクエストは課金されないため、リトライループで請求が倍増しません。同時実行数制限に合わせてサイズを設定したセマフォは、非同期コードで上限を下回るための最もクリーンな方法です。

既存アプリの移行

動作するアプリがある場合、新しい値をハードコードしないでください。ベースURL、キー、モデル名を環境変数に設定し、デプロイなしで環境を切り替えられるようにします。これにより、2つのバックエンドに対して同じテストスイートを実行し、出力を並べて比較することもできます。

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.environ.get("LLM_BASE_URL", "https://api.openaigatewayapi.com/v1"),
    api_key=os.environ["LLM_API_KEY"],
)
MODEL = os.environ.get("LLM_MODEL", "uncensored")

def complete(messages, **kw):
    return client.chat.completions.create(model=MODEL, messages=messages, **kw)

次に、短い移行ルーチンに従ってください:

  1. 既存のプロンプトセットを新しいエンドポイントで実行し、出力を自分で確認してください。自動チェックはフォーマットが崩れていることは検出しますが、トーンは検出しません。
  2. response_formatが設定されている状態で、JSONを解析するコードが依然として機能することを確認し、オブジェクトの周囲の不要なテキストを削除するフォールバックを維持します。
  3. 異なるモデルはテキストを異なる方法でトークン化するため、usageから実際のトークン数を測定してください。古い見積もりが外れている可能性があります。
  4. 負荷がかかったときに同時実行数の上限が最初に失敗しないよう、ワーカープールを8以下に設定します。
  5. トラフィックの小さな割合にリリースし、429率とエラーログを監視してから拡大します。

チームはこのプロセスでシステムプロンプトを忘れがちです。拒否されやすいモデルを説得するために書かれたプロンプトには、ここでは不要なヘッジ行が含まれており、出力を混雑させることがあります。もう一度読み直し、不要な部分を削除してください。

切り替える前に知っておくべきこと

互換性はリクエストとレスポンスのフォーマットをカバーします。これが任意のモデルメーカーの公式APIであることを意味するわけではありません。このサービスは1つのオープンウェイトモデルを実行しており、独立したプロバイダーによってホストされ、法的な成人用途に対してコンテンツ拒否を少なくして回答するように調整されています。ベンダー間のルーターではないため、背後に他のモデルのメニューがあるわけではありません。未成年者を含む性的コンテンツは許可されておらず、この制限は変更できません。

大規模なマルチモデルプラットフォームとの3つの実用的な違いを考慮して計画を立ててください:

  • 1つのモデルのみ。 IDはuncensoredです。タスクによってモデルを切り替えるコードがある場合は、それを1つの値に統一してください。
  • テキストのみ。 このエンドポイントへのパスから画像、音声、埋め込みの呼び出しを削除します。
  • プロンプトの動作が異なる。 異なるモデルは指示の読み取り方が異なるため、切り替え後にプロンプトとテストを再実行してください。出力が逸脱する場合はシステムプロンプトを調整します。

プロンプトはトレーニングには使用されません。パラメータの完全なリストは API ドキュメント を参照してください。使用量の見積もりについては、料金ページ にトークンごとのレートが記載されています:入力トークン 100 万トークンあたり $0.15、出力トークン 100 万トークンあたり $0.50 で、前払いクレジットから請求され、サブスクリプションはありません。チャージは $20 から $500 で、クレジットは期限切れになりません。複数のサービスの手前にプロキシレイヤーを置くことを検討している場合は、LLM ゲートウェイ のページで、その追加の構成要素が効果を発揮する状況について解説しています。

質問と回答

このエンドポイントに新しいSDKが必要ですか?

いいえ。PythonとNodeの公式OpenAI SDKは、ベースURLをhttps://api.openaigatewayapi.com/v1に設定し、当サイトから取得したキーを使用すれば動作します。カスタムエンドポイントを設定できる他のクライアントも同様です。

どのモデルIDを送信すべきですか?

すべてのチャット完了リクエストのモデルフィールドに uncensored を使用してください。GET リクエストを /v1/models に対して送信することで確認できます。

支払いなしでテストできますか?

はい。サインアップ後、APIキーページでワンクリックで$0.50のトライアルクレジットを付与できます。カードは不要で、7日間有効、1人1回限りです。

埋め込みや画像生成に対応していますか?

いいえ。APIはテキストのみで、チャット完了とモデルリストを提供しています。埋め込みや画像生成が必要な場合は、別のプロバイダーが必要です。

プロンプトは学習に使用されますか?

いいえ、プロンプトはトレーニングには使用されません。

キーはフォーム1つで入手可能です

アカウントを作成し、キーをコピーし、ベースURLを変更します。これでセットアップは完了です。

APIキーを取得https://api.openaigatewayapi.com/v1