Módulo 1: Fundamentos de Prompt Engineering
2. Anatomía de un Prompt
Descripción
Un prompt profesional no es texto libre: tiene componentes identificables que el modelo procesa de forma distinta. En esta cápsula aprenderás los 4 componentes fundamentales (instrucción, contexto, input, output format), cómo el modelo los procesa, y el impacto de la tokenización en los resultados. Al final, podrás descomponer cualquier prompt y diagnosticar qué falta o qué sobra.
Por qué importa: Sin entender la anatomía, no puedes mejorar prompts sistemáticamente. Si un prompt falla, no sabes si el problema está en la instrucción, en el contexto, o en el formato de salida. Con anatomía clara, optimizas por partes.
Los 4 Componentes de un Prompt Profesional
1. Instrucción
Qué es: La tarea que quieres que el modelo ejecute. Debe ser explícita y accionable.
Ejemplo vago:
Haz algo con este texto.
Ejemplo explícito:
Extrae las entidades nombradas (personas, organizaciones, lugares) del siguiente texto.
Devuelve una lista con formato JSON: {"personas": [], "organizaciones": [], "lugares": []}
Regla: La instrucción responde "¿Qué debe hacer el modelo?" con suficiente detalle para que no tenga que adivinar.
Verbos de instrucción útiles:
- Clasificar, categorizar
- Extraer, identificar
- Resumir, condensar
- Traducir, parafrasear
- Generar, crear
- Analizar, evaluar
- Comparar, contrastar
- Responder, explicar
2. Contexto
Qué es: Información adicional que el modelo necesita para ejecutar la tarea correctamente. Incluye dominio, restricciones, definiciones, y background.
Ejemplo sin contexto:
Clasifica este ticket.
Ejemplo con contexto:
Eres un clasificador de tickets de soporte. Las categorías son: Billing, Technical, Account, Other.
Solo responde con una de las cuatro categorías, nada más.
Definiciones:
- Billing: problemas de pago, facturas, cargos
- Technical: errores, bugs, problemas de acceso técnico
- Account: cambios de contraseña, configuración, permisos
- Other: cualquier cosa que no encaje en las anteriores
Regla: El contexto responde "¿Qué necesita saber el modelo para hacerlo bien?" y "¿Qué restricciones debe respetar?"
Tipos de contexto:
- Dominio: "Estás en el contexto de una empresa de seguros"
- Definiciones: "Un 'incidente crítico' se define como..."
- Restricciones: "Solo usa información del documento proporcionado"
- Background: "El usuario ya intentó reiniciar su dispositivo"
3. Input
Qué es: Los datos sobre los que el modelo debe actuar. El contenido variable que cambia en cada llamada.
Ejemplo:
[Instrucción y contexto arriba]
Ticket del usuario:
"Mi factura de marzo no llegó y ya pasaron 2 semanas. Necesito ayuda urgente."
Regla: El input es lo que el usuario o el sistema proporciona en cada request. Debe estar claramente delimitado (por ejemplo, con etiquetas como "Input:" o triple comillas ''').
Cómo delimitar el input:
# Opción 1: Etiqueta
prompt = f"""
Instrucción: Clasifica el sentimiento.
Input: {user_text}
"""
# Opción 2: Comillas triples
prompt = f"""
Clasifica el sentimiento del siguiente texto:
'''{user_text}'''
"""
# Opción 3: XML-style (funciona bien con Claude)
prompt = f"""
Clasifica el sentimiento de este texto:
<texto>
{user_text}
</texto>
"""
La delimitación evita que el modelo "mezcle" el input con la instrucción (especialmente importante si el input puede contener instrucciones).
4. Output Format
Qué es: Cómo debe estructurarse la respuesta. JSON, lista, párrafo, tabla, etc.
Ejemplo sin formato:
Resume este artículo.
Ejemplo con formato:
Resume este artículo en exactamente 3 bullet points.
Cada bullet debe tener máximo 15 palabras.
Formato:
- [punto 1]
- [punto 2]
- [punto 3]
Regla: El output format reduce variabilidad y hace la respuesta parseable por código. En producción, casi siempre necesitas formato estructurado.
Formatos comunes:
| Formato | Cuándo usar |
|---|---|
| JSON | Extracción de datos, clasificación con metadatos |
| Lista de bullets | Resúmenes, brainstorming |
| String exacto | Clasificación simple (POSITIVO/NEGATIVO) |
| Tabla Markdown | Comparaciones |
| Código | Generación de código |
| Párrafo estructurado | Análisis narrativo |
Ejemplo Completo Integrado
# Prompt con los 4 componentes explícitos y código completo
from openai import OpenAI
import json
import os
from dotenv import load_dotenv
load_dotenv()
client = OpenAI()
# Componentes del prompt claramente identificados
INSTRUCCION = """
Extrae las entidades nombradas del texto.
Clasifica cada una como PERSONA, ORGANIZACIÓN o LUGAR.
"""
CONTEXTO = """
Reglas:
- Solo incluye entidades que aparezcan explícitamente en el texto
- Si una entidad es ambigua, usa la categoría más probable
- No inventes entidades que no estén en el texto
- Una misma entidad puede aparecer varias veces: inclúyela una sola vez
"""
INPUT = "María García trabaja en Google en Mountain View. Ayer habló con Juan Pérez de Microsoft sobre el proyecto."
OUTPUT_FORMAT = """
Responde con un JSON válido y nada más:
{
"entidades": [
{"texto": "...", "tipo": "PERSONA|ORGANIZACIÓN|LUGAR"}
]
}
"""
# Prompt ensamblado
prompt = f"""
## Instrucción
{INSTRUCCION}
## Contexto
{CONTEXTO}
## Input
{INPUT}
## Output Format
{OUTPUT_FORMAT}
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0 # Determinístico para extracción
)
output = response.choices[0].message.content
print(output)
# Parsear el JSON
data = json.loads(output)
print(f"Entidades encontradas: {len(data['entidades'])}")
for e in data['entidades']:
print(f" - {e['texto']} ({e['tipo']})")
Output esperado:
{
"entidades": [
{"texto": "María García", "tipo": "PERSONA"},
{"texto": "Google", "tipo": "ORGANIZACIÓN"},
{"texto": "Mountain View", "tipo": "LUGAR"},
{"texto": "Juan Pérez", "tipo": "PERSONA"},
{"texto": "Microsoft", "tipo": "ORGANIZACIÓN"}
]
}
Entidades encontradas: 5
- María García (PERSONA)
- Google (ORGANIZACIÓN)
- Mountain View (LUGAR)
- Juan Pérez (PERSONA)
- Microsoft (ORGANIZACIÓN)
Cómo el Modelo Procesa Cada Parte
El modelo no "lee" el prompt como un humano. Lo procesa como secuencia de tokens:
-
Tokens: El texto se divide en subunidades (palabras, partes de palabras, puntuación). "Extrae" puede ser 1 token, "entidades" puede ser 1-2 tokens.
-
Orden importa: El modelo procesa de izquierda a derecha. La instrucción al inicio tiene más "peso" que el contexto al final en algunos escenarios. Por eso se recomienda el orden: Instrucción → Contexto → Input → Output Format.
-
Delimitadores: Usar etiquetas como
## InstrucciónoInput:ayuda al modelo a segmentar mentalmente. No es obligatorio, pero mejora consistencia. -
Longitud: Más contexto no siempre es mejor. Contexto irrelevante puede "diluir" la instrucción. Solo incluye lo necesario.
-
Recency bias: Los LLMs suelen dar más peso a lo que está al final del prompt. Por eso colocar el Output Format al final es una buena práctica — es lo último que el modelo "ve" antes de generar.
Tokens y Tokenización: Impacto en Resultados
Qué son los tokens
Los LLMs no procesan caracteres ni palabras completas. Procesan tokens, que son fragmentos de texto (típicamente 3-4 caracteres en inglés, 1-2 en español).
Ejemplo:
- "Prompt engineering" → ~3-4 tokens
- "ingeniería de prompts" → ~4-5 tokens
Impacto en resultados
-
Límite de contexto: Cada modelo tiene un máximo de tokens (ej: 128K para GPT-4o). Si tu prompt + respuesta excede el límite, se trunca.
-
Costo: La mayoría de APIs cobran por token. Prompt más largo = más costo por llamada.
-
Latencia: Más tokens = más tiempo de procesamiento. Para aplicaciones en tiempo real, importa.
-
Calidad: En algunos casos, prompts muy largos con información redundante pueden degradar la calidad. "Signal vs noise".
Verificar token count
import tiktoken
from openai import OpenAI
# Contar tokens antes de llamar
def count_tokens(text: str, model: str = "gpt-4o-mini") -> int:
encoding = tiktoken.encoding_for_model(model)
return len(encoding.encode(text))
# Ejemplo
prompt = """
Extrae las entidades nombradas del siguiente texto.
Responde con JSON: {"entidades": [{"texto": "...", "tipo": "PERSONA|ORG|LUGAR"}]}
Texto: María García trabaja en Google.
"""
tokens = count_tokens(prompt)
print(f"Tokens del prompt: {tokens}")
# Output: Tokens del prompt: ~42
# Estimación de costo (gpt-4o-mini: $0.15 por millón de tokens de input)
costo_por_llamada = tokens * 0.15 / 1_000_000
print(f"Costo estimado: ${costo_por_llamada:.6f}")
Anatomía vs Roles: La Distinción
Existe una diferencia importante entre anatomía de un prompt (los componentes del contenido) y roles (system/user/assistant que son la estructura de la API):
Anatomía (qué dice el prompt):
- Instrucción, Contexto, Input, Output Format
Roles (cómo se organiza en la API):
system: Instrucción + Contexto (el contrato)user: Input + repetición de Output Format si es necesarioassistant: Historial de respuestas
# Mapeo anatomía → roles
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system", # Instrucción + Contexto
"content": """
Eres un extractor de entidades nombradas.
Categorías: PERSONA, ORGANIZACIÓN, LUGAR.
Responde solo con JSON válido.
"""
},
{
"role": "user", # Input + Output Format
"content": """
Texto: María García trabaja en Google en Mountain View.
Formato: {"entidades": [{"texto": "...", "tipo": "..."}]}
"""
}
],
temperature=0
)
Comparación: Prompt Sin Anatomía vs Con Anatomía
| Aspecto | Sin anatomía | Con anatomía |
|---|---|---|
| Reproducibilidad | Baja (cada intento es distinto) | Alta (misma estructura, resultados consistentes) |
| Debugging | Difícil (no sabes qué cambiar) | Fácil (cambias un componente, mides impacto) |
| Evaluación | Subjetiva ("se ve bien") | Por componente (¿instrucción clara? ¿formato correcto?) |
| Mantenimiento | Caótico | Versionable, documentable |
| Costo | No optimizado | Optimizable (token count por componente) |
Comparación: Órdenes de Componentes
# Orden A: Instrucción primero (recomendado)
prompt_a = """
Clasifica el sentimiento como POSITIVO o NEGATIVO.
Reglas: Solo una palabra. Sin explicaciones.
Texto: "Me encantó el producto"
"""
# Orden B: Input primero (menos efectivo)
prompt_b = """
Texto: "Me encantó el producto"
Clasifica el sentimiento como POSITIVO o NEGATIVO.
Solo una palabra.
"""
# En la mayoría de modelos, orden A es más consistente
# porque la instrucción aparece antes que el input
Conexión con el Proyecto
En el Prompt Analyzer (cápsula 08) usarás la anatomía para:
- Identificar qué componentes tiene un prompt dado
- Detectar componentes faltantes (ej: sin output format)
- Sugerir mejoras específicas por componente
- Puntuar la "calidad" de un prompt por presencia de componentes
Troubleshooting
Problema 1: El modelo ignora el formato de salida
Causa: El output format está enterrado en mucho texto o no es suficientemente explícito.
Solución: Pon el output format al final, con ejemplos concretos. Usa frases como "Responde ÚNICAMENTE con..." o "Formato obligatorio:" y añade un ejemplo:
Formato obligatorio (no incluyas nada más):
{"resultado": "POSITIVO|NEGATIVO", "confianza": 0.0-1.0}
Ejemplo: {"resultado": "POSITIVO", "confianza": 0.95}
Problema 2: El modelo inventa información no presente en el input
Causa: Falta contexto que restrinja explícitamente la invención.
Solución: Agrega en contexto:
IMPORTANTE: No inventes información.
Si no está en el input, indica "No encontrado" en ese campo.
Problema 3: Respuestas inconsistentes entre llamadas
Causa: Temperature > 0 o instrucción ambigua que permite múltiples interpretaciones.
Solución: Usa temperature=0 para tareas determinísticas. Haz la instrucción más explícita con ejemplos de lo que SÍ y lo que NO quieres.
Problema 4: El modelo mezcla el contexto con el input
Causa: Falta delimitación clara del input.
Solución: Usa delimitadores explícitos:
Instrucción: Clasifica el sentimiento.
Input (texto a clasificar):
'''
Me encantó el producto, lo recomiendo.
'''
Responde solo: POSITIVO, NEGATIVO o NEUTRO
Problema 5: El prompt es demasiado largo y el modelo pierde el hilo
Causa: Contexto excesivo que diluye la instrucción.
Solución: Principio de mínimo contexto útil: incluye solo lo que el modelo NECESITA saber para esta tarea específica. Verifica el token count con tiktoken.
Ejercicios
Ejercicio 1: Identificar componentes
Dado este prompt, identifica instrucción, contexto, input y output format:
Eres un asistente que resume artículos. El resumen debe tener máximo 100 palabras.
Solo incluye hechos del artículo, no opiniones.
Artículo: "La inteligencia artificial está transformando la industria..."
Responde con: RESUMEN: [tu resumen aquí]
Ver solución
- Instrucción: "Resume artículos" (implícita en el rol)
- Contexto: Máximo 100 palabras, solo hechos, no opiniones
- Input: El artículo entre comillas
- Output Format: "RESUMEN: [tu resumen aquí]"
Análisis: La instrucción está implícita en el rol (no es explícita como acción). Mejorar: "Resume el siguiente artículo en máximo 100 palabras, incluyendo solo hechos."
Ejercicio 2: Completar componentes faltantes
Este prompt falla frecuentemente. ¿Qué componentes faltan?
Traduce esto al inglés: "El prompt engineering es fundamental."
Ver solución
Componentes presentes:
- Instrucción: ✅ "Traduce... al inglés"
- Input: ✅ El texto entre comillas
Componentes faltantes:
- Contexto: No especifica tono (formal/informal), dialecto (UK/US), si hay términos técnicos que no deben traducirse
- Output Format: ¿Solo la traducción? ¿Con el original? ¿Entre comillas?
Prompt mejorado:
Traduce el siguiente texto al inglés (US). Mantén el tono profesional.
Si hay términos técnicos en español que se usan en inglés (ej: "prompt engineering"), déjalos sin traducir.
Input: "El prompt engineering es fundamental."
Output: Solo la traducción, sin el original ni explicaciones.
Ejercicio 3: Prompt con anatomía completa
Escribe un prompt con los 4 componentes para la siguiente tarea: Extraer el precio, producto y moneda de textos de e-commerce.
Input de ejemplo: "El iPhone 15 Pro está disponible por $1,199 USD"
Ver solución
from openai import OpenAI
import json
client = OpenAI()
INSTRUCCION = "Extrae información de precio de textos de e-commerce."
CONTEXTO = """
Extrae exactamente estos campos:
- producto: nombre del producto
- precio: valor numérico (sin símbolo de moneda)
- moneda: código de 3 letras (USD, EUR, MXN, etc.)
Si algún campo no está presente, usa null.
"""
INPUT = "El iPhone 15 Pro está disponible por $1,199 USD"
OUTPUT_FORMAT = """
JSON válido, sin texto adicional:
{"producto": "...", "precio": 0.0, "moneda": "..."}
"""
prompt = f"""
## Instrucción
{INSTRUCCION}
## Contexto
{CONTEXTO}
## Input
{INPUT}
## Output Format
{OUTPUT_FORMAT}
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0
)
result = json.loads(response.choices[0].message.content)
print(result)
# {"producto": "iPhone 15 Pro", "precio": 1199.0, "moneda": "USD"}
Ejercicio 4: Diagnóstico de prompt fallido
Este prompt produce resultados inconsistentes. Identifica el problema y corrígelo:
Eres un experto en marketing. Analiza este tweet y dime si es bueno o malo para la marca.
Tweet: "Nuestro producto cambió mi vida. #Recomendado"
Ver solución
Problemas identificados:
- Output Format ausente: "dime si es bueno o malo" es vago. ¿Solo una palabra? ¿Con explicación? ¿Con score?
- Contexto insuficiente: ¿Qué criterios definen "bueno para la marca"? ¿Autenticidad? ¿Alcance? ¿Sentimiento?
- Instrucción ambigua: "Analiza" no especifica qué aspectos analizar
Prompt corregido:
Eres un experto en marketing de redes sociales.
Evalúa el siguiente tweet según estos criterios:
- Autenticidad: ¿Parece genuino o pagado?
- Sentimiento: ¿Positivo, neutro o negativo para la marca?
- Riesgo reputacional: ¿Hay algún riesgo?
Tweet: "Nuestro producto cambió mi vida. #Recomendado"
Responde con JSON:
{
"autenticidad": "genuino|pagado|ambiguo",
"sentimiento": "positivo|neutro|negativo",
"riesgo_reputacional": true|false,
"recomendacion": "amplificar|ignorar|responder"
}
Ejercicio 5: Diferencia de orden
Toma este prompt y reorganiza los componentes en el orden recomendado (Instrucción → Contexto → Input → Output):
Input: "La reunión es el martes 15 de julio a las 3pm en la sala B"
Devuelve JSON con los campos: fecha, hora, lugar.
Contexto: Extrae detalles de reuniones de textos en lenguaje natural.
Instrucción: Extrae los detalles de la siguiente reunión.
Ver solución
## Instrucción
Extrae los detalles de la siguiente reunión.
## Contexto
Extrae detalles de reuniones de textos en lenguaje natural.
Si algún campo no está presente, usa null.
Formato de fecha: YYYY-MM-DD. Formato de hora: HH:MM (24h).
## Input
"La reunión es el martes 15 de julio a las 3pm en la sala B"
## Output Format
JSON válido:
{"fecha": "2025-07-15", "hora": "15:00", "lugar": "sala B"}
Mejoras adicionales: Se agregó formato explícito para fecha y hora, y el manejo de campos nulos.
Ejercicio 6 (Avanzado): Prompt con múltiples inputs
Diseña un prompt que pueda procesar múltiples tickets a la vez y devuelva un array de clasificaciones.
Ver solución
from openai import OpenAI
import json
client = OpenAI()
tickets = [
"No puedo acceder a mi cuenta",
"¿Cuándo llega mi pedido?",
"Cobro duplicado en mi factura",
"Hola, necesito ayuda con algo"
]
# Construir la lista de tickets para el prompt
tickets_formatted = "\n".join([f"{i+1}. {t}" for i, t in enumerate(tickets)])
prompt = f"""
## Instrucción
Clasifica cada ticket de soporte en una categoría.
## Contexto
Categorías disponibles: TECNICO, PEDIDO, BILLING, SALUDO, OTRO
Una categoría por ticket. Solo usa las categorías listadas.
## Input
{tickets_formatted}
## Output Format
JSON con array de objetos:
[
{{"id": 1, "categoria": "..."}},
{{"id": 2, "categoria": "..."}}
]
Devuelve exactamente {len(tickets)} objetos.
"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0
)
results = json.loads(response.choices[0].message.content)
for r in results:
print(f"Ticket {r['id']}: {r['categoria']}")
# Output esperado:
# Ticket 1: TECNICO
# Ticket 2: PEDIDO
# Ticket 3: BILLING
# Ticket 4: SALUDO
Resumen
- 4 componentes: Instrucción, Contexto, Input, Output Format
- Instrucción: Qué hacer (explícita, accionable, con verbo claro)
- Contexto: Qué saber, qué restricciones, definiciones del dominio
- Input: Datos variables por llamada, delimitados explícitamente
- Output Format: Estructura de la respuesta (JSON, string, lista); al final del prompt
- Tokens: Impactan costo, latencia, límites. Verificar con
tiktokenantes de producción - Orden recomendado: Instrucción → Contexto → Input → Output Format
- Roles vs anatomía: Los roles (system/user) son la estructura de la API; la anatomía es el contenido
Recursos adicionales
- OpenAI Tokenizer — Herramienta visual para ver cómo se tokeniza texto
- tiktoken (Python) — Librería de OpenAI para contar tokens en código
- Anthropic Token Counting — Cómo contar tokens para Claude
- OpenAI Prompt Engineering Guide — Estrategias recomendadas por OpenAI
- Learn Prompting: Prompt Structure — Guía introductoria de estructura de prompts
- Anthropic Prompt Design — Cómo Claude procesa los prompts