Índice de contenido
- 1. Contexto: La diferencia entre usuarios autenticados y visitantes
- ️ Cómo redactar un prompt efectivo para Antigravity
- El truco de la ruta relativa y la ubicación exacta del código
- Modularización y buenas prácticas (Pinia y Vue)
- Retos en proyectos Flutter y cambios globales
- El flujo de trabajo ideal: probar, revisar y sincronizar con Git
- Google Antigravity IDE: Cómo usar la IA para acelerar tu programación (Ejemplo con Django)
- El proyecto: módulo de Blog con Django
- La herramienta de planificación (Planning Tool)
- Implementación y resultados
- Características del código generado
- Conclusiones
Quiero compartirte un par de trucos y consideraciones para que Google Antigravity IDE (o cualquier agente de IA para programar) te genere exactamente lo que buscas al implementar funcionalidades particulares. Estos son los prompts y estrategias que uso a diario, y estoy seguro de que también te servirán a ti.
1. Contexto: La diferencia entre usuarios autenticados y visitantes
Imagina que quieres agregar una nueva funcionalidad a una academia en línea. En ella coexisten cursos de pago (donde el usuario debe estar autenticado) y material gratuito (donde no es necesario iniciar sesión).
Esta distinción es un punto crítico que debes transmitirle al agente desde el principio:
- Con autenticación: Es posible guardar el progreso en la base de datos usando el
iddel usuario. - Sin autenticación: No existe identidad persistente, por lo que la lógica de almacenamiento cambia por completo y debe apoyarse en alternativas del lado del cliente.
Con este contexto claro, evalúo el código existente. En mi caso, ya tengo la lógica de pago y autenticación cubierta, pero dejé deliberadamente un bloque else para gestionar el progreso del contenido gratuito de forma local, que es justamente lo que quiero resolver.
️ Cómo redactar un prompt efectivo para Antigravity
Para que el agente no invente soluciones que no necesitas, sigo siempre este esquema al escribir mis prompts para Antigravity:
- Dar contexto: Explico el problema y la situación actual del código para que el agente entienda el punto de partida.
- Dar lineamientos claros: Indico la solución técnica que prefiero. Por ejemplo, le pido que utilice
localStoragecomo mecanismo de almacenamiento persistente del navegador.
El navegador ofrece varios tipos de almacenamiento del lado del cliente:
Cookies,IndexedDBylocalStorage, entre otros. PrefierolocalStoragepor su sencillez de implementación y lectura. Puedes inspeccionar su contenido abriendo las DevTools del navegador, en la pestaña Application > Local Storage.
El truco de la ruta relativa y la ubicación exacta del código
Para que Antigravity no se pierda en un mar de archivos —algo que sucede fácilmente en proyectos grandes de Laravel, Django o Flutter—, uso dos estrategias vitales antes de ejecutar cualquier prompt:
- Copiar la ruta relativa: Haz clic derecho en el archivo dentro del explorador y selecciona "Copy Relative Path". Pega esa ruta en el chat para que el agente sepa exactamente en qué archivo debe trabajar, sin tener que adivinar.
- Señalar el bloque exacto: Además de la ruta, le paso la pieza de código donde quiero la implementación. Por ejemplo, le indico que busque el
watchque vigila las propiedadesclassIndexysectionIndexpara actualizar el progreso localmente cuando el recurso es gratuito.
Modularización y buenas prácticas (Pinia y Vue)
Para evitar que el agente "escupa" todo el código en un solo archivo y lo vuelva difícil de mantener, incluyo instrucciones explícitas de modularización. En mi stack, utilizo Pinia para manejar el estado global de la aplicación Vue.
Con este lineamiento, el agente generó una función local para guardar el progreso dado el courseID, la sección y la clase, pero delegó la lógica de almacenamiento a un archivo separado manejado por Pinia. El resultado: código limpio, predecible y fácil de escalar. Si tu prompt es muy genérico, la IA meterá toda la lógica en el mismo componente, lo cual es una mala práctica que te complicará el mantenimiento a futuro.
Retos en proyectos Flutter y cambios globales
Cuando pides cambios que afectan a múltiples archivos del proyecto (como configurar pagos en una app de Flutter), la precisión del prompt es aún más crítica. Un prompt vago puede derivar en dos problemas comunes:
- Versiones obsoletas: Los agentes de IA tienden a instalar versiones antiguas de los paquetes porque sus datos de entrenamiento no siempre reflejan las últimas publicaciones. La solución es sencilla: indica siempre la versión exacta o pide explícitamente "la última versión estable disponible".
- En mi caso, le especifiqué directamente la versión del plugin que quería instalar.
- Archivos olvidados: En un proyecto de Flutter, el agente modificó el
pubspec.yamlcorrectamente, pero olvidó actualizar elAndroidManifest.xml. Sin los permisos declarados en ese archivo, la funcionalidad simplemente no funciona en Android.- El prompt era agregar el paquete
in_app_purchasepara habilitar compras a través de Google Play. Esta operación requiere añadir el permiso<uses-permission android:name="com.android.vending.BILLING" />en elAndroidManifest.xml, paso que el agente omitió hasta que se lo indiqué en un segundo prompt.
- El prompt era agregar el paquete
Si no especificas exactamente qué archivos debe tocar, el agente puede romper la armonía del proyecto: introduce redundancias, cambia el estilo de código establecido o ignora configuraciones existentes. Recuerda que al iniciar una nueva conversación, el agente evalúa el proyecto de cero y no siempre tiene visibilidad completa del contexto previo. Por eso, los cambios puntuales y la verificación manual de cada resultado son hábitos indispensables cuando programas con Antigravity.
El flujo de trabajo ideal: probar, revisar y sincronizar con Git
Una de las ventajas que más valoro de trabajar con Antigravity IDE es su integración con Git: las líneas modificadas se marcan visualmente en el editor (en amarillo) para que puedas revisar exactamente qué cambió antes de aceptarlo. Mi flujo tras cada generación es el siguiente:
- Analizar: Reviso las marcas de cambio en el editor y comparo con el código original.
- Ejecutar y probar: Verifico que la funcionalidad se comporte como espero en el navegador o emulador.
- Sincronizar: Si el cambio es correcto, ejecuto
git add,git commitygit push. - Revertir si es necesario: Si algo sale mal, uso
git reset --hard HEADpara volver al último estado estable y reintentar con un prompt más preciso.
Resumen: dale contexto al agente, pégale la ruta relativa del archivo, señala el bloque de código exacto donde trabajar, revisa los cambios uno a uno y sincroniza constantemente con Git.
Google Antigravity IDE: Cómo usar la IA para acelerar tu programación (Ejemplo con Django)
Es momento de otra práctica para ampliar nuestras capacidades con Inteligencia Artificial. En esta ocasión, usaremos Google Antigravity para programar un módulo completo, aprovechando su integración con agentes inteligentes directamente desde el editor.
Si quieres seguir esta práctica, puedes descargar Antigravity desde su página oficial. La diferencia fundamental frente al editor tradicional (VS Code) es que incluye una pestaña de Agente y una herramienta de Planificación, que es lo que exploraremos hoy.
Mi postura es clara: la forma moderna de programar implica trabajar con IA. Si no la usas, tu competencia sí lo hará y perderás terreno. En este curso buscamos el equilibrio: enseñanza técnica sólida, potenciada con estas herramientas para acelerar desarrollos que ya dominamos.
El proyecto: módulo de Blog con Django
Para esta práctica, le pedí al agente que desarrollara un módulo de Blog que faltaba en el proyecto. El objetivo era crear:
- Listado de posts: Con filtros por categorías, tipos y paginación.
- Página de detalle: Maquetada con Bootstrap.
- Modelos existentes: En lugar de crear un modelo nuevo desde cero, le instruí para que usara el modelo
Element(que actúa como representación de los posts) y sus relaciones conCategoryyType.
El prompt que usé fue el siguiente:
Crea un módulo en la app de elements para tener un Blog con filtros por tipos, categoría, paginado y maquetado con Bootstrap, que tenga el listado y el detalle.
Es un prompt bastante mejorable: no especificamos si queremos que cree un modelo nuevo (en nuestro caso queremos que reutilice el modelo Element existente), ni le adjuntamos capturas del diseño esperado. Aun así, nos sirve para ilustrar el flujo de trabajo con Antigravity. Los modelos que ya teníamos en el proyecto eran:
class Category(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255,blank=True)
def __str__(self):
return self.title
class Type(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255,blank=True)
def __str__(self):
return self.title
class ElementManager(models.Manager):
def get_queryset(self):
# Siempre que usemos Element.objects.all(), incluirá el select_related
return super().get_queryset().select_related('category', 'type')
class Element(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255,blank=True)
description = models.TextField() # blank=True, null=True
price = models.DecimalField(max_digits=10,decimal_places=2, default=6.10) # 12345678.10
category = models.ForeignKey(Category, on_delete=models.CASCADE) #, related_name='elements'
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
type = models.ForeignKey(Type, on_delete=models.CASCADE)Al especificarle la app de elements como punto de inspección, el agente reduce el tiempo que dedica a escanear el proyecto y ahorra tokens, lo que se traduce en respuestas más rápidas y enfocadas.
La herramienta de planificación (Planning Tool)
Esta es, en mi opinión, la principal ventaja de Antigravity frente a otras herramientas como Gemini CLI. Antes de escribir una sola línea de código, el agente genera una Hoja de Ruta (Roadmap) con todos los archivos que planea modificar o crear, lo que te da la oportunidad de corregir el rumbo antes de que sea tarde.
La IA te muestra exactamente qué archivos va a tocar:

Como puedes ver en la Hoja de Ruta, el agente quería generar un nuevo modelo Post, que no es lo que buscamos. Esto ocurrió precisamente porque el prompt inicial fue impreciso. Pero aquí está el valor de la planificación: puedes corregirle antes de que ejecute cualquier cambio. Simplemente le comentas "No crees un nuevo modelo; usa el modelo Element en su lugar" y él reajusta su plan.
Si la IA planifica crear un modelo
Posty tú quieres que useElement, agrega un comentario directamente en la planificación. El agente reajustará su Hoja de Ruta antes de tocar una sola línea de código.
Como recomendación de seguridad: siempre sincroniza tu proyecto con Git antes de aceptar los cambios propuestos. Si el resultado no es el esperado, puedes revertir fácilmente con
git reset --hard HEAD.
Durante la práctica, el editor se quedó colgado en "Pensando…" indefinidamente porque tuvo un problema al intentar levantar el entorno virtual y ejecutar las migraciones. Los errores que aparecieron en la terminal fueron:
python manage.py makemigrationszsh: command not found: python
from django.core.management import execute_from_command_lineModuleNotFoundError: No module named 'django'
ImportError: Couldn't import Django. Are you sure it's installed and available on your PYTHONPATH environment variable? Did you forget to activate a virtual environment?
Lo que ocurrió es que el agente intentó ejecutar python directamente en lugar de python3, y el entorno virtual no estaba activado. Ejecuté el comando manualmente, le informé al agente que ya lo había corrido yo, pero como seguía sin responder, tuve que terminar su ejecución y reiniciarlo indicándole que continuara con la generación de vistas y templates.
Implementación y resultados
Tras algunas iteraciones —siguiendo el mismo proceso: revisar la Hoja de Ruta, corregir lo que no cuadra con un comentario y hacer clic en el botón "Proceed" de la esquina superior derecha—, el agente generó una maqueta funcional.
El resultado fue un listado en tarjetas (cards) de Bootstrap con filtros por categorías y tipos, más una página de detalle:

Características del código generado
Filtros dinámicos: La vista lee de forma opcional los parámetros type y category desde la URL (request.GET) y ajusta el queryset en consecuencia:
elements\views.py
def blog_list(request):
elements = Element.objects.select_related('category', 'type').all()
# Filters
type_slug = request.GET.get('type')
category_slug = request.GET.get('category')
if type_slug:
elements = elements.filter(type__slug=type_slug)
if category_slug:
elements = elements.filter(category__slug=category_slug)Optimización de consultas: Utilizó select_related para traer las relaciones de category y type en una sola consulta SQL, evitando el clásico problema de las consultas N+1 que ralentiza las aplicaciones a medida que crecen:
elements = Element.objects.select_related('category', 'type').all()elements\views.py
Manejo de slugs: Configuró las rutas para usar el campo slug en lugar del id (clave primaria) en las URLs. Esto es una buena práctica tanto para el SEO como para la legibilidad de los enlaces:
elements\urls.py
path('blog/<slug:slug>/', blog_detail, name='blog_detail'),elements\views.py
def blog_detail(request, slug):
element = get_object_or_404(Element, slug=slug)
return render(request, 'elements/blog_detail.html', {'element': element})Paginación: Implementó la lógica estándar de Django para leer el parámetro de página desde la URL y pasar los objetos correspondientes al template.
Conclusiones
Como puedes apreciar, Antigravity y este tipo de herramientas ofrecen ventajas reales en el desarrollo moderno. Eso sí, los resultados no siempre son idénticos entre sesiones: esta misma prueba la hice dos veces sobre el mismo proyecto base y en la primera iteración tuve que hacer correcciones adicionales, como indicarle que usara el slug en vez del id como identificador de URL, o completar el diseño con un segundo prompt adjuntando capturas de pantalla de referencia para que aplicara un estilo similar:
elements\templates\base.html
<!-- Google Fonts -->
<link
href="https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400;0,700;1,400;1,700&family=Open+Sans:ital,wght@0,300;0,400;0,600;0,700;0,800;1,300;1,400;1,600;1,700;1,800&display=swap"
rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
<style>
body {
font-family: 'Lora', 'Times New Roman', serif;
font-size: 20px;
color: #212529;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 800;
}
</style> En resumen: aunque la IA puede inferir estilos a partir de capturas de pantalla que le adjuntes, siempre habrá ajustes manuales necesarios. En esta práctica, por ejemplo, tuvimos que corregir algunos errores de sintaxis en los templates (etiquetas HTML mal cerradas). Las herramientas de IA aceleran el desarrollo, pero no sustituyen al programador; siguen necesitando tu criterio técnico para funcionar bien.