CodeGym /Cursos /ChatGPT Apps /System‑prompt y «contrato de rol» de ChatGPT

System‑prompt y «contrato de rol» de ChatGPT App

ChatGPT Apps
Nivel 5 , Lección 0
Disponible

1. System‑prompt como contrato, no como texto bonito

En módulos anteriores miramos a ChatGPT App desde la arquitectura: widget, tools y servidor MCP. En esta lección cambiaremos el foco a con qué palabras explicamos al modelo su rol: qué puede hacer, qué no debe hacer y cómo usar las herramientas. En esencia, diseñaremos el system‑prompt como un contrato entre tú y el modelo.

En un chat normal con ChatGPT quizá estés acostumbrado a prompts del tipo «Imagina que eres un alegre asistente pirata» o «Explícalo todo como si fuera para un niño de cinco años». Todo eso va de persona y estilo. En el contexto de ChatGPT App el término system‑prompt tiene un significado muy distinto.

Aquí el system‑prompt es el primer mensaje oculto al usuario de la función system, que le define al modelo:

  • quién es dentro de tu App;
  • en qué tarea se centra;
  • de qué NO se ocupa;
  • cómo y cuándo debe invocar las herramientas de tu aplicación.

En esencia, es una especificación de comportamiento muy cercana a un contrato formal. Si hay acuerdo, el modelo intenta seguirlo. Si no lo hay, actuará como un ChatGPT «genérico», y toda tu excelente App quedará al margen.

Es importante que para ChatGPT App este system‑prompt:

  • se vincula a la propia aplicación, no a un diálogo concreto;
  • impone límites tanto al uso del widget como a las llamadas a tools;
  • vive mientras viva la sesión de la App (mientras el usuario interactúe con tu aplicación).

Simplificando, el pacto es: tú das al modelo herramientas y le describes su rol: qué tipo de asistente es, qué hace, qué no hace, cómo usa las herramientas y cómo trata los datos del usuario. El modelo, a cambio, intenta comportarse exactamente así.

2. Dónde vive el system‑prompt en la arquitectura

Para que no parezca algo mágico, conviene verlo en un esquema.

sequenceDiagram
    participant User as Usuario
    participant ChatGPT as ChatGPT + modelo
    participant App as Tu ChatGPT App
    participant MCP as MCP/Backend

    Note over ChatGPT: Al iniciar la App
al modelo se le pasa el system‑prompt User->>ChatGPT: "Elige un regalo para un amigo por hasta 50 $" ChatGPT->>ChatGPT: Aplica el system‑prompt + descripciones de tools ChatGPT->>App: callTool recommend_gifts(...) App->>MCP: HTTP /tools/recommend_gifts MCP-->>App: Lista de regalos App-->>ChatGPT: Tool result (JSON) ChatGPT-->>User: Texto + referencia a un widget con tarjetas

El system‑prompt llega al modelo en el momento de inicialización de la App, cuando ChatGPT decide «conectar» tu aplicación al diálogo. A partir de ahí, cada decisión de ChatGPT —si llamar o no a un tool, si proponer un widget, qué decir cuando no hay datos— pasa por el prisma de ese contrato.

Desde el punto de vista del código en el Apps SDK, normalmente es solo una cadena que vive cerca de la configuración de la App, por ejemplo:

// app/config/systemPrompt.ts
export const giftGeniusSystemPrompt = `
Eres GiftGenius, un asistente para elegir regalos...
`;

Luego esa cadena se envía donde tu aplicación se conecta con ChatGPT. El «andamiaje» técnico puede variar, pero lo importante es: el system‑prompt es un artefacto de código, igual que el schema de una herramienta o un componente de React, y debe diseñarse y almacenarse con el mismo cuidado.

Ahora que está claro dónde vive el system‑prompt en la arquitectura y cómo llega al modelo, lo más importante es qué poner en él para que sea un contrato y no solo la descripción de una «persona simpática».

3. Rol de la App y límites de responsabilidad

La primera y principal sección de cualquier system‑prompt decente es: quién eres y de qué te haces cargo.

La diferencia entre «persona» y «contrato de App» es simple: decir «eres un pirata y hablas como marinero» trata del tono; decir «eres una interfaz de nuestro catálogo de regalos, seleccionas regalos y no te metes en otros temas» ya es un contrato.

Para nuestra aplicación didáctica GiftGenius, que selecciona regalos, el núcleo del rol podría verse así:

Rol:
- Eres GiftGenius, asistente de nuestro servicio para la selección de regalos.
- Tu tarea es ayudar al usuario a elegir un regalo adecuado usando únicamente nuestro catálogo.
- No das consejos médicos, jurídicos ni financieros.

Fíjate en los acentos.

Primero, definimos el dominio de forma estrecha: solo selección de regalos dentro de nuestro servicio. Esto evita que el modelo empiece a «explicar física cuántica» en lugar de abrir tu App, y que intente construir por su cuenta flujos de trabajo extraños alrededor de otras aplicaciones.

Segundo, fijamos explícitamente lo que la App no hace. Por ejemplo:

  • no da consejos sobre temas no relacionados con regalos y compras;
  • no inventa regalos que no estén en el catálogo;
  • no toma decisiones por el usuario: solo propone opciones y argumenta.

Tales restricciones negativas suelen ser más importantes que las instrucciones positivas: el modelo ya «sabe hacerlo todo», y en el system‑prompt justamente recortas lo sobrante.

Para entornos más complejos, donde un desarrollador tiene varias Apps (por ejemplo, «selección de regalos» y «seguimiento de envíos»), conviene escribir en el system‑prompt que en esta App solo te ocupas de la selección de regalos, no gestionas pedidos ni logística y no inicias otras aplicaciones. Esto reduce el riesgo de que el modelo empiece a confundirse sobre «de quién es este trabajo».

4. Cuándo invocar la App y cuándo responder por tu cuenta

El siguiente bloque crítico del contrato: las reglas de uso de las herramientas.

Si no se especifican, todo suele caer en uno de dos extremos:

  • el modelo casi nunca invoca tu App porque le resulta más fácil y barato responder «de cabeza»;
  • o, por el contrario, empieza a invocar herramientas por cualquier motivo, incluso para preguntas puramente teóricas.

En el system‑prompt de la App hay que fijar con claridad:

  • en qué casos hay que usar herramientas;
  • en qué casos hay que responder por cuenta propia, sin tools;
  • qué hacer si el usuario pide explícitamente «no abrir la aplicación».

Fragmento de texto para GiftGenius:

Trabajo con herramientas:
- Usa las herramientas de la App cuando necesites obtener datos fácticos del catálogo (lista de regalos, precios, tipos de artículos, disponibilidad de envíos y descuentos).
- Responde tú mismo si la pregunta es teórica y no requiere acceso al catálogo (por ejemplo, "qué regalos se suelen hacer para una mudanza").
- Si el usuario pide explícitamente "no abrir la aplicación" o "responder sin widget", respétalo y no invoques herramientas.

Aquí suceden varias cosas importantes.

Primero, vinculamos la invocación de tools al tipo de solicitud: datos fácticos/de catálogo → herramienta; teoría general → el modelo responde por sí mismo.

Segundo, hablamos explícitamente del respeto a las intenciones del usuario: si alguien escribe «no pongas nada en marcha, solo explícalo», el modelo no debe ignorar esa señal.

Tercero, así gestionamos la frecuencia de uso de la App. Un buen system‑prompt ayuda al modelo a encontrar el equilibrio: la App se usa cuando hace falta, pero no se convierte en un pop‑up molesto que aparece siempre.

Más adelante, en la siguiente lección sobre instrucciones de UX, hablaremos por separado de cómo debe anunciar el modelo el inicio del widget y qué decir tras finalizar el escenario. Aquí nos interesan las reglas de decisión: usar la App o no.

5. Uso seguro de tools y trabajo con datos del usuario

Ahora, sobre seguridad y sentido común.

Las herramientas de tu App pueden ser de distintos tipos:

  • las que trabajan con datos públicos (catálogos de regalos, disponibilidad de productos, condiciones de envío);
  • las que trabajan con datos personales y/o realizan acciones en nombre del usuario (crear un pedido, cargar importes, cambiar ajustes).

En el system‑prompt hay que indicar cómo debe tratar el modelo estas diferencias.

Conjunto típico de reglas:

Seguridad y confidencialidad:
- No realices acciones que requieran el consentimiento del usuario (compra, suscripción, modificación de datos personales) sin confirmación explícita en el chat.
- No envíes a las herramientas más datos de los necesarios para que funcionen (minimización de datos).
- Si la solicitud implica datos sensibles (salud, finanzas, menores), primero aclara si el usuario confirma el envío de esos datos a la aplicación.

Aquí resolvemos varias tareas a la vez.

Primero, protegemos al usuario de actividad inesperada: el modelo no tiene derecho a comprar un regalo o tramitar un pedido por su cuenta si le diste una herramienta para ello. Primero —confirmación por texto, después— invocación de la herramienta.

Segundo, reducimos el riesgo de fuga de datos innecesarios: el modelo tiende a «arrastrar todo lo que ve» a los argumentos de la herramienta; tú pides explícitamente limitarse a los campos mínimamente necesarios.

Tercero, destacamos por separado los dominios sensibles, donde incluso sin una herramienta financiera puede haber riesgos legales/éticos.

Una buena práctica es anotar en la descripción de las herramientas peligrosas (description) que cambian estado o realizan pagos, y duplicarlo en el system‑prompt. Así obtienes una doble barrera: en el contrato y en la descripción del tool concreto.

6. Formato y estilo del system‑prompt: escríbelo como una especificación

Uno de los errores más comunes es escribir el system‑prompt como texto de marketing: «Eres un asistente innovador e increíblemente inteligente que hace del mundo un lugar mejor…». Es bonito, pero al modelo le da igual. Lo que le interesa es:

  • quién soy;
  • qué hacer;
  • qué no hacer;
  • cómo usar las herramientas;
  • cómo tratar los datos y otras Apps.

Por eso conviene tratar el system‑prompt como una especificación:

  • dividir en bloques lógicos: «Rol», «Tareas», «Límites», «Trabajo con herramientas», «Seguridad»;
  • escribir dentro de los bloques frases cortas y unívocas;
  • destacar explícitamente «hacer» y «no hacer» (sí, dentro del propio prompt las listas son totalmente adecuadas).

Un fragmento de prompt estructurado para GiftGenius puede verse así:

Rol:
- Eres GiftGenius, asistente de nuestro servicio para la selección de regalos.

Tareas:
- Ayuda al usuario a elegir regalos según la necesidad, los intereses del destinatario y el presupuesto.
- Explica las ventajas e inconvenientes de cada opción con lenguaje sencillo.

No hagas:
- No inventes regalos que no estén en el catálogo.
- No prometas funciones del servicio que no existan (por ejemplo, envío gratuito si en el catálogo consta que es de pago).

Es útil mantener un estilo neutro y «seco»: no es texto de venta, es un contrato. Cuantas menos ambigüedades, más estable será el comportamiento.

Otra práctica importante: versionar y almacenar el system‑prompt en el repositorio junto con el código. Los prompts también tienen versiones, y sus cambios rompen el comportamiento tanto como cambios en la lógica TypeScript. Mucho mejor ver un diff en la revisión del PR:

- No inventes regalos que no estén en el catálogo.
+ No inventes regalos que no estén en el catálogo, incluso si el usuario pide explícitamente "inventa algo".

que intentar recordar que «retocaste un poco la redacción directamente en la interfaz».

7. Ejemplo completo de system‑prompt para nuestra App didáctica

Juntémoslo todo y escribamos un system‑prompt cuidado para nuestra GiftGenius didáctica. Lo dividiremos en bloques para facilitar su lectura y mantenimiento.

Primero describimos el rol y las tareas:

Rol:
- Eres GiftGenius, asistente de nuestro servicio para la selección de regalos.
- Te comunicas con el usuario de forma educada y profesional, sin jerga ni bromas, salvo que el usuario las use primero.

Tareas:
- Ayuda a seleccionar regalos según los parámetros dados (perfil del destinatario, sus intereses, ocasión, presupuesto).
- Explica con lenguaje claro por qué propones esas opciones en concreto.

Ahora fijamos los límites y restricciones:

Límites de responsabilidad:
- Trabajas solo con nuestro catálogo de regalos y sus metadatos.
- No inventes regalos, promociones ni descuentos que no estén en el catálogo o en la respuesta de las herramientas.
- No des consejos médicos, jurídicos ni financieros.
- No te responsabilices del funcionamiento de otras aplicaciones o sitios; si el usuario pregunta por ello, indica que no puedes ayudar.

Añadimos las reglas de trabajo con herramientas:

Trabajo con herramientas:
- Usa la herramienta `profile_to_segments` cuando haya que convertir una descripción libre del destinatario en segmentos de intereses.
- Usa la herramienta `recommend_gifts` cuando necesites encontrar o filtrar regalos por parámetros del usuario (segmentos, presupuesto, ocasión, locale).
- Usa la herramienta `get_gift` cuando el usuario necesite detalles de un regalo concreto (descripción, tipo, precio, restricciones de envío).
- Antes de invocar herramientas, intenta aclarar parámetros que falten (edad del destinatario, presupuesto, ocasión) si sin ellos el resultado será inútil.
- Si la solicitud es teórica (por ejemplo, "cómo elegir regalos en general para el primer aniversario de boda"), responde tú mismo sin invocar herramientas.

Ahora, el bloque sobre seguridad y acciones en nombre del usuario:

Seguridad:
- No tramites compra, suscripción ni envío de un regalo sin confirmación explícita del usuario en el chat.
- Si una herramienta necesita datos personales (e‑mail del destinatario, dirección de envío, nombre), primero explica al usuario por qué son necesarios y pide confirmación.
- No envíes a las herramientas más datos de los necesarios (por ejemplo, no mandes el mensaje completo si basta con edad, intereses y presupuesto).

Y el tono general/reglas globales:

Reglas generales:
- Si las herramientas devuelven un resultado vacío, dilo con honestidad y propone relajar las condiciones (cambiar presupuesto, tipo de regalo, categoría u ocasión).
- Si el usuario pide "no abrir la aplicación" o "apáñate sin widget", respétalo y responde solo con texto, sin invocar tools.
- Si la solicitud no está relacionada con regalos o compras, responde como ChatGPT básico y no uses las herramientas de GiftGenius.

Como resultado, esta construcción se parece mucho al ejemplo de los materiales adicionales: hay secciones «Rol», «Tareas», «Hacer/no hacer», «Trabajo con herramientas», «Seguridad», «Reglas generales».

En código de Next.js puedes estructurarlo como un módulo aparte:

// app/config/giftGeniusPrompt.ts
export const giftGeniusSystemPrompt = `
Rol:
- Eres GiftGenius, asistente de nuestro servicio para la selección de regalos.
...

Reglas generales:
- Si la solicitud no está relacionada con regalos, responde como ChatGPT básico y no uses las herramientas de GiftGenius.
`;

Y luego usar esta constante en la configuración de la App (el cómo exacto depende de la versión del Apps SDK, pero la idea es la misma: este texto va a la función system al inicializar el diálogo de la App).

8. Contexto dinámico en el system‑prompt

A veces el system‑prompt necesita «mezclarse» un poco con dinámica: fecha actual, locale, tipo de usuario (nuevo/antiguo cliente), estado de la suscripción, etc.

Por ejemplo, si tu catálogo de regalos y precios varían según región, puedes pasar al system‑prompt la región vigente:

export function buildSystemPrompt(locale: string) {
  return `
Rol:
- Eres GiftGenius, asistente para la selección de regalos para la región ${locale}.

Límites:
- Usa solo los regalos y precios disponibles en la región ${locale}.
...
`;
}

El Apps SDK, al inicializar la App, puede proporcionarte _meta["openai/locale"], y con base en ello generarás la variante necesaria del prompt. Trataremos la localización con detalle más adelante, pero ya ahora es útil ver que el system‑prompt no tiene por qué ser siempre estático.

Lo principal es no convertirlo en «espagueti» de condiciones. Si la lógica se vuelve demasiado compleja, es mejor dividir la App o trasladar las condiciones a tools (por ejemplo, para que el servidor MCP elija la fuente de datos según la locale), y dejar en el system‑prompt solo las reglas de alto nivel.

9. Cómo se relaciona el system‑prompt con la descripción de tools y con las instrucciones de UX

Esta lección se centra en el system‑prompt, pero en una App real no existe en el vacío. También están las descripciones de las herramientas (description, inputSchema) y los ejemplos de follow‑ups que establecerás en los siguientes temas. Todo ello forma un sistema unificado de instrucciones.

Gestión de la invocación de tools:

  • el system‑prompt marca la filosofía general: «herramientas solo para datos fácticos», «no inventar regalos», «no comprar sin confirmación»;
  • las descripciones de tools precisan qué hace exactamente recommend_gifts, qué parámetros requiere y cuándo debería llamarse;
  • las frases de follow‑up marcan el estilo del diálogo tras la llamada de la herramienta: cómo decir con honestidad que no se ha encontrado nada, cómo proponer cambiar la solicitud, cómo resumir los resultados.

Si estas tres capas están alineadas, el modelo se comporta de forma predecible:

  • invoca la App cuando realmente hace falta;
  • no alucina regalos/productos fuera de la base;
  • explica con claridad al usuario qué ha pasado (se encontró / no se encontró / hace falta más información).

Si no, obtienes un comportamiento caótico y largas sesiones de «ajuste mágico del prompt», agotadoras para todos.

10. Errores típicos al trabajar con el system‑prompt de ChatGPT App

Error n.º 1: escribir el system‑prompt «por estética», no como contrato.
Muy a menudo los desarrolladores se limitan a frases genéricas del tipo «Ayuda al usuario a resolver sus tareas como puedas» y «Sé amable». Eso no aclara al modelo cuándo invocar la App, dónde están los límites de responsabilidad, si puede inventar datos y qué hacer ante un error de herramienta. Como resultado, la mitad de la lógica se dispersa entre las pilas de código y la cabeza del autor, en lugar de quedar plasmada en un contrato explícito.

Error n.º 2: rol demasiado amplio («ayuda en todo»).
Si en la sección del rol escribes «Eres un asistente que ayuda al usuario en cualquier asunto», el modelo empieza encantado a hacer exactamente eso y no siempre recuerda tu App. La App se convierte en una opción prescindible que casi no se usa, porque el modelo considera que puede apañarse solo. Es mejor acotar el nicho: selección de regalos, trabajo con el catálogo de regalos, ayuda en un dominio concreto.

Error n.º 3: ausencia de reglas sobre cuándo invocar herramientas.
Formulaciones del tipo «usa herramientas cuando sea necesario» son demasiado vagas. El modelo puede ignorar por completo las tools, o invocarlas incluso donde podría responder «de cabeza». Hay que separar con claridad los escenarios: datos fácticos → tool; explicaciones generales → respuesta del propio modelo; rechazo explícito del usuario a usar la App → solo texto.

Error n.º 4: intentar curar alucinaciones con una sola frase «no inventes».
La frase «no alucines» por sí sola ayuda poco. Es importante describir explícitamente qué está prohibido inventar (productos/regalos fuera del catálogo, elementos sin ID, descuentos inexistentes) y qué hacer cuando el resultado está vacío (decir honestamente que no se ha encontrado nada). Sin esto, el modelo seguirá intentando «complacer» y generará opciones ficticias. Hace falta un conjunto completo: prohibición global en el system‑prompt, restricciones en las descripciones de tools y plantillas de respuesta para casos de «no hay nada».

Error n.º 5: ignorar la seguridad y el consentimiento del usuario.
Si en el system‑prompt no se indica que una compra, reserva o cambio de datos personales requiere confirmación explícita, el modelo puede, con «buenas intenciones», invocar la herramienta por su cuenta. Desde el punto de vista de UX, es una catástrofe. Indica siempre que cualquier acción financiera o sobre la cuenta se realiza solo tras consentimiento explícito en el chat.

Error n.º 6: no tener en cuenta la existencia de otras Apps y herramientas.
En un mundo donde una misma cuenta tiene varias Apps y un montón de tools, no se puede asumir que el modelo «adivinará» qué aplicación usar. Si el system‑prompt no fija que esta es concretamente la App para elegir regalos y solo para eso, el modelo puede alternar de forma impredecible entre distintas Apps o intentar usar herramientas fuera de su propósito.

Error n.º 7: modificar el system‑prompt «en caliente» sin versionado ni pruebas.
Es tentador entrar en la configuración, cambiar una línea y creer que «solo ha mejorado». En la práctica, cualquier ajuste del prompt puede romper el comportamiento de otros escenarios. Si no guardas el system‑prompt en el repositorio, no miras los diffs y no ejecutas un conjunto de solicitudes de prueba (golden prompt set — llegaremos a ello en este módulo), cazarás regresiones durante semanas.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION