Tabla de contenidos
- 🚀 ¿Qué estamos construyendo y por qué importa?
- 🧭 Flujo general de la solución
- 🔧 Primeros pasos: prototipar rápido en AI Studio
- 🕵️ Probar con un cliente real: detectar problemas reales
- 🔁 Cambio radical: cambiar el proveedor de IA
- 🧩 Solución práctica: Gina Reader como puente
- ⚙️ Modelo económico: elegir versiones más baratas con contexto amplio
- ✅ Primera prueba de fuego: análisis textual funciona
- 👁️ Añadir análisis visual: por qué y cómo
- 🐞 Debugging en tiempo real: errores al enviar la imagen
- 🔁 Experimentando con modelos: Gemini 2.5, 3.1 y más
- 🧠 Lección técnica: base64 vs multipart vs URL pública
- 📌 Recomendaciones prácticas para implementar esto en tu app
- 🗂️ Ejemplo rápido: cómo pedir un screenshot a una API (curl)
- 📥 Manejo de la imagen dentro de la app
- 🔒 Errores comunes y cómo resolverlos
- 💡 Ideas para mejorar la app a futuro
- 🧪 ¿Qué aprendí en este build? Resumen de lecciones
- 🎯 Recursos y enlaces mencionados
- 📷 Screenshots del proceso (referencias visuales)
- 🎬 Video del proyecto
- ✍️ Cierre y próximos pasos
🚀 ¿Qué estamos construyendo y por qué importa?
La meta es simple pero potente: una aplicación que ayude a freelancers a ganar proyectos más rápido. En lugar de empezar propuestas desde cero, la app analiza la web de un cliente potencial, extrae información relevante, genera una propuesta comercial estructurada y crea un prototipo visual en minutos.
Para muchos freelancers, la velocidad es diferencial. He vendido sitios web por años y sé que, en ocasiones, se gana simplemente por ser más rápido que la competencia. Una herramienta que automatice la extracción de datos, estructure la propuesta y entregue una maqueta visual reduce el tiempo entre detectar una oportunidad y enviar la primera propuesta.
🧭 Flujo general de la solución
El sistema sigue este flujo básico:
- Entrada: URL del posible cliente.
- Lectura: extracción de texto desde la web (Gina Reader u otra herramienta de scraping/lectura).
- Análisis: modelo de lenguaje que interpreta la información y genera una propuesta comercial.
- Prototipo visual: captura visual (screenshot) de la página, que el modelo puede usar para análisis visual.
- Salida: propuesta comercial estructurada y prototipo visual que el freelancer puede editar o enviar.
🔧 Primeros pasos: prototipar rápido en AI Studio
Para probar ideas rápido, empecé en Google AI Studio. Es ideal para prototipos porque permite iterar con prompts y modelos sin instalar todo localmente. El plan fue: crear un prototipo funcional, luego mover el proyecto a Antigravity para desarrollo y debugging más profundo.
Después de prototipar la idea, descargué el proyecto (zip) y lo trasladé a Antigravity. Abrí la carpeta descomprimida, revisé y levanté el proyecto. Con eso se arranca la aplicación localmente y se puede testear flujo completo contra sitios reales.
🕵️ Probar con un cliente real: detectar problemas reales
Probé con una clínica (una URL real) para ver si la app extraía la información correctamente. En el primer intento surgió un error: «has excedido tu cuota». Este tipo de fallos ocurren cuando trabajas con APIs externas y modelos: límites, claves inválidas o configuraciones que no contemplaste.

Primer aprendizaje: en prototipos reales siempre habrá errores. Lo importante es tener las herramientas para debuggear — abrir la consola del navegador (F12), revisar logs, y verificar si la causa es la cuota, el token o un endpoint mal llamado.
🔁 Cambio radical: cambiar el proveedor de IA
Para sortear la cuota decidí cambiar el proveedor de IA. Migré de Gemini a OpenRouter: obteniendo una nueva API key y configurando el proyecto para usar el nuevo proveedor. Cambiar el proveedor no es sólo intercambiar la API key; hay impactos funcionales que hay que revisar antes de hacerlo.

Al cambiar, la app evaluó el impacto automáticamente. El mayor problema detectado fue que la característica tools google search es exclusiva de la API directa de Gemini y OpenRouter no la soporta de forma nativa. Eso implica que, si dependes de una función propietaria de un proveedor, al migrar tendrás que replicar o reemplazar esa funcionalidad.
🧩 Solución práctica: Gina Reader como puente
Para seguir leyendo webs reales con OpenRouter, opté por implementar una solución combinada: usar Gina Reader para extraer el texto de la página y alimentar el modelo de OpenRouter con ese contenido. Gina Reader actúa como el scraper/lector y OpenRouter como el motor de razonamiento.
Ventajas de esta aproximación:
- Independencia del proveedor: Gina Reader se encarga del scraping y el texto se puede enviar a cualquier modelo.
- Flexibilidad: se puede cambiar el LLM sin perder la capacidad de leer páginas reales.
- Rapidez: la separación de responsabilidades facilita debugging y pruebas A/B.

⚙️ Modelo económico: elegir versiones más baratas con contexto amplio
Para contener costos opté por probar «Grog 4.1 Fast», un modelo más barato con ventana de contexto amplia. La idea es que gran parte del trabajo requiere comprender bastante texto y, en muchos casos, no necesitas el modelo más caro. Buscar el equilibrio entre costo y capacidad es clave si piensas escalar la app.
Algunas consideraciones al elegir modelo:
- Ventana de contexto: esencial si vas a enviar grandes cantidades de texto extraído de la web.
- Coste por token: importante en flujos que generan muchas iteraciones o múltiples propuestas por día.
- Soporte de herramientas: funciones como búsqueda web nativa o capacidades multimodales pueden ser exclusivas de ciertos proveedores.
✅ Primera prueba de fuego: análisis textual funciona
Tras cambiar y ajustar, el sistema pudo leer el texto real de la web y generar un análisis inicial. Ese fue un momento importante: la app ya era capaz de tomar una URL, extraer texto y producir un resumen/análisis. La presentación del análisis necesita pulirse, pero la lógica central funcionaba.

Observación crítica: el análisis estaba basado únicamente en texto. No veía la página como lo haría un humano que la navega y observa diseño, jerarquía visual, imágenes o llamadas a la acción. Esto limita la calidad del diagnóstico y de las propuestas de valor.
👁️ Añadir análisis visual: por qué y cómo
Para enriquecer el análisis, decidí añadir una capa visual: tomar una captura de pantalla (screenshot) de la página y enviarla al modelo junto al texto. La combinación texto+imagen aporta contexto profundo:
- Comprender la jerarquía visual y los elementos de la interfaz.
- Detectar problemas de usabilidad o falta de llamadas a la acción.
- Generar propuestas más relevantes, por ejemplo, sugerir cambios en la página de inicio basados en lo que se ve.
Desafío técnico: no puedes tomar un pantallazo directamente desde el navegador del usuario por restricciones de seguridad y CORS. Necesitas un servicio externo que genere la imagen a partir de la URL.

La solución elegida fue usar Gina Screenshot AI, una API gratuita de la misma familia de herramientas que Gina Reader. El flujo quedó así:
- Gina Screenshot AI recibe la URL y devuelve la imagen (screenshot).
- Se muestra la imagen en la aplicación para que el usuario la vea.
- Se envía la imagen junto con el texto extraído al modelo para análisis multimodal.
🐞 Debugging en tiempo real: errores al enviar la imagen
Al integrar la captura visual surgieron errores. En un intento surgió un «bad request» y, tras probar otros modelos, un error 401. Lo que pasó normalmente es:
- Intenté pasar la imagen directamente en la solicitud al modelo.
- Algunas APIs esperan imágenes como multipart/form-data o URLs públicas en lugar de datos base64 embebidos.
- En otros casos, el modelo o endpoint seleccionado no admite input multimodal (texto + imagen) o requiere un modelo específico.

El comportamiento observado: la app convirtió la imagen a base64 (lo que transforma la imagen en texto) y la pasó al modelo. Algunas plataformas aceptan base64; otras no. Además, algunos modelos nuevos acaban de salir y no están documentados aún, por eso el corrector automático o el IDE puede marcar que el nombre del modelo no existe, aunque sí lo haga en producción.
🔁 Experimentando con modelos: Gemini 2.5, 3.1 y más
Intenté cambiar los modelos para ver si alguno aceptaba la imagen sin errores. Pasé por Gemini 2.5 Flash y también probé una versión más nueva llamada 3.1 Flash Light Preview. A veces los modelos recién lanzados no aparecen en documentación ni en auto completion, pero sí existen en los endpoints reales.
Resultado: varios intentos arrojaron 401 o errores porque el endpoint no aceptaba la forma en que se enviaba la imagen. Eso me hizo comprender mejor dos cosas:
- Documenta qué modelos soportan multimodal y cómo esperan la imagen (URL, multipart o base64).
- Implementa una capa de compatibilidad donde tu app pueda transformar la imagen al formato esperado por cada proveedor.

🧠 Lección técnica: base64 vs multipart vs URL pública
Al integrar imágenes con LLMs o APIs multimodales encontrarás tres enfoques comunes:
- Base64 embebido: la imagen se convierte a una cadena base64 y se incluya en el body JSON. Es útil cuando no quieres subir archivos a un almacenamiento aparte. No todos los endpoints lo aceptan o pueden tener límites de tamaño.
- Multipart/form-data: la imagen se envía como archivo adjunto en una solicitud multipart. Es estándar para endpoints que manejan archivos y suele ser más eficiente con archivos grandes.
- URL pública: subes la imagen a un almacenamiento (S3, Cloud Storage) y envías la URL. Este método es robusto y evita problemas de tamaño en la request, pero requiere gestión de almacenamiento y permisos.
Para la app opté por mantener la opción de generar screenshots con Gina Screenshot AI y tener una capa que soporte convertir la imagen al formato que el modelo requiera. En la prueba la imagen se estaba enviando en base64, pero faltaba la lógica para mostrarla correctamente en la interfaz y/o para mandarla al modelo en el formato esperado.

📌 Recomendaciones prácticas para implementar esto en tu app
Si vas a construir una herramienta parecida, aquí tienes una checklist práctica y recomendaciones basadas en lo vivido:
- Separa responsabilidades: usa un servicio para scraping (Gina Reader), otro para screenshots y un LLM para análisis. Así cambias una parte sin romper las demás.
- Valida soporte multimodal: antes de depender de una característica (imagen+texto), verifica que el modelo y la API la soporten y cómo esperan el input.
- Implementa fallback: si el modelo no soporta imágenes, procesa solo el texto y ofrece una opción para análisis visual manual o con otra ruta técnica.
- Manejo de errores y logs: la consola del navegador y los logs del servidor son tus mejores amigos para identificar 401, 403, bad request y problemas de cuota.
- Optimiza costos: prueba modelos «fast» o «light» con ventana de contexto suficiente antes de escalar a los más caros.
- Transparencia con el usuario: muestra cuando la app no pudo procesar la imagen y ofrece alternativas (ej. subir screenshot manual).
🗂️ Ejemplo rápido: cómo pedir un screenshot a una API (curl)
Aquí tienes un ejemplo de cómo podrías pedir un screenshot a una API externa. Ajusta headers, URL y parámetros según la documentación de la API que uses.
curl -X POST "https://api.gina.ai/screenshot" \
-H "Authorization: Bearer TU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://ejemplo.com",
"width": 1280,
"height": 800,
"fullPage": false
}'📥 Manejo de la imagen dentro de la app
Una vez recibida la imagen puedes:
- Mostrarla en la UI (renderizarla desde la URL o convertir base64 a data URI).
- Almacenar la imagen temporalmente y enviar la URL pública al modelo.
- Convertir a multipart/form-data y reenviarla si el modelo lo requiere.
Si usas base64 para mostrarla en el navegador, recuerda transformar la cadena en una data URI:
const dataUrl = `data:image/png;base64,${base64String}`;
// luego asignar a un en la UI🔒 Errores comunes y cómo resolverlos
- 401 Unauthorized: revisa tu API key, permisos y si la ruta requiere un scope distinto.
- Bad Request: valida el payload (tipo de dato, parámetros obligatorios, tamaño de imagen si se envía base64).
- Límites de cuota: incorpora lógica para manejar rate limits, retries exponenciales y notificar al usuario.
- Nombre del modelo no encontrado: modelos nuevos pueden no aparecer en autocompletado o docs públicas. Verifica con el proveedor.
💡 Ideas para mejorar la app a futuro
La versión básica ya da mucho valor, pero hay muchas formas de expandirla:
- Templates de propuestas: plantillas personalizables por sector (salud, e-commerce, educación) que adapten lenguaje y métricas.
- Análisis de competencia: usar la URL del cliente para buscar competidores y extraer benchmarks.
- Integración con CRM: enviar propuestas generadas directamente a una pipeline de ventas.
- Editor WYSIWYG: permitir editar propuestas y prototipos visuales antes de exportar PDF o enviar email.
- Versionado y tracking: saber qué propuestas se enviaron, cuándo y con qué resultado.
🧪 ¿Qué aprendí en este build? Resumen de lecciones
Construir en público y en tiempo real enseña lecciones prácticas:
- Prototipa rápido en herramientas como AI Studio, pero prepárate para trasladar el proyecto a entornos de desarrollo más controlados.
- Cambiar proveedor de IA puede resolver problemas de cuota, pero requiere planear cómo reemplazar funcionalidades propias del proveedor original.
- Separar el scraping de la inferencia (Gina Reader para texto, LLM para análisis) da flexibilidad y resiliencia.
- Soporte multimodal (texto + imagen) mejora la calidad del análisis, pero introduce complejidad técnica en la transferencia y formato de imágenes.
- Los errores 401/bad request son parte del proceso. Logs y consola son esenciales para resolverlos rápido.
🎯 Recursos y enlaces mencionados
Aquí dejo los enlaces relevantes y recursos comentados en el proceso. Pégalos en tu navegador o intégralos en tu proyecto.
Comunidad Skool (recursos y PrimeraApp.com para miembros):
https://www.skool.com/vibe-coding-crea-apps-con-ia-5930Hosting de apps:
https://hostinger.com/rodrigoPlaylist con más videos sobre crear apps con IA:
https://www.youtube.com/playlist?list=PLBTuX25MUpdo9YuMzu-o9c80p1q40EBfI📷 Screenshots del proceso (referencias visuales)
Las siguientes imágenes corresponden a momentos clave durante la construcción y debugging:
🎬 Video del proyecto
Si quieres ver el flujo corto y las decisiones en acción, está disponible una grabación condensada donde se muestra la construcción en tiempo real.
✍️ Cierre y próximos pasos
Este proyecto es un buen ejemplo de cómo combinar varias piezas: scraping, screenshots, modelos económicos y debugging iterativo. La idea central es entregar valor a freelancers mediante velocidad y calidad en propuestas comerciales. Si decides construir algo similar, comienza por separar responsabilidades, documenta las expectativas de cada API y agrega robustez frente a errores.
Si te interesa que continúe desarrollando y mostrando la evolución de esta app, o que publique una segunda parte con código y soluciones concretas al envío de imágenes y al manejo de multimodalidad, coméntalo y lo preparo.
Un abrazo y buen código.




