Fecha de publicacion: 2026-03-16
Si llegaste hasta aca, probablemente ya usaste alguna herramienta de IA para programar. Quizas fue Copilot, Cursor, Claude Code o ChatGPT con un "hazme un CRUD en Spring Boot". Y seguramente te paso algo asi: la primera vez funciono de maravilla, pero la segunda vez genero un desastre que tardaste mas en arreglar que en escribirlo tu mismo.
Tranquilo, no eres el unico. La realidad es que codear con IA es una habilidad, no un boton magico. Y como toda habilidad, tiene sus tecnicas, sus patrones y sus trampas.
En este post te voy a contar lo que he aprendido usandolas en mi dia a dia. Voy a usar Claude Code como referencia porque es la herramienta que mas uso, pero los conceptos aplican a cualquier herramienta: Cursor, Copilot, Windsurf, Aider, lo que sea.
Los tres modos: Ask, Agent y Plan
Lo primero que necesitas entender antes de tocar cualquier herramienta es que no hay un solo "modo" de interactuar con la IA. La mayoria de herramientas modernas te ofrecen al menos tres formas de trabajar, y cada una tiene un proposito muy distinto. Elegir el modo correcto es tan importante como escribir un buen prompt.
Ask: pregunta sin tocar nada
El modo Ask es el mas seguro y conservador. La IA solo lee y responde. No edita archivos, no ejecuta comandos, no toca nada de tu proyecto. Es como tener un companero senior sentado al lado que puedes consultarle cualquier cosa.
Usalo cuando:
- Necesitas entender como funciona una parte del codigo que no escribiste
- Quieres que te explique un error o un stack trace
- Estas evaluando opciones antes de decidir como implementar algo
- Quieres una opinion sobre tu enfoque sin que modifique nada
bash
1# Ejemplo en modo Ask:
2> Explicame como funciona el flujo de autenticacion en este proyecto.
3 Cual es la ruta que sigue un request desde que llega hasta que se valida el token?
4
5# La IA va a leer tus archivos, seguir el flujo y darte una explicacion.
6# Pero NO va a cambiar ni una linea de codigo.En Claude Code, activas el modo Ask con
-p o simplemente cambiando al modo en la interfaz. En Cursor, es el chat normal (sin Composer). En Copilot Chat, es el comportamiento por defecto cuando preguntas algo.Ask es tu mejor amigo para onboarding
Si acabas de entrar a un proyecto nuevo, usa Ask para entender la arquitectura antes de cambiar cualquier cosa. Preguntale cosas como "que patron de diseno usa este proyecto?", "donde se manejan los errores?", "como se conecta a la base de datos?". Es como tener un tour guiado del codebase.
Agent: manos a la obra
El modo Agent es el que hace cosas. La IA no solo piensa, sino que lee, escribe, ejecuta y verifica. Es como darle las llaves del carro: va a conducir, pero tu le dices a donde ir.
En este modo, la IA puede:
- Leer y editar multiples archivos de tu proyecto
- Ejecutar comandos en la terminal (
./gradlew build,git commit,./gradlew test) - Crear archivos nuevos
- Correr tests y corregir errores automaticamente
- Instalar dependencias si las necesita
bash
1# Ejemplo en modo Agent:
2> Agrega un endpoint GET /api/users/{id} que retorne un usuario por ID.
3 Sigue el patron de OrderController. Incluye validacion del ID
4 y retorna 404 si no existe.
5
6# La IA va a:
7# 1. Leer OrderController.kt para entender el patron
8# 2. Leer la entity User.kt
9# 3. Crear o editar el UserController.kt
10# 4. Registrar la ruta en el controller con @GetMapping
11# 5. (Opcionalmente) correr tests para verificarEn Claude Code, el modo Agent es el comportamiento por defecto cuando le das una instruccion. En Cursor, es el "Composer" o "Agent mode". En Copilot, es el "Copilot Edits".
Agent requiere supervision
El modo Agent es poderoso, pero no es "fire and forget". Siempre revisa lo que genera antes de aceptar los cambios. Piensalo como un junior muy rapido: hace bien el 80%, pero ese 20% restante necesita tu ojo critico.
Plan: piensa antes de actuar
El modo Plan es el punto intermedio. La IA analiza tu solicitud, explora el codebase y te propone un plan de implementacion detallado antes de ejecutar cualquier cambio. Tu lo revisas, lo ajustas si quieres, y recien entonces le das luz verde.
Es ideal para tareas grandes o complejas donde quieres asegurarte de que la IA entendio bien lo que necesitas antes de que empiece a tocar archivos.
bash
1# Ejemplo en modo Plan:
2> Necesito migrar el sistema de autenticacion de sesiones a JWT.
3 Planifica como lo harias paso a paso.
4
5# La IA te va a responder algo como:
6#
7# Plan de migracion: Sesiones -> JWT
8#
9# Paso 1: Crear el middleware de JWT
10# - Archivo: src/security/JwtAuthFilter.kt
11# - Dependencia: jjwt (ya esta en build.gradle.kts)
12#
13# Paso 2: Crear el servicio de tokens
14# - Archivo: src/service/TokenService.kt
15# - Funciones: generateToken(), verifyToken(), refreshToken()
16#
17# Paso 3: Modificar el login
18# - Archivo: src/controller/AuthController.kt
19# - Cambio: retornar JWT en vez de crear sesion
20#
21# Paso 4: Actualizar los endpoints protegidos
22# - Archivos: todos los controllers que usan @Secured
23# - Cambio: reemplazar filtro de sesion por JwtAuthFilter
24#
25# Paso 5: Tests
26# - Actualizar tests existentes
27# - Agregar tests para el flujo de JWT
28#
29# Quieres que proceda con este plan?En Claude Code puedes activar el modo Plan escribiendo
/plan o pidiendole explicitamente que planifique antes de actuar. En Cursor, puedes pedirle "planifica esto antes de hacer cambios" en el Composer.Cuando usar cada modo
| Situacion | Modo | Por que |
|---|---|---|
| Entender codigo ajeno | Ask | Solo necesitas respuestas, no cambios |
| Agregar un endpoint simple | Agent | Tarea concreta y acotada |
| Refactorizar un modulo completo | Plan | Necesitas alinear el enfoque antes de ejecutar |
| Debuggear un error | Ask → Agent | Primero entiende, luego corrige |
| Migrar de una tecnologia a otra | Plan → Agent | Planifica la estrategia, ejecuta por fases |
| Revisar un PR | Ask | Quieres una opinion, no que modifique el PR |
| Generar tests para codigo existente | Agent | Tarea mecanica y bien definida |
Los modos se combinan
En la practica, vas a ir saltando entre modos. Empiezas en Ask para entender, pasas a Plan para definir la estrategia, y ejecutas con Agent. No te cases con un solo modo. Usa el que tenga mas sentido en cada momento.
La anatomia de una herramienta de IA para codear
Ahora que entiendes los modos, vamos un nivel mas profundo. Entendamos como funcionan estas herramientas por dentro. Casi todas comparten tres conceptos fundamentales:
1. El Agente (Agent)
Un agente es la IA que toma decisiones por ti. No es solo "un modelo que responde preguntas". Un agente puede:
- Leer archivos de tu proyecto
- Ejecutar comandos en tu terminal
- Editar codigo directamente
- Buscar en internet
- Decidir que herramienta usar en cada paso
Imaginate que le dices a Claude Code: "Agrega un endpoint POST /users que valide el email". El agente no solo genera el codigo. Primero lee tu proyecto para entender tu estructura, busca donde estan los otros controladores, revisa que ORM usas, y entonces genera el codigo siguiendo tus patrones.
Agente vs. Autocompletado
No confundas un agente con el autocompletado de Copilot. El autocompletado predice la siguiente linea. Un agente planifica, ejecuta y verifica multiples pasos de forma autonoma. Son dos mundos distintos.
En Claude Code, cuando lanzas una tarea, el agente decide de forma autonoma que archivos leer, que comandos ejecutar y como modificar tu codigo. En Cursor, el "Composer" hace algo similar: analiza tu codebase y propone cambios en multiples archivos.
El loop de un agente
Un agente funciona como un ciclo: observa, piensa, actua, repite. Esto es lo que pasa internamente cuando le das una instruccion:
- Recibe tu instruccion ("agrega validacion de email al endpoint de registro")
- Planifica: decide que archivos necesita leer y que herramientas usar
- Ejecuta: lee archivos, busca patrones, edita codigo
- Evalua: verifica si el resultado tiene sentido (a veces corre tests)
- Itera: si algo fallo, ajusta y vuelve al paso 2
Ese loop es lo que hace a un agente fundamentalmente diferente de un chatbot. Un chatbot te da una respuesta y ya. Un agente sigue trabajando hasta completar la tarea. Si un test falla, lee el error, corrige el codigo y vuelve a correr el test. Solo.
Como crear agentes personalizados
Aqui es donde la cosa se pone interesante. No solo puedes usar el agente "default" de tu herramienta, sino que puedes crear tus propios agentes especializados.
En Claude Code, por ejemplo, puedes definir sub-agentes con diferentes roles. Imagina que tienes un proyecto grande y quieres que un agente se enfoque en explorar el codebase mientras otro se encarga de escribir tests:
markdown
1# Ejemplo: instrucciones para un agente de exploracion (en CLAUDE.md)
2
3Cuando necesites explorar el codebase para entender la arquitectura:
4- Primero lee los archivos de configuracion (build.gradle.kts, application.yml)
5- Luego mapea la estructura de carpetas
6- Identifica los patrones de diseno usados
7- Resume tus hallazgos antes de hacer cambiosEn Cursor, puedes crear agentes especializados usando "Custom Instructions" por proyecto. Le defines un rol, restricciones y un flujo de trabajo. Por ejemplo:
markdown
1# .cursorrules - Agente de migracion de base de datos
2
3Eres un especialista en migraciones de base de datos.
4
5## Tu flujo de trabajo:
61. Lee la migracion anterior mas reciente en src/migrations/
72. Sigue la convencion de naming: YYYYMMDD_HHMMSS_descripcion.sql
83. Siempre incluye un bloque DOWN (rollback)
94. Nunca hagas DROP TABLE sin confirmacion
105. Valida que los tipos de datos son compatibles con PostgreSQL 15La idea clave es esta: un agente sin instrucciones claras es como un desarrollador nuevo sin onboarding. Va a hacer algo, pero probablemente no lo que necesitas. Mientras mas contexto le des de su rol y restricciones, mejor resultado vas a obtener.
Paralelizacion de agentes
Una de las capacidades mas poderosas (y menos conocidas) es la posibilidad de correr multiples agentes en paralelo. Esto es particularmente util cuando tienes tareas independientes que no dependen entre si.
Piensalo asi: si necesitas agregar tests a 5 servicios distintos, no tiene sentido hacerlo uno por uno. Puedes lanzar 5 agentes en paralelo, cada uno trabajando en un servicio diferente.
bash
1# En Claude Code, puedes pedirle que lance sub-agentes en paralelo:
2> Necesito que hagas estas 3 tareas en paralelo:
3 1. Agrega tests unitarios para UserService
4 2. Agrega tests unitarios para OrderService
5 3. Agrega tests unitarios para ProductService
6 Cada servicio es independiente. Usa el mismo patron de tests
7 que ya tenemos en src/test/kotlin/services/PaymentServiceTest.ktEl agente principal actua como un coordinador: divide el trabajo, lanza sub-agentes para cada tarea, y luego consolida los resultados. Esto puede reducir drasticamente el tiempo de tareas repetitivas.
En Cursor, la paralelizacion ocurre de forma mas implicita. Cuando le das una tarea que involucra multiples archivos, el Composer puede procesar varios archivos simultaneamente. Pero puedes guiarlo para que sea mas explicito:
bash
1# En Cursor Composer:
2> Necesito actualizar todos los controladores para usar el nuevo middleware de auth.
3 Los controladores son independientes entre si:
4 - src/controller/UserController.kt
5 - src/controller/OrderController.kt
6 - src/controller/ProductController.kt
7 Aplica el mismo cambio en todos: agregar JwtAuthFilter a la cadena de seguridad para cada ruta.Cuidado con las dependencias
Solo paraleliza tareas que sean realmente independientes. Si el Servicio B depende del Servicio A, no los proceses en paralelo. El agente puede terminar con conflictos o imports rotos. Regla simple: si un archivo necesita leer el resultado de otro agente, va secuencial.
Un patron avanzado es usar la paralelizacion para explorar y ejecutar al mismo tiempo. Por ejemplo:
bash
1# Patron "explorador + ejecutor":
2> Haz dos cosas en paralelo:
3 1. Explora el codebase y hazme un resumen de como funciona
4 el sistema de autenticacion actual (archivos involucrados,
5 flujo del token, donde se valida)
6 2. Mientras tanto, agrega tests para el endpoint GET /api/users
7 que ya existe en UserController.kt
8
9# El agente explorador te da contexto mientras el ejecutor avanza
10# con trabajo que no depende de esa exploracion.La paralelizacion no es exclusiva de herramientas especificas. El concepto es el mismo en todas: identifica tareas independientes, lanzalas al mismo tiempo y combina resultados. Si tu herramienta no soporta sub-agentes nativos, puedes simular el efecto abriendo dos ventanas del chat y trabajando en tareas diferentes en cada una.
2. Las Herramientas (Tools)
Las herramientas son las acciones concretas que el agente puede ejecutar. Piensa en ellas como los brazos y piernas del agente. Sin herramientas, la IA solo puede hablar. Con herramientas, puede hacer cosas.
Ejemplos tipicos de herramientas:
| Herramienta | Que hace | Ejemplo |
|---|---|---|
Read | Lee un archivo | Leer src/controller/UserController.kt |
Edit | Modifica un archivo existente | Agregar una validacion en una funcion |
Bash | Ejecuta un comando en terminal | ./gradlew test |
Grep | Busca texto en el codebase | Encontrar todas las rutas que usan /api/v1 |
Write | Crea un archivo nuevo | Crear un nuevo componente React |
Esto es universal. En Cursor se llaman "tools" tambien. En Copilot Workspace son "actions". El nombre cambia, el concepto es el mismo: darle manos a la IA.
3. Las Skills (Habilidades)
Las skills son flujos predefinidos que encadenan herramientas para resolver tareas comunes. En vez de que el agente improvise cada vez, una skill le dice: "para esta tarea, sigue estos pasos".
Piensalo asi: si las herramientas son los verbos (leer, escribir, ejecutar), las skills son las oraciones completas ("lee el diff, analiza los cambios, genera un mensaje de commit y ejecuta el commit").
Skills integradas: las que vienen de fabrica
Cada herramienta trae skills listas para usar. En Claude Code, se invocan con
/ (slash commands):| Skill | Que hace | Cuando usarla |
|---|---|---|
/commit | Analiza tu diff, genera mensaje de commit y ejecuta el commit | Cuando terminaste un cambio y quieres commitear rapido |
/review-pr | Revisa un PR completo: codigo, tests, posibles bugs | Antes de hacer merge, como un code review automatizado |
/simplify | Revisa el codigo cambiado y busca oportunidades de simplificacion | Despues de un refactor, para asegurarte de no sobrecomplicar |
Veamos
/commit en detalle. Cuando lo ejecutas, internamente pasa esto:- Ejecuta
git statusygit diffpara ver tus cambios - Lee los commits recientes para seguir el estilo de mensajes del repo
- Analiza si es un fix, feat, refactor, docs, etc.
- Genera un mensaje descriptivo enfocado en el "por que", no el "que"
- Ejecuta
git addde los archivos relevantes ygit commit - Verifica que el commit fue exitoso con otro
git status
Todo eso pasa con un solo comando. Sin que tengas que pensar en el formato del mensaje, ni en si te olvidaste de agregar algun archivo al staging.
Skills personalizadas: crea las tuyas
Aqui es donde las skills se vuelven realmente poderosas. Puedes crear tus propias skills adaptadas a tu flujo de trabajo. En Claude Code, una skill custom es basicamente un archivo Markdown con instrucciones que se ejecutan cuando invocas un slash command.
Imagina que en tu equipo siempre siguen el mismo flujo al crear un nuevo endpoint: crear el DTO, el controller, el servicio, el repositorio y los tests. En vez de explicar eso cada vez, creas una skill:
markdown
1# Skill: /new-endpoint (ejemplo conceptual)
2
3## Instrucciones
4Cuando el usuario pida crear un nuevo endpoint, sigue estos pasos:
5
6### 1. Recopilar informacion
7- Pregunta: metodo HTTP, ruta, descripcion de lo que hace
8
9### 2. Crear el DTO de request/response
10- Ubicacion: src/dto/{recurso}/
11- Naming: {Recurso}Request.kt y {Recurso}Response.kt
12- Siempre incluir validaciones con Jakarta Validation (@field:NotBlank, etc.)
13
14### 3. Crear el controller
15- Ubicacion: src/controller/{Recurso}Controller.kt
16- Seguir el patron de OrderController como referencia
17- Incluir decoradores de Swagger/OpenAPI
18
19### 4. Crear el servicio
20- Ubicacion: src/service/{Recurso}Service.kt
21- Inyeccion por constructor, nunca usar @Autowired
22
23### 5. Crear tests
24- Ubicacion: src/test/kotlin/controller/{Recurso}ControllerTest.kt
25- Minimo 3 casos: happy path, validacion fallida, recurso no encontrado
26
27### 6. Verificar
28- Ejecutar los tests con ./gradlew test
29- Verificar que compila sin errores con ./gradlew compileKotlinEsto convierte un flujo de 30 minutos de ida y vuelta con la IA en algo que se ejecuta de forma consistente con un solo comando. Y lo mejor: cualquier miembro del equipo puede usarla sin necesitar saber todos los detalles.
En Cursor, el equivalente son las "Custom Rules" o "Notepads". No son slash commands como tal, pero logran lo mismo: definir un flujo reutilizable que la IA sigue cada vez.
markdown
1# Cursor Notepad: "Nuevo Componente React"
2
3Cuando crees un nuevo componente React en este proyecto:
4
51. Usa TypeScript con interfaces (no types) para las props
62. Ubicalo en src/components/{NombreComponente}/
73. Crea estos archivos:
8 - index.tsx (el componente)
9 - {NombreComponente}.test.tsx (tests con Testing Library)
10 - {NombreComponente}.stories.tsx (Storybook)
114. Usa Tailwind para estilos, nunca CSS modules
125. Exporta el componente como named export, no default
136. Si tiene estado complejo, usa useReducer, no multiples useStateSkills como documentacion viva
Hay algo que no se menciona lo suficiente: las skills son una forma increible de documentar los procesos de tu equipo. Piensalo: en vez de tener un Confluence o un Notion con "Como crear un nuevo microservicio" que nadie lee, tienes una skill que ejecuta ese proceso automaticamente.
La skill se convierte en la fuente de verdad. Si el proceso cambia, actualizas la skill y listo. No hay documento desactualizado en algun wiki olvidado.
Piensa en las skills como recetas
Un chef (el agente) tiene ingredientes (las herramientas) y recetas (las skills). Puede improvisar, pero con una receta probada el resultado es mas consistente. Las mejores skills nacen de tareas que haces una y otra vez. Si lo hiciste 3 veces manualmente, es hora de crear una skill.
La diferencia entre una skill y un prompt largo
Podrias pensar: "puedo simplemente copiar y pegar un prompt largo cada vez". Tecnicamente si, pero hay diferencias importantes:
| Aspecto | Prompt copiado | Skill |
|---|---|---|
| Reutilizable | Tienes que buscarlo y pegarlo | Un comando y listo |
| Versionable | Se pierde en el historial del chat | Vive en el repo, se commitea |
| Compartible | Depende de que alguien lo comparta | Todo el equipo la tiene al clonar el repo |
| Consistente | Cada quien lo modifica a su gusto | Siempre el mismo flujo para todos |
| Mantenible | Si el proceso cambia, hay N copias desactualizadas | Actualizas un archivo y todos tienen la version nueva |
Contexto: el ingrediente secreto
Aqui esta la clave de todo: la calidad de lo que la IA genera depende directamente del contexto que le das. Esto es cierto para cualquier herramienta, sin excepcion.
Hay dos tipos de contexto:
Contexto automatico
Es lo que la herramienta descubre sola. Cuando abres un proyecto en Cursor o Claude Code, la IA puede ver:
- La estructura de archivos y carpetas
- Los archivos que tienes abiertos
- El historial de git
- Las dependencias del proyecto (
build.gradle.kts,pom.xml, etc.)
Contexto que tu le das
Aqui es donde la magia realmente sucede. Puedes darle contexto explicito a la IA de varias formas:
Archivos de instrucciones del proyecto: La mayoria de herramientas soportan un archivo tipo "instrucciones" que se carga automaticamente.
markdown
1# CLAUDE.md (Claude Code) / .cursorrules (Cursor) / .github/copilot-instructions.md (Copilot)
2
3## Stack del proyecto
4- Backend: Spring Boot 3.2 con Kotlin
5- Base de datos: PostgreSQL 15
6- ORM: Exposed (no JPA)
7- Testing: Kotest + Testcontainers
8
9## Convenciones
10- Nombres de endpoints en kebab-case
11- Siempre validar DTOs en el controller con @Valid
12- Los servicios nunca deben retornar entidades, solo DTOs
13- Logs estructurados con logback en formato JSON
14
15## Arquitectura
16- Patron: Hexagonal simplificada
17- Capas: controller -> service -> repository
18- Sin usar @Autowired, solo inyeccion por constructorSin contexto, la IA adivina
Si no le dices que usas Exposed como ORM, la IA va a generar codigo con JPA/Hibernate porque es lo mas comun. Si no le dices que tus endpoints son kebab-case, va a usar camelCase. No esperes que adivine tu setup.
Buenas practicas: lo que realmente funciona
Despues de meses usando estas herramientas en proyectos reales, estas son las practicas que marcan la diferencia:
1. Se especifico con lo que pides
La diferencia entre un buen resultado y un desastre muchas veces esta en como escribes tu prompt. Mira la diferencia:
✖
Prompt vago:
"Agrega autenticacion al proyecto"
✔
Prompt especifico:
"Agrega un filtro de autenticacion JWT en src/security/JwtAuthFilter.kt. Debe validar el token del header Authorization, extraer el userId del payload y setearlo en el SecurityContext. Si el token es invalido, retorna 401. Usa la misma libreria jjwt que ya tenemos en build.gradle.kts."
El segundo prompt le da a la IA todo lo que necesita: donde poner el archivo,que debe hacer, como manejar errores y que dependencia usar.
2. Trabaja de forma incremental
No le pidas que construya toda la feature de una vez. Divide el trabajo en pasos y verifica cada uno antes de seguir.
bash
1# Paso 1: Crea la entity
2"Crea la entity User en src/entity/User.kt con campos: id, email, name, createdAt"
3
4# Verificas que la entity se ve bien...
5
6# Paso 2: Crea el repositorio
7"Crea el repositorio UserRepository en src/repository/ usando la entity User que acabamos de crear"
8
9# Verificas...
10
11# Paso 3: Crea el servicio
12"Crea el servicio UserService con metodos create, findById y findByEmail.
13Usa UserRepository por inyeccion de constructor"
14
15# Y asi sucesivamente...Regla de oro
Si el cambio toca mas de 3 archivos, dividelo en pasos. Tu yo del futuro te lo va a agradecer.
3. Revisa TODO lo que genera
Esto parece obvio, pero hay que decirlo: no hagas merge de codigo que no entiendas. La IA puede generar codigo que compila, pasa los tests y hasta se ve bonito, pero que tiene problemas sutiles:
- SQL injection escondido en un query builder
- Race conditions en codigo asincrono
- Dependencias innecesarias que inflan el bundle
- Patrones que no siguen la arquitectura del equipo
Si la IA genero algo y no entiendes una parte, preguntale. Literalmente dile: "Explicame por que usaste esa estructura ahi". Es la forma mas rapida de aprender y de detectar errores.
4. Usa el archivo de instrucciones del proyecto
Esto es lo mas impactante que puedes hacer y lo que menos gente hace. Cada herramienta tiene su version:
| Herramienta | Archivo de instrucciones |
|---|---|
| Claude Code | CLAUDE.md |
| Cursor | .cursorrules |
| GitHub Copilot | .github/copilot-instructions.md |
| Windsurf | .windsurfrules |
| Aider | .aider.conf.yml |
La idea es la misma en todas: un archivo en la raiz del proyecto que le da contexto permanente a la IA. Commitalo al repo. Todo tu equipo se beneficia.
5. Aprende a decir "no"
A veces la IA propone algo que tecnicamente funciona pero que no es lo que necesitas. No tengas miedo de rechazar su sugerencia y redirigirla. Unos ejemplos:
bash
1# La IA propone crear un archivo nuevo...
2"No, no crees un archivo nuevo. Agrega esa logica al servicio existente en src/service/OrderService.kt"
3
4# La IA usa una libreria que no quieres...
5"No uses java.util.Date, usamos kotlinx-datetime en este proyecto. Revisa el build.gradle.kts"
6
7# La IA sobredisena la solucion...
8"Eso es demasiado complejo. Solo necesito un when expression, no un patron Strategy"6. Pide tests (en serio)
Una de las mejores formas de usar IA es para generar tests. En serio. Los tests son repetitivos, toman tiempo, y la IA los genera bastante bien.
bash
1# Despues de crear tu servicio:
2"Genera tests unitarios para UserService.
3Usa Kotest con el estilo BehaviorSpec.
4Mockea el repositorio con MockK.
5Cubre los casos: crear usuario exitosamente, email duplicado, usuario no encontrado."
6
7# Y para tests de integracion:
8"Genera tests de integracion para el endpoint POST /api/users usando
9@SpringBootTest con WebTestClient y Testcontainers.
10Testea: creacion exitosa (201), email invalido (400), email duplicado (409)"Lo bueno es que si ya escribiste el codigo (o la IA lo genero), tiene todo el contexto para crear tests que realmente validen el comportamiento.
Ejemplo practico: workflow real con Claude Code
Veamos un ejemplo completo de como se ve un flujo real. Quiero agregar un endpoint de busqueda de productos a un proyecto Spring Boot existente.
Paso 1: Le doy contexto de lo que quiero.
bash
1> Necesito un endpoint GET /api/products/search que reciba un query param "q"
2 y busque productos por nombre. Usa el patron que ya tenemos en los otros
3 controllers (mira src/controller/OrderController.kt como referencia).
4 La busqueda debe ser case-insensitive y retornar maximo 20 resultados.El agente va a hacer algo como esto (automaticamente):
- Lee
src/controller/OrderController.ktpara entender el patron - Lee
src/entity/Product.ktpara ver los campos disponibles - Lee
src/config/WebConfig.ktpara ver como se configuran las rutas - Crea o edita
src/controller/ProductController.kt - Crea el
src/service/ProductService.ktysrc/repository/ProductRepository.kt
Paso 2: Reviso lo que genero. Veo que uso
LIKE directamente en el query.bash
1> Cambia la busqueda para usar un indice full-text en vez de LIKE.
2 Ya tenemos configurado tsvector en la tabla products.Paso 3: Le pido tests.
bash
1> Genera tests de integracion para el endpoint de busqueda.
2 Usa el setup que ya tenemos con @Testcontainers y PostgreSQL.
3 Cubre: busqueda con resultados, busqueda sin resultados, query vacio retorna 400,
4 limite de 20 resultados.Paso 4: Corro los tests y verifico.
bash
1> Corre ./gradlew test --tests "*ProductSearch*"Todo este flujo dura minutos, no horas. Pero lo clave es que en cada paso yo estoy verificando y dirigiendo. La IA no esta volando sola.
Errores comunes (que todos cometemos)
1. El "si, si, acepta todo": Aceptar cada cambio sin leerlo. Es como hacer merge sin code review. Tarde o temprano algo explota.
2. Contexto cero: Abrir un proyecto nuevo y decir "hazme un login". Sin saber el stack, las convenciones ni la arquitectura, la IA va a generar codigo generico que probablemente no encaje.
3. El prompt infinito: Escribir un prompt de 500 palabras describiendo absolutamente todo. Mejor divide en pasos. La IA trabaja mejor con instrucciones claras y acotadas.
4. No iterar: Si el primer resultado no es perfecto, no lo deseches. Dile que ajuste. Es una conversacion, no un one-shot.
5. Olvidar que el codigo es tuyo: Si la IA genero un bug que llego a produccion, la responsabilidad es tuya. Tu nombre esta en el commit. Trata el codigo generado con el mismo rigor que el que escribes a mano.
Comparacion rapida de herramientas
Cada herramienta tiene su punto fuerte. Aqui va un resumen:
| Herramienta | Tipo | Mejor para |
|---|---|---|
| Claude Code | CLI agentico | Tareas complejas, refactors grandes, flujo en terminal |
| Cursor | IDE con IA integrada | Edicion multi-archivo, quien prefiere UI visual |
| GitHub Copilot | Extension de IDE | Autocompletado rapido, sugerencias inline |
| Windsurf | IDE con IA | Experiencia tipo Cursor con modelo propio |
| Aider | CLI open-source | Flujo git-first, transparencia total |
No hay herramienta perfecta
Lo mas importante no es cual usas, sino como la usas. Un desarrollador con buenas practicas en cualquier herramienta va a obtener mejores resultados que alguien que use "la mejor" herramienta sin criterio.
Mi checklist personal
Antes de empezar a codear con IA en cualquier proyecto, me aseguro de:
- Tener un archivo de instrucciones (
CLAUDE.md/.cursorrules) con el stack y las convenciones - Hacer commits frecuentes (si algo sale mal, puedo hacer
git checkoutsin drama) - Trabajar en una rama separada para features grandes
- Revisar cada diff antes de aceptarlo
- Pedir tests para cada feature nueva
- Si algo no entiendo, preguntarle a la IA que me explique antes de aceptar
Conclusion
Codear con IA no es vibe coding. No es "acepta todo y reza". Es una colaboracion donde tu eres el senior y la IA es un junior muy rapido que necesita direccion, contexto y revision.
Las herramientas van a seguir mejorando. Los agentes van a ser mas autonomos. Pero el criterio tecnico, la capacidad de revisar codigo y la habilidad de dar instrucciones claras van a ser cada vez mas valiosas, no menos.
Asi que la proxima vez que abras tu herramienta favorita, recuerda: no le pidas que haga magia. Dale contexto, se especifico, revisa lo que genera y trabaja de forma incremental. Eso es lo que separa a quien codea con IA de quien simplemente copia y pega IA.
La IA no reemplaza tu criterio. Lo amplifica.


