Todos los recursos

El modo de fallo típico de un revisor LLM es la cortesía: encuentra tres bugs reales y los sepulta bajo veinte notas de 'considera extraer una constante'. Este es un system prompt completo y listo para copiar que impone un contrato de severidad para que la señal quede siempre arriba, además de cómo adaptarlo, para qué sirve cada placeholder, las variantes que vale la pena conservar y las cláusulas que, sin que te des cuenta, deciden si confías en lo que te devuelve.

Un system prompt de revisor de código estricto que sí puedes reutilizar

En resumen

  • El prompt obliga a que cada hallazgo caiga en un nivel BLOCKER / MAJOR / MINOR / NIT, con una regla tajante: 'nunca inventes un hallazgo para llenar un nivel'.
  • Cierra con un único veredicto (APRUEBO, APRUEBO CON NITS o PIDO CAMBIOS) así la revisión te dice qué hacer y no es solo un muro de texto.
  • Pásale el diff más el archivo alrededor, no el repo entero: sale barato y deja de marcar código que ni tocaste.
  • Dos placeholders cargan con casi todo el valor: la lista de linters (acaba con los nits de estilo repetidos) y el contexto del stack de tu equipo.
  • Es una primera pasada rápida con un punto ciego conocido, porque solo ve el diff, así que toma sus hallazgos como preguntas para verificar, no como veredictos.

Cuando le sueltas un pull request a un LLM, lo más probable no es que se le escape un bug. Es que te entierre en ruido cortés. El modelo encuentra el null-deref real y luego sigue de largo: que si extraería una constante aquí, que si renombraría una variable allá, que si le metería un comentario, que mejor un ternario. Para cuando llegas al final, el único hallazgo que importaba quedó en la línea cuatro de veinte y ya vas leyendo por encima. Este es un system prompt completo que resuelve eso imponiendo un contrato de severidad: cada hallazgo tiene que declarar cuánto importa, y al modelo se le prohíbe inflar los niveles altos para parecer útil. Te llevas un prompt que puedes pegar hoy, las palancas para ajustarlo a tu stack y una explicación honesta de dónde te miente.

El centro de todo está abajo. La idea es usarlo tal cual de entrada. Córrelo, mira cómo se comporta con un diff real, y solo después adáptalo. Las secciones que siguen explican por qué está cada cláusula, porque las cláusulas son el producto. Borra la que no es y vuelves directo a los veinte nits corteses.

01 · El prompt

Pégalo como system prompt de un subagente de revisión, o como primer mensaje antes del diff en el chat. Reemplaza los placeholders entre corchetes antes de usarlo por primera vez. Están documentados en la sección 03.

You are a senior engineer reviewing a pull request. You are blunt, specific, and
you respect the reader's time. Your job is to find what is wrong, ranked by how
much it matters, and to say nothing else.

## What you are reviewing
You will receive a unified diff, plus enough surrounding code to judge it. Review
ONLY the changed lines and the code they directly affect. Do not review or comment
on code that did not change, except to point out that a change breaks it.

## Severity tiers
Group every finding under exactly one of these headings, in this order. Omit a
heading entirely if it has no findings. NEVER invent or stretch a finding to fill
a tier — an empty tier is the correct and expected outcome for clean code.

- BLOCKER — a correctness, security, or data-loss bug. The change is wrong or
  unsafe to merge as written. Examples: off-by-one, unhandled null/None, swallowed
  error, race condition, SQL injection, secret committed, broken migration,
  resource leak, a check made dead by an early return.
- MAJOR — not a bug yet, but a real risk: missing error handling on a path that
  will be hit, a public API change with no callers updated, a test that asserts
  nothing, a TODO standing in for required logic.
- MINOR — genuine improvement the author should consider: a clearer name, a
  duplicated block worth extracting, a confusing branch, a missing edge-case test.
- NIT — taste. State it once, do not insist.

## Per-finding format
For each finding, output exactly:
- **file:line** — one-line summary
  - What: the precise problem, quoting the offending code.
  - Why: the concrete consequence (what breaks, for whom, when).
  - Fix: the smallest change that resolves it. Show a few lines if it helps.

## Hard rules
- Do NOT comment on anything these tools already enforce: [LINTERS_AND_FORMATTERS].
- Do NOT restate what the code does or praise it. No "looks good", no summaries of
  correct code.
- Do NOT rewrite working code for taste. If it works and the linter passes, it is
  not a BLOCKER or MAJOR.
- If you are unsure a finding is real, say so and put it one tier lower. A guess
  marked as a guess is useful; a guess stated as fact is not.
- Stack context you may assume: [STACK_AND_CONVENTIONS].

## Verdict
End with one line, nothing after it, exactly one of:
- REQUEST CHANGES — there is at least one BLOCKER or MAJOR.
- APPROVE WITH NITS — only MINOR/NIT findings remain.
- APPROVE — nothing worth raising.

Output only the findings (grouped) and the verdict. No preamble, no closing remarks.

Consejo

Córrelo una vez con los placeholders tal cual, como corchetes literales, para ver cómo se comporta sin adaptar; luego rellénalos. El antes y después te muestra exactamente cuánto ruido te estaban quitando de encima la lista de linters y el contexto del stack.

02 · Por qué cada parte carga peso

Este prompt es corto a propósito, pero casi cada línea cumple un trabajo concreto. Saca la que no toca y el modo de fallo vuelve enseguida.

  • "NEVER invent or stretch a finding to fill a tier." Es la frase más importante de todas. Sin ella, el modelo ve una sección BLOCKER vacía como que no fue lo bastante útil y sube un NIT de categoría para parecer productivo. Con ella, un nivel vacío pasa a ser el resultado esperado para código limpio, y la lista de BLOCKER se mantiene confiable.
  • La tríada What / Why / Fix por hallazgo. El "Why" obliga al modelo a justificar la severidad en vez de darla por sentada, y ahí es donde la mayoría de los BLOCKER falsos se caen solos. El "Fix" lo mantiene aterrizado. Un hallazgo sin un arreglo mínimo casi siempre es gusto personal disfrazado.
  • La única línea de veredicto. Una revisión sin veredicto te deja a ti la cuenta final: ¿esto se puede fusionar o no? La línea de cierre lo responde en tres palabras y sale directo de los niveles, así que el modelo no tiene cómo irse por las ramas.
  • "Review ONLY the changed lines." Acota la corrida al diff. Es lo que la mantiene barata y mata el problema de cien hallazgos sobre código que ni tocaste.

La cláusula que la gente borra primero (y luego lamenta)

La regla de "si no estás seguro, baja un nivel" parece opcional. No lo es. Es la diferencia entre un revisor que marca un BLOCKER equivocado con total seguridad, porque no ve el caller que ya garantiza que el valor no es null, y uno que dice "posible null aquí, MAJOR, depende de si los callers garantizan X." El segundo es honesto sobre su punto ciego. Déjala donde está.

03 · Los placeholders, y qué poner en ellos

Hay dos placeholders. Cargan con casi todo el valor de la adaptación, así que rellénalos con cuidado en lugar de dejarlos genéricos.

  1. [LINTERS_AND_FORMATTERS] son las herramientas exactas que tu CI ya corre. Para un repo de TypeScript podría quedar así: ESLint con la config del proyecto, Prettier, tsc en modo strict. Esta sola línea es lo que evita que el modelo "encuentre" punto y coma que faltan, orden de imports y estilo de comillas, todo lo que una máquina ya impone y en lo que una persona nunca debería gastar un comentario de revisión.
  2. [STACK_AND_CONVENTIONS] es el contexto que el modelo necesita para juzgar bien la severidad. Déjalo en pocas líneas: lenguaje y framework, cómo se manejan los errores, cuál es el test runner, cualquier regla de la casa que pase por encima de los defaults. Para un proyecto de Ilustrari podría decir: Next.js + TypeScript, Supabase para los datos, errores que se devuelven como objetos Result tipados en vez de lanzados, Vitest para los tests, nunca registrar secrets.

Importante

Si dejas [LINTERS_AND_FORMATTERS] vacío, el prompt igual funciona, pero vas a recibir un goteo constante de nits de estilo que el modelo levanta creyendo que ayuda. Lista siempre al menos tu formatter. Es el cambio que más te rinde por el esfuerzo.

Un ejemplo armado del par de placeholders, listo para soltarlo:

[LINTERS_AND_FORMATTERS]: ESLint (project flat config), Prettier, tsc --strict.
Do not raise formatting, import order, unused-import, or quote-style issues.

[STACK_AND_CONVENTIONS]: Next.js 15 + TypeScript, React Server Components by
default. Data via Supabase with row-level security; assume RLS is enforced unless
the diff changes a policy. Errors are returned as typed results, not thrown across
boundaries. Secrets come from env, never literals. Tests use Vitest.

04 · Variantes que vale la pena guardar

El prompt base es el default correcto. Unas pocas variantes puntuales se ganan su lugar. Aguanta las ganas de crear más de las que de verdad vas a usar.

Pasada solo de seguridad

Cuando el diff toca auth, manejo de input o cualquier cosa que llegue a la base de datos, cambia las definiciones de los niveles por categorías de seguridad y corre una segunda pasada con esta variante, en vez de sobrecargar al revisor general. Reemplaza el bloque de severidad por: CRITICAL (explotable ya) / HIGH (explotable con un error más) / NOTE (defensa en profundidad), y agrega una línea: Assume all input is hostile. Check authz on every new endpoint, not just authn. Esto combina bien con un gestor de secretos o vault para el lado del manejo de secrets. El revisor marca un secret en el código, y el vault es donde debió haber estado desde el principio.

Candado estricto vs. consultivo

El veredicto del prompt base es consultivo. Lo lees y decides tú. Si conectas el revisor a un paso previo al merge, agrega una línea para que el veredicto sea parseable por máquina: Print the verdict on its own final line prefixed with VERDICT:, e.g. "VERDICT: REQUEST CHANGES". Así un script chiquito puede hacer fallar el paso cuando hay un REQUEST CHANGES. No dejes que el modelo en sí bloquee el merge. Deja que produzca una señal parseable y mantén el candado en código tonto y auditable.

Modo enseñanza

Para un autor junior, agrega: For each BLOCKER and MAJOR, add one sentence on the general principle, so the same class of bug is recognizable next time. Esto cambia brevedad por pedagogía. Apágalo con revisores senior. Sienten que las líneas de principio los tratan con condescendencia, y tienen razón.

05 · Detalles que deciden si confías en él

  • Solo ve el diff. Su punto ciego más grande es el caller que no alcanza a ver. Un BLOCKER de "falta chequear null" puede estar equivocado porque el único caller ya garantiza el valor. Por eso existe la regla de bajar un nivel cuando hay duda, y por eso tratas los hallazgos como preguntas, no como veredictos.
  • Va a rellenar si lo dejas. Quítale la línea de "nunca inventes un hallazgo" por una sola revisión y mira cómo al nivel BLOCKER se le cuela un pasajero. El relleno es sutil: una preocupación que suena real pero no aguanta ni treinta segundos de chequeo.
  • No es una auditoría de seguridad. El prompt base atrapa los bugs de seguridad obvios del diff. No modela tu superficie de amenaza, tus flujos de auth ni tus reglas de retención de datos. Usa la variante de seguridad para los diffs sensibles, y una persona para la arquitectura.
  • Trátalo como código. Cuando editas el prompt, puedes empeorarlo sin darte cuenta. Guarda tres o cuatro diffs rotos a propósito (un off-by-one, un error tragado, un secret filtrado) y corre el prompt contra ellos después de cada edición. Si deja de atrapar un bug que tú mismo plantaste, tu edición lo dañó. Versiona el prompt para poder volver atrás.

Atención

No dejes que este prompt edite código por su cuenta ni apruebe un merge por su cuenta. Un revisor que escribe se vuelve un segundo autor que nadie revisó, y su ceguera de ver solo el diff garantiza que algunas de esas ediciones van a salir mal. Mantenlo de solo lectura y deja a una persona en el botón de merge.

Un buen prompt de revisión no es un modelo más inteligente. Es uno disciplinado. El contrato de severidad, la regla de que un nivel vacío está perfecto y la lista de linters hacen casi todo el trabajo. El modelo siempre fue capaz, solo le faltaba que le dijeran que dejara de ser tan cortés. Pégalo, rellena los dos placeholders, córrelo contra un diff con un bug conocido y solo entonces empieza a afinarlo. La versión en la que confías es la que viste atrapar un bug plantado, no la que se leía bonito.

Puntos clave

  • El trabajo del prompt es disciplina, no inteligencia: un contrato de severidad que rankea los hallazgos y prohíbe inflar los niveles altos.
  • 'Nunca inventes un hallazgo para llenar un nivel' es la línea estructural. Los niveles vacíos son el resultado correcto para código limpio.
  • Rellena los dos placeholders: la lista de linters acaba con los nits de estilo repetidos, y el contexto del stack hace que los juicios de severidad salgan bien.
  • Solo ve el diff, así que trata los hallazgos como preguntas para verificar, y reserva la variante solo de seguridad para los cambios sensibles.
  • Trátalo como código: pruebas de regresión contra fixtures de diffs rotos, versiónalo y nunca lo dejes auto-editar ni fusionar de forma automática.

Preguntas frecuentes

¿Por qué el cuerpo del prompt está en inglés aunque yo trabaje en español?

Deja el set de instrucciones en el idioma en el que el modelo sigue mejor el razonamiento sobre código, que es inglés. Tiende a sostener el contrato de severidad de forma más confiable. Los hallazgos igual te pueden volver en español: agrega una línea, 'Write findings in Spanish, keep the tier names in English.' Así obtienes el texto en español pero con etiquetas BLOCKER/MAJOR estables y parseables.

¿Cuál es la única línea que nunca debo borrar?

'NEVER invent or stretch a finding to fill a tier.' Sin ella, el modelo ve una sección BLOCKER vacía como que no fue lo bastante útil y sube un NIT de categoría para parecer productivo. Con ella, un nivel vacío es el resultado esperado para código limpio, y las listas de severidad alta siguen valiendo la pena. Todo lo demás se puede afinar; esta es estructural.

¿Debo confiar en un BLOCKER que reporta sin verificarlo?

Trata los hallazgos como preguntas para verificar, no como veredictos. Como el prompt solo ve el diff, puede marcar con total seguridad un 'falta chequear null' que en realidad ya garantiza un caller que no alcanza a ver. La regla de 'baja un nivel cuando hay duda' ayuda, pero tú eres quien conoce el código de alrededor. Descartar un hallazgo equivocado te cuesta segundos, un seguro barato a cambio de los reales que sí atrapa.

¿Puedo conectar esto a CI para bloquear merges automáticamente?

Sí, pero reparte la responsabilidad. Agrega la línea con prefijo 'VERDICT:' para que la salida sea parseable por máquina, y deja que un script chiquito y auditable haga fallar el paso cuando hay un REQUEST CHANGES. No dejes que el modelo en sí sea el candado. Mantén la decisión de bloqueo en código tonto que puedas leer y anular. El modelo produce una señal; el dueño de la política es tu pipeline.

¿En qué se diferencia de solo pedir 'revisa mi diff'?

'Revisa mi diff' te da el default de la inundación cortés: bugs reales enterrados bajo cuestiones de gusto. El contrato de aquí obliga a rankear, prohíbe el relleno, veta duplicar el linter y cierra con un único veredicto. La inteligencia es el mismo modelo en ambos casos. Lo que cambia es la disciplina. El producto es la consistencia, no más inteligencia.

¿Cómo sé que mis ediciones al prompt no lo están empeorando?

Trátalo como código y hazle pruebas de regresión. Guarda tres o cuatro diffs rotos a propósito (un off-by-one, un error tragado, un secret filtrado) y corre el prompt contra ellos después de cada edición. Si deja de atrapar un bug que tú mismo plantaste, tu edición lo dañó. Versiona el prompt para poder volver a la última versión en la que confiabas.

¿Prefieres que lo hagamos por ti?

Esto mismo lo construimos para negocios como el tuyo. La primera conversación es gratis y sin compromiso.

Escríbenos por WhatsApp

Escríbenos por WhatsApp

Escanéalo con tu teléfono para escribirnos por WhatsApp.

Escanéalo con tu teléfono para escribirnos por WhatsApp.

¿Estás desde el teléfono y no puedes escanear? Escríbenos a info@ilustrari.com

Primera conversación gratis. Te responde el fundador.

Recursos relacionados

SkillClaude Code

El skill de revisión de código: un revisor que lee el diff, no el repo

Un revisor empaquetado de Claude Code que invocas antes de cada commit en lugar de repegar las mismas instrucciones. Lee el diff en stage, primero marca los bugs reales de corrección, luego lista aparte las limpiezas opcionales y no opina sobre detalles de estilo que el linter ya cubre. Aquí te explico cómo armarlo, conectarlo y evitar que te reescriba la función completa.

1 jun 202611 min de lectura
SkillClaude Code

Skill de auditoría de seguridad: una revisión repetible de tu código antes de que se te complique

Un skill de auditoría de seguridad le da siempre la misma revisión aburrida y estructurada a tu código (secretos filtrados, authz que falta, inyección, cripto débil) y te devuelve una lista priorizada con archivo:línea y una etiqueta de confianza. Aquí te explico cómo armar uno que de verdad ayude en vez de ahogarte en hallazgos de «quizás deberías revisar esto».

31 may 202611 min de lectura
PromptClaude Code

Un prompt para mensajes de commit que escribe el porqué, no el qué

La mayoría de los mensajes de commit solo repiten el diff, que es justo lo que git ya sabe. Este es un prompt para copiar y pegar que toma un diff en staging y lo convierte en un mensaje de Conventional Commit que explica la intención, se niega a mezclar cambios sin relación y es lo bastante mecánico para usarlo en cada commit. Te llevas la plantilla completa, las variables que puedes ajustar, cuatro variantes y las formas en que puede fallar para que estés pendiente.

18 abr 202610 min de lectura