Начало
В начале был ПРОМПТ и LLM генерировала картинку на его основе. Работать можно было через чат и несколько раз перегенирировать обложку к статье. В этом нестабильном процессе много времени отнимала подготовка самого промпта, выбор краткого содержания — синопсиса статьи, описание деталей и элементов стиля. Картинку сохраняем и дообрабатываем вручную, так как модель часто допускала неточности. В целом не проблема — вариант вполне рабочий, многие им и пользуются даже через https://giga.chat. Но я пошел дальше.
Агент суммаризатор
Главный лайфхак в работе с LLM заключается в том, что промпты для LLM должна готовить LLM. А если операция регулярно повторяется, то можно сделать агента.
Для меня рабочим и несложным вариантом разработки агента является n8n.
Реализовал простую схему:
Диаграмма:
flowchart LR
%% Стили для BPMN элементов
classDef start fill:#d1fae5,stroke:#10b981,stroke-width:2px;
classDef task fill:#dbeafe,stroke:#3b82f6,stroke-width:2px;
classDef gateway fill:#fef3c7,stroke:#f59e0b,stroke-width:2px;
classDef finish fill:#fee2e2,stroke:#ef4444,stroke-width:2px;
classDef boundary stroke-width:4px;
Model("AI model - подключаем LLM по API"):::start
Task1["Chat trigger - передаем статью на вход"]:::task
Task2[["AI agent - суммаризируем статью и генерируем промпт для генерации обложки"]]:::gateway
Task3["Chat response / save to file - сохраняем готовый файл"]:::task
EndNode("Конец"):::finish
Task1 --> Task2
Model --> Task2
Task2 --> Task3
Task3 --> EndNodeПромпт для AI агента:
Ты — профессиональный креативный продюсер и промпт-инженер с опытом в визуализации деловых и технологических тем.
Твоя задача — по тексту статьи, который я пришлю ниже, создать максимально точный и выразительный промпт для генерации обложки в нейросети Nanobanana (или аналогичной).
Полученный от агента ПРОМПТ уже можно было использовать для генерации обложек. Время экономилось, и можно было сравнить результат работы разных GEN-AI.
Где удобней сравнить работу text-to-image LLM? — OpenRouter.ai
Собираем конвейер генерации картинки
В n8n нет ноды для работы с Openrouter.ai, Но есть HTTP-request — используем его и отправляем в модель полученный на предыдущем шаге ПРОМПТ, для этого настраиваем JSON, указываем параметры четной записи.
{
"model": "gemini-3.1-flash-image",
"messages": [
{
"role": "user",
"content": "Сделай изображение по описанию:{{ $json.output }}"
}
],
"modalities": ["image", "text"],
"image_config": {
"aspect_ratio": "16:9",
"image_size": "1K"
}
}
Всё бы хорошо, но HTTP-request возвращает текст.
Испольщуем ноду Кода и вставляем код, собирающий картинку из текста:
const img = $json.choices[0].message.images[0].image_url.url;
const match = img.match(/^data:(image/[a-zA-Z0-9.+-]+);base64,([sS]+)$/);
if (!match) {
throw new Error('Unexpected image data URL format: ' + String(img).slice(0, 64));
}
const mimeType = match[1];
const base64 = match[2];
const ext = mimeType === 'image/jpeg' ? 'jpg' : mimeType.split('/')[1];
const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
const fileName = 'NanoBanana_cover_' + stamp + '.' + ext;
const filePath = '/home/node/.n8n-files/Generated_picts/' + fileName;
return [
{
json: { mimeType, fileName, filePath },
binary: {
data: {
data: base64,
mimeType,
fileName,
},
},
},
];
На выходе уже имеем файл, который осталось только сохранить на диск.
Схема воркфлоу получается такая:
flowchart LR
%% Стили для BPMN элементов
classDef start fill:#d1fae5,stroke:#10b981,stroke-width:2px;
classDef task fill:#dbeafe,stroke:#3b82f6,stroke-width:2px;
classDef gateway fill:#fef3c7,stroke:#f59e0b,stroke-width:2px;
classDef finish fill:#fee2e2,stroke:#ef4444,stroke-width:2px;
classDef boundary stroke-width:4px;
Model("AI model - подключаем LLM по API"):::start
Task1["Chat trigger - передаем статью на вход"]:::task
Task2[["AI agent - суммаризируем статью и генерируем промпт для генерации обложки"]]:::gateway
HTTP["Запрос в LLM на создание картинки"]:::gateway
JavaScript["Преобразование ответа в картинку"]:::gateway
Task3["save to file - сохраняем готовый файл"]:::task
EndNode("Конец"):::finish
Task1 --> Task2
Model --> Task2
Task2 --> HTTP
HTTP --> JavaScript
JavaScript --> Task3
Task3 --> EndNode
В этом варианте Агенты сами анализируют статью, делают ПРОМПТ для генерации обложки и делают обложку.
Если результат генерации не устраивает - можно вернуться в ноду AI-agent, поправить выдачу и перегенерировать картинку. На моей практике такое случалось редко - точность у работы моделей весьма высокая.
Наводим стиль в картинках
Следующей задачей было убрать различие стилей в картинках, добавить персонажи.
Наиболее эффективный к тому путь — доработка системного промпта в ноде AI-agent
Для этого в системном промпте создал раздел с описанием стиля и песонажа, назвал его StyleDNA. промпт получился приблизительно такой:
Ты — профессиональный креативный продюсер и промпт-инженер с опытом в визуализации деловых и технологических тем.
Твоя задача — по тексту статьи, который я пришлю ниже, создать максимально точный и выразительный промпт для генерации обложки в нейросети Nanobanana или аналогичной.
**Порядок действий:**
1. **Прочитай и проанализируй текст**:
- Выяви главную мысль статьи.
- Определи ключевые процессы и контрасты.
- Улови настроение и тональность.
- Найди 2–3 сильные метафоры, которые можно визуализировать.
2. **Сформулируй визуальную концепцию**:
- Опиши композицию: передний, средний и задний планы.
- Определи, как сюжет статьи ложится на единый стиль серии.
- Продумай символы и детали, которые отразят ключевые тезисы.
3. **Обязательно встрой единый стиль серии Style DNA**:
- Каждая обложка должна быть узнаваемой частью одной серии с постоянным главным героем.
- В финальный промпт всегда добавляй следующий постоянный стилевой блок на английском языке:
consistent cover series style: modern editorial semi-flat vector illustration with subtle 3D depth, clean geometric shapes, soft cinematic lighting, fine grain, pop tech aesthetic. Main protagonist is a male, 35 to 45 years old. Keep his facial features, hair, glasses, and clothing absolutely identical across all covers. Composition: clean 16:9 cover, balanced negative space for headline, no text, no logos, no watermarks, no readable letters on the badge.
- Меняй только сюжет, метафоры и композицию под статью. Стиль, палитра, главный герой и графические мотивы остаются постоянными.
- Если статья не подразумевает людей, не вводи персонажа насильно, но сохраняй Style DNA, палитру и мотивы.
- Если в статье упоминаются другие персонажи или команда, используй главного героя как центральную фигуру, а остальных показывай схематично или на втором плане.
4. **Составь промпт для генерации**:
- Он должен быть на английском языке.
- Обязательно включи:
- основной сюжет в 2–3 предложениях;
- детали композиции и объектов;
- постоянный блок Style DNA;
- параметры: соотношение сторон 16:9, степень стилизации, отсутствие текста и логотипов.
- Промпт должен быть чётким, без лишней воды, но достаточно детальным, чтобы нейросеть поняла замысел.
5. **Предоставь результат в формате**:
- **Готовый промпт** — только текст на английском языке для отправки в нейросеть.
- В финальном промпте не используй кавычки. Если кавычки нужны, экранируй их как ", но лучше полностью избегай.
- Не добавляй пояснений, заголовков или русского текста в финальный ответ.
6. **Важные условия:**
- Не придумывай факты, которых нет в статье, — опирайся только на предоставленный текст.
- Если в статье не хватает описания для визуализации, предложи нейтральное, но стильное решение в рамках Style DNA.
- Главный герой — всегда мужчина, соответствующий описанию из Style DNA.
- Если стиль статьи явно выражен, отрази это в настроении промпта, но не ломай единый Style DNA.
Текст статьи для обработки:
{{ $json.chatInput }}
Так и появился «мужик» на моих картинках. Описание мужика, кстати, сгенерировала нейросеть по одной из моих фотографий.
Попробовать мой воркфлоу можно, скачав его из https://gitverse.ru/alzakai/alzakai/content/master/n8n_workflows