Kimi K3: зрение и мультимодальность — ввод изображений, видео и код по макету

Kimi K3 нативно принимает изображения и видео. Как правильно собрать мультимодальные messages: base64 для локальных картинок, видео через files API и ms://, почему публичные URL не работают.

Одно из самых полезных улучшений Kimi K3 — то, что зрение стало нативной возможностью: не нужно ни навешивать OCR, ни вызывать отдельную визуальную модель. Вы кладёте изображения и видео прямо в messages, и модель «смотрит на картинку», чтобы писать код, читать графики и понимать интерфейсы. Но в сборке мультимодального запроса есть несколько деталей, которые нужно сделать в точности верно, иначе он просто вернёт ошибку. Это руководство раскладывает правильный подход по полочкам.

Сначала два железных правила

У ввода изображений в Kimi K3 два жёстких требования — запомните их прежде всего:

  1. Содержимое из изображения и текста должно быть «массивом объектов», а не склеенной сериализованной строкой. То есть content записывается как список вида [{type:"text",...}, {type:"image_url",...}].
  2. Публичные URL изображений не поддерживаются. Локальные картинки вставляйте инлайн как base64, а видео загружайте через files API и ссылайтесь на него как ms://<file-id>. Передача https://example.com/a.png напрямую завершится ошибкой.

Держите эти два правила в голове — и большинство «ошибок визуального запроса» обойдёт вас стороной.

Ввод изображений: инлайн base64

import base64, os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["MOONSHOT_API_KEY"],
    base_url="https://api.moonshot.cn/v1",
)

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

resp = client.chat.completions.create(
    model="kimi-k3",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Какие UI-компоненты есть на этом изображении? Составь список."},
            {"type": "image_url",
             "image_url": {"url": f"data:image/png;base64,{b64}"}},
        ],
    }],
)
print(resp.choices[0].message.content)

Обратите внимание, что image_url.url использует data URI (data:image/png;base64,...). Это «инлайн base64», а не «публичная ссылка» — и именно этот формат поддерживает K3.

Ввод видео: files API + ссылка ms://

Сначала загрузите видеофайл через files API, а получив file id, сошлитесь на него в сообщении через ms://<file-id>:

# 1) Загружаем видео и получаем file id
f = client.files.create(file=open("demo.mp4", "rb"), purpose="assistants")

# 2) Ссылаемся на него в сообщении через ms://<file-id>
resp = client.chat.completions.create(
    model="kimi-k3",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Какие шаги пользователь выполнил в этой записи экрана?"},
            {"type": "image_url", "image_url": {"url": f"ms://{f.id}"}},
        ],
    }],
)

Параметры эндпоинта загрузки, такие как purpose, смотрите в официальной документации — перед интеграцией сверьтесь с актуальной версией.

На практике: превращаем макет в фронтенд

K3 заточен под сценарии, «сочетающие программную инженерию и визуальный анализ», и самый типичный из них — писать фронтенд прямо по макету:

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

resp = client.chat.completions.create(
    model="kimi-k3",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text":
                "Строго по этому макету напиши соответствующий HTML + Tailwind CSS. "
                "Максимально повтори вёрстку, отступы и цвета и выведи полный работающий файл целиком."},
            {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}},
        ],
    }],
)
print(resp.choices[0].message.content)

Тот же подход годится, чтобы читать данные с графика для анализа, находить проблему по скриншоту с ошибкой или править код по скриншоту из игры / CAD. Поскольку у K3 контекст в 1M, вы можете даже засунуть «макет + существующую кодовую базу» вместе и заставить его вносить правки в полном контексте проекта, а не генерировать с нуля (об использовании длинного контекста см. руководство по контексту 1M).

Частые ошибки

  • Визуальный запрос сразу падает: чаще всего вы передали публичный URL или склеили content в строку. Перейдите на base64 / ms:// плюс массив объектов.
  • Слишком большое изображение / превышен бюджет: и изображения, и видео считаются в токенах, а крупная картинка или длинное видео съедают массу контекста. При необходимости сжимайте размеры или прореживайте кадры.
  • Теряется состояние между ходами: в многоходовом диалоге с изображениями не забывайте отправлять полное сообщение assistant обратно дословно — не оставляйте только content.

Итог

Нативное зрение K3 превращает «посмотреть на изображение + написать код» в то, что одна модель делает за один запрос. Держите в уме два железных правила (массив объектов, никаких публичных URL) — и вы, по сути, не оступитесь. Полную интеграцию, цены и миграцию смотрите в руководстве по API Kimi K3. Чтобы одним ключом вызывать K3 вместе с другими мультимодальными моделями и сравнивать результаты по задачам, получите ключ в консоли GetModel и начните.