Saltar al contenido
Lección 5 de 22

Pensar en Prompts

21 min read

Por Qué Prompting ES LA Habilidad Clave

Si el vibe coding es la nueva forma de construir software, entonces el prompting es la nueva forma de escribirlo. La calidad de tu prompt determina directamente la calidad de tu resultado. No hay forma de evitar esto — un prompt vago produce código vago, y un prompt preciso produce código preciso.

Piénsalo de esta manera: cuando contratas a alguien para remodelar tu cocina, las instrucciones que le das importan. "Que quede bonita" produce algo muy diferente a "Instala gabinetes blancos tipo shaker, encimeras de cuarzo y un fregadero estilo farmhouse con grifería de níquel cepillado." El contratista puede ser increíblemente hábil, pero sin una dirección clara, está adivinando lo que quieres.

Las herramientas de codificación con IA funcionan de la misma manera. Claude Code, Cursor y cualquier otro asistente de IA son extraordinariamente capaces — pero necesitan que te comuniques con claridad. La herramienta no es el cuello de botella. Tú lo eres.

Esto puede sonar duro, pero en realidad es liberador. Significa que puedes mejorar dramáticamente tus resultados sin aprender un solo concepto de programación. Solo necesitas mejorar en describir lo que quieres.

El prompting es la nueva "mecanografía." En los años 90, la velocidad de escritura era una habilidad laboral legítima. La gente tomaba cursos para mejorar sus palabras por minuto. Hoy, nadie pone mecanografía en su currículum — se da por sentado. El prompting sigue la misma trayectoria. Ahora mismo es un diferenciador. En cinco años será una expectativa básica. Las personas que lo dominen ahora tendrán una ventaja significativa.

La Jerarquía de Calidad de Prompts

No todos los prompts son iguales. Veamos la misma tarea — agregar un formulario de contacto a un sitio web — en cinco niveles de calidad diferentes. Observa cómo el resultado mejora a medida que el prompt se vuelve más específico.

Nivel 1: Vago

Add a contact form

Esto le dice casi nada a la IA. ¿Qué tipo de formulario? ¿Dónde va? ¿Qué campos necesita? ¿A dónde deben ir los envíos? La IA adivinará en cada decisión, y sus suposiciones probablemente no coincidirán con lo que tienes en mente. Pasarás más tiempo corrigiendo el resultado que el que ahorraste siendo breve.

Nivel 2: Básico

Add a contact form to the homepage with name, email, and message fields

Mejor. Ahora la IA sabe dónde va el formulario y qué campos incluir. Pero todavía hay muchas preguntas sin responder. ¿Qué pasa cuando alguien envía el formulario? ¿Hay validación? ¿Cómo se ve?

Nivel 3: Bueno

Add a contact form to the homepage with name, email, and message fields.
Use a server action to handle submission and send the data to my email.
Show a success message after submission.

Ahora estamos avanzando. La IA conoce los campos, el mecanismo de envío y el flujo esperado del usuario. Esto producirá un formulario funcional en la mayoría de los casos.

Nivel 4: Muy Bueno

Add a contact form section to the homepage, below the testimonials section.
Fields: name (required), email (required, validated), message (required, textarea).
Use a Next.js server action in app/actions/contact.ts to handle submission.
Validate all fields server-side. Send the form data to my email using Resend.
Show a loading spinner on the submit button during submission.
On success, show a green toast notification "Message sent! We'll reply within 24 hours."
On error, show a red toast notification with the error message.
Style it to match the existing sections — use the same padding, max-width, and font styles.

Este es un prompt que producirá código listo para producción al primer intento. La IA conoce la ubicación, los campos con reglas de validación, el stack tecnológico, el manejo de errores y las expectativas de estilo.

Nivel 5: Excelente

Add a contact form section to the homepage (app/page.tsx), positioned between
the testimonials and footer sections.

## Form Fields
- Name: text input, required, min 2 characters
- Email: email input, required, validated with a proper email regex
- Message: textarea, required, min 10 characters, max 1000 characters
- Show character count below the message field

## Submission
- Create a server action in app/actions/contact.ts
- Validate all fields server-side (never trust client-side only)
- Use Resend (already installed) to send to contact@mysite.com
- Rate limit: max 3 submissions per IP per hour using the existing
  rate limiter in lib/rate-limit.ts

## UX
- Disable the submit button and show a spinner during submission
- On success: green toast "Message sent! We'll reply within 24 hours."
  and reset the form
- On error: red toast with the error message, keep the form data intact
- Add client-side validation that shows inline errors below each field
  as the user types (after first blur)

## Style
- Match the existing section pattern: py-24 px-6, max-w-3xl mx-auto
- Use the existing form input styles from the newsletter signup component
- The submit button should use the primary CTA style (bg-blue-600)

A este nivel, estás pensando como un product owner. Cada decisión está tomada de antemano, las referencias a patrones existentes son explícitas, los casos límite están cubiertos, y la IA tiene esencialmente cero ambigüedad. El resultado será exactamente lo que quieres, y probablemente no necesitarás ni un solo prompt de seguimiento.

La lección aquí no es que cada prompt necesite ser así de detallado. Los cambios rápidos merecen prompts rápidos. Pero para funcionalidades importantes, el tiempo que inviertes en el prompt se paga por sí solo muchas veces.

El Rol del Contexto

Los humanos somos excelentes rellenando vacíos. Cuando tu compañero de trabajo dice "arregla el botón," sabes cuál botón porque lo estaban discutiendo. La IA no tiene ese contexto compartido a menos que tú se lo proporciones.

El contexto es la información que rodea tu solicitud y ayuda a la IA a tomar las decisiones correctas. Sin él, la IA tiene que adivinar — y adivinar lleva a reescrituras.

Qué Contexto Proporcionar

Tipo de proyecto: "Esto es un dashboard SaaS" vs. "Esto es una landing page de marketing" lleva a decisiones de diseño completamente diferentes. Un dashboard usa tablas de datos y navegación lateral. Una landing page usa secciones hero y botones de llamada a la acción.

Stack tecnológico: Mencionar tu framework cambia todo. "Agrega autenticación" produce código genérico. "Agrega autenticación usando NextAuth.js con el proveedor de GitHub en un proyecto de Next.js App Router" produce código que realmente puedes usar.

Patrones existentes: "Sigue el mismo patrón que el componente UserProfile" es increíblemente poderoso. Le dice a la IA que mire el código existente y replique su estilo, estructura y convenciones. Así es como mantienes la consistencia en un proyecto.

Expectativas del usuario: "El formulario debe funcionar como el checkout de Stripe — limpio, minimalista, con validación en línea" pinta una imagen que vale más que mil palabras de especificación técnica.

Restricciones: "Estamos usando el tier gratuito de Supabase, así que mantén las consultas a la base de datos eficientes" o "Esto necesita funcionar sin JavaScript por razones de SEO" ayuda a la IA a tomar las decisiones correctas.

Cuanto más contexto proporciones, menos tiene que adivinar la IA. Y cada suposición es una posible discrepancia con lo que realmente querías.

La Técnica de "Describir la Experiencia del Usuario"

Esta es una de las técnicas de prompting más poderosas para vibe coding: en lugar de describir lo que el código debe hacer, describe lo que el usuario ve y hace.

Esto funciona porque la IA es excelente traduciendo experiencias de usuario en implementaciones. Cuando describes la UX, la IA resuelve los detalles técnicos. Cuando describes la implementación, tienes que conocer los detalles técnicos tú mismo.

Ejemplo 1: Autenticación

Prompt enfocado en implementación (más difícil para no-desarrolladores):

Create a middleware that checks for a JWT token in the cookies,
validates it against the JWKS endpoint, and redirects to /login
if the token is expired or invalid. Set up the auth context provider
to wrap the app and expose the user object.

Prompt enfocado en UX (cualquiera puede escribir esto):

When a user visits any page, check if they're logged in.
If they're not logged in, send them to the login page.
The login page has email and password fields, a "Sign In" button,
and a "Forgot password?" link.
After signing in, take them back to the page they originally tried to visit.
Their name should appear in the top-right corner of every page.

Ambos prompts pueden producir autenticación funcional. Pero el segundo es accesible para cualquiera, y en realidad proporciona información más útil sobre el flujo de usuario deseado.

Ejemplo 2: Búsqueda

Enfocado en implementación:

Add a search endpoint that accepts a query parameter, uses full-text
search on the posts table with ts_vector, and returns paginated results
with highlighted matches.

Enfocado en UX:

Add a search bar at the top of the blog page. As the user types,
show a dropdown with matching post titles (debounced, after 300ms).
Clicking a result goes to that post. Pressing Enter shows a full
search results page with the matching text highlighted in yellow.
Show "No results found" with a suggestion to try different keywords
if nothing matches.

Ejemplo 3: Notificaciones

Enfocado en implementación:

Set up a WebSocket connection that listens for notification events,
stores them in a Redux slice, and renders a badge component with
an unread count.

Enfocado en UX:

Add a bell icon in the header that shows a red badge with the number
of unread notifications. Clicking the bell opens a dropdown showing
the 10 most recent notifications with the sender's avatar, the message,
and how long ago it was sent (like "2 hours ago"). Unread ones have
a blue dot. Clicking a notification marks it as read and takes you to
the relevant page. There's a "Mark all as read" link at the bottom.

El patrón es claro: describe las pantallas, las interacciones, la retroalimentación visual y los casos límite — y deja que la IA se encargue de la implementación técnica.

Patrones de Prompts para Tareas Comunes

Aquí tienes patrones de prompts probados en batalla para las tareas que realizarás con más frecuencia. Cada uno muestra la diferencia entre un prompt que causará fricción y uno que producirá resultados limpios.

Agregar una Nueva Funcionalidad

Débil: Add dark mode

Fuerte:

Add a dark mode toggle to the site header, next to the navigation links.
Use a sun/moon icon that switches on click. Store the preference in
localStorage so it persists across visits. Default to the system preference
on first visit. Use CSS variables for the color scheme so all existing
components automatically respect the theme. Add the toggle to the
MobileMenu component as well.

Corregir un Bug

Débil: The form is broken

Fuerte:

The contact form on /contact throws this error when submitted:
"TypeError: Cannot read property 'email' of undefined"
The form was working before I added the phone number field in the last commit.
The error is in app/actions/contact.ts. The form data is probably not being
parsed correctly after adding the new field.

Refactorizar Código

Débil: Clean up this code

Fuerte:

Refactor the user dashboard page (app/dashboard/page.tsx). It's currently
450 lines in a single file. Extract the stats cards into a StatsGrid
component, the activity feed into an ActivityFeed component, and the
chart section into a UsageChart component. Put them in
components/dashboard/. Keep the data fetching in the page component
and pass data as props.

Cambios de Estilo y UI

Débil: Make it look better

Fuerte:

Update the pricing page cards to match this design:
- Three cards in a row on desktop, stacked on mobile
- The middle card (Pro plan) should be slightly larger and have a
  "Most Popular" badge
- Each card has: plan name, price with /month, a list of features
  with checkmark icons, and a CTA button
- Use the existing color palette — primary blue for the Pro card,
  neutral gray for the others
- Add a subtle hover effect: slight scale up and shadow increase

Agregar una Nueva Página

Débil: Add an about page

Fuerte:

Create an About page at app/about/page.tsx with these sections:
1. Hero with headline "About Us" and a short paragraph about our mission
2. Team section with a grid of team member cards (photo, name, role, bio)
   — use placeholder data for 4 team members
3. Values section with 3 columns: Innovation, Transparency, Community
   — each with an icon and short description
4. CTA section at the bottom: "Want to join us?" with a link to /careers
Use the same layout wrapper as the existing pages.
Add the page to the main navigation.

Iniciar un Nuevo Proyecto

Débil: Start a new project

Fuerte:

Create a new Next.js 14 project with App Router, TypeScript, and Tailwind CSS.
Set up the following:
- ESLint and Prettier with the default Next.js config
- A basic layout with header, main, and footer
- A homepage with a hero section placeholder
- Environment variables file (.env.local) with placeholder values for
  DATABASE_URL and NEXT_PUBLIC_SITE_URL
- A .gitignore that covers Node.js, Next.js, and environment files
- Initialize git with an initial commit

Escribir Tests

Débil: Add tests

Fuerte:

Write tests for the auth utilities in lib/auth.ts using Vitest.
Test these scenarios:
- validateEmail returns true for valid emails, false for invalid
- hashPassword produces different hashes for different passwords
- verifyPassword returns true for correct password, false for incorrect
- generateToken creates a valid JWT with the expected payload
- Token expiry: a token created with 1-hour expiry should fail
  validation after that period
Use descriptive test names that explain the expected behavior.

Integración de API

Débil: Add Stripe

Fuerte:

Integrate Stripe for subscription payments:
1. Create a checkout API route at app/api/checkout/route.ts that
   creates a Stripe Checkout Session for the selected plan
2. Create a webhook handler at app/api/webhooks/stripe/route.ts
   that listens for checkout.session.completed and
   customer.subscription.updated events
3. When a subscription is created, update the user's plan field
   in the database
4. Add a "Subscribe" button to the pricing page that calls the
   checkout API and redirects to Stripe
5. Use the STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET from .env.local

Patrones de Prompts Específicos por Framework

Los prompts genéricos producen código genérico. Cuando mencionas tu framework específico y sus convenciones, la IA genera código que realmente encaja en tu proyecto.

Next.js App Router

En lugar de "add a page," di:

Create a server component at app/blog/[slug]/page.tsx that fetches
the blog post by slug using the existing getBlogPost function from
lib/blog.ts. Generate static params using getAllBlogSlugs.
Add metadata generation using generateMetadata for SEO.

Mencionar "server component," "App Router," "generateMetadata," y "generateStaticParams" le dice a la IA exactamente qué patrones de Next.js usar.

Componentes React

En lugar de "make a modal component," di:

Create a reusable Modal component in components/ui/Modal.tsx.
It should use a React portal to render outside the main DOM tree.
Accept children, isOpen, onClose, and title as props.
Close on Escape key and outside click. Trap focus inside the modal
for accessibility. Use Framer Motion for enter/exit animations.

Tailwind CSS

En lugar de "style the card," di:

Style the card component using Tailwind CSS. Use rounded-xl for
border radius, shadow-md with hover:shadow-lg for depth, p-6 for
padding. Add a ring-1 ring-gray-200 border. Make it responsive:
full width on mobile, half width on tablet (md:w-1/2), third width
on desktop (lg:w-1/3). Use the dark: variant for dark mode support.

API Routes

En lugar de "create an API," di:

Create a Next.js Route Handler at app/api/users/route.ts.
Implement GET (list users with pagination) and POST (create user).
Use Zod for request body validation on POST. Return proper HTTP
status codes: 200 for success, 400 for validation errors, 401 for
unauthorized, 500 for server errors. Each error response should
include a message field explaining what went wrong.

Refinamiento Iterativo

Aquí va una verdad sobre el vibe coding: tu primer prompt rara vez produce el resultado perfecto. Y eso está completamente bien. La magia está en la iteración.

La iteración no es fracaso. Es el proceso. Incluso los expertos en prompts iteran. La diferencia entre principiantes y expertos no es que los expertos lo aciertan a la primera — es que los expertos iteran más rápido y con más precisión.

Cómo Dar Feedback de Seguimiento

Después de que la IA genera código, lo probarás y notarás cosas que quieres cambiar. La clave para un seguimiento efectivo es la especificidad.

Seguimiento vago: That's not right, try again

Esto no le dice nada a la IA. Podría cambiar algo al azar, o podría empezar desde cero y perder las partes que estaban funcionando.

Seguimiento específico:

The form layout looks good, but two things need fixing:
1. The submit button should be full width on mobile but auto-width on desktop
2. The success message is showing below the form — it should replace
   the form entirely so the user doesn't see the empty fields

El Arte del "Casi, Pero..."

La mayoría de los seguimientos caen en la categoría de "casi, pero." El código está 80% correcto y necesitas guiarlo al 100%. Esta es la fórmula:

[Lo que funciona] + [Lo que no funciona] + [Lo que quiero en su lugar]

Ejemplos:

The animation is smooth but it starts too abruptly. Add a 200ms delay
before the fade-in starts so the page has time to load.
The data table is displaying correctly, but the columns are too wide
on mobile. Make the email column hidden on screens smaller than 768px
and truncate the name column to 20 characters with an ellipsis.
The API route is working, but it returns all fields including the
password hash. Add a select statement to only return id, name, email,
and createdAt.

Cada uno de estos le dice a la IA exactamente dónde mirar y qué cambiar. Sin necesidad de adivinar.

Anti-Patrones que Pierden Tiempo

Ciertos hábitos de prompting llevan consistentemente a malos resultados. Reconocer estos anti-patrones te ahorrará horas de frustración.

1. Ser Demasiado Vago

"Make it better" o "fix the styling" no le da dirección a la IA. Siempre especifica qué significa "mejor" para ti.

2. Dar Requisitos Contradictorios

"Haz el diseño minimalista y limpio, pero también agrega animaciones, degradados, sombras, íconos para cada elemento y un fondo de partículas." La IA intentará satisfacer todo y el resultado será un desastre.

3. Cambiar Requisitos a Mitad del Prompt

Empezar con "build a simple contact form" y a mitad del mismo prompt agregar "actually, make it a multi-step wizard with file uploads and CRM integration." Sepáralos en prompts secuenciales e independientes.

4. Pedir Demasiadas Cosas a la Vez

"Add authentication, a dashboard, a billing system, and an admin panel." Cada una de estas es una funcionalidad significativa. Abórdalas una a la vez para poder probar y validar cada una antes de continuar.

5. No Proporcionar Mensajes de Error

"It's broken" no es accionable. Siempre pega el mensaje de error real, la URL donde ocurre y los pasos para reproducirlo.

6. Asumir que la IA Recuerda Todo

En una conversación larga, la atención de la IA a los mensajes anteriores se desvanece. Si estás haciendo referencia a una decisión de hace 30 mensajes, vuelve a enunciarla.

7. Sobre-Especificar Detalles de Implementación

Si no conoces los detalles técnicos, no adivines. "Use a useReducer with a dispatch pattern for state management" podría ser incorrecto para tu caso de uso. Describe el comportamiento y deja que la IA elija la implementación.

8. Ignorar Lo Que Ya Existe

"Create a button component" cuando ya tienes uno lleva a código duplicado. Siempre menciona: "Use the existing Button component from components/ui/Button" o "Check if a similar component already exists before creating a new one."

9. Escribir Prompts en un Bloque de Texto

Estructura tus prompts con saltos de línea, encabezados, viñetas y listas numeradas. La IA procesa la entrada estructurada mucho mejor que los párrafos.

10. No Verificar el Resultado Antes de Continuar

Si el primer cambio introdujo un bug y sigues construyendo encima, crearás una cadena de problemas difícil de desenredar. Prueba después de cada cambio significativo.

Ejercicios: Practica Tus Prompts

La mejor manera de mejorar tu prompting es practicar. Aquí tienes tres escenarios. Intenta escribir un prompt para cada uno antes de ver la respuesta sugerida.

Escenario 1: Página de Producto E-Commerce

Estás construyendo una tienda en línea. Necesitas una página de detalle de producto que muestre una imagen del producto, título, precio, descripción, selector de talla y un botón "Add to Cart". La tienda usa Next.js con Tailwind CSS.

Pausa y escribe tu prompt antes de leer la sugerencia.

Prompt sugerido:

Create a product detail page at app/products/[id]/page.tsx.

The page should display:
- A large product image on the left (or top on mobile)
- On the right side: product title (h1), price in bold, a short
  description paragraph, a size selector dropdown (S, M, L, XL),
  quantity selector (1-10), and an "Add to Cart" button
- Below the main section: a tabbed area with "Description,"
  "Reviews," and "Shipping" tabs

Fetch the product data using the getProduct(id) function from lib/products.ts.
Use Next.js generateMetadata for the page title and description.
The "Add to Cart" button should call the addToCart server action
and show a toast confirmation.
Make the layout responsive: side-by-side on desktop (lg:), stacked on mobile.
Style using Tailwind — clean, modern, lots of white space.

Escenario 2: Dashboard de Usuario

Necesitas un dashboard que muestre la vista general de la cuenta del usuario: actividad reciente, estado de suscripción y estadísticas de uso.

Pausa y escribe tu prompt antes de leer la sugerencia.

Prompt sugerido:

Create a user dashboard at app/dashboard/page.tsx (protected route,
redirect to /login if not authenticated).

Layout: sidebar navigation on the left with links to Dashboard,
Settings, and Billing. Main content area on the right.

Dashboard content:
1. Welcome message with the user's first name and today's date
2. Stats row: 4 cards showing Total Projects, API Calls This Month,
   Storage Used, and Current Plan — fetch from getUserStats()
3. Recent Activity: a list of the last 10 actions (icon, description,
   timestamp in relative format like "2 hours ago")
4. Quick Actions: buttons for "New Project," "View Docs," "Upgrade Plan"

On mobile, the sidebar becomes a bottom navigation bar.
Use the existing auth context to get the current user.

Escenario 3: Blog con Búsqueda

Necesitas agregar una función de búsqueda a un blog existente que permita a los usuarios encontrar posts por título y contenido.

Pausa y escribe tu prompt antes de leer la sugerencia.

Prompt sugerido:

Add search functionality to the existing blog at app/blog/page.tsx.

Search bar:
- Place it at the top of the blog page, above the post grid
- As the user types, filter the displayed posts in real time (client-side)
- Debounce the input by 300ms to avoid excessive filtering
- Show the number of results: "Showing 5 of 24 posts"
- If no results, show "No posts found for '[query]'" with a
  "Clear search" button

Search should match against post title, description, and tags.
Highlight the matching text in the results using a yellow background.
Add the search query to the URL as a ?q= parameter so the search
is shareable and persists on refresh.
Keep the existing blog layout and card design unchanged.

Observa cómo cada prompt sugerido describe la experiencia del usuario, especifica la ubicación en el proyecto, menciona patrones y funciones existentes, y maneja los casos límite. Ese es el estándar al que apuntas.

Lo Que Sigue

Ahora tienes un marco para escribir prompts que producen resultados excelentes. Pero escribir grandes prompts para cada solicitud individual es solo parte de la ecuación. ¿Y si pudieras configurar instrucciones persistentes que se apliquen automáticamente a cada interacción?

En la próxima lección, profundizaremos en CLAUDE.md — el archivo de configuración que le da a tu asistente de IA contexto permanente sobre tu proyecto. Es como escribir el documento de onboarding para un nuevo desarrollador que trabajará en tu proyecto todos los días. Si lo configuras bien, cada prompt que escribas se vuelve automáticamente mejor.