Prompt Engineering para desarrolladores: los 5 patrones esenciales
Los 5 patrones de prompt engineering: zero-shot, few-shot, CoT, role prompting y structured output con código TypeScript real.
Colaboradores: Ivan Garcia Villar
Prerequisitos: Para seguir este post necesitas saber qué es una API y haber hecho alguna llamada HTTP desde código. No necesitas saber qué es un LLM, un token, ni haber trabajado con IA antes. Esos conceptos los explico aquí antes de usarlos.
Setup del SDK antes de los ejemplos:
npm install @anthropic-ai/sdk
import Anthropic from '@anthropic-ai/sdk';
const anthropic = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY, // variable de entorno, no hardcodear
});
Todos los snippets de este post asumen que anthropic está inicializado con este bloque.
La primera vez que integré un LLM en código real, escribí algo como “Dame un resumen de este texto.” El modelo me devolvió un resumen. Bien. Pero a veces era demasiado largo, a veces en inglés aunque el texto era en español, y a veces añadía frases como “¡Claro! Aquí tienes el resumen:” que rompían mi parser. El problema no era el modelo. Era yo.
¿Por qué el modelo no “entiende” lo que le pides?
Imagina que le das una nota post-it a un becario nuevo: “resume esto.” Funciona si el becario tiene contexto, si sabe el formato que esperas y para qué sirve el resumen. Sin ese contexto, cada persona interpreta “resume esto” de forma distinta.
Un LLM (modelo de lenguaje: el tipo de IA que hay detrás de ChatGPT, Claude o GPT-4) funciona de forma parecida. No “entiende” tu intención. Predice qué texto es probable que venga después del texto que le das. Eso significa que si cambias cómo escribes la instrucción, cambias el resultado, a veces radicalmente.
El prompt es la especificación técnica que le das al modelo. Un post-it produce resultados aleatorios. Una especificación clara produce resultados predecibles.
Los patrones de prompt engineering son formas probadas de escribir esa especificación para obtener el resultado que necesitas. Son cinco los que aparecen en casi todos los proyectos reales.
Los 5 patrones que necesitas conocer
Zero-shot: la instrucción directa
Zero-shot es el patrón más simple: escribes la instrucción directamente, sin ejemplos previos. El nombre viene de “cero shots” (cero disparos, es decir, cero ejemplos).
Funciona bien para tareas simples y claras: traducir un texto, responder una pregunta factual, generar una lista de ideas. Cuando la tarea es ambigua o requiere un formato muy específico, zero-shot suele dar resultados inconsistentes.
// Zero-shot: solo la instrucción, sin ejemplos previos
const response = await anthropic.messages.create({
model: "claude-opus-4-6", // el modelo que usamos
max_tokens: 1024, // límite de respuesta en tokens (1 token ≈ 4 caracteres en inglés; algo menos en español)
messages: [
{
role: "user", // quién habla: nosotros
content: "Clasifica este email como urgente o normal: 'El servidor está caído.'"
}
]
});
// El texto de la respuesta está aquí
console.log(response.content[0].text);
max_tokens es el número máximo de “trozos de texto” que el modelo puede escribir en su respuesta. Para respuestas cortas, 1024 es más que suficiente.
Few-shot: enseñar con ejemplos
Few-shot añade dos o tres pares de ejemplo (input → output) antes de la tarea real. El modelo aprende el patrón de tus ejemplos y lo aplica al nuevo caso. Es especialmente útil cuando el formato de salida importa mucho o cuando la tarea tiene matices difíciles de describir con palabras.
// Few-shot: damos ejemplos antes de la tarea real
const prompt = `Clasifica el sentimiento. Responde solo con: positivo, negativo, o neutral.
Email: "El envío llegó antes de lo esperado"
Sentimiento: positivo
Email: "Llevo tres días esperando y nadie responde"
Sentimiento: negativo
Email: "El producto funciona como se describe"
Sentimiento: neutral
Email: "La calidad no justifica el precio"
Sentimiento:`;
// El modelo completa el patrón con el sentimiento correcto.
// Para llamar a la API, pasa este string como content en messages[0].content:
// messages: [{ role: "user", content: prompt }]
Con tres ejemplos bien elegidos, el modelo aprende el tono, el formato y la lógica que esperas. Sin ellos, podría responderte con “El sentimiento de este email es negativo porque…” en lugar del simple “negativo” que necesita tu parser.
Chain-of-Thought: pensar antes de responder
Chain-of-Thought (cadena de pensamiento, abreviado CoT) es pedirle al modelo que razone paso a paso antes de dar la respuesta final. Se activa añadiendo frases como “Piensa paso a paso” al final de la instrucción.
Por qué funciona: los LLMs cometen más errores en problemas de razonamiento cuando responden directamente. Al forzar los pasos intermedios, el modelo usa su propio razonamiento como contexto para el siguiente paso y se equivoca menos.
// Chain-of-Thought: forzamos el razonamiento explícito
const content = `Tengo 3 cajas. Cada caja tiene 4 bolsas.
Cada bolsa tiene 6 canicas rojas y 2 canicas azules.
¿Cuántas canicas hay en total?
Piensa paso a paso y muestra cada operación antes de dar la respuesta final.`;
// Sin "piensa paso a paso", el modelo puede saltar a una respuesta incorrecta.
// Con él, el razonamiento queda visible y los errores bajan.
// Para llamar a la API, pasa este string como content en messages[0].content:
// messages: [{ role: "user", content }]
A veces basta añadir esa frase al final de cualquier instrucción de razonamiento. No hace falta un prompt largo.
Role Prompting: cambiar la perspectiva
Role prompting le asigna un rol al modelo antes de la tarea: “Eres un senior developer con 10 años de experiencia en TypeScript.” Esto cambia más que el tono: afecta qué información el modelo considera relevante mencionar, qué asume que ya sabes, y qué profundidad técnica usa.
El lugar correcto para el rol es el system prompt, que es una instrucción especial que va antes de la conversación y define el comportamiento del modelo para toda la sesión. Piénsalo como la descripción del puesto de trabajo que le das al becario desde el primer día.
// Role prompting: el rol va en el system prompt, no en el mensaje del usuario
const response = await anthropic.messages.create({
model: "claude-opus-4-6",
// system aplica a toda la sesión, no solo a este mensaje
system: `Eres un senior developer de TypeScript con experiencia en APIs REST.
Cuando revises código, señala primero los bugs, luego los problemas de rendimiento.
Sé directo: no expliques lo que ya es obvio para alguien con experiencia técnica.`,
max_tokens: 1024,
messages: [
{
role: "user",
content: "Revisa esta función:\n\nfunction getUsers() {\n return db.query('SELECT * FROM users');\n}"
}
]
});
La diferencia entre un rol vago (“eres un experto”) y uno específico (“eres un senior developer de TypeScript especializado en APIs REST”) es clara en la calidad de la respuesta. Cuanto más concreto el rol, menos respuestas de tipo “puede ser por X, Y o Z.”
Structured Output: integrar LLMs en pipelines de código
Structured Output es pedirle al modelo que responda en JSON con un schema exacto. Es el patrón más importante para integrar LLMs en aplicaciones reales, porque necesitas que la respuesta sea parseable por tu código sin tratamiento manual.
// Structured Output: definimos el schema exacto que esperamos
const content = `Analiza este comentario y devuelve ÚNICAMENTE un JSON válido,
sin texto adicional, con esta estructura exacta:
{
"sentimiento": "positivo" | "negativo" | "neutral",
"confianza": número entre 0 y 1,
"temas": array de strings con máximo 3 elementos
}
Comentario: "La app va lenta pero el diseño está muy bien cuidado"`;
const response = await anthropic.messages.create({
model: "claude-opus-4-6",
max_tokens: 1024,
messages: [{ role: "user", content }]
});
// Parseamos la respuesta — siempre dentro de try/catch
const text = response.content[0].text;
try {
const data = JSON.parse(text.trim()); // data.sentimiento, data.confianza, data.temas
console.log(data);
} catch (err) {
// El modelo devolvió algo que no es JSON válido
console.error("Error parseando JSON:", err, "Respuesta recibida:", text);
}
Escribir “ÚNICAMENTE un JSON válido, sin texto adicional” reduce las desviaciones de formato. Para producción hay técnicas más robustas: el post sobre Programmatic Tool Calling en TypeScript (cuando el modelo puede llamar funciones definidas por ti, en lugar de solo generar texto) cubre cómo usar schemas validados a nivel de protocolo.
La anatomía de un prompt perfecto
Un prompt efectivo tiene cinco capas. La mayoría de los desarrolladores solo usa dos de ellas (instrucción y tarea) y se pregunta por qué los resultados son inconsistentes.
Rol es quién es el modelo para este prompt (“Eres un analista de datos especializado en e-commerce”). Va en el system prompt.
Contexto es la información de fondo que el modelo necesita pero no tiene (“Nuestra tienda vende productos de segunda mano; las reseñas suelen ser breves y en tono informal”). Sin contexto, el modelo hace suposiciones.
Instrucción es qué tiene que hacer exactamente (“Clasifica cada reseña en una de estas categorías: producto, envío, atención al cliente”). Una sola instrucción por prompt. Cuando metes dos, el modelo suele priorizar una y descuidar la otra.
Formato es cómo quieres que responda (“Devuelve solo la categoría, sin explicación”). Si no lo especificas, el modelo elige. En producción no puedes depender de esa elección.
Ejemplos son los pares input → output del patrón few-shot. Van al final, justo antes del input real.
No todos los prompts necesitan las cinco capas. Un zero-shot simple puede funcionar bien con solo instrucción y formato. Pero cuando los resultados son inconsistentes, lo primero que hay que revisar es qué capa falta.
Cargando ejercicio...
¿Cuándo usar cada patrón?
La elección no es arbitraria. Cada patrón resuelve un problema específico.
| Situación | Patrón recomendado | Por qué | Costo / Limitación |
|---|---|---|---|
| Tarea simple y clara (traducir, resumir) | Zero-shot | Los ejemplos solo añaden tokens sin beneficio real | Inconsistente en tareas ambiguas o con formato estricto |
| Formato de salida muy específico | Few-shot | Los ejemplos calibran el formato mejor que cualquier descripción verbal | Cada ejemplo añade tokens; en tareas simples el costo supera el beneficio |
| Problema de razonamiento o cálculo | Chain-of-Thought | Reduce errores al externalizar los pasos intermedios | Aumenta latencia y tokens; no aporta en clasificación directa |
| Respuesta que depende del perfil del lector | Role prompting | El rol calibra nivel técnico y tono sin instrucciones adicionales | Un rol vago (“eres un experto”) no cambia nada; requiere especificidad |
| LLM dentro de un pipeline de código | Structured Output | Sin schema, el parser rompe con cualquier variación del modelo | Frágil ante drift de modelo; en producción conviene tool calling con schema validado |
| Tarea ambigua con varias formas correctas | Few-shot + CoT | Los ejemplos delimitan el espacio; CoT reduce errores dentro de él | Combinación con mayor consumo de tokens; reservar para tareas que realmente lo requieren |
La tabla da orientación general, pero en la práctica necesitas probar. Un patrón que funciona para un modelo puede no funcionar igual en otro, incluso del mismo proveedor. Y los patrones se combinan: un prompt de producción típico tiene role prompting en el system prompt, few-shot para calibrar el formato, y structured output para el resultado.
Cargando ejercicio...
Patrones avanzados: qué viene después
Una vez domines los cinco patrones base, hay tres más que vale la pena conocer.
Self-consistency: en lugar de pedir una respuesta, pides varias con temperatura alta y te quedas con la más frecuente. Funciona bien en problemas donde el modelo puede llegar a la respuesta correcta por varios caminos. La temperatura es el parámetro que controla cuánta variedad introduce el modelo en sus respuestas: alta temperatura, más variedad; baja temperatura, más determinismo. El coste de self-consistency es proporcional al número de respuestas que generas.
ReAct (Reason + Act): combina razonamiento y uso de herramientas en un ciclo. El modelo piensa, decide qué herramienta usar, la usa, procesa el resultado, y decide si necesita más información. Es la base de la mayoría de los agentes modernos. Si quieres ver tool calling en código real, el post sobre Programmatic Tool Calling en TypeScript lo cubre paso a paso.
Tree of Thought: extiende Chain-of-Thought con ramificaciones. El modelo genera varios “caminos de razonamiento” en paralelo, los evalúa y selecciona el mejor. Útil para problemas de planificación complejos, aunque caro en tokens.
Estos tres patrones se usan principalmente en sistemas agénticos, donde el LLM no solo responde sino que toma decisiones y actúa. Para saber cómo evaluar si esos sistemas funcionan bien en producción, el post sobre cómo evaluar agentes IA en producción cubre las métricas y el setup concreto.
Prompt Engineering en producción
Usar prompts en producción es diferente a usarlos en un prototipo. Tres problemas aparecen casi siempre.
Versionar prompts como código. Si cambias un prompt en producción sin registrar el cambio, perderás la capacidad de saber qué actualizó qué comportamiento. El enfoque mínimo: guardar cada versión en un archivo con fecha (analyze_v2_2026-03.txt) y tener un registro de qué versión está activa. El enfoque robusto: tratar los prompts como cualquier otro artefacto de código, en control de versiones, con tests que se ejecutan antes de cada cambio.
Testing de regresión. Cuando cambias un prompt, necesitas saber si los casos que ya funcionaban siguen funcionando. Construir un conjunto de pares input/output esperado y ejecutarlos contra el prompt nuevo antes de desplegarlo es la práctica mínima que evita regresiones silenciosas. El post sobre estrategia de tests con IA cubre cómo estructurar esto cuando el output del LLM no es determinista.
Monitoring. En producción, el comportamiento del modelo puede cambiar aunque no cambies el prompt, porque los proveedores actualizan los modelos periódicamente. Loguear inputs, outputs y latencias, y monitorizar la distribución de respuestas a lo largo del tiempo, te permite detectar esos cambios antes de que lleguen reportes de usuarios.
Errores comunes
El prompt demasiado vago
“Resume esto bien” no es una instrucción. ¿Bien para quién? ¿Qué longitud? ¿Qué formato? El modelo rellena los huecos con sus propios valores por defecto, que casi nunca coinciden con los tuyos. Especifica la audiencia, la longitud máxima y el formato. “Resume en 3 frases para un ejecutivo sin contexto técnico. Sin bullet points.”
No especificar el formato de salida
Si no dices cómo quieres la respuesta, puede cambiar de llamada a llamada. A veces el modelo usa markdown, a veces texto plano, a veces añade una introducción. En código esto es especialmente problemático porque tu parser asume un formato fijo y el modelo no tiene por qué dártelo siempre. Especifica el formato cuando el output va a ser procesado en código.
Mezclar idiomas en el mismo prompt
Un system prompt en inglés con instrucciones en español es una fuente de inconsistencias. El modelo intenta inferir qué idioma usar para la respuesta. Elige un idioma para el prompt completo. Si el contexto de negocio requiere mezcla, especifícalo de forma explícita: “Respond always in Spanish regardless of the input language.”
Olvidar que el modelo no tiene memoria entre llamadas
Cada llamada a la API es independiente. El modelo no recuerda la llamada anterior. Este error produce bugs extraños: la primera llamada funciona bien y las siguientes parecen “olvidar” lo que se acordó antes. No es un bug del modelo, es que le estás haciendo preguntas sin el contexto que necesita. Si tu código hace múltiples llamadas relacionadas, tienes que incluir el contexto relevante en cada una.
Meter demasiadas tareas en un solo prompt
“Analiza el texto, clasifica el sentimiento, extrae los temas principales, sugiere una respuesta y evalúa si el usuario está satisfecho” es demasiado para un solo prompt. Cuatro llamadas separadas con una tarea clara cada una producen resultados más fiables que una sola con cinco tareas. La calidad cae cuantas más cosas metes en una instrucción.
Checklist de implementación
-
El prompt especifica el rol del modelo cuando el tono o nivel técnico importan
-
La instrucción está en imperativo y hace una sola cosa (“clasifica”, “extrae”, “resume”)
-
El formato de salida está definido explícitamente (JSON, texto plano, lista, etc.)
-
Los prompts están guardados como archivos versionados, no hardcodeados en la lógica de negocio
-
Existe un conjunto de tests con pares input/output esperado para detectar regresiones
-
Las respuestas JSON se validan antes de parsearlas (
JSON.parsedentro detry/catch) -
El idioma de la respuesta está especificado si el input puede ser multilingüe
-
Cada llamada incluye el contexto necesario (no se asume memoria entre llamadas)
Preguntas Frecuentes
¿Cuál es la diferencia entre un prompt y un system prompt?
Un prompt es el mensaje que le envías al modelo en cada llamada. Un system prompt es un conjunto de instrucciones que va antes de la conversación y define el comportamiento general del modelo para toda la sesión: quién es, qué puede y no puede hacer, en qué formato debe responder. El usuario interactúa mediante prompts; el system prompt define las reglas del juego para toda la interacción.
¿Cuándo vale la pena usar Few-shot en lugar de Zero-shot?
Cuando el formato de salida es muy específico o cuando la tarea tiene matices difíciles de describir con palabras. Si llevas tres intentos ajustando la instrucción y el output sigue siendo inconsistente, añade dos o tres ejemplos. Casi siempre resuelve el problema. Si puedes describir perfectamente la tarea en una instrucción clara, zero-shot es suficiente y más barato en tokens.
¿Chain-of-Thought siempre mejora los resultados?
No. En tareas de clasificación simple o recuperación de información factual, añade verbosidad sin mejorar la precisión. Su beneficio es claro en razonamiento lógico, matemáticas y planificación de pasos. Úsalo cuando el problema requiere razonar, no cuando solo requiere recuperar o clasificar.
¿Por qué el modelo a veces ignora el schema JSON que le pido?
Porque los LLMs generan texto de forma probabilística, no siguen reglas de forma determinista. Si el prompt no es lo suficientemente explícito, el modelo puede añadir texto antes del JSON, cambiar nombres de campos o incluir campos extra. La solución en prompts: ser muy explícito (“Devuelve ÚNICAMENTE el JSON, sin texto adicional, sin markdown, sin explicaciones”). La solución robusta en producción es usar tool calling en la API, que obliga al modelo a seguir el schema a nivel de protocolo.
¿Necesito dominar todos los patrones antes de integrar un LLM en mi proyecto?
No. Empieza con zero-shot para tareas simples y añade structured output desde el principio si la respuesta tiene que ser parseada por código. Con esos dos puedes construir aplicaciones funcionales. Los demás patrones los irás necesitando a medida que encuentres los casos concretos donde lo que tienes no es suficiente.