OpenAI Chat Completions
Вызывайте модели GPT, Claude и Gemini через OpenAI Chat Completions API с официальными SDK OpenAI. Потоковая передача с usage, инструменты, модели с рассуждениями и то, что не поддерживается.
Lovely Router обслуживает POST /v1/chat/completions в точности так, как его определяет OpenAI. Направьте OpenAI SDK на https://lovelyrouter.com/v1 и используйте свой ключ Lovely Router. Тело запроса передаётся без изменений, поэтому справочник API OpenAI применим к каждому параметру.
Настройка 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-совместимых приложений нужны только эти две настройки.
Доступные модели#
Сейчас Chat Completions принимает каждая текстовая модель из GET /v1/models, включая модели Claude и Gemini. Модели изображений (gpt-image-*) используют Images API. Поэтому этот 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 и настроек thinking используйте Anthropic Messages. |
| Gemini | gemini-3.1-pro, gemini-3-flash | Для thinkingConfig и других параметров, специфичных для Gemini, используйте Gemini API. |
Параметры конкретного вендора гарантированно работают только в нативном API модели. См. Какой API поддерживает каждая модель.
Потоковая передача с usage#
Задайте 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 с тем же tool_call_id.
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 также обслуживаются через OpenAI Responses API по адресу POST /v1/responses — это API, который используют Codex CLI и Agents SDK. Базовый URL и ключ те же; client.responses.create() из SDK работает как есть.
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); usage приходит в response.completed и тарифицируется как любой другой вызов. Что нужно знать:
- Отправляйте весь разговор. Lovely Router не хранит ответы за вас:
GET,DELETEи отмена на/v1/responses/{id}возвращают404, аprevious_response_idработает, только пока разговор остаётся на том же канале. Отправляйте полную историю вinputс"store": false, как это делает Codex. - Только модели GPT. Другие модели возвращают
404сnot served in responses format; вызывайте их через Chat Completions или их собственный API. instructionsв ответе показывает то, что вы отправили, илиnull, если вы ничего не отправляли.prompt_cache_keyудерживает разговор на одном канале — точно так же, как в Chat Completions.
Кеширование промптов#
Модели OpenAI автоматически кешируют длинные префиксы промпта. Кешированные токены отображаются в usage.prompt_tokens_details.cached_tokens и тарифицируются по более дешёвой ставке чтения кеша. prompt_cache_key повышает долю попаданий в кеш и заодно сообщает шлюзу, какие запросы относятся к одному разговору. См. Кеширование промптов.
Что не поддерживается#
В формате OpenAI доступны Chat Completions, Responses API и Images API. Эти эндпоинты возвращают 404:
- Сохранённые ответы (
GET,DELETEили отмена на/v1/responses/{id}). - Эмбеддинги (
/v1/embeddings). - Аудио (
/v1/audio/*) и вариации изображений (/v1/images/variations). - Устаревшие Completions, Assistants, файлы, пакетные задания (batches), дообучение и модерация.
GET /v1/models работает с client.models.list() из OpenAI SDK. Получение отдельной модели по id не поддерживается.
Заголовки#
| Заголовок | Примечания |
|---|---|
Authorization: Bearer | Ваш ключ Lovely Router. Обязателен. |
openai-beta | Передаётся как есть. |
x-lovely-group | Необязателен. Закрепляет запрос за группой каналов, если ваш ключ не привязан к группе. |
x-session-id | Необязателен. Объединяет запросы в один разговор для маршрутизации с учётом кеша. То же самое делают prompt_cache_key или user в теле запроса. |
Ошибки имеют формат OpenAI, {"error": {"message": "...", "type": "...", "code": "..."}}; см. Ошибки.