Изображения на вход (Vision)
Отправка изображений в модель для анализа — описание содержимого, OCR, классификация, ответы на вопросы по картинке.
Vision (мультимодальный ввод) — это когда модель получает на вход не только текст, но и изображения. Подходит для описания содержимого, OCR, классификации, ответов на вопросы по картинке, разбора скриншотов и диаграмм.
Не путайте с генерацией изображений: vision — это картинка на вход, image-generation — картинка на выход.
Поддерживающие модели
Vision поддерживает любая модель, у которой в карточке (GET /v1/models) поле input_modalities содержит "image". Это, как правило, актуальные версии Claude (Sonnet/Opus), GPT-4o, Gemini, а также часть open-source моделей (Llama Vision, Qwen-VL). Точный актуальный список — в каталоге с фильтром «принимает изображения».
Минимальный пример
Передайте картинку как content-part типа image_url внутри user-сообщения:
curl -s https://api.hubris.pw/v1/chat/completions \
-H "Authorization: Bearer sk-gw-..." \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-haiku-4.5",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "Что изображено на картинке?" },
{
"type": "image_url",
"image_url": {
"url": "https://example.com/photo.jpg"
}
}
]
}
]
}'Контент user-сообщения — это массив content-part'ов. Каждая часть — либо { "type": "text", "text": "..." }, либо { "type": "image_url", "image_url": { "url": "..." } }. Порядок свободный.
Два способа передать картинку
URL
{
"type": "image_url",
"image_url": {
"url": "https://example.com/photo.jpg"
}
}Должен быть публично-доступный HTTPS URL. Провайдер модели скачает картинку сам. Размер и формат — на усмотрение провайдера; типичный лимит 5–20 МБ, поддерживаются JPEG, PNG, WebP, GIF.
Base64 data URL
Когда картинка не лежит в публичном интернете (генерится на лету, приходит от пользователя), кодируйте её в base64 и шлите как data URL:
{
"type": "image_url",
"image_url": {
"url": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAAAAAAA..."
}
}Формат — data:image/<mime>;base64,<base64-blob>. Mime может быть image/jpeg, image/png, image/webp, image/gif. Base64-сам по себе делает строку на ~33 % длиннее, поэтому общий размер запроса может быть значительным — учитывайте при тарификации (см. ниже).
Несколько изображений в одном запросе
Можно передать сколько угодно картинок в одном сообщении — добавляйте content-part'ы по одной:
{
"role": "user",
"content": [
{ "type": "text", "text": "Сравни эти два скриншота интерфейса." },
{ "type": "image_url", "image_url": { "url": "https://.../before.png" } },
{ "type": "image_url", "image_url": { "url": "https://.../after.png" } }
]
}Модель увидит обе картинки и сможет ссылаться на них в ответе («на первом скриншоте...»).
Параметр detail
Часть моделей (gpt-4o-семейство) принимают подсказку о требуемой детализации:
{
"type": "image_url",
"image_url": {
"url": "https://...",
"detail": "high"
}
}| Значение | Что значит |
|---|---|
"low" | модель смотрит на картинку в низком разрешении — дёшево, годится для общего описания |
"high" | детальное чтение — мелкий текст, цифры, диаграммы |
"auto" (по умолчанию) | модель решает сама |
Не все модели поддерживают detail — он пробрасывается как есть; если модель его не понимает, пара значение/поле просто игнорируется апстримом.
OpenAI SDK
Vision работает в официальных SDK OpenAI без дополнительных манипуляций.
Python:
from openai import OpenAI
client = OpenAI(
base_url="https://api.hubris.pw/v1",
api_key="sk-gw-...",
)
resp = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Распознай текст на этом скриншоте."},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/screenshot.png",
"detail": "high",
},
},
],
}
],
)
print(resp.choices[0].message.content)TypeScript:
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://api.hubris.pw/v1',
apiKey: 'sk-gw-...',
});
const resp = await client.chat.completions.create({
model: 'openai/gpt-4o-mini',
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Опиши, что на фото.' },
{
type: 'image_url',
image_url: { url: 'https://example.com/photo.jpg' },
},
],
},
],
});
console.log(resp.choices[0].message.content);Base64 в Python из файла
import base64
with open("photo.jpg", "rb") as f:
encoded = base64.b64encode(f.read()).decode()
data_url = f"data:image/jpeg;base64,{encoded}"
resp = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Опиши фото."},
{"type": "image_url", "image_url": {"url": data_url}},
],
}
],
)Стриминг
stream: true работает с vision-запросами как с обычными — ответ модели приходит чанками, prompt с изображениями просто длиннее. Никаких особенностей.
Биллинг
Изображение на вход тарифицируется как дополнительные prompt-токены. Количество токенов на одну картинку зависит от модели и от её размера/разрешения. Грубо:
- Маленькая картинка в
detail: "low"— порядка сотни prompt-токенов. - Стандартное разрешение в
detail: "auto"/"high"— от нескольких сотен до нескольких тысяч prompt-токенов.
Точное количество видно в usage.prompt_tokens в ответе. Списание с баланса — стандартная формула: prompt + completion токены умножаются на цену модели из каталога.
Base64 в URL не добавляет токенов — это просто способ доставки байтов. Тарифицируется только распарсенная картинка, не размер JSON-запроса.
Что важно знать
- Большие картинки = большой prompt. Если шлёте 2K-скриншоты, ожидайте по 1000–3000 prompt-токенов на каждую. На сессии с десятком картинок это заметные деньги.
- Картинка в URL должна быть публично-доступной. Авторизованные URL (
Authorization: ...заголовок при загрузке) не подойдут — провайдер скачивает анонимно. Если картинка приватная — шлите как base64. - Vision и structured output совмещаются. Можно передать картинку и попросить вернуть JSON по схеме — например, извлечь поля из чека.
- Vision и tool calling тоже совмещаются. Модель может смотреть на картинку и вызывать функции на основе того, что увидела.
Что дальше
- Генерация изображений — обратная задача: получить картинку на выходе.
- Структурированный вывод — извлечение данных из картинки в JSON-схему.
- POST /v1/chat/completions — полная схема параметров.
- Каталог моделей — фильтр по поддержке Vision.
Обновлено: