Un prompt para programar es una especificación. El modelo no ha visto tu proyecto, no sabe qué versión del lenguaje usas y no puede preguntar qué debe pasar cuando la entrada está vacía. Todo lo que el prompt omite lo rellena con la opción más común de sus datos de entrenamiento, y la opción más común muchas veces no es la tuya. Los prompts de abajo le dejan al modelo menos cosas por adivinar.
Escribe la especificación antes del código
El bloque de abajo pide una pequeña función de Python. Cada parte del prompt responde a una pregunta que el modelo respondería por ti. Desactiva las partes de una en una e imagina la respuesta sin ellas: sin las restricciones puedes recibir una biblioteca de terceros, sin el contexto el modelo tiene que adivinar qué cuenta como entrada válida, sin el formato quizá no recibas pruebas.
La función reconoce las tres partes opcionales en orden y rechaza una coincidencia en la que las tres estén vacías.
import re
_PATTERN = re.compile(r"(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?")
def parse_duration(text: str) -> int:
match = _PATTERN.fullmatch(text)
if not match or not any(match.groups()):
raise ValueError(f"invalid duration: {text!r}")
hours, minutes, seconds = (int(g) if g else 0 for g in match.groups())
return hours * 3600 + minutes * 60 + seconds
import pytest
from duration import parse_duration
@pytest.mark.parametrize("text, expected", [
("1h30m", 5400), ("45m", 2700), ("2h", 7200), ("90s", 90),
])
def test_valid(text, expected):
assert parse_duration(text) == expected
@pytest.mark.parametrize("text", ["", "1m1h", "1.5h"])
def test_invalid(text):
with pytest.raises(ValueError):
parse_duration(text)
Cuatro detalles de ese prompt hacen la mayor parte del trabajo:
- Ejemplos con sus respuestas. "1h30m devuelve 5400" es una prueba con la que el modelo puede comprobar su propio código, y elimina cualquier duda sobre la unidad.
- La versión del lenguaje y las bibliotecas permitidas. Sin ellas puedes recibir una biblioteca que no tienes instalada o una sintaxis más nueva que tu intérprete.
- Qué cuenta como inválido y qué debe pasar entonces. Al modelo le resulta fácil omitir el manejo de errores cuando nadie lo pide.
- Pruebas en la respuesta. Convierten "parece correcto" en algo que puedes ejecutar. Si una prueba falla, pegas el fallo de vuelta, que es un seguimiento mucho mejor que "no funciona".
También vale la pena fijarse en la comprobación any(match.groups()): el patrón por sí solo acepta una cadena vacía, porque todas las partes son opcionales. La línea del prompt sobre la cadena vacía es lo que hace que ese caso aparezca en el código y en las pruebas.
Indica la versión, el stack y lo que ya existe
Los modelos se inclinan por el estilo que era más común en sus datos de entrenamiento. En JavaScript eso puede significar require de CommonJS en un proyecto que usa módulos ES; en Python, la API de una biblioteca que ya cambió (Pydantic 1 frente a 2 es un caso común); y en cualquier framework que evoluciona rápido, el patrón de hace dos versiones mayores. Una línea suele arreglarlo: "Node 22, módulos ES, sin TypeScript" o "React 19, componentes de función, CSS modules sin más".
Cuando añades algo a un proyecto existente, el modelo necesita ver las partes que tocará el código nuevo. Pega la firma de la función a la que debe llamar, la forma de los datos que recibirá y un archivo existente que muestre tus convenciones. "Usa el helper db.query(sql, params) del archivo de abajo" da código que encaja; sin eso puedes recibir una conexión a la base de datos escrita desde cero. Deja fuera los archivos que no tienen nada que ver con el cambio, porque cada línea sin relación es algo que el modelo puede intentar reutilizar.
Pide un paso pequeño a la vez
El fallo más común en el "vibe coding", crear una app describiéndosela a una IA, es pedir la app entera de una vez. El modelo tiene que elegir un framework, una base de datos, una estructura de carpetas y una docena de funciones en una sola respuesta, y una sola respuesta rara vez contiene código que funcione para todo eso, así que a menudo lo que llega es un esquema. Compara las dos pestañas.
Aquí tienes una app de tareas full stack con React, Node.js con Express y MongoDB.
Estructura del proyecto
todo-app/
client/ (front end en React)
server/ (API en Express, autenticación, recordatorios)
server/index.js
const express = require("express");
const mongoose = require("mongoose");
const app = express();
app.use(express.json());
// ... auth routes, todo routes and the reminder scheduler go here
Para la autenticación puedes añadir JWT con jsonwebtoken, y para los recordatorios un programador de tareas como node-cron. Dime si quieres que complete alguna de estas partes.
La primera respuesta no está mal, pero es un esqueleto: eligió tres tecnologías por ti y dejó el trabajo real como comentarios. La segunda es lo bastante corta para leerla, funciona en cuanto abres el archivo y te da una base que funciona para el paso 2 ("ahora guarda la lista en localStorage para que sobreviva a una recarga"). Cada paso es lo bastante pequeño para que, cuando algo se rompa, sepas qué cambio lo rompió.
Esto es encadenamiento de prompts hecho a mano: la salida de una petición se convierte en el punto de partida de la siguiente. Pega la versión actual del archivo en cada paso nuevo, para que el modelo edite el código que tienes de verdad y no el que recuerda haber escrito.
Pide un plan antes de un cambio grande
Para cualquier cosa más grande que una función, pide primero el plan y después el código: "Enumera los archivos que cambiarías y qué hace cada cambio. No escribas código todavía". Un plan se lee rápido y se corrige rápido. Si propone una dependencia nueva que no quieres o se olvida de un archivo que sabes que está implicado, lo arreglas con una frase en lugar de descubrirlo entre trescientas líneas de código.
Revisa lo que recibes
El código generado falla de unas pocas formas previsibles, y cada una tiene un hábito de prompting que la detecta:
- API inventadas. Un modelo puede llamar a una función o importar un paquete que no existe, porque el nombre suena verosímil. Busca las importaciones que no conozcas antes de instalarlas; alucinaciones de la IA explica por qué pasa.
- Casos límite silenciosos. Código que funciona en el camino feliz y se rompe con una lista vacía. Enumerar los casos límite en el prompt y pedir pruebas es la solución más barata.
- Cambios discretos. Cuando pides un arreglo en un archivo largo, el modelo también puede renombrar cosas o reorganizar código que no mencionaste. Añade "cambia solo lo necesario y enumera cada cambio que hiciste".
Cuando el código se ejecuta pero se comporta mal, pasa a un prompt de depuración: prompts para depurar explica qué pegar. Antes de fusionar algo importante, una segunda pasada con un prompt de revisión de código puede detectar problemas que el prompt de escritura no pensó en preguntar.
Preguntas frecuentes
¿Cuál es el mejor prompt para programar con ChatGPT o Claude?
No hay un prompt mágico. Los prompts que funcionan se leen como una especificación breve: el lenguaje y la versión, qué recibe y qué devuelve el código, dos o tres entradas de ejemplo con sus salidas, los casos límite y lo que el código no debe usar. Terminar con "escribe también pruebas para estos casos" te da una forma de comprobar la respuesta en lugar de fiarte de ella.
¿Qué son los prompts de vibe coding?
El "vibe coding" es crear software sobre todo describiéndole a una IA lo que quieres y aceptando el código que escribe, a menudo sin leerlo con detalle. Los prompts que mantienen en pie un proyecto de vibe coding son pequeños: una función por petición, una descripción clara de lo que ya existe y la petición de ejecutar o probar el resultado antes de seguir. Las peticiones grandes de todo a la vez son donde estos proyectos suelen romperse.
¿Debo decirle a la IA qué versión del lenguaje usar?
Sí. Los lenguajes y las bibliotecas cambian entre versiones, y si no, el modelo escribirá con el estilo más común en sus datos de entrenamiento, que puede ser más antiguo que tu entorno. Indicar la versión ("Python 3.12", "React 19 con componentes de función", "Node 22, módulos ES") evita respuestas basadas en API que no tienes.
¿Puedo fiarme del código escrito por IA?
Trátalo como el código de un colega nuevo: probablemente se acerca, a veces está mal de formas que parecen correctas. Ejecútalo, pruébalo con los casos límite que te importan y lee cualquier parte que toque dinero, seguridad o datos de usuarios. Los modelos también pueden inventar funciones o paquetes que no existen, así que revisa las importaciones que no conozcas antes de instalar nada.
¿Por qué el código generado por IA se rompe cuando mi proyecto crece?
El modelo solo ve lo que está en la conversación. A medida que un proyecto crece, deja de ver los archivos que no se le muestran y rellena los huecos con suposiciones sobre nombres, estructura y decisiones anteriores. Pega los archivos relevantes, indica las convenciones que sigue el proyecto y limita cada petición a un solo cambio.