10 · Ingeniería de prompts
Un prompt es una entrada estructurada que ensamblas en código: un rol de sistema que fija el comportamiento, un rol de usuario con la tarea y — cuando hace falta — ejemplos resueltos. Las plantillas y el ensamblado few-shot son el oficio del día a día.
Un prompt no es una frase que tecleas — es una lista de mensajes que construyes programáticamente: un rol de sistema que fija la persona y las reglas, un rol de usuario con la tarea concreta y, opcionalmente, unos ejemplos resueltos. Las plantillas con campos nombrados y un ensamblador few-shot convierten la 'ingeniería de prompts' en código común y comprobable.
Sin esto:
Sin plantillas y roles pegas strings a mano, olvidas separar instrucciones de datos y obtienes respuestas inconsistentes porque el prompt de cada llamada es sutilmente distinto. Con ellos, cada prompt es reproducible y fácil de probar A/B.
Ya sabes que el modelo toma una lista de mensajes y predice el siguiente mensaje. La ingeniería de prompts es el oficio de construir bien esa lista. Tres ideas cargan casi todo el peso:
1. Roles de sistema vs usuario. El mensaje system fija el comportamiento duradero — quién es el modelo, las reglas que debe seguir, el formato de salida. El mensaje user lleva la tarea específica de este turno. Mantenerlos separados te permite cambiar la persona sin tocar la tarea, y probar A/B las instrucciones independientemente de las entradas. Una lista típica es un mensaje system seguido de turnos alternos user/assistant.
2. Zero-shot vs few-shot. Zero-shot significa que solo describes la tarea. Few-shot significa que además incluyes un puñado de ejemplos resueltos (entrada, salida) antes de la entrada real, para que el modelo imite el patrón. El few-shot brilla en tareas donde importa el formato (etiquetas de clasificación, una forma JSON específica, un tono) — los ejemplos enseñan por demostración lo que es difícil decir con palabras.
3. Sé específico, y conviértelo en plantilla. Los prompts vagos dan respuestas vagas. Nombra el formato ("responde en una frase", "devuelve solo la etiqueta"), las restricciones y la audiencia. Luego envuelve el texto en una plantilla de prompt — un string con campos nombrados que rellenas con str.format — para que cada llamada use exactamente las mismas instrucciones aprobadas y solo cambien los datos.
El resto es ingeniería: una plantilla no es más que una función de entradas a una lista de mensajes.
Aquí tienes una plantilla de prompt hecha de un string simple con {campos} nombrados, más un ensamblador few-shot que convierte una lista de pares de ejemplo (entrada, salida) en la lista de mensajes que espera una API de chat. Fíjate en que los ejemplos se vuelven turnos user/assistant reales — para el modelo, tus demostraciones se ven exactamente como una conversación previa que debe continuar.
Python (in browser)
Una plantilla de prompt + ensamblador few-shot: los ejemplos se vuelven turnos user/assistant, así que la nueva entrada es solo el siguiente mensaje de usuario de la conversación.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
El few-shot no es gratis — cada ejemplo gasta tokens (lección 2) y suma latencia. Así que trata el número de "shots" como un mando ajustable: más ejemplos compran más fiabilidad de formato hasta cierto punto, luego las ganancias se aplanan mientras el costo sigue subiendo. El pequeño experimento de abajo usa un clasificador simulado determinista (un sustituto del modelo real) cuya precisión mejora a medida que "ve" más ejemplos, para mostrar la forma de ese compromiso.
Python (in browser)
Shots vs costo (modelo simulado): el primer ejemplo ayuda más; los shots extra siguen costando tokens con ganancias de precisión decrecientes.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
En producción la lista de mensajes ensamblada va directo a la API de chat — tu plantilla y tu lógica few-shot son la parte que realmente posees y pruebas.
Usas prompting few-shot e incluyes tres pares de ejemplo (entrada, salida) antes de la entrada real. En la lista de mensajes, ¿cómo deben aparecer esos ejemplos?
- Un prompt es una lista de mensajes que construyes en código: rol system = comportamiento/reglas/formato duraderos, rol user = la tarea concreta.
- Zero-shot solo describe la tarea; few-shot añade ejemplos resueltos (entrada, salida) como turnos user/assistant previos para enseñar el formato por demostración.
- Envuelve el texto en una plantilla (campos nombrados de str.format) para que las instrucciones queden fijas y aprobadas mientras solo cambian los datos — haciendo los prompts reproducibles y comprobables.
Toda biblioteca de plantillas de prompt (PromptTemplate de LangChain, listas de mensajes de OpenAI, archivos de prompt basados en Jinja) es esta misma idea; el few-shot es la forma más barata de dirigir un modelo sin fine-tuning.
Si lo quitas: Sin plantillas y roles, los prompts derivan de llamada en llamada, las instrucciones se filtran en los datos (invitando a la inyección de prompts) y no puedes reproducir ni probar A/B los resultados.