Ir al contenido principal
Laravel, thinking fast.

En cuanto soportes una segunda variante —una segunda categoría de producto, un segundo idioma, un segundo plan— tendrás la tentación de copiar el prompt y editar la copia.

No lo hagas. Compónlo.

return $siteCategory === 'event'
    ? self::BASE_PROMPT.self::EVENT_EXTRA
    : self::BASE_PROMPT;

Una base, un delta. Todo lo que es cierto para ambas categorías se escribe una vez, y la variante de evento lleva sólo lo que es distinto: sus secciones, sus acciones, sus identificadores editables.

El modo de fallo de bifurcar no es que sea poco elegante. Es que las dos copias se separan de formas que nadie nota, porque nada las compara. Arreglas una regla en una y no en la otra; seis semanas después el flujo de eventos tiene un fallo que el de negocios no, y el diff entre los dos prompts son cuatrocientas líneas de prosa casi idéntica que nadie quiere leer.

Si el delta llega a rivalizar con la base, eso es señal de que tienes dos funciones, no dos variantes —y entonces dos prompts es lo correcto. Pero que sea una decisión y no el resultado de un copiar y pegar.

Separa el texto del montaje

Hay un segundo tipo de prompt: no un bloque estático, sino uno construido por petición a partir de datos del usuario. Ahí la tentación es montar la cadena donde haga falta y, de paso, escribir en línea el texto que ve el modelo.

Eso reparte un contrato entre dos preocupaciones. Las palabras que dan forma al contenido generado acaban esparcidas por código de montaje, y los recuentos y etiquetas que el resto de la aplicación también necesita se escriben dos veces.

Así que el texto vive con el esquema, y el constructor sólo lo monta:

public const COUNTS = [
    'services' => 3,
    'testimonials' => 3,
    'faqs' => 6,
];

public const ITEM_FIELDS = [
    'testimonials' => [
        'paragraph' => 'Write a convincing testimonial review (max 200 characters)
                        from a satisfied client. Include: 1) specific problem solved,
                        2) measurable result or outcome, 3) positive personal touch.',
        'name' => 'Generate a realistic first and last name for this satisfied client.',
    ],
];

Y el servicio no redacta absolutamente nada:

public function generateTestimonials(): string
{
    $fields = ContentSchema::ITEM_FIELDS['testimonials'];

    return self::generateContent(range(1, ContentSchema::COUNTS['testimonials']), fn () => <<<TESTIMONIAL
        {
            "paragraph": "{$fields['paragraph']}",
            "name": "{$fields['name']}"
        }
        TESTIMONIAL);
}

Ahora «cuántos testimonios» es un número, leído por el prompt que los pide y por la capa que los valida. Cámbialo en un sitio y ambos lo siguen. Es el mismo argumento de fuente única del capítulo anterior, aplicado al texto en vez de a la estructura —y por eso el texto del prompt vive en la clase del esquema y no en el constructor.