Пошаговые инструкции intermediate 19 мин

Как сделать ИИ-агента для обработки изображений

Пошаговая инструкция от нуля до рабочего прототипа: очередь изображений, OCR, labels, safe search, resize, alt-текст, review и derivatives.

AI-агенты n8n OCR Cloudinary обработка изображений Google Vision safe search alt-текст

Что получится в результате

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

Первая рабочая версия будет делать так:

  1. исходные изображения попадают в папку `incoming_images`;
  2. n8n забирает новые файлы;
  3. агент сохраняет оригинал и не перезаписывает его;
  4. Vision API извлекает OCR, labels и safe search;
  5. workflow проверяет размер, формат, дубли и риск-категории;
  6. Cloudinary или другой image API создает превью и web-версию;
  7. спорные изображения попадают в `review_queue`;
  8. approved-изображения получают ссылки на derivative-файлы;
  9. результат записывается в `image_queue`;
  10. ошибки и ручные решения пишутся в `image_log`.

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

Что понадобится

  • n8n Cloud или self-hosted n8n.
  • Google Drive или S3-совместимое хранилище.
  • Google Sheets для очередей и журнала.
  • Cloudinary или другой сервис трансформации изображений.
  • Google Cloud Vision API или аналог для OCR/labels/safe search.
  • API-ключ LLM-провайдера для описаний и alt-текста.
  • 10-20 тестовых изображений.
  • Человек, который подтверждает спорные результаты.

Шаг 1. Выберите один сценарий

Не начинайте с “обрабатывать любые картинки”.

Для первого прототипа выберите сценарий:

подготовка изображений для статей: проверка, OCR, alt-текст, теги, resize, web-версия и превью

Что входит:

  • JPG/PNG/WebP;
  • изображения до 10 MB;
  • resize для карточек и статьи;
  • alt-текст;
  • теги;
  • OCR, если на изображении есть текст.

Что не входит:

  • документы с паспортами;
  • медицинские изображения;
  • лица и биометрия;
  • генеративное изменение людей;
  • массовое удаление файлов.

Проверка: вы можете назвать один вход и один результат обработки.

Шаг 2. Создайте структуру папок

В Google Drive или S3 создайте:

Image AI agent
  incoming_images
  originals
  derivatives
  needs_review
  rejected
  archive

Правило:

оригинал всегда копируется в originals
производные файлы пишутся в derivatives

Проверка: workflow не работает напрямую с единственной копией файла.

Шаг 3. Создайте таблицу проекта

Создайте Google Sheet:

Image processing AI agent

Добавьте листы:

image_queue
processing_rules
review_queue
derivatives
image_log
error_log
settings
test_cases

Проверка: у n8n есть доступ на чтение и запись.

Шаг 4. Создайте image_queue

В листе `image_queue` сделайте колонки:

image_id
file_id
file_name
source_url
original_url
mime_type
width
height
file_size_mb
detected_text
labels
safe_search_json
alt_text
status
risk_level
review_status
created_at
processed_at
error

Статусы:

  • `new`;
  • `processing`;
  • `processed`;
  • `needs_review`;
  • `approved`;
  • `rejected`;
  • `error`.

Проверка: каждое изображение будет иметь одну строку состояния.

Шаг 5. Создайте правила обработки

В листе `processing_rules` сделайте колонки:

rule_id
rule_type
condition
action
severity
enabled

Добавьте:

R-001 | format | mime_type not in image/jpeg,image/png,image/webp | reject | high | yes
R-002 | size | file_size_mb > 10 | needs_review | medium | yes
R-003 | dimensions | width < 600 or height < 400 | needs_review | low | yes
R-004 | safe_search | adult likely or violence likely | needs_review | high | yes
R-005 | text | detected_text contains password, token, api_key | reject | critical | yes
R-006 | derivative | create article_card 1200x675 | transform | low | yes
R-007 | derivative | create thumbnail 600x338 | transform | low | yes

Проверка: правила можно менять без редактирования workflow.

Шаг 6. Создайте derivatives

В листе `derivatives` сделайте колонки:

derivative_id
image_id
type
url
width
height
format
transformation
created_at

Типы:

  • `article_card`;
  • `thumbnail`;
  • `web`;
  • `social_preview`;
  • `ocr_preview`.

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

Шаг 7. Создайте review_queue

В листе `review_queue` сделайте колонки:

review_id
image_id
file_name
preview_url
risk_level
reason
review_decision
review_comment
reviewer
created_at
reviewed_at

Решения:

  • `approve`;
  • `reject`;
  • `edit`;
  • `request_new_image`;

Проверка: спорные изображения не публикуются автоматически.

Шаг 8. Создайте settings

В листе `settings` добавьте:

key
value
comment

Заполните:

max_file_size_mb | 10 | лимит первой версии
allowed_formats | image/jpeg,image/png,image/webp | разрешенные форматы
article_card_width | 1200 | ширина обложки
article_card_height | 675 | высота обложки
thumbnail_width | 600 | ширина превью
thumbnail_height | 338 | высота превью
auto_publish_allowed | no | в первой версии всегда no

Проверка: размеры и лимиты управляются настройками.

Шаг 9. Подготовьте тестовые изображения

Положите в `incoming_images`:

  1. нормальное фото;
  2. PNG-скриншот с текстом;
  3. картинку маленького размера;
  4. файл больше лимита;
  5. WebP;
  6. изображение с текстом `api_key`;
  7. изображение с потенциально спорным содержимым;
  8. дубль нормального фото.

Проверка: тестовый набор проверяет не только идеальные изображения.

Шаг 10. Создайте workflow обработки

Назовите workflow:

Image processing pipeline

Добавьте узлы:

  1. `Schedule Trigger`;
  2. `Google Drive` или S3 - список файлов из `incoming_images`;
  3. `Split In Batches`;
  4. `Google Drive` - скачать файл;
  5. `Code` - метаданные файла;
  6. `Cloudinary Upload` или `HTTP Request` - загрузка оригинала;
  7. `Google Vision` или `HTTP Request` - OCR/labels/safe search;
  8. `Code` - проверка правил;
  9. `LLM` - alt-текст и краткое описание;
  10. `Cloudinary Transform` - derivative-файлы;
  11. `Google Sheets` - запись `image_queue`;
  12. `Google Sheets` - запись `derivatives`;
  13. `Google Sheets` - запись `review_queue`;
  14. `Google Sheets` - запись `image_log`;
  15. `Google Drive` - перенос файла в нужную папку.

Проверка: workflow создан и запускается вручную.

Шаг 11. Получите метаданные файла

В узле `Code` зафиксируйте:

file_name
mime_type
file_size_mb
width
height
hash

Если n8n не видит width/height без библиотеки, получите их через Cloudinary после upload или через выбранный image API.

Проверка: у изображения есть формат, размер и уникальный hash.

Шаг 12. Загрузите оригинал

Загрузите файл в Cloudinary или другое хранилище как оригинал.

Пример Cloudinary upload через HTTP Request:

curl https://api.cloudinary.com/v1_1/CLOUD_NAME/image/upload \
  -X POST \
  -F "file=@image.jpg" \
  -F "folder=ezgpt/originals" \
  -F "timestamp=TIMESTAMP" \
  -F "api_key=API_KEY" \
  -F "signature=SIGNATURE"

В n8n секреты храните в credentials или переменных, а не в таблице.

Проверка: Cloudinary вернул `secure_url`, `public_id`, width, height и format.

Шаг 13. Проверьте дубли

Перед обработкой проверьте hash.

Правило:

если hash уже есть в image_queue со статусом processed/approved, новый файл отправить в needs_review как duplicate

Проверка: одно и то же изображение не обрабатывается повторно без причины.

Шаг 14. Запустите OCR и labels

Отправьте изображение в Vision API.

Нужные результаты:

  • `detected_text`;
  • `labels`;
  • `safe_search`;
  • confidence, если API возвращает.

Минимальный объект:

{
  "detected_text": "AI agents workflow",
  "labels": ["diagram", "text", "software"],
  "safe_search": {
    "adult": "VERY_UNLIKELY",
    "violence": "UNLIKELY",
    "racy": "UNLIKELY"
  }
}

Проверка: скриншот с текстом дает OCR, а фото получает labels.

Шаг 15. Проверьте sensitive text

В узле `Code` проверьте OCR-текст.

const text = String($json.detected_text || '').toLowerCase();
const forbidden = [
  'api_key',
  'password',
  'secret',
  'token',
  'bearer ',
  'sk-'
];

const hits = forbidden.filter(x => text.includes(x));

if (hits.length > 0) {
  return [{
    ...$json,
    status: 'rejected',
    risk_level: 'critical',
    reason: `Sensitive text detected: ${hits.join(', ')}`
  }];
}

return [$json];

Проверка: изображение с ключом не уходит в публикацию.

Правила первой версии:

adult likely или very_likely -> needs_review
violence likely или very_likely -> needs_review
racy very_likely -> needs_review
medical/legal/personal document -> needs_review

Не удаляйте файл автоматически. Перенесите его в `needs_review` и создайте строку в `review_queue`.

Проверка: спорное изображение не получает `approved`.

Шаг 17. Сгенерируйте alt-текст

LLM получает только безопасные данные:

file_name
labels
detected_text
контекст страницы или статьи, если есть

System prompt:

Ты пишешь alt-текст для изображения.
Пиши кратко и по фактам.
Не придумывай людей, бренды, места и события.
Не описывай скрытые или чувствительные данные.
Верни только JSON.

User prompt:

Labels:
{{labels}}

OCR:
{{detected_text}}

Контекст:
{{page_context}}

Верни JSON:
{
  "alt_text": "краткое описание до 160 символов",
  "caption": "подпись, если нужна",
  "tags": ["tag1", "tag2"],
  "confidence": 0.0
}

Проверка: alt-текст не длинный и не выдумывает детали.

Шаг 18. Создайте derivative-версии

Для статьи:

article_card: 1200x675, crop/fill
thumbnail: 600x338, crop/fill
web: ширина до 1600, quality auto, format auto

Пример Cloudinary transformation URL:

https://res.cloudinary.com/CLOUD_NAME/image/upload/c_fill,w_1200,h_675,q_auto,f_auto/PUBLIC_ID

Проверка: derivative открывается по URL и имеет нужный размер.

Шаг 19. Запишите image_queue

Добавьте строку:

image_id
file_id
file_name
source_url
original_url
mime_type
width
height
file_size_mb
detected_text
labels
safe_search_json
alt_text
status
risk_level
review_status
created_at
processed_at

Если все хорошо:

status: processed
review_status: draft

Если нужен человек:

status: needs_review
review_status: draft

Проверка: результат виден в таблице.

Шаг 20. Запишите derivatives

Для каждой производной версии добавьте строку:

derivative_id
image_id
type
url
width
height
format
transformation
created_at

Проверка: можно взять URL обложки, thumbnail и web-версии отдельно.

Шаг 21. Отправьте спорные в review_queue

Если `risk_level = high` или `critical`, создайте review.

Причины:

  • sensitive text;
  • safe search risk;
  • низкое качество;
  • слишком маленький размер;
  • дубль;
  • неясные права на изображение;
  • лицо или персональный документ.

Проверка: человек получает понятную причину, а не просто “проверь картинку”.

Шаг 22. Проверьте изображение человеком

Редактор открывает `review_queue`.

Проверяет:

  • можно ли использовать изображение;
  • нет ли секретов в тексте;
  • есть ли права;
  • не содержит ли изображение персональные данные;
  • подходит ли alt-текст;
  • не обрезана ли важная часть на превью;
  • нет ли дубликата.

Решение:

approve
reject
edit
request_new_image

Проверка: без решения редактора спорное изображение не попадает в публикацию.

Шаг 23. Создайте workflow применения review

Назовите workflow:

Image review apply

Он делает:

  1. читает `review_queue`;
  2. берет строки с `review_decision`;
  3. обновляет `image_queue`;
  4. при `approve` ставит `approved`;
  5. при `reject` переносит файл в `rejected`;
  6. пишет событие в `image_log`.

Проверка: ручное решение меняет статус изображения.

Шаг 24. Подключите к публикации

Когда изображение `approved`, можно передать URL в CMS.

Минимальный payload:

{
  "image_id": "IMG-1001",
  "article_card_url": "https://...",
  "thumbnail_url": "https://...",
  "web_url": "https://...",
  "alt_text": "Схема AI-агента для обработки изображений",
  "tags": ["AI", "workflow", "image"]
}

Проверка: CMS получает derivative URL, а не исходный файл.

Шаг 25. Добавьте error_log

В листе `error_log` сделайте колонки:

error_id
image_id
file_name
step
error_type
error_text
payload_preview
created_at
resolved_at

Ошибки:

  • upload failed;
  • OCR failed;
  • transformation failed;
  • invalid format;
  • file too large;
  • LLM JSON invalid;
  • derivative URL not available.

Проверка: сбой обработки не исчезает в истории n8n.

Шаг 26. Сделайте regression test

В листе `test_cases` сделайте колонки:

case_id
file_name
expected_status
expected_review_required
expected_derivatives_count
expected_has_alt
enabled

Добавьте тесты:

  • нормальный JPG;
  • нормальный PNG;
  • WebP;
  • слишком маленькое изображение;
  • слишком большой файл;
  • скриншот с текстом;
  • изображение с `api_key`;
  • дубль;
  • спорное safe search;
  • плохой OCR.

Создайте workflow:

Image processing regression test

Он прогоняет тестовые файлы и сравнивает ожидаемые статусы с фактическими.

Проверка: изменение правил или prompt не ломает базовую обработку.

Минимальная проверка результата

Прототип работает, если выполняются все пункты:

  • файл из `incoming_images` попадает в workflow;
  • оригинал сохраняется отдельно;
  • OCR и labels записываются;
  • sensitive text блокируется;
  • safe search риски идут в review;
  • alt-текст создается по фактам;
  • derivative-файлы создаются и доступны по URL;
  • спорные изображения попадают в `review_queue`;
  • решение редактора меняет статус;
  • ошибки пишутся в `error_log`;
  • regression test проверяет основные сценарии.

Что нельзя автоматизировать в первой версии

  • удаление оригиналов;
  • публикацию спорных изображений без review;
  • обработку паспортов и документов без отдельного процесса;
  • распознавание личности людей;
  • генеративное изменение лиц;
  • массовую замену изображений на сайте;
  • использование картинок без прав;
  • скрытие sensitive text вместо блокировки;
  • отправку изображений с персональными данными в сторонние API без согласования.

Частые вопросы

Можно ли использовать только LLM без Vision API?

Для первого прототипа лучше разделить задачи. Vision API извлекает OCR, labels и safe search, а LLM пишет alt-текст и объяснение по уже извлеченным данным.

Нужно ли сохранять оригинал?

Да. Оригинал нужен для аудита, повторной обработки и исправления ошибок. Производные версии можно пересоздать, а потерянный оригинал восстановить сложно.

Можно ли автоматически публиковать approved-изображения?

Можно после тестов, но в первой версии лучше передавать approved URL в CMS как черновик. Спорные изображения должны проходить review.

Что делать с изображением, где найден API key?

Ставить `rejected` или `needs_review` с критичным риском. Не публиковать и не пытаться “замазать” секрет автоматически без процедуры безопасности.

Какой минимум нужен для запуска?

Папки `incoming_images`, `originals`, `derivatives`, таблицы `image_queue`, `processing_rules`, `review_queue`, `derivatives`, n8n workflow, OCR/labels API, image transformation API, LLM alt-текст и ручной review.

Дальше по теме

Похожие материалы