Генерация маркетинговых изображений в AWS: Bedrock + OpenSearch гайд | AiManual
AiManual Logo Ai / Manual.
04 Фев 2026 Гайд

Система генерации маркетинговых изображений в AWS: когда Bedrock слушает бренд-гайды

Пошаговый гайд по созданию AI-системы генерации изображений с учётом бренд-гайдов и исторических кампаний на AWS Bedrock и OpenSearch.

Проблема: маркетолог против AI-художника

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

Стандартные генераторы вроде Midjourney или Stable Diffusion не знают вашего бренда. Они не анализируют ваши прошлые успешные кампании. Они не читают внутренние гайдлайны. Результат - потраченные часы на ручное ретуширование или полный отказ от использования AI в маркетинге.

Главная ошибка: пытаться заставить генеративную модель работать в вакууме. Без контекста о вашем бренде, без анализа того, что уже работало, без учёта внутренних ограничений. Получается красиво, но бесполезно для бизнеса.

Решение: Bedrock как художник, OpenSearch как историк бренда

Вот что мы строим: система, где AI-генератор (Amazon Bedrock с Nova Canvas v2.1, последняя версия на февраль 2026) получает не только текстовый промпт от маркетолога, но и контекст из двух источников:

  1. Бренд-гайды - формальные правила (цвета, шрифты, запрещённые элементы)
  2. Исторические кампании - неявные паттерны успеха (какие визуальные стили, композиции, эмоции работали лучше всего)

OpenSearch Serverless здесь выступает как память системы. Он хранит эмбеддинги всех когда-либо созданных маркетинговых материалов, аналитику по их эффективности и текстовые описания бренд-гайдов. Когда приходит новый запрос - Lambda ищет релевантный контекст и вплетает его в промпт для Bedrock.

💡
Ключевое отличие от обычной генерации: мы не просто говорим модели "сделай картинку". Мы говорим "сделай картинку, которая будет похожа на наши самые успешные прошлые работы и при этом соблюдёт все формальные правила бренда". Это на порядок сложнее, но и на порядок полезнее для бизнеса.

Архитектура: как всё это уживается в AWS

Давайте посмотрим на компоненты системы глазами инженера, который будет это поддерживать:

Компонент Задача Почему именно он
Amazon Bedrock (Nova Canvas v2.1) Генерация изображений по промпту Лучшее качество среди доступных в AWS моделей, native интеграция, предсказуемые тарифы
OpenSearch Serverless Векторный поиск по историческим кампаниям и гайдам Не нужно управлять кластером, автоматическое масштабирование, встроенная работа с эмбеддингами
AWS Lambda (Python 3.12) Оркестрация всего пайплайна Дешевле контейнеров для непостоянной нагрузки, проще управление
S3 + CloudFront Хранение и раздача сгенерированных изображений Объектное хранилище дешевле EBS, CDN снижает latency для пользователей

1 Подготовка OpenSearch: загружаем память бренда

Первое и самое важное - наполнить OpenSearch Serverless историческими данными. Без этого система будет слепа.

Создаём коллекцию в OpenSearch Serverless (в консоли это занимает минут пять). Важный момент: выбираем тип "векторный поиск" и указываем размерность 1024 - это стандарт для Nova Multimodal Embeddings v3, самой актуальной модели для создания эмбеддингов на февраль 2026.

Теперь пишем скрипт индексации. Берём все исторические маркетинговые материалы: изображения прошлых кампаний, их метаданные (CTR, конверсии, вовлечённость), текстовые описания бренд-гайдов.

import boto3
from opensearchpy import OpenSearch, RequestsHttpConnection
import base64
import json

# Инициализируем клиентов
bedrock = boto3.client('bedrock-runtime', region_name='us-east-1')
os_host = 'your-opensearch-endpoint.us-east-1.aoss.amazonaws.com'
os_client = OpenSearch(
    hosts=[{'host': os_host, 'port': 443}],
    http_auth=('your-iam-role', 'your-secret'),
    use_ssl=True,
    verify_certs=True,
    connection_class=RequestsHttpConnection
)

def create_embedding_for_image(image_path):
    """Создаём мультимодальный эмбеддинг для изображения"""
    with open(image_path, 'rb') as f:
        image_bytes = f.read()
    
    response = bedrock.invoke_model(
        modelId='amazon.nova-multimodal-embedding-v1:0',
        body=json.dumps({
            'embeddingConfig': {'outputEmbeddingLength': 1024},
            'inputs': [{
                'modality': 'IMAGE',
                'image': {
                    'format': 'JPEG',
                    'source': {
                        'bytes': base64.b64encode(image_bytes).decode('utf-8')
                    }
                }
            }]
        })
    )
    
    embedding = json.loads(response['body'].read())['embedding']
    return embedding

def index_campaign(image_path, metadata):
    """Индексируем одну кампанию в OpenSearch"""
    embedding = create_embedding_for_image(image_path)
    
    document = {
        'embedding': embedding,
        'metadata': metadata,
        'campaign_id': metadata['campaign_id'],
        'performance_score': metadata['ctr'] * 0.7 + metadata['conversion_rate'] * 0.3,
        'timestamp': metadata['date']
    }
    
    os_client.index(
        index='marketing-campaigns',
        body=document,
        id=metadata['campaign_id']
    )

Зачем нужен performance_score? Когда система ищет похожие исторические кампании, мы хотим чтобы она в первую очередь ориентировалась на успешные. Кампания с CTR 0.1% и конверсией 0.05% нам неинтересна как референс. Формулу весов (0.7 для CTR, 0.3 для конверсии) настраивайте под свою бизнес-логику.

Не индексируйте всё подряд. Если у вас есть кампании-провалы (CTR ниже 0.01%), лучше их исключить из индекса. Система может начать копировать неудачные паттерны. Фильтруйте по минимальному порогу эффективности.

2 Пишем Lambda-оркестратор: мозг системы

Теперь создаём Lambda функцию, которая будет получать запрос от маркетолога ("сделай изображение для рекламы нового кофе") и координировать весь процесс.

Вот как выглядит основной обработчик:

import json
import boto3
from opensearchpy import OpenSearch, RequestsHttpConnection
import base64

bedrock = boto3.client('bedrock-runtime')
s3 = boto3.client('s3')

def lambda_handler(event, context):
    """Основная Lambda функция для генерации изображений"""
    # 1. Извлекаем промпт от пользователя
    user_prompt = event['prompt']  # "реклама нового кофе для соцсетей"
    brand_constraints = event.get('constraints', [])  # опциональные ограничения
    
    # 2. Ищем релевантные исторические кампании в OpenSearch
    similar_campaigns = find_similar_campaigns(user_prompt)
    
    # 3. Извлекаем бренд-гайды из OpenSearch
    brand_guidelines = get_brand_guidelines()
    
    # 4. Формируем обогащённый промпт для Bedrock
    enriched_prompt = enrich_prompt(
        user_prompt,
        similar_campaigns,
        brand_guidelines,
        brand_constraints
    )
    
    # 5. Генерируем изображение через Nova Canvas v2.1
    image_bytes = generate_image(enriched_prompt)
    
    # 6. Сохраняем в S3 и возвращаем URL
    image_url = save_to_s3(image_bytes, f"generated/{context.aws_request_id}.jpg")
    
    # 7. (Опционально) Индексируем результат в OpenSearch для будущего использования
    index_generated_image(image_bytes, {
        'prompt': enriched_prompt,
        'original_prompt': user_prompt,
        'timestamp': context.aws_request_id
    })
    
    return {
        'statusCode': 200,
        'image_url': image_url,
        'enriched_prompt': enriched_prompt
    }

def enrich_prompt(user_prompt, similar_campaigns, guidelines, constraints):
    """Обогащаем пользовательский промпт контекстом"""
    prompt_parts = [f"Generate marketing image: {user_prompt}"]
    
    # Добавляем информацию о самых успешных похожих кампаниях
    if similar_campaigns:
        best_campaign = max(similar_campaigns, key=lambda x: x['performance_score'])
        prompt_parts.append(f"Style should be similar to our successful campaign '{best_campaign['metadata'].get('description', '')}' "
                          f"which achieved CTR: {best_campaign['metadata'].get('ctr', 0):.2%}.")
    
    # Добавляем бренд-гайды
    if guidelines:
        for guideline in guidelines[:3]:  # Берём 3 самых важных правила
            prompt_parts.append(f"Brand rule: {guideline['text']}")
    
    # Добавляем пользовательские ограничения
    for constraint in constraints:
        prompt_parts.append(f"Constraint: {constraint}")
    
    # Критически важная часть: добавляем negative prompt
    prompt_parts.append("Negative prompt: blurry, distorted, ugly, bad proportions, "
                       "text overlay, watermark, signature, frame, border")
    
    return ". ".join(prompt_parts)

Обратите внимание на negative prompt в конце. Без него Nova Canvas может генерировать изображения с артефактами, текстом поверх картинки или другими нежелательными элементами. Это не просто рекомендация - это обязательный элемент для production-качества.

3 Настройка Bedrock: выбираем правильную модель и параметры

Nova Canvas v2.1 (актуальна на февраль 2026) поддерживает несколько режимов генерации. Для маркетинговых изображений важен баланс между креативностью и предсказуемостью.

def generate_image(prompt):
    """Генерируем изображение через Bedrock"""
    
    response = bedrock.invoke_model(
        modelId='amazon.nova-canvas-v1:2',  # v2.1 доступна под этим ID
        body=json.dumps({
            'taskType': 'TEXT_IMAGE',
            'textToImageParams': {
                'text': prompt,
                'negativeText': 'blurry, distorted, ugly, text, watermark',
            },
            'imageGenerationConfig': {
                'numberOfImages': 1,
                'quality': 'premium',  # 'standard' или 'premium'
                'height': 1024,
                'width': 1024,
                'cfgScale': 7.0,  # Важно! Для маркетинга лучше 7-9
                'seed': 42  # Фиксируем seed для воспроизводимости
            }
        }),
        accept='application/json',
        contentType='application/json'
    )
    
    response_body = json.loads(response['body'].read())
    
    # Nova Canvas возвращает base64 изображение
    base64_image = response_body['images'][0]
    image_bytes = base64.b64decode(base64_image)
    
    return image_bytes

Параметр cfgScale (Classifier-Free Guidance) критически важен для маркетинговых задач. Слишком низкое значение (3-5) даёт креативные, но непредсказуемые результаты. Слишком высокое (10+) делает изображения стерильными и шаблонными. Диапазон 7-9 - золотая середина для брендового контента.

Фиксированный seed (например, 42) позволяет воспроизводить результаты. Если маркетологу понравилась картинка, но нужно чуть изменить промпт - можно использовать тот же seed для получения похожего результата.

Нюансы, которые сломают вашу систему, если их не учесть

1. Стоимость эмбеддингов

Nova Multimodal Embeddings стоит денег. Если у вас 10 000 исторических изображений, и вы создаёте для каждого эмбеддинг размерностью 1024 - это примерно $50-100 за индексацию. Плюс стоимость хранения в OpenSearch Serverless. Решение: индексируйте не все изображения, а только репрезентативную выборку из каждой кампании. Или используйте более дешёвые эмбеддинги для префильтрации, а дорогие Nova Embeddings - только для финального ранжирования.

2. Задержки реального мира

Полный цикл (поиск в OpenSearch + генерация в Bedrock) занимает 8-15 секунд. Это много для интерактивного интерфейса. Решение: кэшируйте результаты. Если два маркетолога запрашивают "рекламу кофе" с разницей в час - второй запрос можно обслужить из кэша или сделать вариант с небольшими изменениями. Используйте техники кэширования из нашей статьи про корпоративного ИИ-ассистента.

3. Качество vs скорость генерации

Nova Canvas v2.1 имеет параметр quality: 'premium'. Он даёт лучшее качество, но дольше генерирует и стоит дороже. Для превью в интерфейсе маркетолога используйте 'standard'. Когда пользователь утверждает результат - перегенерируйте с 'premium' для финального варианта.

4. Консистентность бренда - это не только цвета

Большинство думает, что достаточно добавить в промпт "используй красный цвет #FF0000". На деле бренд-консистентность включает:

  • Композицию (где располагается продукт, где текст)
  • Эмоциональную окраску (радостные vs серьёзные лица)
  • Уровень детализации (минимализм vs реализм)
  • Стиль иллюстрации (плоский дизайн vs 3D)

Эти паттерны не описаны в гайдлайнах явно, но они есть в исторических данных. Именно поэтому векторный поиск по эмбеддингам работает лучше правил вроде "если продукт X, то используй стиль Y".

FAQ: вопросы, которые зададут на code review

Почему не использовать готовые решения вроде Midjourney API?

Потому что они не интегрируются с вашими историческими данными. Вы не можете загрузить в Midjourney 5000 своих прошлых рекламных баннеров и сказать "делай похоже на них". Да, можно пытаться описывать стиль словами, но это неточно и требует экспертизы дизайнера. Наша система делает это автоматически на основе данных.

А если исторических данных мало или нет вообще?

Начинайте с простого. Сначала система будет работать как обычный генератор с учётом бренд-гайдов. По мере накопления данных (сохраняйте каждую сгенерированную картинку в OpenSearch с меткой "сгенерировано системой") она станет умнее. Через месяц у вас будет своя тренировочная выборка.

Как измерять качество системы?

Тремя метриками:

  1. Скорость создания контента (раньше дизайнер делал баннер за день, теперь система - за 15 секунд)
  2. Соответствие бренд-гайдам (процент изображений, которые проходят ручную проверку на compliance)
  3. Бизнес-метрики (сравнивайте CTR сгенерированных изображений с историческими средними)

Если третья метрика падает - значит система копирует неудачные паттерны. Нужно пересмотреть формулу performance_score или добавить фильтрацию.

А если нужны не только изображения, но и видео?

Архитектура масштабируется. Добавляете мультимодальный RAG для видео, расширяете OpenSearch схему для хранения видео-эмбеддингов, используете Nova Canvas v2.1 которая уже умеет генерировать короткие анимированные последовательности. Но начинайте с изображений - они проще и дешевле для отладки.

Что будет дальше? Прогноз на 2026-2027

Сейчас мы обогащаем промпт контекстом из OpenSearch. Следующий шаг - fine-tuning модели на ваших данных. Amazon обещает запустить возможность дообучения Nova Canvas на корпоративных датасетах в конце 2026 года. Это будет дорого (десятки тысяч долларов), но полностью изменит игру.

Представьте: модель, которая не просто получает подсказки в промпте, а внутренне понимает ваш бренд. Которая генерирует изображения в вашем стиле по умолчанию, без необходимости каждый раз искать референсы в OpenSearch.

Но пока этой функции нет - наша архитектура с Bedrock + OpenSearch остаётся оптимальным решением. Она балансирует между кастомностью и стоимостью, между автоматизацией и контролем.

Самый главный совет: начните с малого. Возьмите 100 самых успешных исторических кампаний. Проиндексируйте их. Настройте простой промпт-энричмент. Покажите результат маркетологам. Услышьте их фидбэк. И только потом масштабируйтесь до тысячи кампаний и десятков генераций в день.

Потому что самая сложная часть этой системы - не код, не инфраструктура AWS, а понимание того, что на самом деле делает вашу рекламу успешной. И иногда ответы на этот вопрос вас удивят.