Base de Conocimiento de Yeda AI

Programación Asistida por IA

Técnicas prácticas para entregar software real con agentes de programación por IA.

English

← Todas las categorías

Tip #001

Los ADR son combustible para agentes de IA

Los Architecture Decision Records le dan a los asistentes de código con IA lo único que tu código no puede: por qué elegiste lo que elegiste. Formato, flujo de trabajo y beneficio.

Tip #002

El detector de alucinaciones de la IA en 5 segundos

El código generado por IA puede llamar a APIs que nunca existieron. Un verificador de tipos en modo de solo comprobación lo detecta en segundos — tsc --noEmit para TypeScript, pyright para Python.

Tip #003

Ejecuta dos agentes de IA a la vez con git worktrees

Dos agentes de IA en una misma carpeta se sobrescriben los archivos. Los git worktrees le dan a cada agente su propio directorio y su propia rama sobre el mismo repositorio — aquí está la configuración.

Tip #101

Revisa primero los tests y divide los diffs grandes

Lee los tests antes que la implementación para entender la intención primero — y mantén los diffs cerca de 100 líneas, dividiendo lo que se acerque a 1,000 por apilado, grupo de archivos o corte vertical.

Tip #102

¿Refactor grande? Escribe un codemod, no ediciones a mano

Cuando un refactor toca cientos de líneas, deja de editar a mano: escribe un codemod, un script sed o una transformación de AST para que una sola regla se aplique en todas partes y el diff siga siendo revisable.

Tip #103

Ese código feo sostiene la estructura

La cerca de Chesterton para refactorizar con IA: ejecuta git blame y responde 3 preguntas antes de dejar que un agente borre código que no entiende.

Tip #104

Los retornos tempranos matan el anidamiento; las constantes con nombre matan los números mágicos

Dos refactorizaciones de treinta segundos que hacen legible el código generado por IA: convierte los ifs anidados en cláusulas de guarda y extrae los números sin explicación a constantes con nombre.

Tip #105

Nunca conviertas una variable de entorno a bool con un cast

bool(\“false\”) es True — un cast directo invierte tu kill switch en silencio. Parsea los booleanos con un vocabulario compartido de true/false para env vars y config.

Tip #106

Un valor de configuración malformado debe registrarse y usar el valor por defecto

Pasa cada ajuste por un único lector tipado que registra el valor inválido y degrada a un valor por defecto documentado — para que un typo sea una línea de log, no una caída.

Tip #107

Result y Wait son deadlocks en espera

Por qué bloquear con .Result o .Wait produce deadlocks en apps web C# bajo carga — y cómo ir async hasta el fondo, con cancellation tokens donde importan.

Tip #109

Tu sitio grita hecho por IA: tres señales que puedes buscar con grep

El look de 'AI slop' se detecta con grep: gradientes morados, todo centrado y un único radio de 16px+ — tres comandos lo encuentran, tres arreglos lo rompen.

Tip #110

outline: none sin un estilo de foco de reemplazo

Una línea de CSS deja fuera a los usuarios de teclado — cómo :focus-visible les devuelve el anillo de foco sin ensuciar la UI del mouse.

Tip #111

El estado del servidor va en una capa de caché, no en el estado global

Los datos que pertenecen al backend no van en tu store global: ponlos en una capa de caché de datos y obtén caching, deduplicación e invalidación gratis.

Tip #112

Las UIs generadas por IA se saltan los estados vacíos — pide cada estado en el prompt

La IA construye el camino feliz de tu UI; tus usuarios viven en el camino triste. Checklist para pedir estados de carga, vacío, error y desborde — siempre.

Tip #113

Nunca lances una goroutine sin dueño

Las goroutines no se recolectan como basura: cada `go` en código Go generado por IA necesita una ruta de cancelación, un dueño del canal y un WaitGroup, o se fuga hasta tumbar el servicio.

Tip #115

Usa ?? para valores por defecto, no ||

Por qué `config.port || 3000` descarta en silencio 0, cadena vacía y false — y cómo el operador nullish coalescing (`??`) solo aplica el fallback con null/undefined.

Tip #116

forEach no espera nada

Por qué un callback async dentro de forEach se adelanta en silencio — y cómo elegir deliberadamente entre for...of + await y Promise.all.

Tip #117

Rechaza el doble bang en Kotlin generado

Por qué cada !! en Kotlin generado por IA es un crash diferido, y cómo los nullables explícitos y los resultados sealed hacen imposible omitir el caso vacío.

Tip #118

Prohíbe GlobalScope.launch en los code reviews

Las corrutinas sin scope filtran trabajo y se tragan la cancelación — convierte GlobalScope.launch en un rechazo automático de review y ata cada corrutina a un dueño.

Tip #121

Ese inocente chequeo de `if exists` es una condición de carrera

Por qué el patrón chequear-y-actuar sobre el filesystem es una carrera TOCTOU, y cómo un solo parámetro — exist_ok=True — elimina el bug y una línea de código a la vez.

Tip #122

sum() transmite en flujo perezoso, sum([]) construye primero

Quita los corchetes dentro de sum() y un pico de memoria de un millón de elementos se convierte en un flujo perezoso — mismo resultado, un carácter menos.

Tip #123

¿Dos ifs en una comprensión? Dale un nombre de función

Cuando a una list comprehension le crece una segunda condición, expándela en una función generadora con nombre: legible, testeable y un patrón que tu agente de código va a copiar.

Tip #124

Los threads no arreglan tu Python limitado por CPU

Threads o asyncio para trabajo limitado por I/O, ProcessPoolExecutor para trabajo limitado por CPU: la decisión de una línea que los asistentes de IA fallan, y cómo saber qué límite estás enfrentando.

Tip #125

String += en un loop es O(n²), usa join

Por qué += sobre strings dentro de un loop es cuadrático, y las dos soluciones lineales: ''.join() sobre una lista de partes, o io.StringIO para construcción incremental.

Tip #126

Encadena siempre las excepciones con 'from e'

Relanzar una excepción envuelta sin 'from e' entierra el traceback original — dos palabras mantienen la traza apuntando a la causa real.

Tip #127

Protocol en vez de herencia: costuras de prueba estructurales en Python

Usa typing.Protocol para reemplazar dependencias reales por fakes de prueba sin acoplamiento a clases base — tipado estructural que el checker sigue verificando.

Tip #130

Rechaza los callbacks de Rails generados por IA que hacen trabajo lento

Los asistentes de IA adoran los after_save que llaman APIs — una regla de revisión mantiene los saves rápidos, los tests sin red y el trabajo lento reintentándose en jobs.

Tip #131

Impón la unicidad en la base de datos, no solo en el modelo

validates_uniqueness_of de Rails es propenso a condiciones de carrera bajo carga concurrente: úsalo para errores amigables, pero agrega un índice único en la base de datos para tener la garantía.

Tip #132

Todo bloque unsafe necesita un comentario de seguridad

Un bloque unsafe suspende las verificaciones del compilador — escribe un comentario // SAFETY que declare el invariante que sostiene, y deja que revisores y agentes de IA verifiquen en vez de adivinar.

Tip #133

Nunca Construyas Comandos de Shell Como Cadenas

Una sola variable sin comillas puede borrar el directorio equivocado. Usa arreglos de Bash para las listas de argumentos, pon comillas en cada expansión y arranca los scripts con set -euo pipefail.

Tip #134

Cambia la paginación por offset por la paginación por keyset

En una tabla grande y cambiante, LIMIT/OFFSET salta y repite filas en silencio — la paginación por keyset avanza usando la clave de la última fila y se mantiene consistente aunque la tabla mute debajo de ti.

Tip #135

Audita el Swift generado por IA en busca de Task.detached

¿Ves Task.detached en Swift generado por IA? Detente y revísalo — una tarea detached descarta silenciosamente la cancelación, la prioridad y el aislamiento de actor, y casi siempre es la opción equivocada.

Tip #136

Ponle fecha de vencimiento a cada supresión: ts-expect-error en vez de ts-ignore

@ts-ignore calla para siempre; @ts-expect-error da error apenas se corrige el bug de fondo, así las supresiones de tipos no se pudren en tu código.

Tip #55

Comenta el porqué, nunca el qué

Borra los comentarios que repiten tu código y conserva el único tipo que nunca se pudre: los comentarios de porqué, que registran la intención para humanos y asistentes de IA.

Tip #56

Nunca dejes código comentado

Borra el código muerto en vez de comentarlo: git recuerda cada línea, y tu asistente de IA razona mejor sobre archivos sin cementerios.

Tip #57

Mantén un archivo de reglas para tu agente

Documenta tus convenciones una sola vez en un archivo de reglas — CLAUDE.md, AGENTS.md, .cursor/rules — y cada sesión de IA las sigue sin que tengas que reescribir nada.

Tip #58

Documenta las trampas inline, donde muerden

El bug que te costó un día merece un comentario justo donde la próxima persona va a caer — no en una wiki que nadie abre.

Tip #59

La documentación ahora es contexto ejecutable

Nadie leía tu documentación — hasta que tu agente de código empezó a leer cada palabra. Por qué los registros de decisiones son el contexto de mayor impacto que puedes escribir, y cómo mantener uno en 10 minutos.

Tip #60

La sección de alternativas del ADR es oro

Registra las opciones que rechazaste — pros, contras y una línea sobre por qué perdió cada una — para que tu agente de código con IA deje de proponer ideas que ya descartaste.

Tip #61

Incorpora la IA a un código nuevo como a un humano

Dale a tu agente de código el mismo onboarding que a un nuevo integrante — un orden fijo de reconocimiento en cinco pasos más un request rastreado — para que su código respete tus convenciones.

Tip #62

Rastrea una petición real de punta a punta

La forma más rápida de entender cualquier codebase: sigue una petición real desde el punto de entrada hasta la base de datos y de vuelta — y luego entrégale ese mapa a tu agente de IA.

Tip #63

Registra el dialecto local para que el código de IA se integre

Una checklist de 3 puntos — nombres, patrones, reglas de la casa — para que el código generado por IA coincida con tu codebase y no con un default genérico.

Tip #64

La regla SMIG: Situación, Mecanismo, Implicación, Gotcha

Una regla de cuatro partes para docs de onboarding y code tours: omite lo que el código ya muestra, invierte tus palabras en implicaciones y gotchas.

Tip #65

No vuelques el árbol de archivos y lo llames onboarding

Un listado de carpetas le dice a tu agente de código qué existe, no sobre qué actuar — reemplaza el volcado crudo con cinco movimientos narrados que trazan el camino real por el sistema.

Tip #66

Archivos .tour: recorridos de código por persona

Convierte el onboarding en una ruta guiada: los archivos .tour anclan recorridos paso a paso a archivos y líneas reales, un tour por persona, reproducidos dentro del editor.

Tip #67

Verifica cada afirmación contra el código

Los README se desactualizan; el código no. Cómo hacer onboarding a cualquier repo trazando una request real de punta a punta y verificando cada afirmación contra el código fuente.

Tip #68

Ejecuta tu suite de pruebas nativas bajo sanitizers

Por qué ASan, UBSan y TSan atrapan los bugs de C/C++ que un reporte verde de cobertura de líneas deja pasar — y cómo integrarlos a las pruebas que ya tienes.

Tip #69

Atrapa cada crash antes de arreglarlo

Escribe el test de regresión que falla antes del arreglo, córrelo bajo un sanitizer, y el bug no puede volver en silencio.

Tip #70

No confíes en los tests con base de datos en memoria

Los fakes de base de datos en memoria se saltan la traducción a SQL: la consulta que pasa en tests puede romperse en producción. Cuándo y cómo probar contra el motor real.

Tip #71

Verifica los cuatro estados de tu UI

La mayoría de los tests de widgets solo verifican el render feliz: aquí te mostramos cómo probar loading, vacío, error y éxito, con los patrones de mocking que hacen alcanzable cada estado.

Tip #72

Nunca uses waitForTimeout — espera la red real

Las esperas fijas hacen que los tests E2E sean lentos Y frágiles a la vez — reemplaza cada una por una espera sobre la condición real: una respuesta de red o una aserción con reintentos automáticos.

Tip #73

Haz que un test inestable falle diez veces a propósito

Reproduce un test inestable en tu máquina con --repeat-each=10 (y sus equivalentes en pytest y Go) en vez de quemar una semana de reintentos en CI.

Tip #74

Inyecta relojes, semillas aleatorias y directorios temporales

Los tests inestables casi siempre leen una entrada oculta: el reloj real, un RNG compartido o un directorio temporal común. Inyecta los tres y las mismas entradas darán el mismo resultado en cada ejecución.

Tip #75

Pruebas por capas, no un arranque completo

Por qué @SpringBootTest debería ser la excepción y no el default — usa slices como @WebMvcTest y @DataJpaTest para feedback más rápido, y enséñale el mismo hábito a tu asistente de IA.

Tip #76

Mezcla el orden de tu suite de tests para exponer tests dependientes del orden

Ejecuta tu suite en orden aleatorio para detectar bugs de estado compartido en tu máquina — con los flags exactos de shuffle y seed para Vitest, Jest, pytest, Go y RSpec.

Tip #77

Un test que pasa contra código vacío no prueba nada

Si tu suite sigue en verde después de borrar el código de producción, no verifica nada. La auditoría de cinco minutos, los placeholders sospechosos y las herramientas que automatizan el chequeo.

Tip #78

Nunca lances corrutinas reales en los tests

Por qué los dispatchers reales hacen que los tests asíncronos fallen de forma intermitente en CI, y cómo los TestDispatchers inyectados, el tiempo virtual y los tests del ciclo de vida completo de Flow los vuelven deterministas.

Tip #79

Un Fixture, Tres Bases de Datos

Parametriza un solo fixture de pytest con SQLite, PostgreSQL y MySQL y cada test que lo usa corre una vez por backend — 3x de cobertura con un decorador.

Tip #80

Etiqueta los tests lentos y recupera tu ciclo de trabajo

Usa markers de pytest para separar los tests de integración lentos de los tests unitarios rápidos: cada guardado corre en menos de un segundo y CI corre todo.

Tip #81

Siempre haz mock con autospec=True

Un Mock plano acepta métodos que no existen — parchea con autospec=True para que tus tests fallen cuando el código generado por IA usa mal una API real.

Tip #82

Mocks asíncronos: verifica el await, no la llamada

assert_called_once pasa aunque tu código haya olvidado el await — assert_awaited_once es la aserción que de verdad atrapa el bug.

Tip #83

Nunca desactives los warnings en Pytest

Los deprecation warnings son señales tempranas de falla: por qué silenciar los warnings de pytest cambia una corrida ruidosa hoy por una caída en producción mañana, y cómo filtrar con precisión.

Tip #84

pytest --lf: vuelve a ejecutar solo lo que falló

Reduce tu ciclo de depuración de minutos a segundos con pytest --lf, -x, --ff y --sw — y por qué importa aún más cuando un agente de IA está depurando.

Tip #85

100% de cobertura de tests es una señal de alerta, no una medalla

Por qué perseguir 100% de cobertura en toda la suite desperdicia esfuerzo — apunta a ~80% global y lleva auth, pagos y mutación de datos hacia 100% de cobertura de ramas.

Tip #86

Prueba tus trabajos en segundo plano: idempotencia y reintentos

Las colas entregan al-menos-una-vez, así que todo trabajo terminará ejecutándose dos veces — aquí te mostramos cómo probar que una ejecución duplicada cobre una sola vez, envíe un solo correo y se recupere limpiamente tras un fallo.

Tip #87

Los tests inestables se deben al tiempo, al IO o a la aleatoriedad

Un test que pasa a veces casi siempre toca tiempo real, archivos reales o aleatoriedad real — inyecta los tres y la inestabilidad desaparece.

Tip #88

Haz tus docs ejecutables: doc tests

Compila los ejemplos de tu documentación como parte de la suite de tests — doc tests de Rust, doctest de Python y patrones de pytest que hacen que la documentación obsoleta rompa el CI.

Tip #89

Pasa tus scripts de shell por ShellCheck primero

Analiza el bash generado por IA con ShellCheck antes de probarlo: la mayoría de los bugs de shell son problemas estáticos de comillas y portabilidad que un linter detecta en segundos.

Tip #90

Prueba tus scripts de shell desde una ruta con espacios

Ejecuta tus scripts de shell desde un directorio temporal cuya ruta contiene un espacio: los bugs de comillas y de directorio actual fallan a lo grande, gratis, antes de fallar en producción.

Tip #91

Prueba los invariantes de datos en la capa de la base de datos

La validación en la app no basta: prueba llaves únicas, llaves foráneas y check constraints en una base de datos real y desechable, igual a producción.

Tip #92

Simula la red, la persistencia, los relojes — y el estado de permisos

Ya simulas la red y la base de datos en tus tests — inyecta también un fake para el estado de permisos, y la rama de denegado dejará de llegar rota a producción.

Tip #93

Prueba el bug antes de arreglarlo

Haz que tu agente de código con IA escriba un test que falle y reproduzca el bug antes de tocar el arreglo: prueba de que existe, prueba de que se fue, y una guardia permanente.

Tip #94

Que un subagente aparte escriba el test de reproducción

Separa el test de reproducción del fix: un subagente nuevo escribe el test que falla sin ver el arreglo, para que los puntos ciegos compartidos no aprueben un parche roto.

Tip #95

El mock tautológico

Cuando un mock devuelve exactamente el valor que el test afirma, el test pasa sin ejecutar ni una línea de código de producción — cómo detectar mocks tautológicos y reemplazarlos con implementaciones reales o fakes en memoria.

Tip #96

Mantén tus tests DAMP, no DRY

Por qué la duplicación está bien en los tests: DAMP (Descriptive And Meaningful Phrases) le gana a DRY cuando un test que falla tiene que explicarse solo.

Tip #97

Haz que el agente descubra los comandos propios del proyecto

Evita que tu agente de IA adivine pytest o npm test: haz que lea package.json, pyproject.toml, el Makefile y el CI para encontrar los comandos canónicos del repo.

Tip #98

Nunca confíes en tests escritos por IA para validar código escrito por IA

Cuando un mismo modelo escribe el código y sus tests, ambos pueden compartir la misma suposición errónea: una suite en verde prueba consistencia, no corrección. Así se rompe el ciclo.

Tip #99

Un puntero crudo con ownership en C++ bloquea el code review

Por qué un puntero crudo con ownership debe reprobar el code review en C++, y la checklist RAII (unique_ptr, shared_ptr, span, regla de cero) para aplicarla al código generado por IA.

Tip

Verifica context.mounted después de cada await

Por qué las apps Flutter se caen después de llamadas asíncronas lentas — y la guarda de una línea con context.mounted que elimina el use-after-dispose.

Tip

Un modelo escribe, un modelo distinto revisa

Por qué el modelo que escribió tu código no puede revisarlo con confianza — y cómo un ciclo de dos modelos (escribir/revisar) con decisión humana final atrapa muchos más bugs.

Tip

Java Optional es solo un tipo de retorno

Optional fue diseñado para un solo trabajo: tipos de retorno de métodos. Por qué los campos, los parámetros y el .get() sin verificar pelean contra el diseño, y qué patrones usar en su lugar.