OpenAI Chat Completions
公式の OpenAI SDK を使い、OpenAI Chat Completions API で GPT・Claude・Gemini のモデルを呼び出します。使用量付きのストリーミング、ツール、推論モデル、サポートされていない機能について説明します。
Lovely Router は、POST /v1/chat/completions を OpenAI の定義どおりに提供します。OpenAI SDK の接続先を https://lovelyrouter.com/v1 に向け、Lovely Router のキーを使ってください。リクエスト本文は変更されずに転送されるため、各パラメータには OpenAI の API リファレンスがそのまま当てはまります。
SDK を設定する#
curl https://lovelyrouter.com/v1/chat/completions \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "gpt-6.1-sol",
"messages": [
{"role": "system", "content": "Answer in one sentence."},
{"role": "user", "content": "What does a load balancer do?"}
]
}'SDK は OPENAI_BASE_URL と OPENAI_API_KEY も読み込みます。そのため、OpenAI 互換のアプリの多くは、この 2 つを設定するだけで使えます。
利用可能なモデル#
現在、GET /v1/models にあるすべてのテキストモデルが Chat Completions に対応しています。Claude や Gemini のモデルも含まれます。画像モデル(gpt-image-*)は Images API を使います。そのため、1 つのクライアントでベンダーを切り替えるには、この API が最も簡単です。
| ファミリー | ID の例 | 補足 |
|---|---|---|
| GPT | gpt-6.1-sol、gpt-6-astra、gpt-5.6-terra、gpt-5.6-luna | ネイティブ API。 |
| Claude | claude-sonnet-5.5、claude-opus-5.5 | cache_control や思考の設定には Anthropic Messages を使ってください。 |
| Gemini | gemini-3.1-pro、gemini-3-flash | thinkingConfig など Gemini 専用のオプションには Gemini API を使ってください。 |
ベンダー固有のオプションが確実に機能するのは、モデルのネイティブ API で送った場合だけです。各モデルが対応する API を参照してください。
使用量付きでストリーミングする#
stream: true を設定します。ゲートウェイは常に stream_options.include_usage: true を付与するため、data: [DONE] の直前の最後のチャンクには、空の choices 配列とその呼び出しの usage が含まれます。差分(delta)を読む前に、choices が空でないことを確認してください。
stream = client.chat.completions.create(
model="gpt-6.1-sol",
messages=[{"role": "user", "content": "Name five prime numbers."}],
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 chunk.usage:
print("\nTokens:", chunk.usage.prompt_tokens, "in,", chunk.usage.completion_tokens, "out")ワイヤーフォーマットや、ストリームの途中でエラーがどう現れるかについては、ストリーミングを参照してください。
関数を呼び出す#
関数は tools に記述します。モデルが関数を呼び出すと finish_reason が tool_calls になります。関数を実行し、同じ tool_call_id を持つ tool メッセージで応答してください。
import json
tools = [{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Look up an order by id.",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
},
}]
messages = [{"role": "user", "content": "Where is order A-1042?"}]
response = client.chat.completions.create(model="gpt-6.1-sol", messages=messages, tools=tools)
msg = response.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = {"order_id": args["order_id"], "status": "shipped"} # your code here
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
response = client.chat.completions.create(model="gpt-6.1-sol", messages=messages, tools=tools)
print(response.choices[0].message.content)tool_choice、parallel_tool_calls、response_format は変更されずに転送されます。
推論モデルを使う#
GPT-5 と GPT-6 のモデルは、回答する前に推論を行います。推論の量は reasoning_effort で調整し、出力全体の上限は推論トークンを含む max_completion_tokens で設定します。指定できる effort の値はモデルによって異なります。OpenAI の推論ガイドを参照してください。
response = client.chat.completions.create(
model="gpt-6.1-sol",
reasoning_effort="high",
max_completion_tokens=8000,
messages=[{"role": "user", "content": "Find the bug: for i in range(len(a)): a.pop(i)"}],
)
usage = response.usage
print(response.choices[0].message.content)
print("reasoning tokens:", usage.completion_tokens_details.reasoning_tokens)Chat Completions では、推論の内容そのものは返されません。推論トークンは usage.completion_tokens に含まれ、出力の料金で課金されます。
Responses API を使う#
GPT のモデルは、POST /v1/responses の OpenAI Responses API でも提供されます。Codex CLI や Agents SDK が使う API です。ベース URL とキーは同じものを使います。SDK の client.responses.create() はそのまま使えます。
curl https://lovelyrouter.com/v1/responses \
-H "Authorization: Bearer $LOVELY_API_KEY" \
-H "content-type: application/json" \
-d '{
"model": "gpt-6.1-sol",
"instructions": "Answer in one sentence.",
"input": "What is a router?"
}'stream: true を設定すると、この API の型付きイベント(response.created、response.output_text.delta、…、response.completed)を受け取れます。使用量は response.completed で届き、他の呼び出しと同じように課金されます。注意点は次のとおりです。
- 会話全体を送ってください。 Lovely Router はレスポンスを保存しません。
/v1/responses/{id}に対するGET、DELETE、キャンセルは404を返し、previous_response_idは会話が同じチャネルにとどまっている間しか機能しません。Codex と同じように、"store": falseを付けて履歴全体をinputで送ってください。 - GPT のモデルのみ。 それ以外のモデルは
404とnot served in responses formatを返します。Chat Completions か、そのモデル自身の API で呼び出してください。 - レスポンスの
instructionsには、送信した値が表示されます。送信しなかった場合はnullです。 prompt_cache_keyは、Chat Completions とまったく同じように、会話を 1 つのチャネルに固定します。
プロンプトキャッシュ#
OpenAI のモデルは、長いプロンプトのプレフィックスを自動でキャッシュします。キャッシュされたトークンは usage.prompt_tokens_details.cached_tokens に表示され、より安いキャッシュ読み取りの料金で課金されます。prompt_cache_key を設定するとヒット率が上がり、どのリクエストが 1 つの会話に属するかをゲートウェイに伝えることもできます。プロンプトキャッシュを参照してください。
サポートされていないもの#
OpenAI 形式で利用できるのは Chat Completions、Responses API、Images API です。以下のエンドポイントは 404 を返します。
- 保存されたレスポンス(
/v1/responses/{id}に対するGET、DELETE、キャンセル)。 - Embeddings(
/v1/embeddings)。 - 音声(
/v1/audio/*)と画像のバリエーション(/v1/images/variations)。 - 旧来の Completions、Assistants、files、batches、ファインチューニング、moderation。
GET /v1/models は OpenAI SDK の client.models.list() で使えます。ID を指定した単一モデルの取得には対応していません。
ヘッダー#
| ヘッダー | 説明 |
|---|---|
Authorization: Bearer | Lovely Router のキー。必須です。 |
openai-beta | 送ったとおりに転送されます。 |
x-lovely-group | 任意。キーがグループに紐付けられていない場合に、リクエストをチャネルグループに固定します。 |
x-session-id | 任意。キャッシュを意識したルーティングのために、リクエストを 1 つの会話としてまとめます。本文の prompt_cache_key または user でも同じことができます。 |
エラーは OpenAI の形式 {"error": {"message": "...", "type": "...", "code": "..."}} で返ります。エラーを参照してください。