Casos de uso y soluciones

Generar descripciones de productos con IA en varios idiomas: títulos y viñetas en lote desde un CSV

6 pasos 18 min de lectura 84 vistas 0
Contenido

Los vendedores transfronterizos suelen publicar el mismo producto en Shopee, Lazada, Amazon, TikTok Shop y su propia tienda, y en varios idiomas. Un modelo de lenguaje puede redactar en una sola noche títulos, viñetas y descripciones para cientos de productos a partir de una hoja de cálculo con sus datos. Esta guía crea un pequeño script de Python que lee un archivo CSV, pide a un modelo local en Ollama (o a cualquier API de IA compatible con OpenAI) una ficha en cada idioma y escribe los resultados en un nuevo archivo CSV, que usted revisa y después importa en las plantillas de sus marketplaces.

Los borradores generados por IA deben revisarse antes de publicarse. Los modelos pueden inventar características o usar expresiones que un marketplace prohíbe, como afirmaciones médicas o "el mejor del mundo". Mantenga siempre a una persona en el proceso, sobre todo en categorías reguladas, y siga las normas de publicación de cada marketplace.

Paso 1: Preparar los datos de los productos

Cree una hoja de cálculo con una fila por producto y guárdela como products.csv en UTF-8 (en Excel: CSV UTF-8). Los nombres de las columnas los elige usted; todas las columnas se envían al modelo, y el script necesita una columna sku con valores únicos:

sku,name,category,specs,keywords
LS-01,Bamboo laptop stand,Office,"6 height levels; fits 10-17 inch laptops; foldable; 1.1 kg; natural bamboo","laptop stand, bamboo, ergonomic"
BT-07,Wireless earbuds,Audio,"Bluetooth 5.3; 30 h playback with case; IPX5; USB-C charging","wireless earbuds, bluetooth, sport"

Cuanto más precisos sean los datos (material, medidas, modelos compatibles, contenido del paquete), mejor y más seguro será el resultado, porque el script indica al modelo que use únicamente estos datos.

Paso 2: Instalar el entorno del script

apt install -y python3-venv
python3 -m venv /opt/listing
/opt/listing/bin/pip install openai

La biblioteca de Python openai funciona con el endpoint compatible con OpenAI de Ollama y con la mayoría de los proveedores de IA, de modo que el mismo script se ejecuta con un modelo local o en la nube. La configuración de Ollama se explica en ejecutar un LLM local con Ollama.

Paso 3: Crear el script

cat > /opt/listing/listing.py <<'EOF2'
import csv, json, os, re, sys, time
from openai import OpenAI

client = OpenAI(base_url=os.environ.get("AI_BASE_URL", "http://127.0.0.1:11434/v1"),
                api_key=os.environ.get("AI_API_KEY", "ollama"))
MODEL = os.environ.get("AI_MODEL", "qwen2.5:7b")
LANGS = [l.strip() for l in os.environ.get("LANGS", "English").split(",")]

SYSTEM = """You write e-commerce product listings for online marketplaces.
Use only the product facts provided. Never invent features, materials,
certifications, prices or delivery promises. No exaggerated claims.
Return JSON only, in this format:
{"title": "...", "bullets": ["...", "...", "...", "...", "..."], "description": "..."}
title: at most 120 characters, main keyword first.
bullets: 5 short points, each starting with the benefit.
description: 80 to 150 words of plain text."""

def ask(product, lang):
    prompt = f"Write the listing in {lang}.\nProduct facts:\n{json.dumps(product, ensure_ascii=False)}"
    for attempt in range(3):
        r = client.chat.completions.create(model=MODEL, temperature=0.4, messages=[
            {"role": "system", "content": SYSTEM}, {"role": "user", "content": prompt}])
        m = re.search(r"\{.*\}", r.choices[0].message.content or "", re.S)
        try:
            data = json.loads(m.group(0))
            if data.get("title") and isinstance(data.get("bullets"), list) and data.get("description"):
                return data
        except (AttributeError, ValueError):
            pass
        time.sleep(2)
    raise RuntimeError(f"no valid answer for {product['sku']} / {lang}")

src, dst = sys.argv[1], sys.argv[2]
done = set()
if os.path.exists(dst):
    with open(dst, encoding="utf-8-sig") as f:
        done = {(r["sku"], r["language"]) for r in csv.DictReader(f)}
with open(src, encoding="utf-8-sig") as f:
    products = list(csv.DictReader(f))

new_file = not os.path.exists(dst)
with open(dst, "a", newline="", encoding="utf-8-sig") as f:   # utf-8-sig: Excel shows every language correctly
    w = csv.writer(f)
    if new_file:
        w.writerow(["sku", "language", "title", "bullets", "description"])
    for p in products:
        for lang in LANGS:
            if (p["sku"], lang) in done:
                continue
            d = ask(p, lang)
            w.writerow([p["sku"], lang, str(d["title"]).strip(),
                        "\n".join(str(b).strip() for b in d["bullets"]), str(d["description"]).strip()])
            f.flush()
            print(p["sku"], lang, "done", flush=True)
EOF2

El script pide la respuesta en JSON, la comprueba y reintenta hasta tres veces. Cada fila terminada se escribe de inmediato y, en una segunda ejecución, se omiten los productos e idiomas que ya figuran en el archivo de salida, así que un trabajo interrumpido simplemente continúa donde se detuvo.

Paso 4: Ejecutarlo

cd /data/listings
LANGS="English,Thai,Malay,Japanese" nohup /opt/listing/bin/python /opt/listing/listing.py \
  products.csv listings.csv > listing.log 2>&1 &
tail -f listing.log

En un servidor con CPU, un modelo de 7B suele necesitar decenas de segundos por ficha, así que 500 productos en cuatro idiomas son un trabajo para toda la noche. Para usar un modelo en la nube, indique la dirección de la API, la clave y el nombre del modelo de cualquier API compatible con OpenAI:

AI_BASE_URL=https://ai.example.com/v1 AI_API_KEY=sk-your-key AI_MODEL=cloud-chat \
LANGS="English,Thai" /opt/listing/bin/python /opt/listing/listing.py products.csv listings.csv

Use proveedores de IA solo desde las regiones que admiten y conforme a sus condiciones.

Paso 5: Revisar e importar

  1. Abra listings.csv en Excel o Google Sheets y filtre por idioma.
  2. Compruebe la longitud de los títulos frente a los límites de cada marketplace y verifique por muestreo los datos con sus especificaciones.
  3. Pida a hablantes nativos que revisen, al menos una vez, sus productos más vendidos para confirmar que el estilo es el adecuado.
  4. Copie las columnas en la plantilla de carga masiva de cada marketplace; los nombres de las columnas varían de una plataforma a otra.

Paso 6: Mejorar los resultados

  • Añada a SYSTEM el tono de su marca y las normas de cada marketplace, por ejemplo una lista de palabras que nunca usa, inglés británico o americano, o la prohibición de usar emojis.
  • Pegue una ficha aprobada en SYSTEM como ejemplo; los modelos imitan muy de cerca su estructura y su tono.
  • Los modelos más grandes, como qwen2.5:14b, escriben bastante mejor en tailandés, malayo y vietnamita, a costa de velocidad y memoria.
  • Mantenga el mismo modelo y el mismo prompt en todo un catálogo para que todas las fichas compartan un estilo coherente.

Preguntas frecuentes

¿Penalizan los marketplaces o los buscadores las fichas escritas con IA?

A los marketplaces les importan la exactitud y el cumplimiento de sus políticas, y a los buscadores, que el contenido sea útil. Las fichas precisas y concretas que ha revisado una persona no plantean problemas; el texto producido en masa con errores o afirmaciones inventadas es un riesgo, lo haya escrito quien lo haya escrito.

¿El script se detiene con "no valid answer"?

El modelo devolvió tres veces seguidas algo que no era JSON válido. Vuelva a ejecutar el mismo comando (se reanuda donde se quedó), baje la temperatura o use un modelo más grande.

¿Puede la IA preparar también las imágenes de los productos?

Sí. Para recortar productos y crear en lote imágenes principales con fondo blanco, consulte quitar el fondo de fotos de productos en lote con rembg.

¿Sigue sin resolverlo después de seguir estos pasos? Abra un ticket de soporte y el equipo técnico de IMIDC, disponible 24/7, le ayudará. Incluya la IP del servidor, el modelo que utiliza, el comando que ejecutó y las últimas líneas de listing.log para que podamos localizar el problema más rápido.

¿Fue útil la respuesta?

Tutoriales relacionados