Реалізація автоматичної генерації alt-текстів для зображень товарів (AI)

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація автоматичної генерації alt-текстів для зображень товарів (AI)
Проста
від 1 робочого дня до 3 робочих днів
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Реалізація автоматичної генерації alt-текстів для зображень товарів (AI)

Alt-текст у зображення виконує дві функції: допомагає пошуковику зрозуміти вміст сторінки та робить сайт доступним для незрячих користувачів. У більшості інтернет-магазинів alt-теги або пусті, або містять лише назву файлу типу IMG_4821.jpg. Це упущений SEO-сигнал та порушення доступності.

При наявності тисяч товарних зображень завдання вирішується автоматично — або на основі даних про товар, або через мультимодальний аналіз самого зображення.

Два підходи

Підхід 1: генерація за метаданими товару — швидко, дешево, не потребує завантаження зображень у модель. Підходить, коли фотографії стандартні (білий фон, один ракурс).

Підхід 2: мультимодальний аналіз зображення — модель бачить саме фото та описує, що на ньому. Потрібен для lifestyle-фотографій, зображень з кількома об'єктами або коли важливі візуальні деталі.

Підхід 1: за метаданими

function buildAltFromMetadata(
  product: Product,
  imageIndex: number,
  imageType: "main" | "detail" | "lifestyle"
): string {
  const base = `${product.brand} ${product.name}`;

  if (imageType === "main") {
    return `${base} — фото ${imageIndex + 1}`;
  }

  if (imageType === "detail") {
    const feature = product.attributes.detailFeatures?.[imageIndex] ?? "деталь";
    return `${base}: ${feature}`;
  }

  return `${base} у використанні`;
}

Простий, детерміністичний варіант. Не потребує API-вызовів, працює миттєво при імпорті товарів.

Підхід 2: мультимодальний (GPT-4o Vision)

import { openai } from "../lib/openai";

async function generateAltFromImage(
  imageUrl: string,
  product: Product
): Promise<string> {
  const response = await openai.chat.completions.create({
    model: "gpt-4o-mini",
    messages: [
      {
        role: "user",
        content: [
          {
            type: "image_url",
            image_url: { url: imageUrl, detail: "low" }, // low — дешевше, достатньо для alt
          },
          {
            type: "text",
            text: `Напиши короткий alt-текст для цього зображення товару українською.
Товар: ${product.name}, бренд: ${product.brand}, категорія: ${product.category}.
Правила:
- 60–120 символів
- Опиши, що видно в зображенні, а не товар загалом
- Починай з назви товару тільки якщо вона ясно видна на фото
- Без слів "фото", "зображення", "картинка" на початку
- Без markdown, просто простий текст`,
          },
        ],
      },
    ],
    max_tokens: 80,
    temperature: 0.3,
  });

  return response.choices[0].message.content?.trim() ?? "";
}

detail: "low" знижує вартість з ~$0.002 до ~$0.0003 за зображення — достатньо для генерації alt, не потрібна висока роздільна здатність.

Пакетна обробка зображень

import { Queue, Worker } from "bullmq";

const altQueue = new Queue("alt-generation");

export async function queueImagesForAltGeneration(
  productIds: string[]
) {
  const products = await db.products.findMany({
    where: { id: { in: productIds } },
    include: { images: true },
  });

  const jobs = products.flatMap((product) =>
    product.images
      .filter((img) => !img.altText || img.altText === "")
      .map((img) => ({
        name: "generate-alt",
        data: { imageId: img.id, productId: product.id, imageUrl: img.url },
      }))
  );

  await altQueue.addBulk(jobs);
}

const altWorker = new Worker(
  "alt-generation",
  async (job) => {
    const { imageId, productId, imageUrl } = job.data;
    const product = await db.products.findById(productId);

    // Визначаємо, потрібен ли мультимодальний аналіз
    const useVision = product.imageType === "lifestyle" || product.useVisionForAlt;

    let altText: string;

    if (useVision) {
      altText = await generateAltFromImage(imageUrl, product);
    } else {
      const imageIndex = product.images.findIndex((i: any) => i.id === imageId);
      altText = buildAltFromMetadata(product, imageIndex, "main");
    }

    await db.productImages.update({
      where: { id: imageId },
      data: { altText, altGeneratedAt: new Date() },
    });
  },
  { connection: redisConnection, concurrency: 20 }
);

Вбудовування в CMS

Після генерації alt-текст зберігається в таблиці зображень та рендеруються в шаблоні:

<img
  src="{{ image.url }}"
  alt="{{ image.altText }}"
  loading="lazy"
  width="{{ image.width }}"
  height="{{ image.height }}"
/>

Якщо alt пустий (генерація ще не пройшла або провалилася) — fallback на назву товару, але не порожній рядок:

const alt = image.altText || `${product.brand} ${product.name}`;

Аудит існуючого каталогу

Перед запуском генерації корисно зрозуміти масштаб проблеми:

SELECT
  COUNT(*) FILTER (WHERE alt_text IS NULL OR alt_text = '') AS missing_alt,
  COUNT(*) FILTER (WHERE alt_text = file_name) AS filename_as_alt,
  COUNT(*) total
FROM product_images;

Це покаже, скільки зображень потребують обробки і дозволить спланувати навантаження на API. 50 000 зображень при мультимодальній генерації — близько $15, при генерації за метаданими — безкоштовно.