Главная/Блог/Гайд/Как отправить изображение в LLM: Полное…
Гайд10 мин чтения · 14 августа 2026 г.

Как отправить изображение в LLM: Полное руководство по Vision API

Пошаговое руководство по интеграции мультимодальных моделей: от базовых запросов до продвинутого RAG с изображениями.

Как отправить изображение в LLM: Полное руководство по Vision API

В эпоху, когда большие языковые модели (LLM) стали неотъемлемой частью разработки, способность ИИ не только читать текст, но и «видеть» мир через изображения открывает совершенно новые горизонты для автоматизации. Представьте себе сценарий, где ваша система автоматически анализирует сканы счетов-фактур, извлекает данные из сложных графиков или помогает пользователям находить информацию в технических инструкциях с иллюстрациями. Это уже не футуристическая концепция, а рабочая реальность, доступная через стандартные API.

Однако, чтобы заставить LLM «понять» изображение, недостаточно просто загрузить файл. Необходимо правильно сформировать структуру запроса, выбрать подходящую модель и учесть технические нюансы, такие как токенизация изображений и стоимость обработки. В этом подробном руководстве мы разберем, как эффективно отправлять изображения в LLM через API, используя платформу OpenRouter, и как построить надежные мультимодальные пайплайны для production-среды.

01Основы: Как прикрепить изображение к чату

Базовый принцип работы с мультимодальными моделями прост, но требует понимания специфической структуры данных. В отличие от текстовых запросов, где поле content является простой строкой, при добавлении изображения оно превращается в массив объектов. Каждый объект в этом массиве имеет свой тип: text для текста и image_url для изображения.

Ключевой момент, который часто упускают новички: порядок элементов в массиве content имеет значение. Текстовая часть должна идти первой, а затем следует часть с изображением. Это связано с тем, как парсеры интерпретируют входящие данные. Если ваша логика требует, чтобы изображение было «в центре внимания» до текста, перенесите этот контекст в системное промпт-сообщение, а не пытайтесь менять порядок в массиве контента пользователя.

💡
Совет по структуре. Всегда начинайте массив контента с объекта типа text. Пример: [{"type": "text", "text": "Что изображено на фото?"}, {"type": "image_url", "image_url": {"url": "..."}}]. Это гарантирует корректную обработку запроса большинством провайдеров.

Эндпоинт для таких запросов — стандартный POST /api/v1/chat/completions. Тело запроса содержит массив сообщений, где роль пользователя (user) включает в себя этот составной контент. После того как вы освоили эту базовую структуру, форма запроса остается неизменной. Единственное, что меняется, — это поле model, позволяющее вам переключаться между различными моделями, поддерживающими анализ изображений, без переписывания кода интеграции.

Пример структуры запроса с изображением
Пример структуры запроса с изображением

02Выбор модели: URL против Base64

Поле image_url.url принимает два формата данных: публичную ссылку HTTP(S) или строку в формате base64 data URL. Выбор между ними зависит от того, где физически хранится ваш файл.

Публичные URL: Если изображение уже доступно в интернете — например, оно лежит на CDN, в публичном бакете S3 или на вашем веб-сервере — используйте прямую ссылку. Это делает запрос более легким, так как провайдер сам загружает байты изображения. Однако этот метод уязвим к проблемам с доступом: если ссылка истечет, будет заблокирована географически или потребует авторизации, запрос может завершиться ошибкой.

Base64: Для локальных файлов, конфиденциальных данных (например, сканы паспортов) или изображений, не имеющих публичного доступа, необходимо закодировать файл в формат base64 и передать его внутри запроса. Хотя это увеличивает размер полезной нагрузки и время загрузки, это гарантирует, что файл покидает вашу систему только через защищенный API-вызов. Оба формата поддерживают PNG, JPEG, WebP и GIF.

Схема потока обработки изображения
Схема потока обработки изображения

Примеры кода на разных языках

Давайте рассмотрим практическую реализацию на трех популярных языках программирования. Обратите внимание, что единственная строка, которую нужно изменить для тестирования разных моделей, — это переменная MODEL.

terminalbash
# cURL (использование публичного URL)
curl https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "model": "anthropic/claude-opus-4.8",
  "messages": [
    {
      "role": "user",
      "content": [
        { "type": "text", "text": "Какова общая сумма на этом чеке?" },
        { "type": "image_url", "image_url": { "url": "https://example.com/receipt.jpg" } }
      ]
    }
  ]
}'
terminalpython
# Python (локальный файл → base64)
import base64, os, requests

def to_data_url(path: str, mime: str = "image/jpeg") -> str:
    with open(path, "rb") as f:
        b64 = base64.b64encode(f.read()).decode("utf-8")
    return f"data:{mime};base64,{b64}"

MODEL = "anthropic/claude-opus-4.8"  # замените эту строку на любую vision-модель

resp = requests.post(
    "https://openrouter.ai/api/v1/chat/completions",
    headers={"Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}"},
    json={
        "model": MODEL,
        "messages": [{
            "role": "user",
            "content": [
                {"type": "text", "text": "Какова общая сумма на этом чеке?"},
                {"type": "image_url", "image_url": {"url": to_data_url("receipt.jpg")}}
            ]
        }],
    },
)
print(resp.json()["choices"][0]["message"]["content"])
terminaltypescript
// TypeScript (локальный файл → base64)
import { readFile } from "node:fs/promises";

const MODEL = "anthropic/claude-opus-4.8"; // измените только это для смены модели

const bytes = await readFile("receipt.jpg");
const dataUrl = `data:image/jpeg;base64,${bytes.toString("base64")}`;

const res = await fetch("https://openrouter.ai/api/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: MODEL,
    messages: [{
      role: "user",
      content: [
        { type: "text", text: "Какова общая сумма на этом чеке?" },
        { type: "image_url", image_url: { url: dataUrl } },
      ],
    }],
  }),
});

const data = await res.json();
console.log(data.choices[0].message.content);
Сравнение передачи URL и Base64
Сравнение передачи URL и Base64

03Выбор Vision-модели: Что и зачем

Не каждая модель на рынке умеет работать с изображениями. Модель считается «vision-моделью» (VLM — Vision Language Model), если она сочетает текстовую модель с энкодером изображений, позволяя обрабатывать пиксели наряду с токенами. В каталоге OpenRouter вы можете проверить поддержку изображений, посмотрев архитектуру модели: если в input_modalities есть значение image, модель принимает изображения.

Разные модели специализируются на разных задачах. Вот сравнительная таблица популярных вариантов:

Каталог моделей с поддержкой изображений
Каталог моделей с поддержкой изображений
| Модель | Цена за 1M токенов | Контекст | Для чего лучше всего подходит | | :--- | :--- | :--- | :--- | | anthropic/claude-opus-4.8 | $5.00 | 1M | Сложные документы, тщательный анализ графиков и таблиц | | anthropic/claude-sonnet-5 | $2.00 | 1M | Баланс между пониманием документов и стоимостью | | google/gemini-3-flash-preview | $0.50 | 1M | Высокий объем скриншотов, общие вопросы, низкая задержка | | google/gemini-2.5-flash | $0.30 | 1M | Дешевый пакетный OCR и создание описаний | | qwen/qwen3-vl-235b-a22b-instruct | ~$0.26 | 256K | Открытый вес, OCR и извлечение текста на нескольких языках | | meta-llama/llama-4-scout | ~$0.10 | 1.3M | Открытый вес, общее зрительное понимание, удобно для самохостинга |

Цены и окна контекста могут меняться, поэтому всегда проверяйте актуальные данные через API /models. Преимущество использования таких платформ, как OpenRouter, заключается в возможности программно фильтровать каталог. Вы можете запросить список всех моделей, поддерживающих изображения, и выбирать их динамически на основе цены, скорости или точности, не меняя код интеграции.

terminalpython
import requests

models = requests.get("https://openrouter.ai/api/v1/models").json()["data"]
vision = [m["id"] for m in models if "image" in m["architecture"]["input_modalities"]]
print(vision)  # модели, принимающие изображения

04Работа с несколькими изображениями и документами

Вы не ограничены одним изображением в запросе. Вы можете добавить столько объектов image_url, сколько необходимо, в массив контента. Это полезно для сравнения «до и после», анализа многостраничных сканов или ответа на вопрос, который охватывает несколько графиков одновременно.

Однако здесь вступают в силу практические ограничения. Хотя универсального лимита на количество изображений нет, каждый провайдер устанавливает свои пределы. Отправка десятков изображений одновременно может привести к ошибкам или высокой стоимости. Каждое изображение добавляет токены, поэтому цена растет пропорционально количеству и разрешению изображений, особенно при отправке полных сканированных документов.

⚠️
Важно оптимизировать. Фотография чека с телефона может иметь ширину 4000 пикселей. Модели не нужно такое высокое разрешение, чтобы прочитать итоговую сумму. Уменьшите изображение до минимального размера, при котором текст остается читаемым. Если вы знаете, какая часть изображения важна, обрежьте лишнее. Это снижает стоимость токенов и часто повышает точность, так как модель не отвлекается на визуальный шум.

05Как работает токенизация изображений

Понимание того, как модели «видят» изображения, критически важно для контроля затрат. Изображения разбиваются на патчи (кусочки), преобразуются в эмбеддинги, а затем обрабатываются как токены. Энкодер изображений, обычно Vision Transformer, разрезает изображение на сетку фиксированных патчей. Каждый патч преобразуется в вектор (эмбеддинг), представляющий этот фрагмент. Эти эмбеддинги передаются языковой модели как токены, смешиваясь с вашими текстовыми токенами.

Модель никогда не видит «сырые» пиксели. Она видит эмбеддинги патчей. Следствие простое: больше пикселей означает больше патчей, а больше патчей означает больше токенов в вашем счете. Именно поэтому уменьшение масштаба изображения (downscaling) напрямую снижает количество токенов, которые генерирует энкодер. Точное количество токенов для конкретного изображения варьируется в зависимости от провайдера, поэтому для точного планирования бюджета изучайте документацию конкретной модели.

06Мультимодальный RAG: Поиск по документам с изображениями

Мультимодальный RAG (Retrieval-Augmented Generation) позволяет индексировать изображения, графики и сканированные страницы вместе с текстом. Это решает проблему, когда ключевая информация в документе (например, число в столбчатой диаграмме) не может быть найдена текстовым поиском, так как она не представлена в виде текста. Обычный OCR часто ошибается в сложных графиках или пропускает их.

Существует две основные стратегии индексирования:

  1. Стратегия A: Суммаризация в текст. На этапе индексации отправляйте каждый график или скан через VLM, прося создать текстовое описание. Затем создайте эмбеддинг этого описания вместе с обычным текстом. Это позволяет использовать любые существующие векторные базы данных. Недостаток: качество поиска зависит от качества суммаризации. Если VLM упустит деталь при создании описания, она не будет найдена позже.
  2. Стратегия B: Нативные мультимодальные эмбеддинги. Пропустите шаг суммаризации и используйте модель эмбеддинга, которая помещает изображения и текст в одно векторное пространство. Текстовый запрос может напрямую сопоставляться с изображением. Это сохраняет больше визуальных деталей, но требует наличия мультимодальной модели эмбеддингов в вашем стеке.

На этапе ответа (answer step) для обеих стратегий используется один и тот же подход: вы берете лучшие текстовые и визуальные фрагменты, собранные поиском, и формируете единый массив контента, включающий вопрос, извлеченный текст и извлеченные изображения.

terminalpython
def answer(question, retrieved):
    content = [{"type": "text", "text": question}]
    for r in retrieved:
        if r["type"] == "text":
            content.append({"type": "text", "text": r["text"]})
        else:  # chunk изображения
            content.append({"type": "image_url", "image_url": {"url": r["url"]}})
    
    return requests.post(
        "https://openrouter.ai/api/v1/chat/completions",
        headers={"Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}"},
        json={
            "model": "anthropic/claude-opus-4.8",
            "messages": [{"role": "user", "content": content}],
        },
    ).json()

07Что это значит на практике

Интеграция мультимодальных возможностей в ваши приложения требует внимательности к деталям, но предлагает огромную гибкость. Вот три ключевых вывода, которые стоит запомнить:

  1. Универсальное тело запроса. Один и тот же формат JSON работает для всех vision-моделей. Вам не нужно переписывать логику отправки данных при смене модели с Claude на Gemini или Llama. Вы меняете только одну строку — идентификатор модели.
  2. Выбор формата передачи. Используйте публичные URL для уже размещенных в сети изображений для экономии трафика и скорости. Используйте base64 для локальных или конфиденциальных файлов, чтобы обеспечить безопасность и избежать проблем с доступом. В обоих случаях старайтесь уменьшать разрешение изображений перед отправкой, чтобы оптимизировать стоимость.
  3. RAG как надстройка. Мультимодальный RAG добавляет слой поиска перед стандартным вызовом API. Индексируйте графики и сканы рядом с текстом, извлекайте релевантные фрагменты и отправляйте их в модель, используя тот же базовый запрос, что и для простых изображений.

Этот подход не идеален для всех задач. Он не предназначен для обработки видео в реальном времени (где нужны специализированные пайплайны выборки кадров) или для сверхточного OCR мелкого текста в низком разрешении. Также помните, что этот метод предназначен только для ввода изображений. Генерация или редактирование изображений требуют совершенно других API и форматов запросов.

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

Источник: OpenRouter ↗