Разработка ИИ-агентов · Модуль 2 · Урок 2.7
Мультимодальность: изображения и PDF как вход агента
Агент видит, а не только читает
До сих пор вход агента был текстом. Но современные модели мультимодальны: в сообщение можно вложить изображение или PDF, и модель «увидит» его содержимое — прочитает текст со скриншота, опишет диаграмму, извлечёт поля из чека или счёта.
Для агента это открывает целый класс задач: разобрать скриншот ошибки, прочитать накладную, проверить вёрстку по макету, понять график. Механика цикла (урок 1.4) не меняется — меняется лишь содержимое сообщения пользователя: вместо одной строки это список блоков, где есть и текст, и картинка.
Как передать изображение модели
Сообщение становится массивом контентных блоков (content blocks). Текстовый блок несёт вопрос, блок-изображение — сами пиксели. Картинку передают двумя способами:
- base64: байты изображения кодируются в строку и кладутся прямо в запрос (вместе с media type, например
image/png). Удобно для локальных файлов. - по URL: модель скачивает изображение по ссылке (если провайдер это поддерживает).
PDF обрабатывается похоже: документ передаётся как отдельный блок, модель читает и текст, и расположение. Конкретные имена полей, лимиты на размер и поддерживаемые форматы версионно-зависимы — сверяйтесь с актуальными доками провайдера.
Изображение как результат инструмента
Мультимодальность работает не только на входе пользователя. Инструмент агента может вернуть изображение — например, take_screenshot() отдаёт скрин экрана, render_chart() — картинку графика. Тогда tool-результат содержит блок-изображение, и на следующем ходу модель «смотрит» на него, чтобы решить, что делать дальше.
Это основа браузерных и computer-use агентов (подробно — в продвинутом курсе): агент делает скриншот, модель видит интерфейс и решает, куда «кликнуть». Здесь важно помнить про безопасность: на картинке может оказаться текст с инструкцией («сделай X») — это та же prompt injection, только визуальная (см. урок 2.5).
Стоимость и ограничения
Изображение — это токены: модель раскладывает картинку на «плитки», и чем выше разрешение, тем больше токенов и дороже запрос. Практические следствия:
- не шлите 4K-скриншот, если хватает уменьшенной версии — масштабируйте под нужную деталь;
- много изображений в истории быстро раздувают контекст (вспомните управление окном, урок 2.2) — выносите старые картинки во внешнее состояние, оставляя ссылку/описание;
- модель может ошибаться в мелком тексте и точных координатах — не полагайтесь на пиксельную точность без проверки.
flowchart LR
IMG["Изображение / PDF
(скрин, чек, макет)"] --> CB["content blocks:
text + image"]
CB --> M{{LLM видит картинку}}
M -->|tool_use| ACT["Действие: извлечь поля,
кликнуть, ответить"]
ACT --> M
M -->|end_turn| OUT["Структурированный ответ"]// ContentBlock — часть мультимодального сообщения: либо текст, либо изображение.
// Реальные имена полей зависят от провайдера/SDK — СВЕРЯЙТЕСЬ С ДОКАМИ.
type ContentBlock struct {
Type string // "text" | "image"
Text string // для Type=="text"
MediaType string // для Type=="image", напр. "image/png"
DataB64 string // для Type=="image": байты в base64
}
type Message struct {
Role string
Blocks []ContentBlock // вместо одной строки — список блоков
}
// userImageMessage собирает сообщение «вот картинка + вопрос к ней».
func userImageMessage(question string, img []byte, media string) Message {
return Message{
Role: "user",
Blocks: []ContentBlock{
{Type: "text", Text: question},
{Type: "image", MediaType: media, DataB64: base64.StdEncoding.EncodeToString(img)},
},
}
}
func main() {
png, err := os.ReadFile("invoice.png")
if err != nil {
log.Fatal(err)
}
msg := userImageMessage("Извлеки номер счёта и сумму к оплате в JSON.", png, "image/png")
// дальше — обычный агентный цикл из урока 1.4; модель «прочитает» картинку.
_ = msg
}Anti-patterns
| Анти-паттерн | Почему плохо | Как правильно |
|---|---|---|
| Слать максимальное разрешение всегда | Изображение = токены; 4K дорого и медленно | Масштабировать под нужную деталь |
| Копить все картинки в истории | Контекст раздувается, растёт стоимость | Старые изображения — во внешнее состояние, в контексте ссылка |
| Доверять пиксельной точности модели | Ошибки в мелком тексте и координатах | Проверять извлечённое детерминированно, не полагаться на глазомер |
| Игнорировать текст на картинке как ввод | Визуальная prompt injection («сделай X» на скрине) | Относиться к содержимому изображения как к недоверенному вводу |
| Слать картинку строкой в text-блок | Модель не получит изображение | Использовать отдельный image-блок с media type |
Практическое задание
- Передайте модели скриншот или фото чека и попросите извлечь 2–3 поля в строгий JSON (свяжите с уроком 2.4).
- Сравните результат на полном разрешении и на уменьшенной копии — оцените разницу в качестве и в токенах.
- Сделайте инструмент, возвращающий изображение (например, заранее заготовленный график), и проверьте, что модель «видит» его результат на следующем ходу.
- Добавьте проверку: извлечённую сумму валидируйте детерминированно (формат, диапазон), а не доверяйте «на глаз».
- Проверьте безопасность: положите на тестовую картинку текст-инструкцию и убедитесь, что агент не выполняет её слепо.
Проверка знаний
Как корректно передать модели изображение вместе с вопросом?
Верный ответ: B
B верно. Мультимодальное сообщение — это массив блоков: текст + изображение (base64/URL с media type). A — путь к файлу модель не откроет; C — мультимодальная модель именно «видит» пиксели; D — без вопроса непонятно, что делать.
Агент-помощник по интерфейсу на каждом шаге шлёт модели полноэкранный скриншот 4K и хранит все скриншоты в истории. Счёт и задержка резко выросли.
Что в первую очередь исправить?
Верный ответ: B
B верно. Изображения тарифицируются как токены и зависят от разрешения; накопление картинок раздувает окно. Решение — масштабировать и выносить старое во внешнее состояние. A может помочь по цене, но не лечит корень; C ломает агента; D невозможно для изображения.
Почему текст, видимый на изображении, нужно считать недоверенным вводом?
Верный ответ: B
B верно. Визуальная prompt injection — реальный риск: инструкция на скрине/документе может перехватить поведение агента. Содержимое изображения — это данные из внешнего мира, к ним применимы те же guardrails (урок 2.5). A — модель как раз читает текст; C/D — неверные утверждения.