Перейти к основному контенту

Руководство по интеграции

Клиент остаётся. Меняются базовый адрес и значение model.

Текстовые модели здесь говорят на протоколах, которые ваш SDK уже знает: Chat Completions, бессостоятельное подмножество Responses, Anthropic Messages и Google generateContent. Интересно другое: что происходит с параметром, которого целевая модель никогда не объявляла.

Задача

Слои совместимости чаще всего лгут умолчанием

Классический сбой — не 500. Это параметр, который шлюз принял, выбросил и ни словом не упомянул: модель отработала без вашей temperature, без описаний инструментов и без формата ответа, а результат выглядел просто слабым, а не сломанным.

01

Необъявленный параметр отклоняется, а не выбрасывается

messages, tools, tool_choice, response_format, max_tokens, temperature и top_p ложатся на объявленные поля модели. Всё остальное передаётся в её схему и возвращает 400, если модель этого не объявляет. Молчание никогда не бывает ответом.

02

Форма ошибки следует вызванному протоколу

На /v1 тело — это объект ошибки OpenAI или Anthropic, а не конверт {code, msg, data, request_id} из /api/v1. Если продукт использует обе поверхности, обрабатывайте обе формы.

03

Поток и расчёт — разные вещи

stream: true возвращает события chat.completion.chunk, завершённые data: [DONE]. Тарификация по-прежнему идёт по измеренному потреблению, поэтому прерванный поток не становится бесплатным запросом.

Подход

Смените эндпоинт и прогоните свои проверки заново

Измените base_url и api_key, замените строку модели значением из GET /v1/models и запустите уже имеющийся набор тестов. Если параметр вернул 400, выбранная модель никогда его не поддерживала — этой информации «тихий» вариант не давал.

Подойдёт любой OpenAI-совместимый клиент. Меняются только базовый адрес и значение model.

POST /v1/chat/completions

from openai import OpenAI

client = OpenAI(
    base_url="https://api.spicyapi.ai/v1",
    api_key=os.environ["SPICY_API_KEY"],
)

stream = client.chat.completions.create(
    model="<publisher>/<model>/chat",          # exact value from GET /v1/models
    messages=[{"role": "user", "content": "Summarise these notes in three bullets."}],
    temperature=0.7,
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")

text/event-stream

data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"- "}}]}
data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"Ships"}}]}
data: [DONE]

Контракт

Что стоит зафиксировать сразу

OpenAI-совместимое LLM API: смените базовый адрес — Что стоит зафиксировать сразу
Поле или заголовокЗначение или предел
POST /v1/chat/completionschat.completion · SSE with stream: true
GET /v1/modelsevery callable model value
Authorization: Bearer · x-api-key · x-goog-api-keyaccepted on /v1
undeclared parameter400 · never silently dropped

Проведите по горизонтали, чтобы увидеть все столбцы.

Интеграция

От первого вызова до продакшена

  1. 01Создайте ключ и запросите GET /v1/models, чтобы получить идентификаторы, доступные прямо сейчас.
  2. 02Направьте клиент на базовый адрес и отправьте первый запрос без потока: вернётся обычный объект chat.completion.
  3. 03Включите поток и убедитесь, что ваш читатель обрабатывает chat.completion.chunk и маркер [DONE].
  4. 04Следите за расходом по ключу в консоли и задайте дневной лимит до перевода боевого трафика.

Применимость

Когда этот путь подходит

Выбирайте, если

  • У вас уже есть рабочий клиентский код OpenAI, Anthropic или Google, и нужно сменить только модель за ним.
  • Нужны изображения, видео и текст на одном ключе, одном балансе и одном наборе лимитов расхода.

Ищите другое, если

  • Вы опираетесь на серверные треды или ассистентов с состоянием. Здесь поддержано бессостоятельное подмножество Responses.
  • Нужен медиарезультат. Он идёт через createTask или через проекцию Videos для клиентов, которые уже знают её форму.

Проверки

Что вы можете проверить сами

Четыре поверхности протоколов, один ключ

/v1/chat/completions, /v1/responses, /v1/messages и /v1beta/models/{model}:generateContent аутентифицируются одним ключом. Authorization: Bearer, x-api-key и x-goog-api-key принимаются там, где их ожидает SDK.

Список моделей и есть контракт

GET /v1/models возвращает ровно те идентификаторы, которые принимает любая операция /v1 и /api/v1, а разработчик указан в owned_by. Цены приходят из /api/v1/models: они зависят от аккаунта и потому не публичны.

Проверка, лимиты и резервы общие

Слой совместимости использует ту же аутентификацию, те же ограничения частоты, ту же проверку ввода, тот же расчёт цены и тот же резерв, что и нативная поверхность. Отличается только конверт.

Перед запуском

Поведение платформы, которое стоит подтвердить

  • Держите ключ на сервере: учётные данные в строке запроса не принимаются никогда.
  • Записывайте при каждом вызове идентификатор ответа самого протокола, чтобы у обращений была опора.
  • До запуска решите, как 400 из-за неподдержанного параметра доходит до ваших пользователей.
  • Задайте дневной, месячный и накопительный лимиты по ключу, а не полагайтесь на один баланс.

Частые вопросы

О чём спрашивают на этой странице

Любой клиент, где можно задать базовый адрес и строку модели. Клиенты формата OpenAI используют /v1/chat/completions и /v1/responses, клиенты Anthropic — /v1/messages, клиенты Google GenAI — пути generateContent.

Дальше

Направить клиент на текстовую модель

Направьте существующий клиент OpenAI, Anthropic или Google на SpicyAPI. Что проходит как есть, что отклоняется намеренно и как тарифицируется текст.

Другие руководства