PostCorporate APIBLOG
← все заметки

OpenAI-совместимый endpoint: что менять в коде, а что нет

Хорошая совместимость выглядит скучно: вы меняете два поля, а приложение продолжает думать, что разговаривает с OpenAI. Плохая совместимость начинается там, где «почти такой же» ответ ломает streaming, usage или обработку ошибок. Поэтому миграцию проверяем не по лендингу, а по четырём точкам: base URL, ключ, формат ответа и поведение стрима.

Коротко
  • В коде меняются base_url и api_key.
  • Модель выбирается строкой из тарифа, а не привязкой к вендору.
  • Streaming и ошибки проверяются отдельным запросом до переключения трафика.

1. Миграция — это два поля

В OpenAI SDK достаточно заменить адрес и ключ:

from openai import OpenAI

client = OpenAI(
    api_key="ВАШ_КЛЮЧ",
    base_url="https://postcorporate.tech/v1",
)

resp = client.chat.completions.create(
    model="claude-sonnet-5",
    messages=[{"role": "user", "content": "привет"}],
    stream=True,
)

Если приложение уже использует официальный SDK, менять сериализацию сообщений не нужно. Роль, content, tools, response_format и stream уезжают в том же виде.

2. Модель — это строка тарифа, а не религия

После смены endpoint не тащите за собой старую карту «вендор → модель». Смотрите на текущую таблицу цен и берите модель по задаче: фронтир для сложного кода, китайские модели для дешёвой рутины, vision-варианты для скриншотов. Один ключ не означает одну модель: он означает один баланс и один набор ограничений.

3. Streaming проверяется отдельно

Синхронный ответ может быть идеальным, а стрим — ломаться на SSE-разделителях или финальном usage. Минимальная проверка:

curl -N https://postcorporate.tech/v1/chat/completions \
  -H "Authorization: Bearer ВАШ_КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{"model":"claude-sonnet-5","stream":true,
       "messages":[{"role":"user","content":"считай до трёх"}]}'

Смотрите, что события идут постепенно, завершаются [DONE], а клиент не повисает без таймаута.

4. Ошибки должны оставаться машиночитаемыми

Нормальный gateway не прячет 401/402/429/500 в HTML-страницу. Проверьте намеренно неверный ключ и слишком большую модель: код ошибки и JSON должны быть пригодны для retry-логики, а не для парсинга глазами.

Практический вывод. Переводите сначала один некритичный сервис. Если у него совпадают latency, usage в биллинге и поведение стрима — переносите остальные. «Поменяли base URL» не отменяет приёмочный прогон.