Complete "Lección 1: Fundamentos de la Ingeniería de Prompts" primero para desbloquear esta lección.Ir a la lección anterior

Introducción

Los modelos de lenguaje grandes son flexibles por defecto: pueden responder en cualquier formato, cualquier longitud, cualquier estilo. Para un uso real en producción dentro de aplicaciones web, esa flexibilidad se convierte en un problema. Necesitas una salida predecible y parseable. Esta lección cubre cuatro técnicas fundamentales para controlar lo que produce un LLM: prompts de sistema para establecer un comportamiento persistente, ejemplos few-shot para enseñar patrones de salida mediante demostración, aplicación de formato para garantizar la estructura y gestión de casos extremos para cuando el modelo intenta salirse del guion.

Prompts de sistema vs prompts de usuario

Los prompts de sistema se envían como un mensaje separado con mayor prioridad que los mensajes del usuario. Definen el rol, las restricciones y el tono del modelo durante toda la conversación. Los prompts de usuario son la tarea o pregunta concreta. Mantén el prompt de sistema centrado en reglas estables y el prompt de usuario centrado en la tarea variable.

typescript
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{ role: "system", content: "You are a JSON API. Respond ONLY with valid JSON. Never include explanations, markdown fences, or extra text. If you cannot comply, return {\"error\": \"reason\"}." },
{ role: "user", content: "List 3 colors" }
],
temperature: 0
});

Observa `temperature: 0`: cuando necesitas salida estructurada, fija la aleatoriedad a cero. Temperaturas más altas introducen desviaciones en el formato incluso con un prompt de sistema fuerte.

Ejemplos Few-Shot

Few-shot prompting significa mostrar al modelo 2-4 ejemplos de la correspondencia exacta entrada-salida que deseas, en lugar de describirla. El modelo aprende el patrón mediante pattern matching. Coloca los ejemplos dentro del prompt de usuario o como pares alternados de mensajes user/assistant.

typescript
const messages = [
{ role: "system", content: "Extract the product name and price from review text." },
{ role: "user", content: "Review: The Sony WH-1000XM5 headphones cost $399." },
{ role: "assistant", content: '{"product": "Sony WH-1000XM5", "price": 399}' },
{ role: "user", content: "Review: Got the Instant Pot Duo for $99, works great." },
{ role: "assistant", content: '{"product": "Instant Pot Duo", "price": 99}' },
{ role: "user", content: "Review: My new Logitech MX Master 3S was a steal at 79 dollars." },
];

El tercer mensaje de usuario no tiene respuesta del assistant: el modelo la completa. Como vio dos ejemplos consistentes, casi siempre seguirá la misma estructura JSON.

diagrama de flujo que muestra el prompt de sistema + ejemplos few-shot entrando al LLM y produciendo una salida JSON estructurada que consume la aplicación web

Estrategias de aplicación de formato

Cuando el modelo es terco e ignora tus instrucciones de formato, aplica estas defensas en orden: primero, afina el prompt de sistema con ejemplos negativos explícitos ("NO escribas 'Aquí está tu JSON:'"). Segundo, cambia a un modelo que soporte el modo de salida estructurada (modo JSON o tool/function calling) donde la API garantiza JSON válido. Tercero, añade un paso de post-procesamiento en tu código que valide la salida con un esquema y reintente en caso de fallo.

typescript
import { z } from "zod";
import { ZodError } from "zod";
const ColorList = z.object({
colors: z.array(z.string()).length(3)
});
async function getColors() {
const raw = await callLLM("List 3 colors");
try {
const parsed = ColorList.parse(JSON.parse(raw));
return parsed;
} catch (e) {
if (e instanceof ZodError) {
return { colors: [] as string[] };
}
throw e;
}
}

El esquema Zod actúa como un contrato: si el LLM devuelve un número en lugar de un string, o devuelve 4 colores en lugar de 3, el parse lanza un error y entra tu fallback. Nunca confíes en la salida cruda del LLM en código de producción.

Gestión de casos extremos

Surgen tres casos extremos constantemente. Primero, el modelo se niega y devuelve una disculpa en lugar de datos: manéjalo detectando frases de rechazo y reintentando con un prompt más claro. Segundo, el modelo alucina un campo que no existe en tu esquema: manéjalo validando contra el esquema, no solo con JSON.parse. Tercero, el modelo devuelve salida truncada porque alcanzó el límite de tokens: manéjalo estableciendo max_tokens explícitamente y fragmentando las solicitudes largas, o pidiendo al modelo que sea conciso.

Resumen

Controlar la salida de un LLM no es un solo truco: es una pila de defensas. Empieza con un prompt de sistema claro, añade ejemplos few-shot cuando el formato sea ambiguo, aplica la estructura con esquemas y validación, y ten siempre un fallback para rechazos, alucinaciones y truncamiento. En la próxima lección veremos function calling, que permite al modelo elegir entre herramientas en lugar de generar texto libre.

Práctica de la lección

Punto de control de la lección

Repasa lo aprendido y recibe comentarios sobre tu trabajo.

0/1
Respondidas · 0/1
Lección 2: Controlar la salida del modelo con prompts estructurados