AI Automatic Product Description Generation System

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1 servicesAll 1566 services
AI Automatic Product Description Generation System
Medium
~3-5 business days
FAQ
AI Development Areas
AI Solution Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822

AI Product Description Generation System

Automatic generation of product descriptions for e-commerce: marketplaces (Wildberries, Ozon, Amazon), online stores, B2B catalogs. Productivity: 1,000–10,000 descriptions per day versus 50–200 for a copywriter.

System Architecture

from openai import AsyncOpenAI
from dataclasses import dataclass
from typing import Optional
import asyncio

client = AsyncOpenAI()

@dataclass
class ProductData:
    name: str
    category: str
    brand: str
    sku: str
    attributes: dict          # {color: "red", size: "M", material: "cotton"}
    images: list[str] = None  # Image URLs
    price: float = None
    target_audience: str = ""

@dataclass
class GeneratedDescription:
    title: str              # SEO title
    short_description: str  # 150–200 characters (marketplace preview)
    full_description: str   # Formatted HTML
    bullet_points: list[str]  # 3–7 key benefits
    seo_keywords: list[str]
    meta_description: str   # 160 characters for SEO

class ProductDescriptionGenerator:
    def __init__(self, platform: str = "general"):
        self.platform = platform
        self.platform_configs = {
            "wildberries": {"max_title": 60, "max_desc": 4000, "bullet_count": 5},
            "ozon": {"max_title": 100, "max_desc": 6000, "bullet_count": 7},
            "amazon": {"max_title": 200, "max_desc": 2000, "bullet_count": 5},
            "general": {"max_title": 80, "max_desc": 3000, "bullet_count": 5},
        }

    async def generate(
        self,
        product: ProductData,
        tone: str = "professional",
        language: str = "en"
    ) -> GeneratedDescription:
        config = self.platform_configs.get(self.platform, self.platform_configs["general"])

        # If images available — use GPT-4 Vision
        if product.images:
            return await self.generate_from_images(product, config, tone, language)
        else:
            return await self.generate_from_text(product, config, tone, language)

    async def generate_from_text(
        self,
        product: ProductData,
        config: dict,
        tone: str,
        language: str
    ) -> GeneratedDescription:
        attributes_str = "\n".join([f"- {k}: {v}" for k, v in product.attributes.items()])

        response = await client.chat.completions.create(
            model="gpt-4o",
            messages=[{
                "role": "system",
                "content": f"""You are an expert in writing selling descriptions for {self.platform}.
                Tone: {tone}.
                Language: {language}.
                Limits: title up to {config['max_title']} characters,
                description up to {config['max_desc']} characters,
                {config['bullet_count']} benefit bullets.

                Create product description. Return JSON with fields:
                title, short_description, full_description (HTML),
                bullet_points (array), seo_keywords (array), meta_description."""
            }, {
                "role": "user",
                "content": f"""Product: {product.name}
                Brand: {product.brand}
                Category: {product.category}
                Attributes:
                {attributes_str}
                Target audience: {product.target_audience or 'not specified'}"""
            }],
            response_format={"type": "json_object"}
        )

        data = json.loads(response.choices[0].message.content)
        return GeneratedDescription(**data)

    async def generate_from_images(
        self,
        product: ProductData,
        config: dict,
        tone: str,
        language: str
    ) -> GeneratedDescription:
        """Use Vision to analyze product photos"""
        import base64

        image_contents = [
            {"type": "image_url", "image_url": {"url": url}}
            for url in product.images[:3]  # Maximum 3 images
        ]

        response = await client.chat.completions.create(
            model="gpt-4o",
            messages=[{
                "role": "user",
                "content": [
                    {"type": "text", "text": f"""Analyze product images and create description.
                    Platform: {self.platform}. Tone: {tone}. Language: {language}.
                    Additional data: Category: {product.category}, Brand: {product.brand}.
                    Return JSON: title, short_description, full_description, bullet_points, seo_keywords, meta_description."""},
                ] + image_contents
            }],
            response_format={"type": "json_object"}
        )

        data = json.loads(response.choices[0].message.content)
        return GeneratedDescription(**data)

Batch Generation from Excel/CSV

import pandas as pd
import asyncio

async def process_product_catalog(
    catalog_path: str,
    platform: str = "wildberries",
    batch_size: int = 20
) -> pd.DataFrame:
    df = pd.read_csv(catalog_path)
    generator = ProductDescriptionGenerator(platform=platform)
    results = []

    for i in range(0, len(df), batch_size):
        batch = df.iloc[i:i+batch_size]
        tasks = []

        for _, row in batch.iterrows():
            product = ProductData(
                name=row["name"],
                category=row["category"],
                brand=row.get("brand", ""),
                sku=row.get("sku", ""),
                attributes={k: row[k] for k in row.index if k not in ["name", "category", "brand", "sku"]}
            )
            tasks.append(generator.generate(product))

        batch_results = await asyncio.gather(*tasks, return_exceptions=True)
        for j, result in enumerate(batch_results):
            if isinstance(result, GeneratedDescription):
                row_data = batch.iloc[j].to_dict()
                row_data.update({
                    "generated_title": result.title,
                    "generated_short_desc": result.short_description,
                    "generated_full_desc": result.full_description,
                    "generated_bullets": " | ".join(result.bullet_points),
                    "seo_keywords": ", ".join(result.seo_keywords),
                })
                results.append(row_data)

    return pd.DataFrame(results)

Platform Adaptation

class WildberriesFormatter:
    def format(self, desc: GeneratedDescription) -> dict:
        return {
            "naimenovanie": desc.title[:60],
            "opisanie": desc.full_description[:4000],
            "harakteristiki": "\n".join(desc.bullet_points),
        }

class OzonFormatter:
    def format(self, desc: GeneratedDescription) -> dict:
        return {
            "name": desc.title[:100],
            "description": desc.full_description,
            "short_description": desc.short_description,
            "keywords": desc.seo_keywords,
        }

Timeline: basic description generator with batch CSV processing — 1–2 weeks. Integration with Wildberries/Ozon API for direct upload — additional 1–2 weeks.