Известные ограничения
Список того, что сейчас работает не так, как можно ожидать от OpenAI-совместимого API. Написан честно, чтобы вы не отлаживали чужие баги как свои.
Мультимодальный ввод не поддерживается
Поле content в сообщении принимает только строку. Массив блоков, которым OpenAI
передаёт изображения, отклоняется валидацией:
{
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Что на картинке?"},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}}
]
}]
}
{
"statusCode": 400,
"message": ["content must be a string"],
"error": "Bad Request"
}
Следствие: vision-возможности недоступны даже у моделей, которые их поддерживают, а плагины с прикреплением скриншотов (Cline, Roo Code, Continue) не смогут отправить изображение.
Обходного пути на стороне API нет. Описывайте изображение текстом либо распознавайте его отдельным сервисом.
/v1/ai/responses не умеет стриминг
Параметр stream принимается без ошибки, но игнорируется — ответ всегда приходит
целиком. Клиент, ожидающий поток, будет ждать полной генерации.
Для стриминга используйте Chat Completions или Messages.
stop_sequences в /v1/ai/messages не применяется
Поле парсится и проходит валидацию, но до провайдера не доходит — генерация не остановится на указанной последовательности.
Обход: используйте stop в Chat Completions, где
параметр работает, либо обрезайте ответ на своей стороне.
Путь Anthropic-эндпоинта нестандартный
Эндпоинт находится по адресу /v1/ai/messages, а не /v1/messages. Клиенты, жёстко
дописывающие /v1/messages к базовому URL (Claude Code, client.messages.create() в
Anthropic SDK), напрямую не подключаются.
Рабочие варианты описаны в Claude Code и Anthropic SDK.
Нет списка моделей во внешнем API
Эндпоинта GET /v1/ai/models не существует. Плагины и клиенты, подтягивающие модели
автоматически, покажут пустой список — слаг вводится вручную.
Список моделей доступен через GET /models (без префикса /v1, ключ не требуется),
но этот путь не соответствует ожиданиям OpenAI-клиентов. См. Модели.
Ошибка внутри стрима приходит пустой
Если генерация оборвалась после начала стриминга, кадр с ошибкой может не содержать текста сообщения:
data: {"error":{"message":{}}}
Причина — сериализация объекта ошибки. HTTP-статус при этом уже 200, поскольку заголовки отправлены до первого токена.
Практический вывод: проверяйте наличие поля error в кадрах и не рассчитывайте на
информативный текст. Причину смотрите по коду ответа при повторе того же запроса без
stream.
Формат ошибок отличается от OpenAI
Ответ не обёрнут в объект error с полями type и code:
{ "statusCode": 401, "message": "Invalid or inactive API key", "error": "Unauthorized" }
Ошибки провайдера (502) приходят в третьем формате — вообще без statusCode:
{ "message": "Provider returned error: model not found" }
Библиотеки, разбирающие OpenAI-формат ошибок, покажут текст, но не определят тип. См. Ошибки и лимиты.
Rate limit считается по IP
60 запросов в минуту привязаны к IP-адресу, не к API-ключу. Следствия:
- Несколько сервисов за одним NAT или на одном сервере делят общий лимит.
- Создание дополнительных ключей не увеличивает пропускную способность.
- Ограничение нельзя поднять на уровне аккаунта.
Исключение — POST /v1/ai/embeddings, он не лимитируется.
Статистика только по аккаунту
Расходы агрегируются по пользователю; разбивки по отдельным ключам нет. Чтобы разделять
затраты по проектам, передавайте session_id или metadata в запросах и считайте на
своей стороне.
Rerank не поддерживается
Эндпоинта переранжирования нет. В Continue и Roo Code не назначайте роль rerank.
Если какое-то из ограничений блокирует ваш сценарий — напишите на agent@agentapi.ru.