tunnel_ docs

Эмбеддинги и мультимодальность

POST /v1/embeddings совместим с OpenAI: каждый элемент input → один вектор в ответе. Поверх стандарта шлюз добавляет мультимодальное расширение — элемент input может быть не строкой, а массивом «частей» (text/image/audio/video/pdf), которые агрегируются в один вектор.

Обычный текстовый ввод

from openai import OpenAI

client = OpenAI(
    base_url="https://api.aigateway.andrewdev.ru/v1",
    api_key="sk-tn-ВАШ_КЛЮЧ",
)
response = client.embeddings.create(
    model="gemini-embedding-2",
    input=["первый текст", "второй текст"],
)
for item in response.data:
    print(item.index, len(item.embedding))

input принимает строку или массив; каждый элемент массива — это либо строка (обычный текст), либо массив частей (см. ниже). Несколько элементов input уходят апстриму одним батч-запросом.

Мультимодальное расширение

Вместо строки элемент input может быть массивом частей. Все части одного элемента объединяются в один запрос эмбеддинга и дают один вектор на выходе (не по вектору на часть):

{
  "model": "gemini-embedding-2",
  "input": [
    [
      { "type": "text", "text": "Подпись к товару" },
      {
        "type": "image_url",
        "image_url": { "url": "data:image/png;base64,iVBORw0KGgo..." }
      }
    ]
  ]
}

Поддерживаемые типы частей:

typeФормаОграничение (400, если превышено)
text{"type": "text", "text": string}
image_url{"type": "image_url", "image_url": {"url": "data:image/png|image/jpeg;base64,..."}}не более 6 изображений на элемент input; только PNG/JPEG base64 data-URI
input_audio{"type": "input_audio", "input_audio": {"data": string, "format": "mp3" | "wav"}}см. практический лимит Gemini ниже
input_video{"type": "input_video", "input_video": {"data": string, "format": "mp4" | "mov"}}см. практический лимит Gemini ниже
input_file{"type": "input_file", "input_file": {"data": string, "mime_type": "application/pdf"}}не более 1 PDF на элемент input

data во всех случаях — содержимое файла в base64 (без data: префикса для audio/video/file — в отличие от image_url, где нужен полный data-URI).

Изображения и PDF шлюз проверяет до обращения к апстриму — превышение лимита возвращает наш собственный 400 invalid_request с понятным сообщением, апстрим не вызывается.

Только для Gemini-моделей эмбеддингов

Части (image_url/input_audio/input_video/input_file) принимает только модель на маршруте Google (например, gemini-embedding-2). Если такой элемент input отправить модели на OpenAI-совместимом маршруте, шлюз вернёт 400: "This model does not support multimodal embeddings". Обычная строка в input работает с любой моделью эмбеддингов.

Практические лимиты Gemini Embedding 2

Помимо проверок count (6 изображений, 1 PDF), сама модель gemini-embedding-2 на стороне Google ограничивает содержимое так:

МедиаЛимит
Аудио (MP3/WAV)до 180 с
Видео (MP4/MOV)до 120 с (32 кадра)
PDF1 файл, до 6 страниц (~258 токенов/страница)
Суммарно на запрос8192 токена

Эти лимиты — не наша локальная валидация (шлюз их не пересчитывает заранее), а ограничение самой модели: превышение вернёт ошибку от апстрима, транслированную в наш стандартный 502/400. Планируйте контент в этих рамках, чтобы не терять запрос на середине пайплайна.

Пример полного запроса на Python

import base64

with open("product.png", "rb") as f:
    image_b64 = base64.b64encode(f.read()).decode()

response = client.embeddings.create(
    model="gemini-embedding-2",
    input=[
        "обычный текстовый запрос",
        [
            {"type": "text", "text": "Фото товара с описанием"},
            {
                "type": "image_url",
                "image_url": {"url": f"data:image/png;base64,{image_b64}"},
            },
        ],
    ],
)
print(len(response.data))  # 2 вектора: один на строку, один на элемент-массив

Ответ

{
  "object": "list",
  "model": "gemini-embedding-2",
  "data": [
    { "object": "embedding", "index": 0, "embedding": [0.0123, -0.0456, "..."] },
    { "object": "embedding", "index": 1, "embedding": [0.0031, 0.0789, "..."] }
  ],
  "usage": { "prompt_tokens": 342, "total_tokens": 342 }
}

usage для Gemini-эмбеддингов — всегда оценка

Gemini не возвращает точное число токенов для embedContent/ batchEmbedContents — для моделей на маршруте Google usage всегда оценивается шлюзом по документированным правилам Google (символы текста / 4, ~258 токенов на изображение, ~1000 на аудио, ~1500 на видео, ~1548 на PDF) и помечен как оценочный. Для эмбеддинг-моделей на OpenAI-совместимом маршруте usage берётся из ответа апстрима, если он его вернул.