Lección 4 de 7 30 min

Genera contenido con IA: descripciones, traducciones y resúmenes

Generación de contenido es el caso de uso #1 de IA en proyectos PHP reales: descripciones de producto en tiendas online, traducciones de posts en blogs WordPress, resúmenes de artículos largos, ampliación de fichas. En esta lección montas los 3 patrones que vas a reutilizar siempre.

Lo que vas a construir

  1. Generador de descripciones de producto (caso ecommerce).
  2. Traductor de texto castellano → inglés (caso multiidioma).
  3. Resumidor de texto largo a 100 palabras (caso blog / noticias).
  4. Bonus: cómo conseguir respuesta JSON estructurada en lugar de texto libre.

1. Generador de descripciones de producto

Imagina una tienda Magento con 200 productos sin descripción. Pasártelos a mano son días. Con IA, minutos.

<?php
require __DIR__ . '/vendor/autoload.php';

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

use Symfony\Component\HttpClient\HttpClient;

$client = HttpClient::create();

function generarDescripcion(string $nombreProducto, array $caracteristicas): string
{
    global $client;

    $caracteristicasTexto = implode(', ', $caracteristicas);

    $prompt = "Eres redactor de ecommerce. Escribe una descripción persuasiva pero honesta (máx 60 palabras) para este producto:\n\n"
            . "Nombre: $nombreProducto\n"
            . "Características: $caracteristicasTexto\n\n"
            . "Tono: cercano, profesional, en español de España. Sin marketing-speak vacío.";

    $response = $client->request('POST', 'https://api.anthropic.com/v1/messages', [
        'headers' => [
            'x-api-key' => $_ENV['ANTHROPIC_API_KEY'],
            'anthropic-version' => '2023-06-01',
        ],
        'json' => [
            'model' => 'claude-haiku-4-5-20251001',
            'max_tokens' => 200,
            'messages' => [['role' => 'user', 'content' => $prompt]],
        ],
    ]);

    return $response->toArray()['content'][0]['text'];
}

// Lista de productos a procesar
$productos = [
    ['Camiseta básica algodón', ['algodón orgánico 100%', 'talla M', 'color negro', 'fabricación europea']],
    ['Auriculares bluetooth ANC', ['cancelación de ruido activa', 'autonomía 30h', 'estuche de carga']],
    ['Maceta cerámica artesana', ['hecha a mano', '15cm diámetro', 'incluye drenaje', 'apta interior y exterior']],
];

foreach ($productos as [$nombre, $caracs]) {
    echo "📦 $nombre\n";
    echo generarDescripcion($nombre, $caracs) . "\n";
    echo str_repeat('─', 60) . "\n\n";
}

Resultado: 3 descripciones en menos de 10 segundos. Coste: menos de 1 céntimo. Producción: deshágalo en un loop sobre los productos de tu BD.

2. Traductor castellano → inglés

<?php
function traducir(string $texto, string $idiomaDestino = 'inglés británico'): string
{
    global $client;

    $prompt = "Traduce el siguiente texto al $idiomaDestino. Mantén el tono, el formato y los nombres propios. "
            . "Devuelve SOLO la traducción, sin notas:\n\n$texto";

    $response = $client->request('POST', 'https://api.anthropic.com/v1/messages', [
        'headers' => [
            'x-api-key' => $_ENV['ANTHROPIC_API_KEY'],
            'anthropic-version' => '2023-06-01',
        ],
        'json' => [
            'model' => 'claude-haiku-4-5-20251001',
            'max_tokens' => 1000,
            'messages' => [['role' => 'user', 'content' => $prompt]],
        ],
    ]);

    return $response->toArray()['content'][0]['text'];
}

$post = "BacaSoftware es un estudio de desarrollo web profesional. "
      . "Creamos webs a medida para pequeñas empresas y autónomos en España "
      . "usando Symfony, WordPress y mucha IA para acelerar la entrega.";

echo traducir($post, 'inglés británico');
echo "\n\n";
echo traducir($post, 'catalán');

3. Resumidor de texto largo

<?php
function resumir(string $textoLargo, int $palabrasMax = 100): string
{
    global $client;

    $prompt = "Resume el siguiente texto en máximo $palabrasMax palabras, "
            . "manteniendo los puntos clave y el tono original. "
            . "Devuelve solo el resumen sin introducción:\n\n$textoLargo";

    $response = $client->request('POST', 'https://api.anthropic.com/v1/messages', [
        'headers' => [
            'x-api-key' => $_ENV['ANTHROPIC_API_KEY'],
            'anthropic-version' => '2023-06-01',
        ],
        'json' => [
            'model' => 'claude-haiku-4-5-20251001',
            'max_tokens' => (int) ($palabrasMax * 2.5),  // tokens ≈ 1.5x palabras + margen
            'messages' => [['role' => 'user', 'content' => $prompt]],
        ],
    ]);

    return $response->toArray()['content'][0]['text'];
}

// Ejemplo: artículo de 1500 palabras → resumen 100
$articulo = file_get_contents('articulo-largo.txt');  // tu archivo
echo resumir($articulo, 100);

4. Bonus: respuesta JSON estructurada

Cuando tu PHP necesita procesar la respuesta programáticamente (no solo mostrarla), pide al modelo que devuelva JSON con estructura definida:

<?php
function analizarProducto(string $descripcion): array
{
    global $client;

    $prompt = "Analiza esta descripción de producto. Responde SOLO con JSON válido "
            . "con estas claves exactas: categoria (string), publico_objetivo (string), "
            . "puntos_fuertes (array de 3 strings), precio_estimado_eur (number).\n\n"
            . "Descripción: $descripcion";

    $response = $client->request('POST', 'https://api.anthropic.com/v1/messages', [
        'headers' => [
            'x-api-key' => $_ENV['ANTHROPIC_API_KEY'],
            'anthropic-version' => '2023-06-01',
        ],
        'json' => [
            'model' => 'claude-haiku-4-5-20251001',
            'max_tokens' => 500,
            'messages' => [['role' => 'user', 'content' => $prompt]],
        ],
    ]);

    $textoBruto = $response->toArray()['content'][0]['text'];

    // Limpia ```json ... ``` si el modelo lo envuelve
    $textoBruto = preg_replace('/^```json\s*|\s*```$/m', '', trim($textoBruto));

    return json_decode($textoBruto, true) ?? [];
}

$analisis = analizarProducto("Camiseta básica algodón orgánico negra, talla M, fabricación europea, 19,90€");

print_r($analisis);
// Array (
//     [categoria] => Moda / Camisetas
//     [publico_objetivo] => adultos eco-conscientes
//     [puntos_fuertes] => Array ([0] => algodón orgánico [1] => fabricación europea [2] => básico atemporal)
//     [precio_estimado_eur] => 19.9
// )

Con esto puedes guardar el análisis directamente en tu BD MySQL, generar reports, etc.

Buenas prácticas de prompts

  • Sé específico: en lugar de "describe esto", di "descripción persuasiva, máx 60 palabras, tono cercano".
  • Da contexto: "Eres redactor de ecommerce" antes de la tarea ayuda al modelo.
  • Limita el formato: "Devuelve SOLO la traducción, sin notas" evita preámbulos innecesarios.
  • Itera: si la respuesta no te gusta, ajusta el prompt. La calidad del output depende 90% del prompt, 10% del modelo.

Checklist antes de marcar completada

  • Has ejecutado el generador de descripciones de productos y ves 3 outputs distintos.
  • Has probado el traductor con un texto propio (no solo el ejemplo).
  • Has resumido un texto largo y comprobado que el resultado respeta el límite de palabras.
  • Entiendes cómo pedir JSON estructurado para procesarlo después en PHP.
  • Tienes claras las 4 buenas prácticas de prompts.

En la próxima lección damos un salto cualitativo: vamos a combinar tu base de datos MySQL con un LLM para que el modelo responda preguntas usando datos que solo tú tienes. Esto se llama RAG y es el patrón estrella en aplicaciones empresariales de IA.

📝 Comprueba lo aprendido

Responde estas 4 preguntas y acierta al menos el 60% para desbloquear el botón "Marcar como completada".

1 ¿Por qué pedimos al modelo "responde SOLO con JSON válido"?

2 Si la respuesta del modelo incluye ```json al inicio y ``` al final (envuelta en code block), ¿qué haces?

3 En el generador de descripciones de producto, ¿qué pasa si el cliente tiene 1.000 productos para generar?

4 Buena práctica de prompts: ¿qué hace que un prompt sea bueno?

Cuando termines, guarda tu avance. Así podrás continuar desde tu panel y desbloquear el certificado al completar el curso.