Cómo automatizar tareas repetitivas de desarrollo con IA
Hay una categoría de trabajo en programación que casi nadie disfruta y casi todo el mundo pospone: tests que hay que escribir para código que ya funciona, documentación que se queda desactualizada, renombrados que tocan veinte archivos. Es precisamente ahí donde un asistente de IA aporta más valor por tiempo invertido, porque son tareas mecánicas, verificables y de bajo riesgo si algo sale mal. Esta guía recorre los casos de uso concretos, con ejemplos de cómo plantear cada uno.
Generación de tests para código existente
Es el caso de uso con mejor relación entre esfuerzo y resultado, porque los tests son autoverificables: o pasan o no pasan, y eso da una forma directa de comprobar el resultado sin depender solo de leerlo.
Cómo plantearlo:
Aquí tiene la función
calcular_descuento. Escribe tests con pytest que cubran: el caso normal, cantidad cero, un porcentaje de descuento mayor que el precio, y un valor negativo. Ejecuta los tests después de escribirlos.
Lo importante aquí no es solo pedir tests, sino revisarlos con el mismo cuidado que revisarías el código de producción: un test que no comprueba nada útil (assert True, o que compara un valor con el mismo cálculo que hace la función) pasa igual y no aporta ninguna protección real. El valor está en que los casos cubiertos sean los que de verdad importan para esa función.
Documentación que se mantiene sincronizada con el código
Escribir un README que explique cómo se instala y ejecuta un proyecto, o dejar por escrito los pasos de un proceso (un despliegue, una migración) es trabajo que aporta valor real al equipo y que, sin embargo, casi nunca es lo primero que se prioriza.
Cómo plantearlo:
Lee el código de este módulo y escribe una sección de README que explique qué hace, cómo se configura (qué variables de entorno necesita) y un ejemplo de uso básico.
Es especialmente útil cuando hay que mantener la documentación en varios idiomas, o cuando el código ha cambiado y la documentación existente ha quedado desactualizada: pedir que se regenere a partir del código real, en lugar de editar a mano un documento que ya no refleja el comportamiento actual.
Refactors mecánicos y renombrados
Cambiar el nombre de un concepto en todo un proyecto, migrar llamadas de una API antigua a una nueva, o adaptar un patrón que ya existe en un sitio a varios sitios más. Es trabajo tedioso, propenso a erratas por despiste humano, y con una propiedad muy útil: sabes exactamente qué resultado esperas, así que es fácil de verificar después.
Cómo plantearlo:
Renombra la función
getUserafetchUsuarioen todo el proyecto, incluidos los imports y las llamadas. No cambies el comportamiento de la función, solo el nombre.
Para este tipo de tarea, delimitar explícitamente el alcance (“solo el nombre, no el comportamiento”) evita que el cambio se convierta en una refactorización más amplia de lo pedido, que sería más difícil de revisar.
Changelogs y notas de versión a partir de commits
Redactar qué ha cambiado entre una versión y la siguiente, en un lenguaje claro para quien no ha visto el código, es una tarea de traducción que un asistente puede hacer razonablemente bien a partir del historial de Git.
Cómo plantearlo:
Aquí está el
git logentre las etiquetas v1.2.0 y v1.3.0. Genera una entrada de changelog agrupada en “Nuevas funcionalidades”, “Correcciones” y “Cambios internos”, en un lenguaje dirigido a usuarios del producto, no a desarrolladores.
Conviene revisar el resultado contra los commits reales: un mensaje de commit ambiguo o mal escrito puede llevar a una descripción del cambio que no refleja bien lo que ocurrió realmente.
Boilerplate y configuración inicial
Un Dockerfile, un workflow de CI, la estructura inicial de un módulo que sigue un patrón ya usado en el proyecto. Son piezas donde existe una forma bastante estándar de resolverlas y el valor no está en la originalidad, sino en tenerlas listas rápido y bien hechas.
Cómo plantearlo:
Necesito un workflow de GitHub Actions que instale dependencias con pnpm, ejecute los tests y, solo en la rama main, despliegue con el script
scripts/deploy.shque ya existe en el repo.
Aquí es especialmente útil dar contexto del proyecto real (el gestor de paquetes concreto, si ya existe un script de despliegue) para que el resultado no necesite adaptarse después — la plantilla genérica de una guía casi nunca encaja exactamente con las particularidades de un proyecto real.
Traducir o adaptar código entre lenguajes o librerías equivalentes
Migrar una función de una librería a otra con una API similar, o portar un fragmento de lógica de un lenguaje a otro, es un trabajo mecánico de traducción una vez que entiendes bien qué hace el original.
Cómo plantearlo:
Esta función está escrita con la librería antigua de peticiones HTTP del proyecto. Reescríbela usando la nueva librería que ya hemos adoptado, manteniendo exactamente el mismo comportamiento observable (mismos errores, mismos reintentos).
Lo que conviene revisar siempre, en cualquiera de estos casos
Automatizar la generación no elimina la necesidad de revisar — la cambia de sitio. Antes de dar por bueno el resultado de cualquiera de estos casos de uso:
- Que el diff sea del tamaño que puedes revisar completo, con atención, de una vez.
- Que no se hayan colado cambios fuera del alcance pedido (reorganización de imports, “mejoras” no solicitadas).
- Que, si el encargo era ejecutable (tests, un build), se haya ejecutado de verdad y no solo se prometa que funciona.
Dónde no compensa automatizar
No todo lo repetitivo merece delegarse sin más. Si la tarea repetitiva es también la forma en la que estás aprendiendo un concepto —escribir tus primeros tests, entender cómo funciona un patrón por primera vez— automatizarla te da el resultado sin el aprendizaje, que es precisamente lo que buscabas de esa tarea en primer lugar. La automatización tiene más sentido cuando ya dominas la tarea y el valor está en el tiempo que ahorra, no cuando la tarea es la que te está enseñando algo.
Conclusión
El patrón común a todos estos casos de uso es el mismo: son tareas mecánicas, con un resultado esperado bastante claro, y fáciles de verificar una vez hechas. Esa combinación —mecánico, claro, verificable— es la que hace que delegarlas compense de verdad, frente a delegar decisiones de diseño o código que nadie va a poder evaluar después con confianza.