<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Gemini on KnightLi Blog</title>
        <link>https://knightli.com/es/tags/gemini/</link>
        <description>Recent content in Gemini on KnightLi Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>es</language>
        <lastBuildDate>Thu, 21 May 2026 00:07:06 +0800</lastBuildDate><atom:link href="https://knightli.com/es/tags/gemini/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Resumen de Google I/O 2026: Gemini 3.5, Omni, Antigravity y Agents a nivel de sistema</title>
        <link>https://knightli.com/es/2026/05/21/google-io-2026-gemini-agentic-ai-summary/</link>
        <pubDate>Thu, 21 May 2026 00:07:06 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/21/google-io-2026-gemini-agentic-ai-summary/</guid>
        <description>&lt;p&gt;La línea principal de Google I/O 2026 es clara: Google está llevando Gemini desde &amp;ldquo;modelo&amp;rdquo; y &amp;ldquo;asistente de chat&amp;rdquo; hacia un ecosistema Agent más completo. Ya no se trata solo de responder preguntas. Gemini entra en Search, Android, herramientas de desarrollo, creación de video, compras, Workspace, hardware y plataformas empresariales para ayudar a los usuarios a completar cadenas de tareas más largas.&lt;/p&gt;
&lt;p&gt;Este artículo resume los principales anuncios de Google I/O 2026 desde la información oficial y una perspectiva de desarrolladores. Para desarrollo real, conviene seguir siempre la documentación oficial de Google, Android Developers y Gemini API.&lt;/p&gt;
&lt;h2 id=&#34;resumen-en-una-frase&#34;&gt;Resumen en una frase
&lt;/h2&gt;&lt;p&gt;La palabra clave de Google I/O 2026 es &lt;code&gt;agentic Gemini era&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Google anunció o reforzó varias líneas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Gemini 3.5 Flash&lt;/code&gt;: velocidad, capacidad de acción y flujos Agent.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini Omni&lt;/code&gt;: crear contenido desde cualquier entrada, empezando por creación y edición de video.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini app&lt;/code&gt;: pasar de asistente de chat a Agent personal proactivo, siempre disponible y capaz de ejecutar tareas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google Antigravity 2.0&lt;/code&gt;: evolucionar de herramienta de programación con IA a plataforma de desarrollo agent-first.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini API Managed Agents&lt;/code&gt;: crear Agents alojados mediante API, capaces de razonar, usar herramientas y ejecutar código.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Google AI Studio&lt;/code&gt;: expansión a móvil, soporte nativo para Android y exportación de proyectos a Antigravity.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Search&lt;/code&gt;, &lt;code&gt;Shopping&lt;/code&gt;, &lt;code&gt;YouTube&lt;/code&gt;, &lt;code&gt;Workspace&lt;/code&gt; y &lt;code&gt;Android&lt;/code&gt;: todos incorporan capacidades más fuertes de Gemini y Agent.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En otras palabras, Google ya no solo muestra &amp;ldquo;qué tan inteligente es el modelo&amp;rdquo;, sino cómo el modelo entra en productos, herramientas y sistemas para ejecutar tareas reales para el usuario.&lt;/p&gt;
&lt;h2 id=&#34;gemini-35-flash-del-prompt-a-la-acción&#34;&gt;Gemini 3.5 Flash: del prompt a la acción
&lt;/h2&gt;&lt;p&gt;Gemini 3.5 es la nueva familia de modelos que Google presentó en I/O 2026, con &lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; como primer foco público.&lt;/p&gt;
&lt;p&gt;Google no lo posiciona simplemente como &amp;ldquo;un modelo de chat más rápido&amp;rdquo;, sino como un motor de alta velocidad para flujos Agent reales. El artículo para desarrolladores de Google señala que 3.5 Flash combina inteligencia de frontera y alta velocidad para apoyar el paso de prompt a acción.&lt;/p&gt;
&lt;p&gt;Su importancia principal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Optimizado para escenarios Agent y coding.&lt;/li&gt;
&lt;li&gt;Soporta cadenas de tareas más largas y uso de herramientas.&lt;/li&gt;
&lt;li&gt;Disponible en Antigravity, Gemini API, Google AI Studio, Android Studio, Gemini Enterprise y otras entradas.&lt;/li&gt;
&lt;li&gt;Más adecuado para aplicaciones que requieren respuesta rápida, ejecución en múltiples turnos y llamadas frecuentes a herramientas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para desarrolladores, Gemini 3.5 Flash no es solo otra opción de modelo. Es uno de los motores por defecto de la nueva cadena de herramientas Agent de Google.&lt;/p&gt;
&lt;h2 id=&#34;gemini-omni-video-y-capacidades-de-modelo-del-mundo&#34;&gt;Gemini Omni: video y capacidades de modelo del mundo
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Gemini Omni&lt;/code&gt; es otro anuncio central de I/O 2026. Google lo describe como creación de contenido desde cualquier entrada, con foco inicial en video.&lt;/p&gt;
&lt;p&gt;Sus puntos principales son tres:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Entrada multimodal: texto, imágenes, video, audio y más pueden usarse como referencia.&lt;/li&gt;
&lt;li&gt;Edición de video: el usuario puede modificar video en múltiples turnos con lenguaje natural, en lugar de terminar tras una sola generación.&lt;/li&gt;
&lt;li&gt;Comprensión del mundo: enfatiza consistencia física, escenas, acciones, narrativa y salida audiovisual.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto significa que las herramientas de video con IA pasan de &amp;ldquo;escribir un prompt para generar un clip&amp;rdquo; a &amp;ldquo;revisar paso a paso como si hablaras con un editor&amp;rdquo;. Para creadores, el valor real no es la generación de una sola vez, sino un flujo de edición controlable, trazable e iterativo.&lt;/p&gt;
&lt;h2 id=&#34;gemini-app-de-asistente-de-chat-a-agent-personal-siempre-activo&#34;&gt;Gemini App: de asistente de chat a Agent personal siempre activo
&lt;/h2&gt;&lt;p&gt;Google también empuja Gemini app hacia una dirección más agentic. Las publicaciones oficiales dicen que Gemini app será más proactiva, con briefs diarios y ayuda continua.&lt;/p&gt;
&lt;p&gt;Algunos puntos clave:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; llega a Gemini app.&lt;/li&gt;
&lt;li&gt;Nueva UI e interacción más dinámica.&lt;/li&gt;
&lt;li&gt;Conceptos de AI Agent personal como &lt;code&gt;Gemini Spark&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Proactive daily briefs, que organizan de forma proactiva lo que el usuario debe atender cada día.&lt;/li&gt;
&lt;li&gt;Más énfasis en asistencia de fondo 24/7, en lugar de esperar a que el usuario inicie cada chat.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esta parte afecta más a usuarios normales. Antes Gemini se parecía más a un asistente de &amp;ldquo;preguntas y respuestas&amp;rdquo;. Después de I/O 2026, Google quiere que se parezca más a un Agent personal que sigue tareas, recuerda de forma proactiva y coordina entre productos.&lt;/p&gt;
&lt;h2 id=&#34;antigravity-20-las-herramientas-de-desarrollo-se-vuelven-agent-first&#34;&gt;Antigravity 2.0: las herramientas de desarrollo se vuelven Agent-first
&lt;/h2&gt;&lt;p&gt;Uno de los anuncios más importantes para desarrolladores es &lt;code&gt;Google Antigravity 2.0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Google posiciona Antigravity como agent-first development platform. Después de I/O 2026, no solo ayuda a escribir código, sino que busca ayudar al desarrollador desde la idea y el prototipo hasta la orquestación de Agents y la entrega de aplicaciones en producción.&lt;/p&gt;
&lt;p&gt;Los cambios principales que menciona Google incluyen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Aplicación de escritorio independiente Antigravity 2.0.&lt;/li&gt;
&lt;li&gt;Orquestación paralela de múltiples Agents.&lt;/li&gt;
&lt;li&gt;Subagents dinámicos.&lt;/li&gt;
&lt;li&gt;Tareas programadas en segundo plano.&lt;/li&gt;
&lt;li&gt;Integración con Google AI Studio, Android, Firebase y otros ecosistemas.&lt;/li&gt;
&lt;li&gt;Antigravity CLI para usuarios de terminal.&lt;/li&gt;
&lt;li&gt;Antigravity SDK para personalizar comportamiento y despliegue de Agents.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto muestra que las herramientas de programación con IA entran en una etapa posterior a &amp;ldquo;autocompletado / generación conversacional&amp;rdquo;: los desarrolladores gestionarán múltiples Agents ejecutables, no solo una ventana de chat.&lt;/p&gt;
&lt;h2 id=&#34;gemini-api-managed-agents-alojar-agents-como-capacidades-api&#34;&gt;Gemini API Managed Agents: alojar Agents como capacidades API
&lt;/h2&gt;&lt;p&gt;Google también presentó &lt;code&gt;Managed Agents in the Gemini API&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Según la descripción oficial, estos Agents pueden crearse con una sola llamada API. Pueden razonar, usar herramientas y ejecutar código en un entorno Linux aislado, con soporte del Antigravity agent harness.&lt;/p&gt;
&lt;p&gt;Esto es clave para desarrolladores:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No hace falta construir todo el runtime Agent por cuenta propia.&lt;/li&gt;
&lt;li&gt;Se obtiene un entorno de ejecución persistente y aislado.&lt;/li&gt;
&lt;li&gt;Las interacciones en múltiples turnos pueden conservar archivos y estado.&lt;/li&gt;
&lt;li&gt;Se pueden extender Agents con markdown skills, instrucciones personalizadas y plantillas.&lt;/li&gt;
&lt;li&gt;Están disponibles mediante Interactions API y Google AI Studio.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si esta línea madura, las plataformas Agent se parecerán cada vez más a servicios cloud: los desarrolladores no solo llamarán a modelos, sino a Agents con estado, herramientas, entorno de ejecución y límites de seguridad.&lt;/p&gt;
&lt;h2 id=&#34;google-ai-studio-de-prompt-playground-a-entrada-de-generación-de-apps&#34;&gt;Google AI Studio: de prompt playground a entrada de generación de apps
&lt;/h2&gt;&lt;p&gt;En I/O 2026, Google AI Studio también avanza.&lt;/p&gt;
&lt;p&gt;Cambios principales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google AI Studio mobile app para capturar ideas y generar prototipos desde móvil.&lt;/li&gt;
&lt;li&gt;Integración con Workspace API, para que los Agents accedan de forma más natural a Google Workspace.&lt;/li&gt;
&lt;li&gt;Exportación de proyectos a Antigravity, llevando contexto al desarrollo local y a producción.&lt;/li&gt;
&lt;li&gt;Soporte nativo para Android, permitiendo construir apps Android con prompts.&lt;/li&gt;
&lt;li&gt;Integración con Google Play Console para publicar apps en canales de prueba.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto convierte AI Studio de &amp;ldquo;lugar para ajustar prompts y probar modelos&amp;rdquo; en una entrada desde la idea hasta la aplicación. Su relación con Antigravity también queda más clara: AI Studio sirve para idear y generar rápido; Antigravity para seguir desarrollando, orquestar, depurar y entregar.&lt;/p&gt;
&lt;h2 id=&#34;android-y-appfunctions-interfaces-clave-para-agents-móviles&#34;&gt;Android y AppFunctions: interfaces clave para Agents móviles
&lt;/h2&gt;&lt;p&gt;Los Agents a nivel de sistema en Android son una dirección que merece atención propia, pero deben entenderse con interfaces y límites de producto precisos.&lt;/p&gt;
&lt;p&gt;Lo más importante ahora es &lt;code&gt;AppFunctions&lt;/code&gt; oficial de Android. La documentación lo describe como una API de plataforma Android con bibliotecas Jetpack, que permite a las apps exponer sus capacidades a agents, asistentes y otros llamadores autorizados. También simplifica la integración de Android MCP.&lt;/p&gt;
&lt;p&gt;Su importancia está en que la automatización móvil ya no tiene que depender solo de capturas de pantalla, OCR, taps simulados y localización de controles UI.&lt;/p&gt;
&lt;p&gt;La automatización móvil tradicional sigue este camino:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reconocer la pantalla.&lt;/li&gt;
&lt;li&gt;Encontrar el botón.&lt;/li&gt;
&lt;li&gt;Simular un tap.&lt;/li&gt;
&lt;li&gt;Esperar cambios de página.&lt;/li&gt;
&lt;li&gt;Reintentar tras errores.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La dirección de AppFunctions es:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La app declara qué puede hacer.&lt;/li&gt;
&lt;li&gt;El Agent llama esas capacidades con autorización.&lt;/li&gt;
&lt;li&gt;El sistema gestiona permisos, límites de llamada y restricciones de seguridad.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto afectará al diseño de apps Android. Las apps futuras no solo tendrán que diseñar UI para humanos, sino también convertir sus funciones centrales en interfaces invocables por Agents.&lt;/p&gt;
&lt;h2 id=&#34;search-compras-y-productos-de-contenido-también-se-vuelven-agentic&#34;&gt;Search, compras y productos de contenido también se vuelven agentic
&lt;/h2&gt;&lt;p&gt;Los cambios de Google I/O 2026 no están solo en modelos y herramientas de desarrollo. Search y productos de consumo también cambian en paralelo.&lt;/p&gt;
&lt;p&gt;Los resúmenes oficiales de I/O mencionan:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Search entra en una nueva etapa de AI Search.&lt;/li&gt;
&lt;li&gt;Information agents aparecen en escenarios de búsqueda.&lt;/li&gt;
&lt;li&gt;Gemini Spark y Daily Brief llegan a Gemini app.&lt;/li&gt;
&lt;li&gt;Universal Cart hace más inteligente el carrito de compras.&lt;/li&gt;
&lt;li&gt;Ask YouTube permite consultar y navegar contenido de video de forma conversacional.&lt;/li&gt;
&lt;li&gt;Las capacidades de Gemini se expanden a más productos y formatos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Estos anuncios muestran que la dirección Agent de Google no es un producto aislado, sino una expansión horizontal hacia búsqueda, video, compras, productividad, móvil y hardware.&lt;/p&gt;
&lt;h2 id=&#34;impacto-práctico-para-desarrolladores&#34;&gt;Impacto práctico para desarrolladores
&lt;/h2&gt;&lt;p&gt;El mayor impacto de Google I/O 2026 para desarrolladores no es &amp;ldquo;otro modelo más&amp;rdquo;, sino que cambia el objeto de desarrollo.&lt;/p&gt;
&lt;p&gt;Antes los desarrolladores construían principalmente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apps.&lt;/li&gt;
&lt;li&gt;Sitios web.&lt;/li&gt;
&lt;li&gt;APIs.&lt;/li&gt;
&lt;li&gt;Plugins.&lt;/li&gt;
&lt;li&gt;Scripts de automatización.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ahora también tendrán que construir:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Capacidades de app invocables por Agents.&lt;/li&gt;
&lt;li&gt;Flujos de trabajo multi-Agent.&lt;/li&gt;
&lt;li&gt;Entornos de ejecución de herramientas con estado.&lt;/li&gt;
&lt;li&gt;Flujos de automatización auditables.&lt;/li&gt;
&lt;li&gt;Mecanismos human-in-the-loop.&lt;/li&gt;
&lt;li&gt;Integraciones con MCP, AppFunctions, Workspace API, Playwright, Firebase y otras herramientas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El software se parecerá cada vez más a un &amp;ldquo;conjunto de capacidades&amp;rdquo;, no solo a un &amp;ldquo;conjunto de interfaces&amp;rdquo;. Quien exponga sus capacidades de forma clara, fiable y segura a Agents tendrá más posibilidades de entrar en las cadenas de tareas automatizadas del usuario.&lt;/p&gt;
&lt;h2 id=&#34;impacto-en-automatización-móvil&#34;&gt;Impacto en automatización móvil
&lt;/h2&gt;&lt;p&gt;La automatización móvil pasará gradualmente de &amp;ldquo;GUI primero&amp;rdquo; a &amp;ldquo;interfaces primero, GUI como respaldo&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;A corto plazo, reconocimiento de capturas, OCR, taps simulados y automatización de navegador siguen teniendo valor, porque muchas apps antiguas no tienen interfaces estándar.&lt;/p&gt;
&lt;p&gt;A largo plazo, si Android AppFunctions, MCP y el modelo de permisos a nivel de sistema maduran, la ejecución estable de tareas tenderá a:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Llamar primero capacidades declaradas por la app.&lt;/li&gt;
&lt;li&gt;Llamar interfaces del sistema cuando sea necesario.&lt;/li&gt;
&lt;li&gt;Usar automatización GUI como respaldo cuando no haya otra opción.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto cambiará RPA, Agents móviles, herramientas de prueba y ecosistemas de apps. Las apps que expongan capacidades serán más fáciles de invocar por Agents a nivel de sistema. Las que no lo hagan quizá sigan dependiendo del viejo método de &amp;ldquo;mirar pantalla y tocar pantalla&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;seguridad-permisos-y-auditoría-serán-requisitos-duros&#34;&gt;Seguridad, permisos y auditoría serán requisitos duros
&lt;/h2&gt;&lt;p&gt;Cuanto más fuertes sean los Agents, mayor será el riesgo.&lt;/p&gt;
&lt;p&gt;Si un Agent puede ejecutar tareas entre apps, invocar pagos, cambiar configuraciones, acceder a archivos y leer contexto, necesita límites de seguridad claros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Niveles de permisos.&lt;/li&gt;
&lt;li&gt;Autorización explícita del usuario.&lt;/li&gt;
&lt;li&gt;Confirmación secundaria para acciones sensibles.&lt;/li&gt;
&lt;li&gt;Aislamiento por sandbox.&lt;/li&gt;
&lt;li&gt;Logs de operación.&lt;/li&gt;
&lt;li&gt;Capacidad de deshacer y rollback.&lt;/li&gt;
&lt;li&gt;Auditoría y cumplimiento empresarial.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por eso Google enfatiza entornos aislados para Agents alojados, requisitos de permisos de AppFunctions, plataformas empresariales y despliegues controlados. El futuro de los Agents no es &amp;ldquo;poder hacer todo sin límites&amp;rdquo;, sino ejecutar de forma controlada, trazable y gobernable dentro de límites de seguridad.&lt;/p&gt;
&lt;h2 id=&#34;resumen&#34;&gt;Resumen
&lt;/h2&gt;&lt;p&gt;El contenido principal de Google I/O 2026 puede resumirse así: Google está convirtiendo Gemini en una plataforma Agent que cruza modelos, apps, sistemas, herramientas de desarrollo y hardware.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Gemini 3.5 Flash&lt;/code&gt; aporta velocidad y capacidad de acción. &lt;code&gt;Gemini Omni&lt;/code&gt; lleva la creación multimodal hacia video y comprensión del mundo. &lt;code&gt;Gemini app&lt;/code&gt; avanza hacia asistente personal proactivo. &lt;code&gt;Antigravity 2.0&lt;/code&gt; y &lt;code&gt;Managed Agents&lt;/code&gt; empujan las herramientas de desarrollo hacia lo Agent-native. &lt;code&gt;AppFunctions&lt;/code&gt; permite que las apps Android empiecen a exponer capacidades a agentes inteligentes.&lt;/p&gt;
&lt;p&gt;Para desarrolladores, lo siguiente a vigilar no son solo parámetros de modelo, sino cómo estructurar capacidades de aplicación, cómo integrarse con cadenas de herramientas Agent, cómo diseñar permisos y auditoría, y cómo hacer que los productos sean invocables de forma segura y fiable dentro de un ecosistema Agent a nivel de sistema.&lt;/p&gt;
&lt;p&gt;Referencias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/google-io-2026-collection/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: Google I/O 2026 news and announcements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/technology/developers-tools/google-io-2026-developer-highlights/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: I/O 2026 developer highlights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/innovation-and-ai/products/gemini-app/next-evolution-gemini-app/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: The Gemini app becomes more agentic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.android.com/ai/appfunctions?hl=zh-cn&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Android Developers: AppFunctions overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Cómo usar gratis Gemini 3.5 Flash y Gemini Omni: entradas para usuarios y desarrolladores</title>
        <link>https://knightli.com/es/2026/05/20/gemini-3-5-flash-omni-free-access/</link>
        <pubDate>Wed, 20 May 2026 23:13:35 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/20/gemini-3-5-flash-omni-free-access/</guid>
        <description>&lt;p&gt;Después de que Google lanzara Gemini 3.5 Flash y Gemini Omni, la pregunta práctica no es el benchmark, sino cómo pueden usarlos realmente los usuarios normales y los desarrolladores, qué entradas son gratuitas y cuáles son solo pruebas de bajo umbral.&lt;/p&gt;
&lt;p&gt;Resumen rápido:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Para chat, escritura, comprensión de imágenes y preguntas cotidianas: primero Gemini app.&lt;/li&gt;
&lt;li&gt;Para probar parámetros, prompts y entradas multimodales de Gemini 3.5 Flash: Google AI Studio.&lt;/li&gt;
&lt;li&gt;Para llamar a Gemini 3.5 Flash desde código: crear una API key en AI Studio.&lt;/li&gt;
&lt;li&gt;Para probarlo gratis desde la terminal: mirar Gemini CLI.&lt;/li&gt;
&lt;li&gt;Para probar la edición de video de Gemini Omni: empezar por Gemini app y Google Flow.&lt;/li&gt;
&lt;li&gt;Para producción real: no depender de cuotas gratuitas; pasar a una API de pago o Vertex AI.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nota: las cuotas gratuitas, disponibilidad regional, niveles de suscripción y menús de modelos cambian con el tiempo. Este artículo fue escrito el 20 de mayo de 2026. Antes de usarlo formalmente, conviene revisar las páginas actuales de Google.&lt;/p&gt;
&lt;h2 id=&#34;método-gratuito-1-para-gemini-35-flash-gemini-app&#34;&gt;Método gratuito 1 para Gemini 3.5 Flash: Gemini app
&lt;/h2&gt;&lt;p&gt;La entrada más sencilla es Gemini app:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://gemini.google.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://gemini.google.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El uso es directo:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Abrir Gemini.&lt;/li&gt;
&lt;li&gt;Iniciar sesión con una cuenta de Google.&lt;/li&gt;
&lt;li&gt;Buscar &lt;code&gt;3.5 Flash&lt;/code&gt; en el selector de modelos.&lt;/li&gt;
&lt;li&gt;Empezar a conversar.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Esta entrada es adecuada para usuarios normales. Puedes usarla para escribir, resumir, entender imágenes, analizar archivos, responder preguntas cotidianas y hacer planificación simple. Según información pública, Gemini 3.5 Flash ya está disponible para usuarios globales y puede seleccionarse desde el menú de modelos de Gemini.&lt;/p&gt;
&lt;p&gt;Los límites también son claros: los usuarios gratuitos suelen tener límites diarios de mensajes, región y funciones. Si superas el límite, tendrás que esperar a que se renueve la cuota o actualizar la suscripción.&lt;/p&gt;
&lt;h2 id=&#34;método-gratuito-2-para-gemini-35-flash-google-ai-studio&#34;&gt;Método gratuito 2 para Gemini 3.5 Flash: Google AI Studio
&lt;/h2&gt;&lt;p&gt;Si no solo quieres conversar, sino ajustar prompts, revisar parámetros o probar salida estructurada, Google AI Studio encaja mejor:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://aistudio.google.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://aistudio.google.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Flujo básico:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Iniciar sesión en Google AI Studio.&lt;/li&gt;
&lt;li&gt;Crear un nuevo prompt.&lt;/li&gt;
&lt;li&gt;Seleccionar &lt;code&gt;gemini-3.5-flash&lt;/code&gt; en el menú de modelos.&lt;/li&gt;
&lt;li&gt;Escribir el prompt y ejecutarlo.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;La ventaja de AI Studio es el mayor control. Puedes ajustar temperatura, instrucciones del sistema, salida estructurada y entrada con múltiples imágenes, y también exportar el prompt probado como código o llamada API.&lt;/p&gt;
&lt;p&gt;Para desarrolladores, AI Studio es un banco de pruebas gratuito. Ajustar primero el prompt y el formato de entrada aquí ayuda a desperdiciar menos cuota cuando pases a la integración por API.&lt;/p&gt;
&lt;h2 id=&#34;método-gratuito-3-para-gemini-35-flash-api-key-gratuita&#34;&gt;Método gratuito 3 para Gemini 3.5 Flash: API key gratuita
&lt;/h2&gt;&lt;p&gt;Lo que más interesa a los desarrolladores es la API. AI Studio permite crear una Gemini API key para llamar a &lt;code&gt;gemini-3.5-flash&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Flujo básico:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Abrir Google AI Studio.&lt;/li&gt;
&lt;li&gt;Buscar &lt;code&gt;Get API key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Elegir o crear un proyecto.&lt;/li&gt;
&lt;li&gt;Crear una API key.&lt;/li&gt;
&lt;li&gt;Guardar la key en una variable de entorno local.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ejemplo en Python:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GEMINI_API_KEY&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-3.5-flash&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Explica en tres frases para qué escenarios es adecuado Gemini 3.5 Flash.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ejemplo en Node.js:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;GoogleGenAI&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;@google/genai&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ai&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;GoogleGenAI&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;apiKey&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;GEMINI_API_KEY&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ai&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;generateContent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-3.5-flash&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Explica en tres frases para qué escenarios es adecuado Gemini 3.5 Flash.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Ejemplo con &lt;code&gt;curl&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash:generateContent&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;x-goog-api-key: &lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$GEMINI_API_KEY&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -H &lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -d &lt;span class=&#34;s1&#34;&gt;&amp;#39;{&amp;#34;contents&amp;#34;:[{&amp;#34;parts&amp;#34;:[{&amp;#34;text&amp;#34;:&amp;#34;Hello Gemini 3.5 Flash&amp;#34;}]}]}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La información pública indica que el nivel gratuito de AI Studio suele ofrecer a los modelos Gemini Flash cierta cuota diaria de solicitudes. La cifra puede cambiar según tiempo, región y estado de la cuenta. Se mencionan con frecuencia cifras como unas 1.500 solicitudes al día, límites por minuto y límites de token. No conviene fijar esos números en un plan de producción; antes de lanzar algo, revisa las páginas actuales de precios y límites de Google AI.&lt;/p&gt;
&lt;h2 id=&#34;método-gratuito-4-para-gemini-35-flash-gemini-cli&#34;&gt;Método gratuito 4 para Gemini 3.5 Flash: Gemini CLI
&lt;/h2&gt;&lt;p&gt;Si te gusta la línea de comandos, puedes mirar Gemini CLI. Sirve para scripts temporales, resúmenes de repositorios, lectura de archivos y preguntas rápidas desde la terminal.&lt;/p&gt;
&lt;p&gt;La instalación suele ser:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install -g @google/gemini-cli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Después ejecuta:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;gemini
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La CLI encaja mejor con el uso diario de desarrolladores individuales, no con integraciones de producción. En producción conviene usar API keys, cuentas de servicio, control de permisos y formas de llamada auditables.&lt;/p&gt;
&lt;h2 id=&#34;acceso-gratuito-o-de-baja-fricción-a-gemini-omni-gemini-app-y-google-flow&#34;&gt;Acceso gratuito o de baja fricción a Gemini Omni: Gemini app y Google Flow
&lt;/h2&gt;&lt;p&gt;Gemini Omni es un modelo multimodal para creación y edición de video. Su capacidad central no es la pregunta-respuesta de texto común, sino la edición de video en múltiples turnos mediante lenguaje natural, con referencias de imagen, texto, video y audio.&lt;/p&gt;
&lt;p&gt;La página de Google DeepMind menciona estas entradas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gemini app.&lt;/li&gt;
&lt;li&gt;Google Flow.&lt;/li&gt;
&lt;li&gt;YouTube Shorts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La página también indica que se requiere una suscripción a Google AI y que las funciones varían según el nivel de suscripción y la región. Por eso, el &amp;ldquo;uso gratuito&amp;rdquo; de Gemini Omni debe entenderse con cuidado: algunas entradas podrían permitir a usuarios gratuitos ver o probar parte de la experiencia, pero la edición completa de video puede requerir suscripción, disponibilidad regional o despliegue gradual.&lt;/p&gt;
&lt;p&gt;Si solo quieres probarlo, sigue este orden:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Abre primero Gemini app y revisa si aparece Gemini Omni o una entrada relacionada con edición de video.&lt;/li&gt;
&lt;li&gt;Luego abre Google Flow: &lt;a class=&#34;link&#34; href=&#34;https://flow.google/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://flow.google/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Si creas videos cortos, observa si aparecen funciones de edición relacionadas con Omni en YouTube Shorts.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Si la entrada no aparece, normalmente no significa que hayas hecho algo mal. Puede depender de la cuenta, región, nivel de suscripción o grupo de despliegue.&lt;/p&gt;
&lt;h2 id=&#34;cómo-conviene-usar-gemini-omni&#34;&gt;Cómo conviene usar Gemini Omni
&lt;/h2&gt;&lt;p&gt;Gemini Omni es más adecuado para creadores que para chat común.&lt;/p&gt;
&lt;p&gt;Puedes probar estas direcciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Subir o elegir un video y pedirle que cambie el estilo.&lt;/li&gt;
&lt;li&gt;Hacer que una acción concreta del video sea más exagerada.&lt;/li&gt;
&lt;li&gt;Usar una imagen de referencia para reemplazar un objeto o personaje de la escena.&lt;/li&gt;
&lt;li&gt;Modificar cámara, acción, entorno y estilo en múltiples turnos.&lt;/li&gt;
&lt;li&gt;Combinar bocetos, imágenes de referencia, audio o video en una nueva salida.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El prompt puede escribirse como una instrucción para un editor:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Mantén sin cambios la persona y la estructura de la habitación del video original. Cambia el efecto después de tocar el espejo por ondas líquidas. El movimiento debe ser natural y la luz no debe cambiar de forma brusca.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;En edición de múltiples turnos, no metas demasiadas solicitudes de una sola vez. Un enfoque más estable es:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Cambiar primero la acción principal.&lt;/li&gt;
&lt;li&gt;Cambiar después el estilo.&lt;/li&gt;
&lt;li&gt;Ajustar luego el ángulo de cámara.&lt;/li&gt;
&lt;li&gt;Ajustar al final sonido, texto y ritmo.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Así es más fácil mantener la coherencia y ubicar en qué paso aparece un problema.&lt;/p&gt;
&lt;h2 id=&#34;errores-comunes-al-usar-opciones-gratuitas&#34;&gt;Errores comunes al usar opciones gratuitas
&lt;/h2&gt;&lt;p&gt;Primero, la cuota gratuita no es cuota de producción. Una API key gratuita sirve para pruebas, herramientas personales y prototipos, no para prometer un servicio estable.&lt;/p&gt;
&lt;p&gt;Segundo, no envíes datos sensibles a entradas gratuitas o de terceros. Esto incluye código no publicado, datos de clientes, contratos, claves, hojas financieras y documentos internos.&lt;/p&gt;
&lt;p&gt;Tercero, revisa la configuración de uso de datos. Los niveles gratuitos pueden tener políticas distintas de uso de datos; antes de usar, revisa la configuración en AI Studio o en tu cuenta de Google.&lt;/p&gt;
&lt;p&gt;Cuarto, las capacidades de video suelen estar más limitadas que las de texto. Funciones como Gemini Omni pueden depender de suscripción, región, cola, duración, resolución y políticas de seguridad de contenido.&lt;/p&gt;
&lt;p&gt;Quinto, cuidado con las &amp;ldquo;API ilimitadas gratis&amp;rdquo; de terceros. Muchas pasarelas limitan velocidad, reenvían solicitudes, registran logs o exigen métodos de pago poco transparentes. No es recomendable usarlas para tareas sensibles.&lt;/p&gt;
&lt;h2 id=&#34;qué-entrada-elegir&#34;&gt;Qué entrada elegir
&lt;/h2&gt;&lt;p&gt;Si eres usuario normal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gemini 3.5 Flash: usa Gemini app.&lt;/li&gt;
&lt;li&gt;Gemini Omni: mira primero Gemini app y luego Google Flow.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si eres creador:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usa Google Flow para probar flujos de video con Omni.&lt;/li&gt;
&lt;li&gt;Usa Gemini app para guiones, storyboards, prompts y descripciones de materiales.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si eres desarrollador:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usa AI Studio para depurar prompts.&lt;/li&gt;
&lt;li&gt;Usa una API key para integrar &lt;code&gt;gemini-3.5-flash&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Usa Gemini CLI para flujos personales en terminal.&lt;/li&gt;
&lt;li&gt;Para producción, considera Vertex AI o la API de pago.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si eres empresa:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No dependas de cuotas gratuitas.&lt;/li&gt;
&lt;li&gt;Prioriza permisos, logs, auditoría, residencia de datos, cumplimiento y gestión de claves.&lt;/li&gt;
&lt;li&gt;En generación y edición de video, añade marcas de agua, revisión de contenido y procesos de derechos de autor.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;resumen&#34;&gt;Resumen
&lt;/h2&gt;&lt;p&gt;Las rutas gratuitas para Gemini 3.5 Flash son relativamente claras: Gemini app, Google AI Studio, API key de AI Studio y Gemini CLI pueden servir como entradas de bajo umbral. Es adecuado para chat, escritura, programación, prototipos de Agent y pruebas multimodales.&lt;/p&gt;
&lt;p&gt;Gemini Omni se centra en edición de video y creación multimodal. Sus entradas principales están en Gemini app, Google Flow y YouTube Shorts, pero las capacidades completas probablemente dependan más de suscripción y región. Es adecuado para que los creadores empiecen con pruebas y validación de conceptos, no para planificar desde el principio un servicio de producción estable.&lt;/p&gt;
&lt;p&gt;La estrategia más prudente es: probar primero tareas de texto y código con el nivel gratuito de Gemini 3.5 Flash; validar efectos de creación de video con Gemini Omni en Gemini app o Flow; y, cuando haya que lanzar algo real, pasar a una solución formal con auditoría, facturación y permisos controlados.&lt;/p&gt;
&lt;p&gt;Referencias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://deepmind.google/models/gemini/flash/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google DeepMind: Gemini 3.5 Flash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://deepmind.google/models/gemini-omni/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google DeepMind: Gemini Omni&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://apidog.com/blog/how-to-use-gemini-3-5-for-free/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Apidog: How to Use Gemini 3.5 Flash for Free&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.freedidi.com/24249.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;enlace original de freedidi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Gemini 3.5 ya está aquí: Flash llega primero y Google pone el foco en agentes y tareas largas</title>
        <link>https://knightli.com/es/2026/05/20/google-gemini-3-5-flash-agent-coding/</link>
        <pubDate>Wed, 20 May 2026 22:51:31 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/20/google-gemini-3-5-flash-agent-coding/</guid>
        <description>&lt;p&gt;Google lanzó oficialmente la serie Gemini 3.5 el 20 de mayo de 2026. El primer modelo disponible es Gemini 3.5 Flash. Su posicionamiento no es solo chat, sino agentes, generación de código y ejecución de tareas complejas de larga duración.&lt;/p&gt;
&lt;p&gt;El mensaje de esta presentación es claro: Google quiere que Gemini 3.5 no solo responda preguntas, sino que también planifique, ejecute, compruebe resultados y mantenga el avance en flujos de trabajo de varios pasos.&lt;/p&gt;
&lt;h2 id=&#34;gemini-35-flash-llega-primero&#34;&gt;Gemini 3.5 Flash llega primero
&lt;/h2&gt;&lt;p&gt;Gemini 3.5 Flash ya está disponible para varios tipos de usuarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Los usuarios generales pueden probarlo en la app Gemini y en AI Mode de Google Search.&lt;/li&gt;
&lt;li&gt;Los desarrolladores pueden usarlo mediante Google Antigravity, Google AI Studio y la Gemini API en Android Studio.&lt;/li&gt;
&lt;li&gt;Los usuarios empresariales pueden acceder a él mediante Gemini Enterprise Agent Platform y Gemini Enterprise.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google también dijo que Gemini 3.5 Pro sigue en desarrollo, ya se usa internamente en Google y se espera para el próximo mes.&lt;/p&gt;
&lt;p&gt;Esto indica que la serie 3.5 mantiene la división entre Flash y Pro: Flash enfatiza velocidad, costo y ejecución a escala, mientras que Pro probablemente apuntará a escenarios más complejos y con mayores requisitos de capacidad.&lt;/p&gt;
&lt;h2 id=&#34;el-foco-está-en-agentes-y-código&#34;&gt;El foco está en agentes y código
&lt;/h2&gt;&lt;p&gt;Google describe Gemini 3.5 Flash como uno de sus modelos más fuertes para agentes y programación. El anuncio afirma que supera algunos resultados de Gemini 3.1 Pro en benchmarks de código y agentes como Terminal-Bench 2.1, GDPval-AA, MCP Atlas y CharXiv Reasoning.&lt;/p&gt;
&lt;p&gt;La mayoría de usuarios no necesita obsesionarse con cada número. Lo más importante es que Google está llevando la capacidad del modelo hacia flujos ejecutables: no solo escribir código, sino migrar proyectos antiguos, desarrollar aplicaciones complejas, organizar reportes financieros, analizar datos y ejecutar pruebas repetidas.&lt;/p&gt;
&lt;p&gt;Dentro del framework de desarrollo Antigravity, Gemini 3.5 Flash puede usar varios subagents colaborativos para manejar tareas grandes. Google mostró ejemplos como analizar el paper de AlphaZero y crear un juego jugable, convertir código legacy a Next.js y generar paisajes urbanos y opciones de UI en paralelo.&lt;/p&gt;
&lt;p&gt;La dirección es clara: las herramientas de programación con IA están pasando de &amp;ldquo;generar un fragmento de código&amp;rdquo; a &amp;ldquo;coordinar varios agentes para completar un proyecto&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;ui-multimodal-y-gráficos-más-potentes&#34;&gt;UI multimodal y gráficos más potentes
&lt;/h2&gt;&lt;p&gt;Gemini 3.5 Flash se apoya en la base multimodal de Gemini 3. Google dice que puede generar interfaces web más ricas, animaciones interactivas y contenido visual.&lt;/p&gt;
&lt;p&gt;El anuncio incluye ejemplos como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Crear animaciones interactivas para papers de investigación.&lt;/li&gt;
&lt;li&gt;Convertir descripciones de texto en modelos de hardware interactivos.&lt;/li&gt;
&lt;li&gt;Generar un concepto completo de marca para una campaña escolar de recaudación.&lt;/li&gt;
&lt;li&gt;Producir varias opciones de UX para un flujo de checkout en poco tiempo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto importa para desarrolladores y equipos de producto. El modelo ya no solo escribe explicaciones. También puede participar en prototipos frontend, diseño de interacción y visualización.&lt;/p&gt;
&lt;h2 id=&#34;uso-empresarial-automatizar-flujos-que-consumen-tiempo&#34;&gt;Uso empresarial: automatizar flujos que consumen tiempo
&lt;/h2&gt;&lt;p&gt;Google citó varios ejemplos de socios. Shopify usa subagents para analizar datos complejos y predecir crecimiento de comerciantes. Macquarie Bank prueba 3.5 Flash con documentos de más de 100 páginas para acelerar la apertura de cuentas. Salesforce lo integra en Agentforce. Ramp lo usa para mejorar OCR en facturas complejas. Xero usa agentes de IA para procesos administrativos. Databricks usa flujos automatizados para monitorear anomalías de datos y sugerir correcciones.&lt;/p&gt;
&lt;p&gt;Estos casos apuntan a la misma tendencia: la adopción empresarial de modelos grandes se está moviendo de preguntas puntuales a automatización de procesos. Que un modelo sea barato, rápido y estable en tareas largas puede importar más que una respuesta aislada muy llamativa.&lt;/p&gt;
&lt;h2 id=&#34;gemini-spark-un-agente-personal-de-ia&#34;&gt;Gemini Spark: un agente personal de IA
&lt;/h2&gt;&lt;p&gt;Google también anunció Gemini Spark, un agente personal de IA impulsado por Gemini 3.5 Flash. Su objetivo es ejecutarse durante largos periodos y realizar tareas de forma proactiva bajo la guía del usuario.&lt;/p&gt;
&lt;p&gt;Gemini Spark ya empezó a desplegarse para testers de confianza. Google planea abrir una beta la próxima semana para suscriptores de Google AI Ultra en Estados Unidos.&lt;/p&gt;
&lt;p&gt;Vale la pena seguir esta parte. Google Search, la app Gemini, Android, Workspace y el ecosistema del navegador ya están presentes en muchas áreas de la vida digital personal. Si un agente personal puede conectarse con estas entradas, su impacto puede ser mayor que el de un chatbot aislado.&lt;/p&gt;
&lt;h2 id=&#34;la-seguridad-se-mueve-más-arriba-en-el-proceso&#34;&gt;La seguridad se mueve más arriba en el proceso
&lt;/h2&gt;&lt;p&gt;Google dice que Gemini 3.5 fue desarrollado bajo su Frontier Safety Framework, con protecciones reforzadas para seguridad de la información y riesgos CBRN. El anuncio también menciona herramientas de interpretabilidad para ayudar a examinar y entender el razonamiento del modelo antes de entregar respuestas.&lt;/p&gt;
&lt;p&gt;Esto muestra que los lanzamientos de modelos frontera ya no son solo una competencia de capacidad. Cuanto más se enfatizan agentes, ejecución autónoma y tareas largas, más importantes se vuelven los controles de seguridad, la tasa de rechazos erróneos, la prevención de salidas dañinas y la interpretabilidad.&lt;/p&gt;
&lt;h2 id=&#34;cómo-mirar-gemini-35&#34;&gt;Cómo mirar Gemini 3.5
&lt;/h2&gt;&lt;p&gt;Gemini 3.5 Flash no es solo otro lanzamiento de modelo. Parece más bien la apuesta de Google por la siguiente forma de los productos de IA: modelos que llaman herramientas, dividen tareas, coordinan ejecución, generan UI y entran en flujos personales y empresariales.&lt;/p&gt;
&lt;p&gt;Para desarrolladores, lo importante será la experiencia real en Google Antigravity, AI Studio, Gemini API y Android Studio. Para empresas, la pregunta es si puede reducir trabajo manual de forma estable en flujos reales, no solo sacar buenos resultados en benchmarks.&lt;/p&gt;
&lt;p&gt;Gemini 3.5 Pro todavía no está disponible públicamente. Cuando Pro llegue, las diferencias entre Flash y Pro en capacidad, precio, velocidad y manejo de contexto determinarán para qué escenarios de producción conviene cada uno.&lt;/p&gt;
&lt;p&gt;Referencias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/intl/zh-tw/products/explore-get-answers/gemini-3-5/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: Gemini 3.5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Filtración de Google Gemini Spark: podría llegar un Gemini Agent online las 24 horas</title>
        <link>https://knightli.com/es/2026/05/17/google-gemini-spark-ai-agent-leak/</link>
        <pubDate>Sun, 17 May 2026 11:58:08 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/17/google-gemini-spark-ai-agent-leak/</guid>
        <description>&lt;p&gt;Google todavía no ha lanzado oficialmente &lt;code&gt;Gemini Spark&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;La información actual proviene sobre todo de interfaces internas de prueba en Gemini Web, capturas de la comunidad, reportes de TestingCatalog y resúmenes de 36Kr / Xinzhiyuan sobre filtraciones relacionadas. La lectura más consistente es que &lt;code&gt;Gemini Spark BETA&lt;/code&gt; podría ser un AI Agent always-on que Google está preparando. Su posición ya no sería solo la de un asistente de chat, sino la de un &amp;ldquo;agente de IA cotidiano&amp;rdquo; capaz de manejar correo, tareas online y flujos de varios pasos en segundo plano.&lt;/p&gt;
&lt;p&gt;Así que conviene fijar primero el límite: esto es un análisis de filtraciones, no un anuncio oficial de Google. Funciones, nombre y fecha de lanzamiento aún deben ser confirmados por Google.&lt;/p&gt;
&lt;h2 id=&#34;conclusión-rápida&#34;&gt;Conclusión rápida
&lt;/h2&gt;&lt;p&gt;Según la información expuesta hasta ahora, Gemini Spark tiene tres puntos clave:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Podría ser un Agent online las 24 horas dentro del sistema Gemini, no un modelo de chat normal.&lt;/li&gt;
&lt;li&gt;Podría usar un contexto personal más amplio, incluyendo apps de Google, historial de chats, tareas, sitios con sesión iniciada y ubicación.&lt;/li&gt;
&lt;li&gt;Sus riesgos son tan grandes como su atractivo, porque puede involucrar compartir información, datos de navegador remoto, compras y llamadas a servicios de terceros.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Si Google realmente lanza Spark, el papel de Gemini cambiará: de &amp;ldquo;IA que responde preguntas&amp;rdquo; a &amp;ldquo;IA que gestiona tareas por ti de forma continua&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;qué-es-gemini-spark&#34;&gt;Qué es Gemini Spark
&lt;/h2&gt;&lt;p&gt;TestingCatalog reportó el 14 de mayo de 2026 que Google está probando &lt;code&gt;Gemini Spark BETA&lt;/code&gt; dentro de Gemini Web. El texto de bienvenida expuesto lo describe como un everyday AI agent que puede ayudar 24/7 con inbox, online tasks y más trabajo de varios pasos.&lt;/p&gt;
&lt;p&gt;El artículo de 36Kr / Xinzhiyuan también menciona que, tras descubrirse Spark, lo que se ve desde fuera es una dirección de &amp;ldquo;Agent de tiempo completo&amp;rdquo;: puede permanecer disponible todo el día, procesar la bandeja de entrada, ejecutar tareas online e incluso involucrar compras y compartición de información.&lt;/p&gt;
&lt;p&gt;Esto significa que Spark no es simplemente el nombre de un nuevo modelo. Se parece más a una actualización de la capa de producto de Gemini: sacar a Gemini de la ventana de conversación y llevarlo al correo, la web, el calendario, las tareas y los flujos entre apps del usuario.&lt;/p&gt;
&lt;h2 id=&#34;cómo-podría-funcionar&#34;&gt;Cómo podría funcionar
&lt;/h2&gt;&lt;p&gt;Según el texto de onboarding oculto divulgado por TestingCatalog, Gemini Spark obtendría contexto de varias fuentes, incluyendo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Connected Apps.&lt;/li&gt;
&lt;li&gt;skills.&lt;/li&gt;
&lt;li&gt;chats.&lt;/li&gt;
&lt;li&gt;tasks.&lt;/li&gt;
&lt;li&gt;Sitios web donde el usuario inició sesión.&lt;/li&gt;
&lt;li&gt;Personal intelligence.&lt;/li&gt;
&lt;li&gt;location.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esta información ayudaría a Spark a entender qué quiere completar el usuario y a invocar el contexto necesario durante la ejecución de tareas. El texto también menciona que, para completar algunas acciones, Gemini podría compartir información necesaria con terceros, como nombre, datos de contacto, archivos, preferencias e información que el usuario podría considerar sensible.&lt;/p&gt;
&lt;p&gt;Si estas descripciones terminan siendo correctas, Spark funcionaría más como un sistema de agente con contexto que como una herramienta de preguntas y respuestas de una sola vez. No miraría solo el prompt actual, sino que podría combinar preferencias a largo plazo, apps conectadas, estado del navegador e historial de tareas.&lt;/p&gt;
&lt;h2 id=&#34;por-qué-importa&#34;&gt;Por qué importa
&lt;/h2&gt;&lt;p&gt;La clave de Gemini Spark no es añadir otra entrada de chat. La clave es que Google tiene una entrada natural al ecosistema.&lt;/p&gt;
&lt;p&gt;OpenAI y Anthropic pueden construir Agents muy fuertes, pero no poseen de forma natural la cadena completa de Gmail, Calendar, Drive, Chrome, Android y Workspace. Si Google conecta Spark con estos productos, los usuarios no necesitarán montar demasiados flujos adicionales para que un Agent entre en su trabajo diario.&lt;/p&gt;
&lt;p&gt;Esto puede traer tres cambios.&lt;/p&gt;
&lt;p&gt;Primero, Gemini pasaría de preguntas y respuestas pasivas a ejecución activa. Los usuarios ya no solo preguntarían &amp;ldquo;resúmeme este correo&amp;rdquo;, sino que podrían pedirle que organice el inbox, siga tareas y ejecute acciones posteriores de forma continua.&lt;/p&gt;
&lt;p&gt;Segundo, los Agents dependerán más del contexto personal. Cuanto más entienda tu correo, calendario, archivos, estado del navegador y preferencias, más útiles podrán ser sus resultados.&lt;/p&gt;
&lt;p&gt;Tercero, los límites de permisos serán más sensibles. Poder hacer más también significa que el usuario debe saber con más claridad cuándo puede actuar, hasta dónde puede llegar y si necesita confirmación.&lt;/p&gt;
&lt;h2 id=&#34;dónde-están-los-riesgos&#34;&gt;Dónde están los riesgos
&lt;/h2&gt;&lt;p&gt;Hay varios puntos en el texto divulgado por TestingCatalog que merecen atención.&lt;/p&gt;
&lt;p&gt;Primero, Spark es experimental. Incluso si se lanza, no debería tratarse como un sistema completamente maduro que no requiere supervisión.&lt;/p&gt;
&lt;p&gt;Segundo, aunque el sistema está diseñado para pedir permiso antes de operaciones sensibles, el texto también advierte que podría compartir información o completar compras sin preguntar.&lt;/p&gt;
&lt;p&gt;Tercero, para mantener la continuidad de la sesión, Gemini guardará remote browser data, como detalles de inicio de sesión y remote code execution data. Los usuarios pueden borrar estos datos en Settings y también desactivar Connected Apps y capacidades relacionadas con Personal intelligence.&lt;/p&gt;
&lt;p&gt;En conjunto, estos puntos muestran que la dirección de producto de Spark es agresiva: quiere ser un Agent que realmente ejecute tareas, no solo que genere sugerencias. Pero cuanto más se acerca a la ejecución real, más necesita permisos estrictos, auditoría, confirmación y mecanismos de reversión.&lt;/p&gt;
&lt;h2 id=&#34;relación-con-remy-y-ai-ultra&#34;&gt;Relación con Remy y AI Ultra
&lt;/h2&gt;&lt;p&gt;TestingCatalog menciona que Spark podría ser una versión renombrada de la agentic Gemini upgrade antes conocida internamente como &lt;code&gt;Remy&lt;/code&gt;, y que también podría estar relacionada con la dirección de Gemini Agent para suscriptores de Google AI Ultra.&lt;/p&gt;
&lt;p&gt;Si esta pista es correcta, Spark no sería un proyecto nuevo surgido de la nada. Podría ser una forma de reempaquetar capacidades de Agent más avanzadas y cerradas, para prepararlas para una audiencia más amplia.&lt;/p&gt;
&lt;p&gt;36Kr / Xinzhiyuan también lo describe como una evolución de “Remy” a “Spark”: Gemini Agent deja de ser solo una función y se mueve hacia un gestor digital de vida 24/7.&lt;/p&gt;
&lt;p&gt;Pero esto sigue siendo una interpretación basada en filtraciones. Si Google usará &lt;code&gt;Spark&lt;/code&gt; como nombre oficial, si será solo para AI Ultra o si habrá una suscripción más ligera todavía necesita confirmación oficial.&lt;/p&gt;
&lt;h2 id=&#34;mcp-skills-y-ecosistema-de-herramientas&#34;&gt;MCP, skills y ecosistema de herramientas
&lt;/h2&gt;&lt;p&gt;En la misma tanda de capturas comunitarias también aparecieron entradas del selector de modelos como &lt;code&gt;MCP Tool Testing&lt;/code&gt;. El artículo de 36Kr cree que esto podría sugerir soporte nativo de Gemini para integración de herramientas de terceros vía MCP, además de una reconstrucción del modo Thinking.&lt;/p&gt;
&lt;p&gt;Esta pista se vuelve más interesante al mirarla junto a Spark.&lt;/p&gt;
&lt;p&gt;Si Spark fuera solo un &amp;ldquo;asistente que chatea&amp;rdquo;, skills y MCP tendrían menos importancia. Pero si Spark es un Agent de larga duración, necesita llamar herramientas de forma fiable, acceder a páginas web, ejecutar tareas, leer y escribir contexto, y entregar resultados al usuario.&lt;/p&gt;
&lt;p&gt;Es decir, Spark quizá no sea una función aislada, sino parte del ecosistema de herramientas Agent de Google: el modelo entiende y planifica, mientras skills / MCP / connected apps ejecutan y amplían.&lt;/p&gt;
&lt;h2 id=&#34;qué-significa-para-usuarios-comunes&#34;&gt;Qué significa para usuarios comunes
&lt;/h2&gt;&lt;p&gt;Si Gemini Spark se lanza de verdad, los cambios más directos para usuarios comunes podrían ser:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El correo no solo se resume, sino que se clasifica, se sigue y se convierte en tareas.&lt;/li&gt;
&lt;li&gt;Las tareas web no solo reciben sugerencias, sino que podrían ejecutarse de forma continua en un navegador remoto.&lt;/li&gt;
&lt;li&gt;Calendario, ubicación, preferencias y conversaciones previas se convierten en contexto a largo plazo del Agent.&lt;/li&gt;
&lt;li&gt;Compras, reservas, formularios y acciones similares podrían entrar en el alcance de ejecución de la IA.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Suena cómodo, pero los usuarios tendrán que crear nuevos hábitos: no solo mirar qué dice la IA, sino también qué se prepara para hacer, qué ya hizo, si se puede deshacer y si hay registro.&lt;/p&gt;
&lt;p&gt;La experiencia futura de AI Agent no dependerá solo de qué tan inteligente sea el modelo, sino también de si los avisos de permisos son claros, si los logs de tareas se pueden revisar y si los errores se pueden recuperar.&lt;/p&gt;
&lt;h2 id=&#34;qué-significa-para-desarrolladores-y-equipos&#34;&gt;Qué significa para desarrolladores y equipos
&lt;/h2&gt;&lt;p&gt;Para desarrolladores, Spark importa porque Google podría estar moviendo los Agents desde &amp;ldquo;productos demo&amp;rdquo; hacia plataformas reales de workflow.&lt;/p&gt;
&lt;p&gt;Si Spark puede conectar de forma estable apps de Google, herramientas de terceros y estado del navegador, los desarrolladores se preguntarán:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Si habrá APIs o mecanismos de extensión abiertos.&lt;/li&gt;
&lt;li&gt;Si MCP o skills podrán ser conectados por terceros.&lt;/li&gt;
&lt;li&gt;Si administradores empresariales podrán controlar permisos, retención de datos y auditoría.&lt;/li&gt;
&lt;li&gt;Si los fallos de ejecución del Agent tendrán logs rastreables.&lt;/li&gt;
&lt;li&gt;Si habrá sandboxing, flujos de aprobación y confirmación para operaciones sensibles.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para equipos, Spark probablemente entraría primero por escenarios frecuentes como Gmail, Calendar, Docs, Drive y Chrome. Quizá al principio no sea adecuado para automatizar por completo tareas de alto riesgo, pero encaja bien como asistente para inbox triage, seguimiento de reuniones, organización de documentos, investigación de mercado y tareas ligeras de operaciones.&lt;/p&gt;
&lt;h2 id=&#34;cómo-leerlo-ahora&#34;&gt;Cómo leerlo ahora
&lt;/h2&gt;&lt;p&gt;Esta noticia se entiende mejor como &amp;ldquo;dirección de alta confianza, detalles de baja certeza&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;La dirección de alta confianza es que Google está empujando Gemini Agent hacia algo más proactivo, más duradero y más profundamente integrado con su ecosistema. El texto de prueba de Gemini Web reportado por TestingCatalog, las capturas comunitarias y la recopilación de filtraciones de 36Kr apuntan en la misma dirección.&lt;/p&gt;
&lt;p&gt;Los detalles de baja certeza son el nombre oficial, la fecha de lanzamiento, las reglas de permisos, los niveles de suscripción, las regiones disponibles, si habrá API abierta y si realmente se llamará Gemini Spark.&lt;/p&gt;
&lt;p&gt;La lectura más prudente por ahora:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No tratar Spark como un producto oficial ya lanzado.&lt;/li&gt;
&lt;li&gt;Verlo como una señal fuerte de la próxima ruta de Google en AI Agents.&lt;/li&gt;
&lt;li&gt;Esperar cómo Google explicará permisos, privacidad, compartición de datos con terceros y almacenamiento de datos de navegador remoto.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;resumen&#34;&gt;Resumen
&lt;/h2&gt;&lt;p&gt;Si &lt;code&gt;Gemini Spark&lt;/code&gt; finalmente se lanza, podría ser un paso clave para que Gemini pase de asistente de chat a Agent always-on. No es solo cambiar un modelo, sino colocar Gemini dentro del ecosistema de Google: correo, web, tareas, ubicación, personal intelligence y servicios de terceros.&lt;/p&gt;
&lt;p&gt;Su potencial es grande: más proactivo, más cercano a flujos reales y más fácil de distribuir a muchos usuarios gracias al ecosistema de Google. Sus riesgos son igual de grandes: si la IA puede compartir información, guardar estado del navegador, ejecutar compras y llamar servicios de terceros, los límites de permisos deben ser muy claros.&lt;/p&gt;
&lt;p&gt;Por eso lo más importante de Gemini Spark no es &amp;ldquo;qué tan inteligente es&amp;rdquo;, sino cómo piensa Google hacer que un AI Agent online las 24 horas sea controlable, auditable y confiable.&lt;/p&gt;
&lt;p&gt;Referencias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.testingcatalog.com/google-prepares-gemini-spark-ai-agent-ahead-of-i-o-launch/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;TestingCatalog: Google prepares Gemini Spark AI Agent ahead of I/O launch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://36kr.com/p/3810432812162816&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;36Kr: Gemini 3.5 Pro filtrado, coding supuestamente alcanza a GPT-5.5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Filtración de Gemini 3.5 Pro: con nombre en clave Cappuccino, Google intenta recuperar ritmo en coding y agentes</title>
        <link>https://knightli.com/es/2026/05/17/gemini-35-pro-cappuccino-spark-leak/</link>
        <pubDate>Sun, 17 May 2026 11:47:27 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/17/gemini-35-pro-cappuccino-spark-leak/</guid>
        <description>&lt;p&gt;Google todavía no ha lanzado oficialmente &lt;code&gt;Gemini 3.5 Pro&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;La información disponible por ahora proviene sobre todo de capturas de comunidades de desarrolladores, benchmarks anónimos, filtradores y reportes de medios. El 15 de mayo de 2026, 36Kr / Xinzhiyuan publicó que un checkpoint de la próxima generación de Gemini podría tener el nombre interno &lt;code&gt;Cappuccino&lt;/code&gt;, y que modelos relacionados ya habrían aparecido en comunidades y plataformas de evaluación.&lt;/p&gt;
&lt;p&gt;Esta información no debe tratarse como un lanzamiento oficial, pero sí muestra una dirección clara: Google intenta cubrir dos brechas a la vez, coding y razonamiento por un lado, y agentes de IA always-on por el otro.&lt;/p&gt;
&lt;h2 id=&#34;conclusión-rápida&#34;&gt;Conclusión rápida
&lt;/h2&gt;&lt;p&gt;Esta filtración puede leerse en tres capas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Gemini 3.5 Pro&lt;/code&gt; aún no ha sido lanzado oficialmente, y &lt;code&gt;Cappuccino&lt;/code&gt; parece más un checkpoint interno o una build candidata.&lt;/li&gt;
&lt;li&gt;La información filtrada sugiere que el nuevo Gemini mejora en generación de código, generación SVG / web interactiva y salida multimodal.&lt;/li&gt;
&lt;li&gt;La prueba paralela de &lt;code&gt;Gemini Spark&lt;/code&gt; por parte de Google puede ser más importante que el modelo en sí, porque apunta a un agente personal de IA funcionando 24 horas.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;En otras palabras, no es solo una historia de benchmarks. Parece más una señal de roadmap antes de Google I/O: el modelo necesita alcanzar a GPT-5.5, mientras la capa de agentes necesita capturar flujos de trabajo de usuarios.&lt;/p&gt;
&lt;h2 id=&#34;qué-es-cappuccino&#34;&gt;Qué es Cappuccino
&lt;/h2&gt;&lt;p&gt;El artículo de 36Kr menciona que, según una publicación de Lentils, el checkpoint de &lt;code&gt;Gemini 3.5 Pro&lt;/code&gt; con nombre en clave &lt;code&gt;Cappuccino&lt;/code&gt; ya habría empezado a producirse. La comunidad todavía hablaba de &lt;code&gt;Gemini 3.2&lt;/code&gt; horas antes, pero la filtración más reciente saltó directamente a &lt;code&gt;3.5&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si ese nombre termina siendo correcto, Google podría querer presentar el próximo Gemini como un salto de versión más grande, no como una actualización menor.&lt;/p&gt;
&lt;p&gt;Por ahora, &lt;code&gt;Cappuccino&lt;/code&gt; debe tratarse como un nombre interno filtrado. No significa que Google haya lanzado públicamente el modelo final, ni garantiza que el nombre de lanzamiento vaya a ser &lt;code&gt;Gemini 3.5 Pro&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;por-qué-el-coding-es-el-foco&#34;&gt;Por qué el coding es el foco
&lt;/h2&gt;&lt;p&gt;La parte más comentada de la filtración es la capacidad de coding del nuevo Gemini.&lt;/p&gt;
&lt;p&gt;Según capturas y supuestos benchmarks citados por 36Kr, el nuevo modelo parece más fuerte en:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generación de SVG y componentes visuales.&lt;/li&gt;
&lt;li&gt;Generación de aplicaciones web interactivas.&lt;/li&gt;
&lt;li&gt;Manejo de animación, 3D, paneles de parámetros ajustables y otras salidas frontend complejas.&lt;/li&gt;
&lt;li&gt;Mejoras en razonamiento lógico y generación de código.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El artículo también cita a Bindu Reddy, CEO de Abacus.AI, diciendo que &lt;code&gt;3.2 Flash&lt;/code&gt; se acerca a &lt;code&gt;GPT-5.5&lt;/code&gt; en coding y razonamiento, con un coste mucho menor. Otras fuentes de medios creen que el nuevo Gemini se ubica aproximadamente en el nivel de &lt;code&gt;GPT-5.5&lt;/code&gt;, aunque quizá no represente un salto cualitativo.&lt;/p&gt;
&lt;p&gt;Por eso conviene leer con cautela la frase &amp;ldquo;alcanza a GPT-5.5&amp;rdquo;. Se parece más a un juicio relativo basado en filtraciones y pruebas anónimas que a un resultado oficial de benchmark de Google.&lt;/p&gt;
&lt;h2 id=&#34;por-qué-google-necesita-ponerse-al-día-en-coding&#34;&gt;Por qué Google necesita ponerse al día en coding
&lt;/h2&gt;&lt;p&gt;El AI coding pasó de ser una categoría de herramientas para desarrolladores a ocupar el centro de la competencia entre modelos fundacionales.&lt;/p&gt;
&lt;p&gt;OpenAI tiene Codex y Anthropic tiene Claude Code. No solo sirven a ingenieros: también llevan a product managers, diseñadores y equipos de operaciones a flujos donde el lenguaje natural produce productos ejecutables.&lt;/p&gt;
&lt;p&gt;En comparación, Google tiene Gemini y Antigravity, pero no ha logrado formar el mismo punto de entrada predeterminado en la mente de los desarrolladores. El artículo de 36Kr también señala que Antigravity no ha logrado despegar claramente en el mercado externo, y que precios, avisos de cuota y estabilidad de experiencia han generado discusión en la comunidad.&lt;/p&gt;
&lt;p&gt;Así que, si el nuevo Gemini necesita demostrar algo, coding será el campo de batalla más directo. La pregunta no es solo si puede escribir código, sino si puede producir interfaces completas de forma estable, entender requisitos complejos, llamar herramientas, corregir errores e integrarse en flujos reales de desarrollo.&lt;/p&gt;
&lt;h2 id=&#34;spark-puede-importar-más-que-35-pro&#34;&gt;Spark puede importar más que 3.5 Pro
&lt;/h2&gt;&lt;p&gt;En la misma ola de filtraciones también apareció &lt;code&gt;Gemini Spark BETA&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Según TestingCatalog y otras fuentes, Spark se posiciona como un agente de IA always-on: puede procesar la bandeja de entrada, ejecutar tareas online, gestionar flujos de varios pasos y conectar contexto de apps de Google, módulos de habilidades, historial de chats, tareas programadas, sitios con sesión iniciada e información de ubicación.&lt;/p&gt;
&lt;p&gt;Eso significa que Spark no es una entrada de chat normal. Podría ser un sistema que permanece online, lee contexto de forma continua y ejecuta tareas por el usuario.&lt;/p&gt;
&lt;p&gt;El atractivo es obvio: si Google puede conectar Gmail, Calendar, Chrome, Android, Workspace y Gemini, Spark tendrá una ventaja de distribución difícil de copiar para OpenAI y Anthropic.&lt;/p&gt;
&lt;p&gt;El riesgo también es obvio. El artículo de 36Kr menciona una descripción de Spark según la cual podría compartir información o completar compras sin preguntar. Aunque el sistema esté diseñado para pedir permiso antes de operaciones sensibles, este tipo de agente sigue planteando riesgos de privacidad, límites de autorización y acciones accidentales.&lt;/p&gt;
&lt;h2 id=&#34;qué-significa-para-usuarios-comunes&#34;&gt;Qué significa para usuarios comunes
&lt;/h2&gt;&lt;p&gt;Si eres un usuario normal de Gemini, lo más importante de esta filtración no es el nombre del modelo, sino tres cambios.&lt;/p&gt;
&lt;p&gt;Primero, Google puede seguir reforzando la capacidad de producir resultados completos. Antes, usuarios se quejaban de que Gemini podía ser perezoso en generación visual, SVG y páginas frontend. Si el nuevo modelo puede generar varias propuestas completas en una sola pasada, la experiencia mejorará de forma visible.&lt;/p&gt;
&lt;p&gt;Segundo, la capacidad de coding seguirá bajando a modelos más ligeros. La filtración menciona varias veces mejoras de Flash en coding, razonamiento y generación interactiva, lo que significa que en el futuro no siempre hará falta un modelo Pro para tareas complejas.&lt;/p&gt;
&lt;p&gt;Tercero, los agentes serán más proactivos. Si Spark se lanza, Gemini podría dejar de limitarse a responder preguntas y empezar a asumir correo, web, compras, calendario y tareas entre apps durante periodos largos.&lt;/p&gt;
&lt;p&gt;Eso es bueno para la eficiencia, pero crea un nuevo desafío de gestión de permisos.&lt;/p&gt;
&lt;h2 id=&#34;qué-significa-para-desarrolladores&#34;&gt;Qué significa para desarrolladores
&lt;/h2&gt;&lt;p&gt;Los desarrolladores deberían vigilar dos cuestiones.&lt;/p&gt;
&lt;p&gt;La primera es el ecosistema de herramientas. El artículo de 36Kr dice que la comunidad vio una entrada no publicada llamada &lt;code&gt;MCP Tool Testing&lt;/code&gt; en el selector de modelos. Si Gemini soporta MCP o pruebas de herramientas de terceros de forma nativa, será más fácil conectarlo a las toolchains propias de los desarrolladores.&lt;/p&gt;
&lt;p&gt;La segunda es coste y estabilidad. Aunque el nuevo Gemini alcance a GPT-5.5 en algunos benchmarks, los desarrolladores acabarán mirando tres cosas: calidad real del código, estabilidad del contexto, y si precios y cuotas son predecibles.&lt;/p&gt;
&lt;p&gt;El último año de competencia en herramientas de AI coding ha demostrado que la capacidad del modelo es solo el billete de entrada. Lo que retiene a los desarrolladores es si la herramienta puede editar código, ejecutar tests, leer contexto y manejar casos límite de forma fiable en proyectos diarios.&lt;/p&gt;
&lt;h2 id=&#34;cómo-leer-esta-noticia-ahora&#34;&gt;Cómo leer esta noticia ahora
&lt;/h2&gt;&lt;p&gt;Esta noticia se entiende mejor como &amp;ldquo;señal fuerte, confirmación débil&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;La señal fuerte es que múltiples pistas comunitarias apuntan a que Google prepara un Gemini más fuerte y un Gemini Spark Agent más proactivo.&lt;/p&gt;
&lt;p&gt;La confirmación débil es que &lt;code&gt;Gemini 3.5 Pro&lt;/code&gt; aún no ha sido lanzado oficialmente, &lt;code&gt;Cappuccino&lt;/code&gt; sigue siendo un nombre filtrado, y la afirmación de que &amp;ldquo;alcanza a GPT-5.5&amp;rdquo; necesita validación con benchmarks oficiales de Google, pruebas de terceros y experiencia real de usuarios.&lt;/p&gt;
&lt;p&gt;La lectura más prudente por ahora:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No tratarlo como un producto ya lanzado.&lt;/li&gt;
&lt;li&gt;Tratarlo como una vista previa temprana de la próxima dirección de Gemini.&lt;/li&gt;
&lt;li&gt;Observar si I/O u otros eventos oficiales confirman el nombre del modelo, disponibilidad de API, precios, ventana de contexto, tool calling y límites de permisos del agente.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;resumen&#34;&gt;Resumen
&lt;/h2&gt;&lt;p&gt;La exposición de &lt;code&gt;Gemini 3.5 Pro / Cappuccino&lt;/code&gt; sugiere que Google podría estar preparando un empuje más fuerte para la próxima generación de Gemini. No intenta corregir una sola capacidad aislada, sino todo un flujo de trabajo de IA: el modelo debe escribir mejor código, generar interfaces y manejar razonamiento complejo, mientras Spark empuja Gemini hacia un agente always-on.&lt;/p&gt;
&lt;p&gt;Pero antes de un lanzamiento oficial, todos los benchmarks y capturas siguen siendo pistas. Lo que decidirá si Gemini 3.5 Pro puede recuperar impulso no será si el nombre en clave suena bien, sino si puede ganar de forma fiable en desarrollo real, trabajo de oficina real y tareas reales de varios pasos.&lt;/p&gt;
&lt;p&gt;Referencias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://m.36kr.com/p/3810432812162816&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;36Kr: Gemini 3.5 Pro filtrado, coding supuestamente alcanza a GPT-5.5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.testingcatalog.com/google-prepares-gemini-spark-ai-agent-ahead-of-i-o-launch/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;TestingCatalog: Google prepares Gemini Spark AI agent ahead of I/O launch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://x.com/alexeheath/status/2054747125616169229&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X: Alex Heath sobre el nuevo Gemini y GPT-5.5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://x.com/Lentils80/status/2054628116094501377&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;X: Lentils sobre Gemini 3.5 / Cappuccino&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Gemini Intelligence on Android: Google está convirtiendo el teléfono en un sistema de IA proactivo</title>
        <link>https://knightli.com/es/2026/05/17/google-gemini-intelligence-android/</link>
        <pubDate>Sun, 17 May 2026 09:13:32 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/17/google-gemini-intelligence-android/</guid>
        <description>&lt;p&gt;El 12 de mayo de 2026, Google publicó “A smarter, more proactive Android with Gemini Intelligence”, presentando Gemini Intelligence on Android. No es una app de chat independiente. Lleva capacidades de Gemini a Android, Chrome, Gboard, Autofill, widgets y experiencias multidispositivo, moviendo el teléfono desde “esperar a que el usuario toque” hacia “ayudar de forma proactiva a completar tareas”.&lt;/p&gt;
&lt;p&gt;En pocas palabras, Google quiere que Android pase de operating system a intelligence system. El teléfono ya no solo abre apps, muestra notificaciones y ejecuta ajustes; puede entender la pantalla, las apps, la voz y el contexto personal, y completar acciones más complejas con confirmación del usuario.&lt;/p&gt;
&lt;h2 id=&#34;resumen-rápido&#34;&gt;Resumen rápido
&lt;/h2&gt;&lt;p&gt;Gemini Intelligence on Android se centra en cinco áreas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automatización de varios pasos: Gemini puede completar flujos entre apps, como transporte, compras o investigación.&lt;/li&gt;
&lt;li&gt;Navegación inteligente en Chrome: resumir páginas, comparar información y manejar algunas tareas web repetitivas en Android.&lt;/li&gt;
&lt;li&gt;Autofill mejorado: usar Gemini y contexto personal para completar formularios más complejos.&lt;/li&gt;
&lt;li&gt;Rambler: convertir habla natural en texto más claro y pulido.&lt;/li&gt;
&lt;li&gt;Widgets por lenguaje natural: describir lo que quieres y Android genera widgets personalizados.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Estas funciones empezarán a desplegarse en verano de 2026, primero en algunos Samsung Galaxy y Google Pixel, y después en más dispositivos Android, incluidos relojes, coches, gafas y portátiles.&lt;/p&gt;
&lt;h2 id=&#34;automatización-de-varios-pasos-de-sugerir-a-ejecutar&#34;&gt;Automatización de varios pasos: de sugerir a ejecutar
&lt;/h2&gt;&lt;p&gt;La dirección más importante es permitir que Gemini complete tareas de varios pasos entre apps.&lt;/p&gt;
&lt;p&gt;Google da ejemplos como reservar una clase de spinning, encontrar un temario en Gmail y añadir los libros necesarios al carrito, o ver un cartel de viaje y pedir a Gemini que busque un viaje similar en Expedia.&lt;/p&gt;
&lt;p&gt;Lo difícil no es solo entender una frase. El sistema necesita entender:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qué aparece en la pantalla o imagen actual del usuario.&lt;/li&gt;
&lt;li&gt;Información de apps que el usuario haya autorizado.&lt;/li&gt;
&lt;li&gt;Qué app debe abrirse después.&lt;/li&gt;
&lt;li&gt;Qué pasos pueden automatizarse.&lt;/li&gt;
&lt;li&gt;Qué pasos deben detenerse para pedir confirmación.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google subraya que Gemini actúa bajo instrucciones del usuario y se detiene cuando termina la tarea, manteniendo la confirmación final bajo control del usuario. No es un agente totalmente autónomo, sino un agent móvil con confirmación humana.&lt;/p&gt;
&lt;h2 id=&#34;la-pantalla-y-la-imagen-importan-más&#34;&gt;La pantalla y la imagen importan más
&lt;/h2&gt;&lt;p&gt;Un cambio importante es el uso de screen context e image context.&lt;/p&gt;
&lt;p&gt;Los asistentes móviles anteriores dependían más de comandos de voz e integraciones fijas dentro de apps. Gemini Intelligence pone más énfasis en “ver” la pantalla actual. Por ejemplo, si el usuario tiene una lista de compras en notas, puede mantener presionado el botón de encendido para invocar Gemini y pedirle que cree un carrito de entrega a partir de la lista.&lt;/p&gt;
&lt;p&gt;Esto significa que la IA de Android no es solo un chatbot. Está intentando entender el entorno operativo que el usuario tiene delante. La competencia futura de IA móvil puede depender no solo de quién responda mejor, sino también de:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Si entiende la pantalla actual.&lt;/li&gt;
&lt;li&gt;Si puede actuar entre apps.&lt;/li&gt;
&lt;li&gt;Si puede seguir el progreso de tareas en segundo plano.&lt;/li&gt;
&lt;li&gt;Si pide confirmación de forma fiable en momentos clave.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esa es una diferencia importante entre la IA móvil y la IA de chat web.&lt;/p&gt;
&lt;h2 id=&#34;chrome-de-búsqueda-a-agente-de-tareas-web&#34;&gt;Chrome: de búsqueda a agente de tareas web
&lt;/h2&gt;&lt;p&gt;Google dice que los dispositivos Android recibirán un Gemini in Chrome más inteligente a partir de finales de junio de 2026.&lt;/p&gt;
&lt;p&gt;Podrá ayudar a investigar, resumir y comparar contenido web, y Chrome auto browse podrá manejar algunas tareas repetitivas como reservas, citas o aparcamiento.&lt;/p&gt;
&lt;p&gt;Esto significa que Gemini in Chrome no es solo una función de resumen de páginas. Avanza hacia un agente de navegador. El navegador ya es donde los usuarios completan muchas tareas web. Si Gemini puede entender páginas, rellenar información, comparar opciones y ejecutar algunos pasos, Chrome pasa de herramienta de lectura a superficie de ejecución.&lt;/p&gt;
&lt;p&gt;Los retos son prácticos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Los sitios web son complejos y la automatización puede fallar.&lt;/li&gt;
&lt;li&gt;Formularios, pagos, inicios de sesión y CAPTCHAs requieren cautela.&lt;/li&gt;
&lt;li&gt;El usuario necesita saber qué hizo Gemini.&lt;/li&gt;
&lt;li&gt;El envío final, pago o reserva debería conservar confirmación humana.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La dificultad no está solo en el modelo, sino en automatización del navegador, límites de seguridad y confianza del usuario.&lt;/p&gt;
&lt;h2 id=&#34;autofill-de-contraseñas-a-formularios-complejos&#34;&gt;Autofill: de contraseñas a formularios complejos
&lt;/h2&gt;&lt;p&gt;Autofill with Google se centraba sobre todo en contraseñas, direcciones y pagos. Google ahora quiere convertirlo en un asistente de formularios más inteligente.&lt;/p&gt;
&lt;p&gt;Con Personal Intelligence de Gemini, Android puede usar información relevante de apps conectadas para completar campos más complejos, incluidos formularios en Chrome.&lt;/p&gt;
&lt;p&gt;Es muy práctico. Rellenar formularios complejos en móvil es incómodo: pantalla pequeña, muchos campos e información repartida entre correo, calendario, chats y documentos. Si Gemini puede organizar y rellenar esa información con permiso del usuario, ahorra mucho tiempo.&lt;/p&gt;
&lt;p&gt;Google también recalca que conectar Gemini y Autofill with Google es estrictamente opt-in. El usuario decide si conectarlos y puede activar o desactivar la conexión en ajustes.&lt;/p&gt;
&lt;p&gt;Esto importa porque Autofill toca datos personales, direcciones, cuentas, pagos, información laboral y formularios sensibles. Cuanto más útil es, más importantes son el permiso explícito y la salida controlable.&lt;/p&gt;
&lt;h2 id=&#34;rambler-convertir-habla-en-texto-listo-para-enviar&#34;&gt;Rambler: convertir habla en texto listo para enviar
&lt;/h2&gt;&lt;p&gt;Rambler es una de las funciones más interesantes.&lt;/p&gt;
&lt;p&gt;Gboard ya puede convertir voz en texto, pero al hablar de forma natural solemos repetir, pausar, usar muletillas y corregirnos. Rambler busca transformar habla natural en texto más claro y listo para enviar.&lt;/p&gt;
&lt;p&gt;Sirve para situaciones como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dictar rápidamente un mensaje sin editar cada palabra.&lt;/li&gt;
&lt;li&gt;Hablar con pausas, repeticiones o muletillas.&lt;/li&gt;
&lt;li&gt;Convertir una idea improvisada en un SMS, email o chat más profesional.&lt;/li&gt;
&lt;li&gt;Cambiar entre idiomas y esperar que el sistema entienda el contexto.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google dice que Rambler mostrará claramente cuándo está activado y que el audio solo se usa para transcripción en tiempo real, sin guardarse. Es una respuesta a preocupaciones de privacidad y transparencia.&lt;/p&gt;
&lt;p&gt;Desde el punto de vista del producto, Rambler convierte “entrada por voz” en “escritura por voz”. No solo registra lo que dijiste; ayuda a convertirlo en texto enviable.&lt;/p&gt;
&lt;h2 id=&#34;widgets-creados-con-lenguaje-natural&#34;&gt;Widgets creados con lenguaje natural
&lt;/h2&gt;&lt;p&gt;Gemini Intelligence también incluye Create My Widget. El usuario puede describir en lenguaje natural el widget que quiere, por ejemplo “recomiéndame tres recetas semanales altas en proteína”, y Android genera un widget personalizado para la pantalla de inicio.&lt;/p&gt;
&lt;p&gt;Esto apunta a generative UI. El usuario ya no elige solo entre plantillas fijas; describe la información y presentación que quiere.&lt;/p&gt;
&lt;p&gt;Si madura, la pantalla de inicio podría volverse mucho más personal. Clima, agenda, salud, transporte, comida, aprendizaje y recordatorios de trabajo podrían convertirse en módulos dinámicos generados según la necesidad del usuario.&lt;/p&gt;
&lt;p&gt;Pero la UI generativa también necesita estabilidad. Un widget no es una respuesta de chat de una sola vez. Permanece en la pantalla y debe ser fiable, legible, configurable y no invadir el diseño.&lt;/p&gt;
&lt;h2 id=&#34;material-3-expressive-e-interfaz-inteligente&#34;&gt;Material 3 Expressive e interfaz inteligente
&lt;/h2&gt;&lt;p&gt;Google también dice que Gemini Intelligence traerá actualizaciones de diseño basadas en Material 3 Expressive.&lt;/p&gt;
&lt;p&gt;No es solo decoración. Cuando la IA empieza a actuar proactivamente, la interfaz debe mostrar claramente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qué está haciendo la IA.&lt;/li&gt;
&lt;li&gt;Qué pasos se han completado.&lt;/li&gt;
&lt;li&gt;Dónde hace falta confirmación.&lt;/li&gt;
&lt;li&gt;Cómo cancelar o modificar la acción.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Una IA proactiva sin una UI clara puede hacer que el usuario sienta que pierde control. El lenguaje de diseño se convierte en parte de la experiencia del producto de IA.&lt;/p&gt;
&lt;h2 id=&#34;disponibilidad-y-despliegue&#34;&gt;Disponibilidad y despliegue
&lt;/h2&gt;&lt;p&gt;Según Google, las funciones de Gemini Intelligence empezarán en los últimos Samsung Galaxy y Google Pixel durante el verano de 2026. Después llegarán a más dispositivos Android, incluidos relojes, coches, gafas y portátiles.&lt;/p&gt;
&lt;p&gt;No será un lanzamiento global instantáneo. La disponibilidad puede depender de dispositivo, región, idioma, soporte de apps y configuración de cuenta.&lt;/p&gt;
&lt;p&gt;Si quieres probarlo, las expectativas realistas son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mirar primero Pixel y Samsung de gama alta.&lt;/li&gt;
&lt;li&gt;Seguir las actualizaciones del sistema tras el verano de 2026.&lt;/li&gt;
&lt;li&gt;Buscar nuevos interruptores en Gemini, Chrome, Gboard, Autofill y ajustes de Android.&lt;/li&gt;
&lt;li&gt;No todas las regiones e idiomas admitirán todas las funciones al mismo tiempo.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;qué-significa-para-android&#34;&gt;Qué significa para Android
&lt;/h2&gt;&lt;p&gt;Gemini Intelligence on Android no significa solo añadir unas cuantas funciones de IA. Cambia la dirección del producto Android.&lt;/p&gt;
&lt;p&gt;Los sistemas móviles tradicionales gestionan apps, notificaciones, permisos, archivos y hardware. Google ahora quiere que el sistema entienda la intención del usuario y complete tareas entre apps. Si funciona, la competencia de Android se moverá desde “funciones del sistema y ecosistema de apps” hacia “cuánto puede ayudar proactivamente al usuario”.&lt;/p&gt;
&lt;p&gt;También cambia la competencia de IA móvil:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apple enfatizará integración local, privacidad y control del sistema.&lt;/li&gt;
&lt;li&gt;Google enfatizará Gemini, Search, Chrome, Android y ecosistema multidispositivo.&lt;/li&gt;
&lt;li&gt;Las apps de IA de terceros lo tendrán más difícil frente a entradas de nivel sistema.&lt;/li&gt;
&lt;li&gt;Los desarrolladores deberán pensar cómo sus apps serán llamadas por agentes de IA.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En los próximos años, la IA en el teléfono puede dejar de ser solo una entrada de chat y convertirse en una capa de ejecución del sistema.&lt;/p&gt;
&lt;h2 id=&#34;resumen&#34;&gt;Resumen
&lt;/h2&gt;&lt;p&gt;Gemini Intelligence on Android no trata de añadir otra caja de chat Gemini al teléfono. Trata de colocar IA dentro del flujo operativo de Android. Automatización de varios pasos, Chrome inteligente, Autofill, Rambler y widgets por lenguaje natural buscan convertir el teléfono de herramienta pasiva en asistente proactivo.&lt;/p&gt;
&lt;p&gt;Que cambie realmente los hábitos del usuario dependerá de la fiabilidad de la automatización, la claridad de los controles de privacidad, la fluidez entre apps y que el usuario conserve el control final. Al menos con este anuncio, Google define la siguiente etapa de Android como un sistema de IA proactivo, no solo como un sistema operativo móvil tradicional.&lt;/p&gt;
&lt;p&gt;Referencia:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/products-and-platforms/platforms/android/gemini-intelligence/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Blog: A smarter, more proactive Android with Gemini Intelligence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Filtraciones de Gemini 3.5 Pro: Google quiere recuperar la entrada de programación AI con Spark Agent</title>
        <link>https://knightli.com/es/2026/05/15/gemini-35-pro-spark-agent-ai-coding-race/</link>
        <pubDate>Fri, 15 May 2026 23:45:34 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/15/gemini-35-pro-spark-agent-ai-coding-race/</guid>
        <description>&lt;p&gt;Gemini 3.5 Pro todavía no se ha lanzado oficialmente, pero las filtraciones a su alrededor ya están ganando fuerza.&lt;/p&gt;
&lt;p&gt;La información actual gira alrededor de varios términos: Gemini 3.5 Pro, el nombre en clave Cappuccino, Gemini Spark, programación AI e integración de herramientas MCP. Todos apuntan en la misma dirección: Google no solo quiere actualizar otro modelo de chat. Quiere volver a conectar modelos, herramientas, Agents y puntos de entrada del ecosistema Google.&lt;/p&gt;
&lt;p&gt;Antes de un lanzamiento oficial, todo esto debe tratarse como información filtrada. La señal importante no está en una captura concreta ni en un resultado de benchmark, sino en las carencias que Google podría estar intentando cerrar.&lt;/p&gt;
&lt;h2 id=&#34;por-qué-gemini-35-pro-importa&#34;&gt;Por Qué Gemini 3.5 Pro Importa
&lt;/h2&gt;&lt;p&gt;Según la información expuesta, Gemini 3.5 Pro podría representar un salto de nombre.&lt;/p&gt;
&lt;p&gt;Hasta hace poco se hablaba de Gemini 3.2, y luego apareció Gemini 3.5 Pro en filtraciones. Si el nombre es real, Google probablemente quiere contar una historia de versión más grande en la próxima presentación, no solo lanzar una actualización menor.&lt;/p&gt;
&lt;p&gt;Los puntos filtrados se concentran principalmente en tres áreas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mejoras continuas en programación y razonamiento;&lt;/li&gt;
&lt;li&gt;mayor capacidad para generar SVG, páginas interactivas, animaciones y 3D;&lt;/li&gt;
&lt;li&gt;un nuevo producto Agent, Gemini Spark, que podría pasar al primer plano.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ninguna de estas direcciones sorprende. Gemini siempre ha enfatizado la multimodalidad, y Google tiene canales de distribución muy fuertes. La verdadera pregunta es si puede alcanzar el ritmo de OpenAI y Anthropic en herramientas para desarrolladores y flujos de trabajo tipo Agent.&lt;/p&gt;
&lt;h2 id=&#34;la-programación-es-la-asignatura-que-google-más-necesita-recuperar&#34;&gt;La Programación Es La Asignatura Que Google Más Necesita Recuperar
&lt;/h2&gt;&lt;p&gt;En 2026, la programación ya no es solo un punto de evaluación de modelos. Se ha convertido en uno de los puntos de entrada de producto más directos.&lt;/p&gt;
&lt;p&gt;La razón es simple: las herramientas de programación AI tienen uso frecuente y generan muchos datos de retroalimentación. Los desarrolladores piden a los modelos leer código, modificar código, ejecutar pruebas y corregir errores todos los días. Estas interacciones empujan de forma natural la siguiente generación de modelos y herramientas.&lt;/p&gt;
&lt;p&gt;Durante el último año, Claude Code ha ganado mucha presencia entre desarrolladores, mientras OpenAI ha seguido reforzando la colaboración entre Codex y ChatGPT. Google tiene productos como Antigravity, pero su presencia externa no ha sido tan fuerte.&lt;/p&gt;
&lt;p&gt;Por eso Gemini 3.5 Pro está bajo observación. Si solo chatea mejor o responde más rápido, el impacto será limitado. Si realmente mejora la comprensión de código, la edición entre varios archivos, las llamadas a herramientas y la ejecución de tareas largas, entonces sí puede cambiar flujos de trabajo de desarrollo.&lt;/p&gt;
&lt;h2 id=&#34;gemini-spark-puede-ser-la-variable-más-grande&#34;&gt;Gemini Spark Puede Ser La Variable Más Grande
&lt;/h2&gt;&lt;p&gt;Más agresivo que el modelo en sí es el rumoreado Gemini Spark.&lt;/p&gt;
&lt;p&gt;Según las filtraciones, Spark no se posiciona como un asistente de chat normal, sino como un AI Agent siempre activo. Podría conectarse a correo, calendario, páginas web, tareas, estado de cuenta y contexto personal para ayudar al usuario a manejar flujos de varios pasos.&lt;/p&gt;
&lt;p&gt;Este tipo de producto abre mucho espacio de imaginación. Por ejemplo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;organizar automáticamente la bandeja de entrada;&lt;/li&gt;
&lt;li&gt;hacer seguimiento de tareas para el usuario;&lt;/li&gt;
&lt;li&gt;ejecutar acciones en páginas web;&lt;/li&gt;
&lt;li&gt;manejar procesos entre aplicaciones;&lt;/li&gt;
&lt;li&gt;organizar asuntos diarios según preferencias personales.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pero los riesgos son igual de evidentes. Si un Agent siempre activo puede acceder al estado de sesión, datos del navegador, archivos, ubicación y servicios de terceros, debe responder varias preguntas: ¿cuándo debe confirmar el usuario una acción? ¿qué operaciones deben quedar prohibidas para la automatización? ¿se compartirán datos con terceros? ¿cómo se aíslan el navegador remoto y las credenciales?&lt;/p&gt;
&lt;p&gt;Así que el punto clave de Spark no es solo si puede hacer trabajo por ti. Es si Google puede dejar suficientemente claros los permisos, la auditoría, los flujos de confirmación y el control del usuario.&lt;/p&gt;
&lt;h2 id=&#34;qué-sugiere-la-integración-de-herramientas-mcp&#34;&gt;Qué Sugiere La Integración De Herramientas MCP
&lt;/h2&gt;&lt;p&gt;Las filtraciones también mencionan que el nuevo selector de Gemini podría incluir modelos o entradas de prueba relacionadas con MCP.&lt;/p&gt;
&lt;p&gt;Si esto llega al producto, sugiere que Google también está empujando los modelos desde un sistema de preguntas y respuestas hacia un sistema operativo de herramientas. El modelo ya no solo genera texto. Debe llamar herramientas externas, acceder a sistemas de negocio, leer y escribir archivos, ejecutar comandos y mantener estado de tarea entre varios pasos.&lt;/p&gt;
&lt;p&gt;Es la misma dirección que siguen OpenAI y Anthropic. Quien logre llamadas a herramientas más estables tendrá más facilidad para insertar AI en flujos reales.&lt;/p&gt;
&lt;p&gt;Pero la integración MCP no es el final. Lo difícil es la estabilidad:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;si el modelo puede elegir la herramienta correcta;&lt;/li&gt;
&lt;li&gt;si los parámetros son fiables;&lt;/li&gt;
&lt;li&gt;si puede recuperarse tras un fallo;&lt;/li&gt;
&lt;li&gt;si los límites de permisos están claros;&lt;/li&gt;
&lt;li&gt;si el usuario puede rastrear cada paso.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si estas preguntas no se resuelven, más herramientas también significan más superficie de error.&lt;/p&gt;
&lt;h2 id=&#34;la-multimodalidad-sigue-siendo-una-carta-fuerte-para-google&#34;&gt;La Multimodalidad Sigue Siendo Una Carta Fuerte Para Google
&lt;/h2&gt;&lt;p&gt;El área donde Google tiene más opciones de diferenciarse sigue siendo la multimodalidad.&lt;/p&gt;
&lt;p&gt;Según los ejemplos filtrados de SVG, páginas interactivas, animaciones y generación visual, Gemini podría seguir reforzando la capacidad de generar contenido interactivo a partir de prompts. Frente a escribir solo un fragmento de código, esto se acerca más al prototipado de producto: el usuario describe una idea y el modelo entrega directamente una interfaz operable, ajustable y previsualizable.&lt;/p&gt;
&lt;p&gt;Esta ruta encaja bien con Google. Aprovecha las fortalezas multimodales de Gemini y también puede conectarse con Android, Chrome, Workspace, Search, Ads y Cloud.&lt;/p&gt;
&lt;p&gt;Si Google quiere evitar competir solo en &amp;ldquo;qué modelo programa mejor&amp;rdquo;, probablemente pondrá más peso en un sistema Agent multimodal más completo.&lt;/p&gt;
&lt;h2 id=&#34;las-tres-compañías-empiezan-a-diferenciar-sus-jugadas&#34;&gt;Las Tres Compañías Empiezan A Diferenciar Sus Jugadas
&lt;/h2&gt;&lt;p&gt;La competencia actual de grandes modelos ya no es solo una competencia de rankings.&lt;/p&gt;
&lt;p&gt;La ventaja de OpenAI está en la velocidad de iteración de producto y distribución. Codex, ChatGPT, herramientas empresariales y APIs están cada vez más conectados.&lt;/p&gt;
&lt;p&gt;La ventaja de Anthropic está en la mente de los desarrolladores y en la calidad de sus modelos de código. Claude Code ya se ha convertido en el punto de entrada de programación AI por defecto para muchas personas.&lt;/p&gt;
&lt;p&gt;La ventaja de Google es el acceso al ecosistema. Gmail, Docs, Chrome, Android, Search, YouTube, Maps y servicios cloud forman una enorme red de datos personales y empresariales. Si los Agents pueden conectarse a estos puntos de entrada de forma segura, Google puede pasar de ser un &amp;ldquo;perseguidor de modelos&amp;rdquo; a controlar entradas de flujo de trabajo.&lt;/p&gt;
&lt;p&gt;Por eso Gemini Spark merece atención. No necesita quedar primero en todos los benchmarks. Si logra entrar en los flujos diarios, puede construir su propio foso.&lt;/p&gt;
&lt;h2 id=&#34;cómo-deberían-leer-esto-los-usuarios-comunes&#34;&gt;Cómo Deberían Leer Esto Los Usuarios Comunes
&lt;/h2&gt;&lt;p&gt;Para usuarios comunes, no hace falta dejarse arrastrar por cada filtración a corto plazo.&lt;/p&gt;
&lt;p&gt;Los puntos prácticos a observar son tres:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Si la capacidad de programación de Gemini 3.5 Pro mejora de verdad, especialmente en repositorios complejos, contexto largo y llamadas a herramientas.&lt;/li&gt;
&lt;li&gt;Si Gemini Spark es seguro por defecto, con confirmación clara y registros rastreables antes de operaciones sensibles.&lt;/li&gt;
&lt;li&gt;Si Google ofrece precios, cuotas y gestión de permisos empresariales claros, no solo demos llamativas.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Generar unas cuantas capturas bonitas tiene valor limitado. Poder conectarse de forma estable a flujos reales es la línea divisoria de esta generación de productos AI Agent.&lt;/p&gt;
&lt;h2 id=&#34;qué-significa-para-desarrolladores&#34;&gt;Qué Significa Para Desarrolladores
&lt;/h2&gt;&lt;p&gt;Los desarrolladores deberían preocuparse menos por &amp;ldquo;qué modelo ganó&amp;rdquo; y más por si su flujo de trabajo es portable.&lt;/p&gt;
&lt;p&gt;Claude Code, Codex, Gemini, Antigravity, Cursor, Windsurf y muchas otras herramientas compiten por el punto de entrada. Si todos los procesos quedan atados a una sola plataforma, cualquier cambio futuro de coste, cuota, política de modelo o regla de permisos hará dolorosa la migración.&lt;/p&gt;
&lt;p&gt;Una postura más segura es:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mantener flujos Git estándar en proyectos importantes;&lt;/li&gt;
&lt;li&gt;revisar siempre el diff después de ediciones automáticas;&lt;/li&gt;
&lt;li&gt;usar pruebas y CI como respaldo para tareas clave;&lt;/li&gt;
&lt;li&gt;no entregar credenciales de producción a Agents opacos;&lt;/li&gt;
&lt;li&gt;cuando se puedan conectar herramientas con protocolos abiertos, preferir opciones reemplazables.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Los modelos seguirán mejorando, pero la disciplina de ingeniería no quedará obsoleta.&lt;/p&gt;
&lt;h2 id=&#34;resumen&#34;&gt;Resumen
&lt;/h2&gt;&lt;p&gt;Las filtraciones de Gemini 3.5 Pro sugieren que Google está acelerando para cerrar brechas en programación AI y puntos de entrada tipo Agent. La mejora del modelo es solo una parte; Agents siempre activos como Gemini Spark podrían ser el movimiento estratégico más grande.&lt;/p&gt;
&lt;p&gt;Pero cuanto más puede un sistema &amp;ldquo;hacer cosas automáticamente&amp;rdquo; por el usuario, más necesita límites estrictos de permisos y flujos verificables. Para Google, el reto real no es solo alcanzar a GPT-5.5 o Claude. Es combinar modelos fuertes, mecanismos de seguridad y entradas de ecosistema en un flujo diario confiable.&lt;/p&gt;
&lt;p&gt;Si lo consigue, Gemini no necesitará liderar todos los rankings para recuperar parte de la iniciativa en los puntos de entrada de AI.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>¿Cómo conectar Codex con modelos chinos? Gestionar APIs compatibles con OpenAI usando CCX</title>
        <link>https://knightli.com/es/2026/05/13/ccx-ai-api-proxy-gateway/</link>
        <pubDate>Wed, 13 May 2026 23:20:40 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/13/ccx-ai-api-proxy-gateway/</guid>
        <description>&lt;p&gt;CCX es una pasarela de proxy y conversión de protocolos para APIs de IA. Coloca Claude Messages, OpenAI Chat Completions, OpenAI Images, Codex Responses y Gemini API detrás de una única entrada de servicio, y ofrece una interfaz web para configurar canales, claves, mapeos de modelos, prioridades, failover y monitoreo de tráfico.&lt;/p&gt;
&lt;p&gt;Si usas Claude, OpenAI, Gemini y Codex al mismo tiempo, o mantienes varios servicios aguas arriba compatibles con OpenAI API, el valor de CCX está en unificar la entrada y la gestión. Los clientes se conectan a una sola dirección; CCX decide qué canal aguas arriba debe atender cada solicitud.&lt;/p&gt;
&lt;p&gt;Proyecto: &lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;qué-problema-resuelve-ccx&#34;&gt;Qué problema resuelve CCX
&lt;/h2&gt;&lt;p&gt;Cuando se mezclan varias APIs de IA, aparecen rápidamente algunos problemas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cada proveedor tiene rutas, autenticación y formatos de solicitud diferentes.&lt;/li&gt;
&lt;li&gt;Una misma clase de modelos puede tener varios upstreams, lo que obliga a cambiar manualmente base URL y API key.&lt;/li&gt;
&lt;li&gt;Cuando una clave o canal falla, el cliente normalmente no cambia automáticamente a un canal de respaldo.&lt;/li&gt;
&lt;li&gt;En equipos, cuesta centralizar allowlists de modelos, proxies, cabeceras personalizadas y logs.&lt;/li&gt;
&lt;li&gt;Al conectar Claude, Gemini, OpenAI Chat, APIs de imagen y Codex Responses, la configuración se dispersa.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La idea de CCX es concentrar esas diferencias en una capa proxy. Las herramientas frontend, scripts o servicios de negocio llaman a CCX; luego CCX enruta la solicitud al upstream adecuado según tipo de API, modelo, estado del canal, prioridad y salud.&lt;/p&gt;
&lt;h2 id=&#34;endpoints-soportados&#34;&gt;Endpoints soportados
&lt;/h2&gt;&lt;p&gt;CCX expone una entrada backend unificada. El puerto predeterminado es &lt;code&gt;3000&lt;/code&gt;. Las rutas principales incluyen:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET  /                         -&amp;gt; Interfaz web de administración
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET  /health                   -&amp;gt; Health check
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/api/*                         -&amp;gt; API de administración
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/messages              -&amp;gt; Proxy de Claude Messages
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/chat/completions      -&amp;gt; Proxy de OpenAI Chat
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/responses             -&amp;gt; Proxy de Codex Responses
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/images/generations    -&amp;gt; Generación con OpenAI Images
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/images/edits          -&amp;gt; Edición con OpenAI Images
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1/images/variations     -&amp;gt; Variaciones con OpenAI Images
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;GET  /v1/models                -&amp;gt; Lista de modelos
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;POST /v1beta/models/*          -&amp;gt; Proxy de Gemini
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Es decir, CCX no se limita a un protocolo. Gestiona APIs comunes de IA como tipos de canal separados: Messages, Chat, Responses, Gemini e Images. Cada protocolo mantiene su propio estado de salud y espacio de logs, lo que ayuda al diagnóstico.&lt;/p&gt;
&lt;h2 id=&#34;arquitectura&#34;&gt;Arquitectura
&lt;/h2&gt;&lt;p&gt;CCX usa backend en Go y frontend en Vue 3. El build del frontend se incrusta en el binario del backend, por lo que puede desplegarse en un solo puerto: el mismo servicio ofrece Web UI, API de administración y API proxy.&lt;/p&gt;
&lt;p&gt;Una solicitud pasa aproximadamente por esta cadena:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Client -&amp;gt; Auth Middleware -&amp;gt; Route Handler -&amp;gt; Channel Scheduler -&amp;gt; Provider / Converter -&amp;gt; Upstream API -&amp;gt; Metrics / Channel Logs -&amp;gt; Client Response
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Los módulos principales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;handlers&lt;/code&gt;: reciben solicitudes de distintos protocolos y operaciones de administración.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;providers&lt;/code&gt;: encapsulan el manejo de solicitudes y respuestas del upstream.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;converters&lt;/code&gt;: gestionan conversiones de protocolo en escenarios como Responses.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;scheduler&lt;/code&gt;: elige canales según prioridad, periodo promocional, salud, circuito abierto y afinidad de traza.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;metrics&lt;/code&gt;: registra volumen, tasa de éxito, latencia, logs y estado de circuit breaker.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;config&lt;/code&gt;: mantiene configuración en tiempo de ejecución, con hot reload y respaldo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El objetivo no es forzar todas las APIs a un único formato, sino proxyar cada tipo de protocolo por separado y unificar gestión, planificación, logs y autenticación.&lt;/p&gt;
&lt;h2 id=&#34;diferencias-entre-ccx-y-codexbridge&#34;&gt;Diferencias entre CCX y CodexBridge
&lt;/h2&gt;&lt;p&gt;CCX y CodexBridge están relacionados con Codex y las APIs compatibles con OpenAI, pero resuelven problemas distintos.&lt;/p&gt;
&lt;p&gt;CodexBridge es más bien un puente dedicado para Codex. Su objetivo principal es encapsular Codex CLI/SDK como un servicio &lt;code&gt;/v1/chat/completions&lt;/code&gt; compatible con OpenAI, para que OpenWebUI, Cherry Studio, scripts u otros clientes compatibles puedan llamar a Codex local. En resumen, CodexBridge se centra en exponer Codex.&lt;/p&gt;
&lt;p&gt;CCX se parece más a una pasarela unificada de APIs de IA. No solo maneja Codex Responses; también soporta Claude Messages, OpenAI Chat, OpenAI Images y Gemini API, con interfaz web, prioridad de canales, failover, monitoreo de logs y gestión de múltiples claves. En resumen, CCX se centra en gestionar varios modelos y proveedores juntos.&lt;/p&gt;
&lt;p&gt;Comparación rápida:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Aspecto&lt;/th&gt;
          &lt;th&gt;CodexBridge&lt;/th&gt;
          &lt;th&gt;CCX&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Posicionamiento&lt;/td&gt;
          &lt;td&gt;Puente local para Codex&lt;/td&gt;
          &lt;td&gt;Pasarela AI API multiprotocolo&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Objetivo principal&lt;/td&gt;
          &lt;td&gt;Convertir Codex en endpoint compatible con OpenAI&lt;/td&gt;
          &lt;td&gt;Gestionar juntos Claude, OpenAI, Gemini, Codex y otros canales&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Interfaz de gestión&lt;/td&gt;
          &lt;td&gt;Se centra en el servicio API&lt;/td&gt;
          &lt;td&gt;Ofrece interfaz web de administración&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Planificación multicanal&lt;/td&gt;
          &lt;td&gt;No es el foco&lt;/td&gt;
          &lt;td&gt;Soporta prioridad, failover y monitoreo de logs&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Mejor escenario&lt;/td&gt;
          &lt;td&gt;Llamadas locales o de un solo servicio a Codex&lt;/td&gt;
          &lt;td&gt;Equipos, múltiples claves, proveedores y protocolos&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Si solo quieres conectar Codex a OpenWebUI o Cherry Studio, CodexBridge es más directo. Si quieres gestionar Codex, Claude, Gemini, DeepSeek, Qwen, Kimi y otros upstreams juntos, CCX encaja mejor.&lt;/p&gt;
&lt;h2 id=&#34;despliegue-rápido&#34;&gt;Despliegue rápido
&lt;/h2&gt;&lt;p&gt;La forma más sencilla es descargar el binario. Luego crea &lt;code&gt;.env&lt;/code&gt; en el mismo directorio:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-proxy-access-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_WEB_UI&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;APP_UI_LANGUAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;zh-CN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Tras iniciar, abre:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://localhost:3000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Si desde WSL, Docker, PowerShell u otro entorno en Windows &lt;code&gt;localhost&lt;/code&gt; no funciona, usa la IPv4 LAN del host Windows, por ejemplo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;http://192.168.1.23:3000
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;CCX escucha por defecto en &lt;code&gt;:PORT&lt;/code&gt; para todas las interfaces, así que debes controlar el acceso si lo expones a la LAN.&lt;/p&gt;
&lt;h2 id=&#34;despliegue-con-docker&#34;&gt;Despliegue con Docker
&lt;/h2&gt;&lt;p&gt;Docker es adecuado para mantener el servicio en ejecución:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run -d &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --name ccx &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -p 3000:3000 &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -e &lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-proxy-access-key &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -e &lt;span class=&#34;nv&#34;&gt;APP_UI_LANGUAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;zh-CN &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -v &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;pwd&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;/.config:/app/.config &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  crpi-i19l8zl0ugidq97v.cn-hangzhou.personal.cr.aliyuncs.com/bene/ccx:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Si el repositorio ya incluye &lt;code&gt;docker-compose.yml&lt;/code&gt;, también puedes ejecutar:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Para actualizaciones automáticas, añade la configuración de Watchtower:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker compose -f docker-compose.yml -f docker-compose.watchtower.yml up -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Tras desplegar, &lt;code&gt;.config&lt;/code&gt; guarda configuración de runtime y datos persistentes. Conviene montarlo en el host para no perder configuración al recrear el contenedor.&lt;/p&gt;
&lt;h2 id=&#34;ejecutar-desde-código-fuente&#34;&gt;Ejecutar desde código fuente
&lt;/h2&gt;&lt;p&gt;Para desarrollo o builds personalizados:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/BenedictKing/ccx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; ccx
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cp backend-go/.env.example backend-go/.env
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Comandos comunes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make dev
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make run
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make build
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make frontend-dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Desarrollo solo del frontend:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; frontend
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun install
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bun run dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Desarrollo solo del backend:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; backend-go
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make dev
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;variables-de-entorno-clave&#34;&gt;Variables de entorno clave
&lt;/h2&gt;&lt;p&gt;Una configuración mínima suele incluir:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PORT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;3000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENV&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;production
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_WEB_UI&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-proxy-access-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ADMIN_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your-admin-secret-key
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;APP_UI_LANGUAGE&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;zh-CN
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;LOG_LEVEL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;REQUEST_TIMEOUT&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;300000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Notas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PROXY_ACCESS_KEY&lt;/code&gt; se usa para la API proxy y debe cambiarse.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ADMIN_ACCESS_KEY&lt;/code&gt; se usa para la Web UI y &lt;code&gt;/api/*&lt;/code&gt;; conviene separarlo de la clave proxy.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ENABLE_WEB_UI&lt;/code&gt; controla si la interfaz de administración está activa.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;REQUEST_TIMEOUT&lt;/code&gt; controla el timeout; aumenta el valor para contextos largos o tareas de imagen.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;LOG_LEVEL&lt;/code&gt; controla la verbosidad; en producción suele usarse &lt;code&gt;info&lt;/code&gt; o &lt;code&gt;warn&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para limitar el tamaño del cuerpo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;MAX_REQUEST_BODY_SIZE_MB&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;50&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La edición de imágenes, imágenes base64 y solicitudes multimodales pueden aumentar mucho el cuerpo.&lt;/p&gt;
&lt;h2 id=&#34;orquestación-de-canales-y-failover&#34;&gt;Orquestación de canales y failover
&lt;/h2&gt;&lt;p&gt;La interfaz de CCX permite configurar múltiples canales, con opciones como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tipo de servicio upstream.&lt;/li&gt;
&lt;li&gt;API key o rotación de múltiples claves.&lt;/li&gt;
&lt;li&gt;Dirección proxy.&lt;/li&gt;
&lt;li&gt;Cabeceras personalizadas.&lt;/li&gt;
&lt;li&gt;Allowlist de modelos.&lt;/li&gt;
&lt;li&gt;Prefijo de ruta.&lt;/li&gt;
&lt;li&gt;Prioridad.&lt;/li&gt;
&lt;li&gt;Health checks y recuperación de circuit breaker.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La planificación considera estado del canal, prioridad, periodo promocional, afinidad de traza, estado de circuit breaker y claves disponibles. En simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Normalmente se usan primero los canales de mayor prioridad.&lt;/li&gt;
&lt;li&gt;Si un canal falla, CCX puede cambiar a un canal de respaldo.&lt;/li&gt;
&lt;li&gt;El circuit breaker evita seguir llamando a un upstream claramente no disponible.&lt;/li&gt;
&lt;li&gt;La afinidad de traza intenta mantener sesiones relacionadas en canales adecuados.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Estas funciones son útiles con múltiples claves, proveedores o upstreams regionales. Para uso personal ligero, también puedes configurar un solo canal y usar CCX como capa proxy con Web UI.&lt;/p&gt;
&lt;h2 id=&#34;logs-y-monitoreo&#34;&gt;Logs y monitoreo
&lt;/h2&gt;&lt;p&gt;CCX ofrece métricas de canal y logs de solicitudes, incluyendo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Volumen de solicitudes.&lt;/li&gt;
&lt;li&gt;Tasa de éxito.&lt;/li&gt;
&lt;li&gt;Tasa de fallo.&lt;/li&gt;
&lt;li&gt;Latencia media.&lt;/li&gt;
&lt;li&gt;Historial por modelo.&lt;/li&gt;
&lt;li&gt;Estado de canales y circuit breakers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En producción conviene una configuración de logs contenida:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-env&#34; data-lang=&#34;env&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENV&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;production
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;LOG_LEVEL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;info
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_REQUEST_LOGS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ENABLE_RESPONSE_LOGS&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Así conservas información básica sin escribir respuestas completas en logs. Para investigar problemas puedes activar logs más detallados temporalmente, pero después deberías volver a una configuración segura, sobre todo en producción.&lt;/p&gt;
&lt;h2 id=&#34;recomendaciones-de-seguridad&#34;&gt;Recomendaciones de seguridad
&lt;/h2&gt;&lt;p&gt;CCX es una pasarela proxy y almacena API keys aguas arriba, así que no basta con que &amp;ldquo;funcione&amp;rdquo;. Como mínimo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No uses un &lt;code&gt;PROXY_ACCESS_KEY&lt;/code&gt; predeterminado o demasiado corto.&lt;/li&gt;
&lt;li&gt;Define un &lt;code&gt;ADMIN_ACCESS_KEY&lt;/code&gt; separado.&lt;/li&gt;
&lt;li&gt;No expongas directamente la Web UI a internet.&lt;/li&gt;
&lt;li&gt;Si necesitas acceso público, colócala detrás de reverse proxy, VPN, control de acceso o SSO.&lt;/li&gt;
&lt;li&gt;No subas &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;.config&lt;/code&gt; ni logs a Git.&lt;/li&gt;
&lt;li&gt;No mantengas logs completos de cuerpo de solicitud y respuesta en producción.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Puedes generar claves aleatorias así:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PROXY_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;openssl rand -base64 32&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ADMIN_ACCESS_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;openssl rand -base64 32&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;para-quién-es-adecuado&#34;&gt;Para quién es adecuado
&lt;/h2&gt;&lt;p&gt;CCX encaja mejor en estos escenarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mantener Claude, OpenAI, Gemini, Codex o APIs de imagen al mismo tiempo.&lt;/li&gt;
&lt;li&gt;Tener varias API keys que requieren rotación, enrutamiento y failover.&lt;/li&gt;
&lt;li&gt;Gestionar upstreams desde una Web UI en vez de editar archivos manualmente.&lt;/li&gt;
&lt;li&gt;Observar tasa de éxito, latencia y logs de cada canal.&lt;/li&gt;
&lt;li&gt;Proporcionar a un equipo una entrada AI API unificada.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si solo llamas ocasionalmente a un modelo en tu equipo local, el SDK oficial o un proxy compatible con OpenAI más simple será suficiente. La ventaja de CCX está en múltiples canales, múltiples protocolos y operación unificada.&lt;/p&gt;
&lt;h2 id=&#34;resumen&#34;&gt;Resumen
&lt;/h2&gt;&lt;p&gt;CCX es una pasarela AI API, no un cliente para un modelo concreto. Coloca Claude Messages, OpenAI Chat, OpenAI Images, Codex Responses y Gemini en una capa proxy, y ofrece orquestación de canales, failover, logs, monitoreo y Web UI.&lt;/p&gt;
&lt;p&gt;Para usuarios individuales, reduce la molestia de cambiar direcciones API y claves. Para equipos o servicios de larga duración, se parece más a una pasarela ligera de IA. Antes de producción, lo importante no es solo configurar modelos, sino también claves, entrada de administración, niveles de log, prioridades de canal y estrategia de failover.&lt;/p&gt;
&lt;h2 id=&#34;referencias&#34;&gt;Referencias
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Proyecto GitHub: &lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Arquitectura: &lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx/blob/main/ARCHITECTURE.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx/blob/main/ARCHITECTURE.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Variables de entorno: &lt;a class=&#34;link&#34; href=&#34;https://github.com/BenedictKing/ccx/blob/main/ENVIRONMENT.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/BenedictKing/ccx/blob/main/ENVIRONMENT.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>En qué se diferencian los mecanismos de memoria de ChatGPT, Claude Code y Gemini</title>
        <link>https://knightli.com/es/2026/05/07/chatgpt-claude-code-gemini-memory-comparison/</link>
        <pubDate>Thu, 07 May 2026 14:47:17 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/07/chatgpt-claude-code-gemini-memory-comparison/</guid>
        <description>&lt;p&gt;La &amp;ldquo;memoria&amp;rdquo; se está volviendo cada vez más importante en los productos de IA. Marca el paso de conversaciones puntuales a colaboración de largo plazo: ya no necesitas volver a explicar tu contexto, repetir tus preferencias ni pedir al modelo que entienda el mismo proyecto una y otra vez.&lt;/p&gt;
&lt;p&gt;Pero memoria no significa lo mismo en todos los productos. &lt;code&gt;ChatGPT&lt;/code&gt;, &lt;code&gt;Claude Code&lt;/code&gt; y &lt;code&gt;Gemini&lt;/code&gt; intentan ayudar a la IA a recordar más tiempo, pero sus objetivos, lugares de almacenamiento, transparencia y casos de uso son muy distintos.&lt;/p&gt;
&lt;p&gt;Al 7 de mayo de 2026, se pueden entender aproximadamente como tres tipos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT se parece más a memoria de asistente personal.&lt;/li&gt;
&lt;li&gt;Claude Code se parece más a memoria de proyecto de ingeniería.&lt;/li&gt;
&lt;li&gt;Gemini se parece más a contexto del ecosistema Google.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;chatgpt-preferencias-de-largo-plazo-alrededor-de-la-persona&#34;&gt;ChatGPT: preferencias de largo plazo alrededor de la persona
&lt;/h2&gt;&lt;p&gt;La memoria de ChatGPT está diseñada principalmente para colaboración personal. Le importa quién eres, qué prefieres y en qué trabajas a lo largo del tiempo.&lt;/p&gt;
&lt;p&gt;OpenAI separa actualmente la memoria de ChatGPT en &lt;code&gt;saved memories&lt;/code&gt; y &lt;code&gt;chat history&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;saved memories&lt;/code&gt; son piezas importantes de información que ChatGPT guarda, como tu nombre, preferencias, objetivos, stack tecnológico habitual y hábitos de escritura. Puedes pedirle explícitamente que recuerde algo, y también puede guardar información de una conversación cuando cree que será útil más adelante.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;chat history&lt;/code&gt; permite a ChatGPT consultar conversaciones anteriores al responder. No significa que cada chat se convierta en una memoria permanente. Más bien, ChatGPT puede buscar en conversaciones pasadas contexto relevante cuando lo necesita.&lt;/p&gt;
&lt;p&gt;La lógica central de ChatGPT es: entender al mismo usuario entre sesiones.&lt;/p&gt;
&lt;p&gt;Ejemplos típicos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;ldquo;Mantén mis ejemplos de código concisos.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Uso principalmente Python y TypeScript.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Estoy escribiendo un blog Hugo sobre herramientas de IA.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Prefiero conclusiones primero y detalles después.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Estas memorias no están ligadas a un solo proyecto. Siguen a la cuenta y a los hábitos de trabajo del usuario.&lt;/p&gt;
&lt;h2 id=&#34;memory-sources-hacer-más-visible-la-personalización&#34;&gt;Memory Sources: hacer más visible la personalización
&lt;/h2&gt;&lt;p&gt;OpenAI destacó &lt;code&gt;Memory sources&lt;/code&gt; en su actualización de mayo de 2026.&lt;/p&gt;
&lt;p&gt;El objetivo no es añadir otro tipo de memoria, sino mostrar al usuario qué fuentes consultó ChatGPT al personalizar una respuesta. Según los documentos de ayuda de OpenAI, Memory Sources puede mostrar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chats anteriores.&lt;/li&gt;
&lt;li&gt;Memorias guardadas.&lt;/li&gt;
&lt;li&gt;Instrucciones personalizadas.&lt;/li&gt;
&lt;li&gt;Archivos de la biblioteca de archivos.&lt;/li&gt;
&lt;li&gt;Correos de Gmail conectado.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La visibilidad de archivos y Gmail depende del plan, la región y el estado de conexión. OpenAI también dice que Memory sources puede no mostrar todos los factores que influyeron en una respuesta, pero ayuda a entender y gestionar la personalización.&lt;/p&gt;
&lt;p&gt;Esto importa. Cuanto más puede la IA &amp;ldquo;recordarte&amp;rdquo;, más necesitas saber qué usó para responder. De lo contrario, la personalización se vuelve una caja negra: parece conocerte, pero no sabes por qué.&lt;/p&gt;
&lt;p&gt;La ventaja de ChatGPT es su comprensión de preferencias personales entre sesiones y temas. El riesgo es que las memorias se vuelvan obsoletas, o que el usuario olvide que una memoria antigua sigue afectando respuestas. Vale la pena limpiar periódicamente memorias guardadas y chats antiguos.&lt;/p&gt;
&lt;h2 id=&#34;claude-code-alrededor-de-codebases-y-reglas-de-ingeniería&#34;&gt;Claude Code: alrededor de codebases y reglas de ingeniería
&lt;/h2&gt;&lt;p&gt;La memoria de Claude Code está más orientada a ingeniería. Le importan menos las preferencias cotidianas del usuario y más cómo debe modificarse este codebase.&lt;/p&gt;
&lt;p&gt;Claude Code tiene dos mecanismos de memoria que se confunden fácilmente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Memoria explícita del proyecto: &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Memoria automática del proyecto: Auto Memory.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; es el archivo de memoria de proyecto más básico y estable. Puede vivir en la raíz del proyecto o dentro de subdirectorios. Claude Code lee estos archivos como instrucciones de proyecto y reglas operativas.&lt;/p&gt;
&lt;p&gt;Buen contenido para &lt;code&gt;CLAUDE.md&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Comandos comunes de build, test y lint.&lt;/li&gt;
&lt;li&gt;Reglas de estilo y nombres.&lt;/li&gt;
&lt;li&gt;Notas de arquitectura del proyecto.&lt;/li&gt;
&lt;li&gt;Límites de módulos y zonas de riesgo.&lt;/li&gt;
&lt;li&gt;Convenciones del equipo y flujo de commits.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si &lt;code&gt;CLAUDE.md&lt;/code&gt; se guarda en el repositorio, puede versionarse con Git y compartirse como guía de agente para el equipo. Esto es completamente distinto de la memoria personal en la nube de ChatGPT.&lt;/p&gt;
&lt;h2 id=&#34;claude-code-auto-memory-acumular-experiencia-de-proyecto&#34;&gt;Claude Code Auto Memory: acumular experiencia de proyecto
&lt;/h2&gt;&lt;p&gt;Claude Code también tiene &lt;code&gt;Auto Memory&lt;/code&gt;. Su objetivo es permitir que Claude acumule conocimiento del proyecto entre sesiones sin obligar al usuario a escribir cada nota manualmente.&lt;/p&gt;
&lt;p&gt;Según la documentación de Claude Code, Auto Memory permite a Claude guardar notas mientras trabaja, como comandos de build, descubrimientos de depuración, notas de arquitectura, preferencias de estilo y hábitos de workflow. No guarda cada sesión, sino que decide qué puede ser útil más adelante.&lt;/p&gt;
&lt;p&gt;Un malentendido común es creer que Auto Memory escribe por defecto en &lt;code&gt;.claude/memory.md&lt;/code&gt; dentro de la raíz del proyecto. La documentación oficial dice que cada proyecto tiene su propio directorio de memoria bajo el home del usuario, con una ruta similar a:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;~/.claude/projects/&amp;lt;project&amp;gt;/memory/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;MEMORY.md&lt;/code&gt; carga las primeras 200 líneas o 25KB al inicio de cada conversación, mientras que el contenido detallado puede dividirse en otros archivos temáticos. Los archivos de Auto Memory son Markdown locales, y el usuario puede verlos, editarlos o borrarlos mediante &lt;code&gt;/memory&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Esto hace que la memoria de Claude Code se parezca más a una base local de conocimiento de proyecto. Está más cerca del codebase que la memoria personal de ChatGPT, y es más dinámica que un simple &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Pero Auto Memory es local a la máquina. No sigue naturalmente al repositorio hacia otras máquinas o entornos cloud. Para reglas estables compartidas por el equipo, ponlas en el &lt;code&gt;CLAUDE.md&lt;/code&gt; del repositorio.&lt;/p&gt;
&lt;h2 id=&#34;gemini-alrededor-del-contexto-del-ecosistema-google&#34;&gt;Gemini: alrededor del contexto del ecosistema Google
&lt;/h2&gt;&lt;p&gt;La lógica de memoria de Gemini vuelve a ser distinta.&lt;/p&gt;
&lt;p&gt;Gemini también soporta información guardada y referencias a chats anteriores. Los documentos de ayuda de Google dicen que los usuarios pueden guardar información sobre vida, trabajo o preferencias, y Gemini puede consultar chats pasados antes de responder. Cuando usa esta información, la respuesta puede mostrar fuentes como &lt;code&gt;Your saved info&lt;/code&gt; o &lt;code&gt;Previous chats&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Pero la diferenciación de Gemini no es solo &amp;ldquo;guardar unas preferencias&amp;rdquo;. Es la integración con el ecosistema Google.&lt;/p&gt;
&lt;p&gt;Con autorización del usuario y disponibilidad de funciones, Gemini puede acceder a contexto de apps conectadas de Google como Gmail, Google Drive, Docs y Sheets. Su ventaja no es hacer que el usuario le enseñe cada dato manualmente, sino convertir los datos existentes de la cuenta Google en contexto de trabajo buscable.&lt;/p&gt;
&lt;p&gt;Una diferencia típica:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT recuerda: &amp;ldquo;Últimamente he estado reparando una unidad de cinta LTO.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Gemini puede encontrar el correo de confirmación de compra en Gmail o leer notas de reparación desde Drive.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto no significa que Gemini pueda leer todos los datos de Google sin condiciones. Depende del tipo de cuenta, región, permisos, apps conectadas, ajustes de Keep Activity y disponibilidad del producto. Las cuentas empresariales y escolares también pueden estar controladas por administradores de Google Workspace.&lt;/p&gt;
&lt;p&gt;Más exactamente, la memoria de Gemini es una combinación de información guardada, chats anteriores y datos conectados del ecosistema Google.&lt;/p&gt;
&lt;h2 id=&#34;diferencias-centrales&#34;&gt;Diferencias centrales
&lt;/h2&gt;&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Dimensión&lt;/th&gt;
          &lt;th&gt;ChatGPT&lt;/th&gt;
          &lt;th&gt;Claude Code&lt;/th&gt;
          &lt;th&gt;Gemini&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Objeto central&lt;/td&gt;
          &lt;td&gt;Persona y preferencias&lt;/td&gt;
          &lt;td&gt;Proyecto y codebase&lt;/td&gt;
          &lt;td&gt;Cuenta Google y datos del ecosistema&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Memoria típica&lt;/td&gt;
          &lt;td&gt;Preferencias, contexto personal, objetivos de largo plazo&lt;/td&gt;
          &lt;td&gt;Arquitectura, comandos, convenciones, experiencia de depuración&lt;/td&gt;
          &lt;td&gt;Información guardada, chats anteriores, contexto de Gmail/Drive/Docs&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Forma de almacenamiento&lt;/td&gt;
          &lt;td&gt;Memoria y contexto de chat en la cuenta OpenAI&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;MEMORY.md&lt;/code&gt;, archivos Markdown locales&lt;/td&gt;
          &lt;td&gt;Actividad de cuenta Google, información guardada, datos de apps conectadas&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Transparencia&lt;/td&gt;
          &lt;td&gt;Memory sources muestra parte de la fuente&lt;/td&gt;
          &lt;td&gt;Los archivos Markdown se pueden abrir y editar&lt;/td&gt;
          &lt;td&gt;Se gestiona con indicaciones de fuente, Gemini Apps Activity y ajustes Google&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Capacidad entre proyectos&lt;/td&gt;
          &lt;td&gt;Fuerte, sigue a la cuenta de usuario&lt;/td&gt;
          &lt;td&gt;Débil, principalmente sigue al proyecto o memoria local&lt;/td&gt;
          &lt;td&gt;Fuerte, depende de datos y permisos de Google&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Compartición en equipo&lt;/td&gt;
          &lt;td&gt;No adecuada para compartir directamente&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; puede compartirse por Git&lt;/td&gt;
          &lt;td&gt;Depende sobre todo de Workspace y permisos&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Mejor para&lt;/td&gt;
          &lt;td&gt;Preferencias personales y comportamiento de asistente a largo plazo&lt;/td&gt;
          &lt;td&gt;Proyectos de código largos y colaboración con agentes&lt;/td&gt;
          &lt;td&gt;Recuperación en Google Workspace y trabajo entre herramientas&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;cómo-elegir&#34;&gt;Cómo elegir
&lt;/h2&gt;&lt;p&gt;Si quieres que la IA recuerde quién eres, qué estilo prefieres y cómo sueles trabajar, la memoria de ChatGPT es más adecuada.&lt;/p&gt;
&lt;p&gt;Sirve para guardar preferencias personales como estilo de escritura, stack técnico, formato de respuesta, contexto profesional y dirección de proyectos de largo plazo. Su foco es reducir el coste de presentarte de nuevo para que cada conversación empiece más rápido.&lt;/p&gt;
&lt;p&gt;Si quieres que la IA recuerde cómo debe cambiarse un codebase, qué comandos funcionan y qué trampas evitar, Claude Code es más adecuado.&lt;/p&gt;
&lt;p&gt;Pon reglas estables en &lt;code&gt;CLAUDE.md&lt;/code&gt; para compartirlas con el equipo. Deja que Auto Memory ayude con experiencia dinámica. Las decisiones importantes deberían organizarse aún en documentación o &lt;code&gt;CLAUDE.md&lt;/code&gt;, no quedar solo en memoria automática local.&lt;/p&gt;
&lt;p&gt;Si la mayoría de tus materiales viven en Gmail, Drive, Docs y Sheets, el contexto de ecosistema de Gemini tiene ventaja.&lt;/p&gt;
&lt;p&gt;Es útil para encontrar correos antiguos, organizar documentos de Drive y conectar calendario y materiales de oficina. La clave al usar Gemini no es recordarle todo repetidamente en chat, sino asegurarse de que las conexiones de apps, permisos y ajustes de actividad relevantes estén correctos.&lt;/p&gt;
&lt;h2 id=&#34;una-división-práctica-del-trabajo&#34;&gt;Una división práctica del trabajo
&lt;/h2&gt;&lt;p&gt;Puedes dividirlos así:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT recuerda preferencias personales generales.&lt;/li&gt;
&lt;li&gt;Claude Code recuerda conocimiento de ingeniería para un repositorio.&lt;/li&gt;
&lt;li&gt;Gemini recupera materiales de tu ecosistema Google.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En otras palabras, ChatGPT es como un secretario personal, Claude Code como un ingeniero senior dentro del proyecto, y Gemini como un indexador de tu cuenta Google.&lt;/p&gt;
&lt;p&gt;No hay ganador absoluto. Tienen objetivos distintos.&lt;/p&gt;
&lt;p&gt;El mayor error es mezclarlos. Las preferencias personales no siempre pertenecen a la memoria de proyecto; la arquitectura del proyecto no siempre pertenece a la memoria personal en la nube; y recuperar datos del ecosistema Google no significa que el modelo te entienda de verdad a largo plazo.&lt;/p&gt;
&lt;h2 id=&#34;lectura-breve&#34;&gt;Lectura breve
&lt;/h2&gt;&lt;p&gt;La siguiente etapa de la memoria en IA no es simplemente &amp;ldquo;recordar más&amp;rdquo;. La memoria necesita capas, visibilidad y control.&lt;/p&gt;
&lt;p&gt;ChatGPT se centra en personalización entre sesiones. Claude Code se centra en continuidad de proyectos de código. Gemini se centra en contexto del ecosistema Google. Una buena colaboración de largo plazo con IA no pone toda la información en una sola caja negra; mantiene cada tipo de memoria en el lugar correcto.&lt;/p&gt;
&lt;p&gt;Pon preferencias personales en memoria personal, reglas de ingeniería en el codebase, y materiales históricos en los sistemas originales de documentos y correo. El trabajo de la IA es llamar el contexto correcto cuando hace falta, no mezclar todo en una sola pila.&lt;/p&gt;
&lt;h2 id=&#34;enlaces&#34;&gt;Enlaces
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;OpenAI Memory FAQ: &lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/8590148-memory-faq&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.openai.com/en/articles/8590148-memory-faq&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ChatGPT Release Notes: &lt;a class=&#34;link&#34; href=&#34;https://help.openai.com/en/articles/6825453-chatgpt-release-notes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://help.openai.com/en/articles/6825453-chatgpt-release-notes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Claude Code Memory: &lt;a class=&#34;link&#34; href=&#34;https://code.claude.com/docs/en/memory&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://code.claude.com/docs/en/memory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Gemini Saved info: &lt;a class=&#34;link&#34; href=&#34;https://support.google.com/gemini/answer/15637730&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://support.google.com/gemini/answer/15637730&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Gemini Apps Privacy Hub: &lt;a class=&#34;link&#34; href=&#34;https://support.google.com/gemini/answer/13594961&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://support.google.com/gemini/answer/13594961&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Gemini Embedding 2: texto, imagen, video y audio en un mismo espacio vectorial</title>
        <link>https://knightli.com/es/2026/05/04/gemini-embedding-2-multimodal-rag/</link>
        <pubDate>Mon, 04 May 2026 06:01:10 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/04/gemini-embedding-2-multimodal-rag/</guid>
        <description>&lt;p&gt;Google Developers Blog presento el uso de Gemini Embedding 2 para desarrollo. El modelo ya esta en GA a traves de Gemini API y Gemini Enterprise Agent Platform. Lo importante no es solo que sea &amp;ldquo;un nuevo modelo de embedding&amp;rdquo;, sino que puede mapear texto, imagenes, video, audio y documentos al mismo espacio semantico.&lt;/p&gt;
&lt;p&gt;Esto amplia los limites de los sistemas de recuperacion. Antes, muchos flujos RAG necesitaban convertir imagenes, videos o audio en texto o metadatos y crear indices separados. Gemini Embedding 2 puede procesar directamente entradas multimodales, haciendo que agents, busqueda y sistemas de clasificacion trabajen mas facilmente con materiales reales de negocio.&lt;/p&gt;
&lt;p&gt;Enlace original: &lt;a class=&#34;link&#34; href=&#34;https://developers.googleblog.com/building-with-gemini-embedding-2/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Building with Gemini Embedding 2: Agentic multimodal RAG and beyond&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;capacidades-del-modelo&#34;&gt;Capacidades del modelo
&lt;/h2&gt;&lt;p&gt;Gemini Embedding 2 admite mas de 100 idiomas. Una sola solicitud puede procesar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hasta 8,192 tokens de texto.&lt;/li&gt;
&lt;li&gt;Hasta 6 imagenes.&lt;/li&gt;
&lt;li&gt;Hasta 120 segundos de video.&lt;/li&gt;
&lt;li&gt;Hasta 180 segundos de audio.&lt;/li&gt;
&lt;li&gt;Hasta 6 paginas PDF.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La clave es el &amp;ldquo;espacio semantico unificado&amp;rdquo;. Los desarrolladores pueden poner contenidos de distintas modalidades en una misma representacion vectorial y aplicar la misma logica de recuperacion, clustering o reranking.&lt;/p&gt;
&lt;p&gt;Por ejemplo, una descripcion de texto y una imagen pueden ir en la misma solicitud de embedding:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google.genai&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;types&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dog.png&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;image_bytes&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;embed_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;gemini-embedding-2&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;An image of a dog&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;types&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;from_bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_bytes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;mime_type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;image/png&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;embeddings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Si quieres obtener un embedding separado para cada entrada, en vez de agregarlas en un unico vector, puedes usar Batch API. El articulo tambien menciona que Agent Platform sigue avanzando en este soporte por lotes.&lt;/p&gt;
&lt;h2 id=&#34;que-significa-para-rag&#34;&gt;Que significa para RAG
&lt;/h2&gt;&lt;p&gt;El embedding multimodal es muy util para RAG agentico. Un AI agent puede necesitar revisar al mismo tiempo repositorios de codigo, PDF, capturas, graficos, transcripciones de reuniones y fotos de producto. Si todos los materiales entran en el mismo espacio semantico, la recuperacion no necesita una entrada distinta para cada formato.&lt;/p&gt;
&lt;p&gt;Google recomienda usar task prefix segun la tarea para acercar el embedding al objetivo de recuperacion. Por ejemplo, preguntas y respuestas, fact checking, recuperacion de codigo y resultados de busqueda pueden usar prefijos distintos:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate embedding for your task&amp;#39;s query:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;prepare_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;task: question answering | query: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#34;task: fact checking | query: {content}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#34;task: code retrieval | query: {content}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#34;task: search result | query: {content}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate embedding for document of an asymmetric retrieval task:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;prepare_document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;title&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;none&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;title: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt; | text: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Este prefijo encaja con recuperacion asimetrica: las consultas suelen ser cortas y los documentos largos. Preparar query y document con formatos de tarea distintos puede mejorar el emparejamiento entre consulta corta y documento largo.&lt;/p&gt;
&lt;p&gt;El articulo da dos resultados reales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Harvey mejoro un 3% el Recall@20 precision frente a la generacion anterior de embedding en benchmarks legales.&lt;/li&gt;
&lt;li&gt;Supermemory mejoro un 40% el Recall@1 en precision de busqueda y lo usa en memoria, indexacion, busqueda y Q&amp;amp;A.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Estos numeros no significan que todos los escenarios mejoren igual, pero muestran que el embedding multimodal ya no es solo una demostracion, sino que produce efecto en productos reales de busqueda.&lt;/p&gt;
&lt;h2 id=&#34;busqueda-visual&#34;&gt;Busqueda visual
&lt;/h2&gt;&lt;p&gt;Gemini Embedding 2 tambien encaja con busqueda por imagen, busqueda mixta imagen-texto e identificacion de productos. El articulo menciona que Nuuly, una empresa de alquiler de ropa, lo uso para emparejar fotos de ropa sin etiquetar en almacen: Match@20 subio de 60% a casi 87%, y el exito total de identificacion paso de 74% a mas de 90%.&lt;/p&gt;
&lt;p&gt;La clave de estos escenarios no es generar contenido, sino entender &amp;ldquo;a que inventario, documento o registro de producto se parece mas esta imagen&amp;rdquo;. Si tu negocio tiene muchas imagenes, clips de video o documentos escaneados, el embedding multimodal es mas natural que un indice puramente textual.&lt;/p&gt;
&lt;h2 id=&#34;reranking-de-recuperacion&#34;&gt;Reranking de recuperacion
&lt;/h2&gt;&lt;p&gt;El embedding tambien puede usarse para rerank. Una practica comun es recuperar primero un grupo de candidatos y luego calcular la similitud entre cada candidato y la consulta del usuario, subiendo los resultados mas relevantes:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 1. Define a function to calculate the dot product (cosine similarity)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;dot_product&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ndarray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;a&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;@&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 2. Retrieve your embeddings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# (Assuming &amp;#39;summaries&amp;#39; is your list of search results)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;search_res&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_embeddings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;summaries&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;embedded_query&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_embeddings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 3. Calculate similarity scores&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;sim_value&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dot_product&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_res&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;embedded_query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 4. Select the most relevant result&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;best_match_index&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;np&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;argmax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sim_value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;El articulo tambien menciona otra idea: pedir primero al modelo que genere una respuesta hipotetica con su conocimiento interno, hacer embedding de esa respuesta y compararla con los candidatos. Esto ayuda a elegir resultados semanticamente mas cercanos, especialmente en RAG de preguntas y respuestas.&lt;/p&gt;
&lt;h2 id=&#34;clustering-clasificacion-y-deteccion-de-anomalias&#34;&gt;Clustering, clasificacion y deteccion de anomalias
&lt;/h2&gt;&lt;p&gt;Ademas de recuperacion, los embeddings sirven para clustering, clasificacion y deteccion de anomalias. A diferencia de la recuperacion de preguntas y respuestas, estas son tareas simetricas: query y document pueden usar el mismo prefijo de tarea.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Generate embedding for query &amp;amp; document of your task.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;prepare_query_and_document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#39;task: clustering | query: {content}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#39;task: sentence similarity | query: {content}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# return f&amp;#39;task: classification | query: {content}&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Estas tareas pueden aplicarse a clasificacion de opinion publica, moderacion de contenido, agrupacion de activos similares y deteccion de muestras anomalas. Tambien pueden ayudar a un agent a ordenar mucho contexto antes de entrar en razonamiento posterior.&lt;/p&gt;
&lt;h2 id=&#34;almacenamiento-y-coste&#34;&gt;Almacenamiento y coste
&lt;/h2&gt;&lt;p&gt;Gemini Embedding 2 devuelve por defecto vectores de 3,072 dimensiones. Usa Matryoshka Representation Learning, por lo que puedes truncar el vector a una dimension menor con &lt;code&gt;output_dimensionality&lt;/code&gt;. Google recomienda 1,536 o 768 dimensiones cuando la eficiencia es prioritaria:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;embed_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-embedding-2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;What is the meaning of life?&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dimensionality&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;768&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Los vectores pueden almacenarse en Agent Platform Vector Search, Pinecone, Weaviate, Qdrant, ChromaDB y sistemas similares. En coste, el articulo menciona que Batch API ofrece mayor throughput y puede llegar al 50% del precio por defecto de embeddings.&lt;/p&gt;
&lt;h2 id=&#34;como-usarlo-como-desarrollador&#34;&gt;Como usarlo como desarrollador
&lt;/h2&gt;&lt;p&gt;Si ya tienes RAG textual, puedes empezar con dos mejoras incrementales:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Poner PDF, capturas, descripciones de imagen y documentos de texto en un mismo indice, y comprobar si la recuperacion se vuelve mas estable.&lt;/li&gt;
&lt;li&gt;Agregar task prefix para distintas tareas, como Q&amp;amp;A, fact checking, recuperacion de codigo y busqueda de productos. No proceses todo con el mismo formato de embedding.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Si estas creando un producto nuevo, considera primero estas direcciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Base de conocimiento empresarial: recuperar documentos, graficos, capturas de presentaciones y material de reuniones al mismo tiempo.&lt;/li&gt;
&lt;li&gt;Busqueda visual: encontrar productos, activos, disenos y archivos usando imagen, texto o entradas mixtas.&lt;/li&gt;
&lt;li&gt;Toolchain de Agent: permitir que coding agents, research agents o agentes de soporte recuperen materiales de negocio en varios formatos.&lt;/li&gt;
&lt;li&gt;Gobernanza de contenido: clasificar, agrupar y detectar anomalias en texto, imagenes y clips de video.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El valor de Gemini Embedding 2 esta en convertir materiales multimodales en un mismo conjunto de activos recuperables. Para desarrolladores, reduce la capa intermedia de &amp;ldquo;convertir primero a texto y luego buscar&amp;rdquo;, y acerca los sistemas RAG a la forma real de los datos del mundo.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Gemini llega a los coches con Google built-in: el asistente de voz del vehículo empieza a parecer un asistente de IA real</title>
        <link>https://knightli.com/es/2026/05/01/gemini-cars-with-google-built-in/</link>
        <pubDate>Fri, 01 May 2026 06:09:57 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/05/01/gemini-cars-with-google-built-in/</guid>
        <description>&lt;p&gt;Google anunció el 30 de abril de 2026 que &lt;code&gt;Gemini&lt;/code&gt; empezaría a llegar a coches con &lt;code&gt;Google built-in&lt;/code&gt;, como una evolución del Google Assistant dentro del vehículo.&lt;/p&gt;
&lt;p&gt;Lo importante no es solo que &amp;ldquo;hay otro asistente de IA en el coche&amp;rdquo;. El cambio real es que la interacción por voz en el automóvil empieza a moverse desde comandos rígidos hacia conversaciones más naturales. El usuario no necesita recordar fórmulas exactas: puede hablar con Gemini para navegar, manejar mensajes, consultar información del coche o controlar algunos ajustes del habitáculo.&lt;/p&gt;
&lt;h2 id=&#34;primero-para-usuarios-de-inglés-en-estados-unidos&#34;&gt;Primero para usuarios de inglés en Estados Unidos
&lt;/h2&gt;&lt;p&gt;Según Google, la actualización cubrirá vehículos nuevos y existentes, siempre que el coche soporte &lt;code&gt;Google built-in&lt;/code&gt; y el usuario haya iniciado sesión con su cuenta de Google en el sistema del vehículo.&lt;/p&gt;
&lt;p&gt;El despliegue empieza con usuarios de inglés en Estados Unidos y luego se ampliará a más idiomas y países. Los usuarios compatibles verán una indicación para actualizar a Gemini. Después, podrán invocarlo con:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;decir &lt;code&gt;Hey Google&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;tocar el micrófono en la pantalla principal;&lt;/li&gt;
&lt;li&gt;usar el botón de voz del volante.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Google no está creando una entrada nueva que haya que aprender desde cero: conserva el punto de acceso de voz existente y cambia el asistente de fondo por Gemini.&lt;/p&gt;
&lt;h2 id=&#34;la-voz-en-el-coche-deja-de-depender-solo-de-comandos-fijos&#34;&gt;La voz en el coche deja de depender solo de comandos fijos
&lt;/h2&gt;&lt;p&gt;El problema clásico de los asistentes de voz en coches es que podían hacer bastantes cosas, pero el usuario tenía que hablar de forma muy &amp;ldquo;estándar&amp;rdquo;. Si la petición era un poco compleja, el asistente fallaba o ejecutaba solo una acción básica.&lt;/p&gt;
&lt;p&gt;Con Gemini, Google subraya la conversación natural. Por ejemplo, el usuario puede decir:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I need to grab lunch, find some highly rated sit-down restaurants along the way. I&amp;rsquo;m not in a rush, oh, and I’d like to eat outside.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Gemini puede combinar esa intención con Google Maps para buscar restaurantes adecuados en la ruta. Luego el usuario puede preguntar por aparcamiento, opciones vegetarianas u otros detalles sin iniciar una búsqueda completa desde cero.&lt;/p&gt;
&lt;p&gt;Esto encaja mejor con la conducción. Al manejar es difícil filtrar, tocar y ajustar condiciones como en un móvil. Si el asistente entiende una intención más completa, reduce distracciones.&lt;/p&gt;
&lt;h2 id=&#34;mapas-mensajes-y-música-se-vuelven-más-fluidos&#34;&gt;Mapas, mensajes y música se vuelven más fluidos
&lt;/h2&gt;&lt;p&gt;Los ejemplos de Google giran alrededor de necesidades comunes mientras se conduce.&lt;/p&gt;
&lt;p&gt;La primera categoría es búsqueda de rutas y lugares. Gemini puede buscar restaurantes, sitios turísticos o cargadores en el camino con información de Google Maps, y responder preguntas relacionadas con la ruta actual. Si pasas cerca de un estadio, puedes preguntar si hay un evento y si afectará al tráfico.&lt;/p&gt;
&lt;p&gt;La segunda categoría es mensajería. Gemini puede resumir mensajes nuevos y responder usando el contexto. Por ejemplo, puede decir a un amigo que vas en camino e incluir la hora estimada de llegada. Si quieres ajustar el texto, puedes seguir hablando sin empezar de nuevo.&lt;/p&gt;
&lt;p&gt;La tercera categoría es música y ambiente. No hace falta conocer una emisora o lista exacta. Puedes describir lo que quieres escuchar, como una radio de jazz o folk-rock alegre de los 70 en YouTube Music para conducir por montaña, y pedir que salte canciones lentas.&lt;/p&gt;
&lt;p&gt;Las funciones no son completamente nuevas, pero el valor de Gemini está en procesar varias condiciones en una frase natural en lugar de obligar al usuario a usar comandos fijos.&lt;/p&gt;
&lt;h2 id=&#34;gemini-live-también-entra-al-coche&#34;&gt;Gemini Live también entra al coche
&lt;/h2&gt;&lt;p&gt;Google también mencionó que &lt;code&gt;Gemini Live&lt;/code&gt; llegará al contexto del vehículo, por ahora en beta. El usuario puede tocar el botón de Gemini Live o decir &lt;code&gt;Hey Google, let&#39;s talk&lt;/code&gt; para iniciar una conversación más libre.&lt;/p&gt;
&lt;p&gt;Esto se parece más a una experiencia de aprendizaje o lluvia de ideas durante el viaje. Por ejemplo, al ir a Lake Tahoe, Gemini puede contar historia y datos locales; si algo interesa, se puede interrumpir y preguntar más. También puede ayudar a planear rutas a pie y actividades al llegar.&lt;/p&gt;
&lt;p&gt;La diferencia con el asistente tradicional es clara: el asistente clásico es más parecido a un botón de herramienta; Gemini Live se acerca más a una interfaz de voz continua.&lt;/p&gt;
&lt;h2 id=&#34;manual-del-coche-y-estado-en-tiempo-real-son-la-diferencia-clave&#34;&gt;Manual del coche y estado en tiempo real son la diferencia clave
&lt;/h2&gt;&lt;p&gt;Más interesante aún, Gemini no responde solo preguntas generales. Google dice que trabaja con fabricantes para integrarlo más profundamente en los sistemas del vehículo.&lt;/p&gt;
&lt;p&gt;Esto permite varios tipos de capacidades más cercanas al coche real.&lt;/p&gt;
&lt;p&gt;Primero, el usuario puede preguntar por funciones del vehículo. Por ejemplo: &amp;ldquo;¿Qué debo hacer antes de un lavado automático?&amp;rdquo; o &amp;ldquo;El techo de mi garaje es bajo, ¿cómo limito la apertura del portón trasero?&amp;rdquo;. Gemini puede usar el manual del propietario proporcionado por el fabricante para responder según el modelo concreto. El detalle disponible dependerá de cada marca y vehículo.&lt;/p&gt;
&lt;p&gt;Segundo, los usuarios de EV pueden preguntar por batería y autonomía en tiempo real: carga actual, carga estimada al llegar o cargadores cercanos. También puede combinarlo con Google Maps para buscar cafeterías cerca de estaciones de carga.&lt;/p&gt;
&lt;p&gt;Tercero, algunos ajustes del habitáculo pueden controlarse con lenguaje natural. El ejemplo de Google es decir que el coche está &amp;ldquo;húmedo y frío&amp;rdquo;; Gemini puede entender la intención, subir la calefacción y activar desempañado.&lt;/p&gt;
&lt;p&gt;Este tipo de integración es más útil que meter un chatbot genérico en el coche. Un automóvil tiene estado, hardware y límites de seguridad claros. Si el asistente entiende ese contexto, aporta más valor.&lt;/p&gt;
&lt;h2 id=&#34;los-límites-del-ai-en-el-coche-importan-más&#34;&gt;Los límites del AI en el coche importan más
&lt;/h2&gt;&lt;p&gt;El contexto del coche exige más que el móvil o la web. Al conducir, el usuario no puede mirar la pantalla constantemente ni dedicar demasiada atención a corregir al asistente. El sistema debe ser breve, fiable y no crear carga adicional en momentos críticos.&lt;/p&gt;
&lt;p&gt;Por eso, Gemini en coches no significa que todas las tareas complejas deban hacerse durante la conducción. La dirección razonable es:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;reducir el coste operativo de navegación y consultas;&lt;/li&gt;
&lt;li&gt;sustituir menús de varias capas por lenguaje natural;&lt;/li&gt;
&lt;li&gt;ayudar a entender funciones del vehículo;&lt;/li&gt;
&lt;li&gt;manejar mensajes y medios sin distraer;&lt;/li&gt;
&lt;li&gt;dar a usuarios EV información más fluida de carga y ruta.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En sentido contrario, las operaciones de alto riesgo necesitan límites claros. Ajustes que afecten a la seguridad, envío de mensajes que requieran confirmación o acciones de control del vehículo deben tener flujos de confirmación explícitos.&lt;/p&gt;
&lt;h2 id=&#34;resumen&#34;&gt;Resumen
&lt;/h2&gt;&lt;p&gt;Gemini en coches con &lt;code&gt;Google built-in&lt;/code&gt; es otro paso de los asistentes de IA desde el móvil y la web hacia entornos cotidianos.&lt;/p&gt;
&lt;p&gt;Su importancia no está en poder &amp;ldquo;charlar con el coche&amp;rdquo;, sino en que el asistente de voz entiende intenciones más complejas y combina mapas, mensajes, música, manual del vehículo y parte del estado del coche para completar tareas.&lt;/p&gt;
&lt;p&gt;Si el despliegue funciona bien, la interacción por voz en coches podría pasar de &amp;ldquo;recordar comandos&amp;rdquo; a &amp;ldquo;describir necesidades&amp;rdquo;. Eso importa mucho al conducir, porque un buen AI para el coche no debería exigir demasiada atención del conductor.&lt;/p&gt;
&lt;p&gt;Referencias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.google/products-and-platforms/platforms/android/cars-with-google-built-in-gemini-tips-2026/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Your car with Google built-in is about to get smarter, thanks to Gemini - Google Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Cómo dividir tareas entre ChatGPT, Claude y Gemini: elección de uso diario, codificación y capacidades especiales</title>
        <link>https://knightli.com/es/2026/04/25/chatgpt-claude-gemini-task-selection/</link>
        <pubDate>Sat, 25 Apr 2026 10:51:19 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/04/25/chatgpt-claude-gemini-task-selection/</guid>
        <description>&lt;p&gt;Mucha gente ya no confía en un solo modelo. En cambio, alternan entre &amp;ldquo;ChatGPT&amp;rdquo;, &amp;ldquo;Claude&amp;rdquo; y &amp;ldquo;Gemini&amp;rdquo;. Eso hace que la pregunta sea mucho más práctica: &lt;strong&gt;¿qué tipo de tareas deberían asignarse a qué modelo?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Esto resulta confuso no porque los tres sean débiles, sino porque ahora son fuertes de diferentes maneras. Si aún así eliges basándose en un estándar vago como “cuál es más inteligente”, fácilmente puedes terminar eligiendo la herramienta equivocada.&lt;/p&gt;
&lt;p&gt;Si simplificamos primero la conclusión, queda más o menos así:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Para conversaciones diarias y tareas de propósito general, muchas personas comienzan con &lt;code&gt;ChatGPT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Para la codificación de línea de comandos, la colaboración de contexto prolongado y la ejecución sostenida de tareas, &amp;ldquo;Claude&amp;rdquo; a menudo se siente más fluido.&lt;/li&gt;
&lt;li&gt;Cuando necesita integración del ecosistema de Google, búsqueda, puntos de entrada multimodales o ciertas capacidades a nivel de producto, &amp;ldquo;Gemini&amp;rdquo; tiende a destacar más.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dividámoslo en tres partes.&lt;/p&gt;
&lt;h2 id=&#34;1-conversaciones-diarias-por-qué-muchas-personas-todavía-abren-chatgpt-primero&#34;&gt;1. Conversaciones diarias: por qué muchas personas todavía abren &lt;code&gt;ChatGPT&lt;/code&gt; primero
&lt;/h2&gt;&lt;p&gt;Para la mayoría de los escenarios cotidianos, &amp;ldquo;ChatGPT&amp;rdquo; todavía se siente como el &amp;ldquo;punto de entrada predeterminado&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;No se trata de un único punto de referencia. Se trata de la experiencia general:&lt;br&gt;
cuando desea hacer una pregunta rápida, organizar sus pensamientos, redactar un borrador, crear una primera versión o resumir un material, &amp;ldquo;ChatGPT&amp;rdquo; generalmente se siente bastante equilibrado.&lt;/p&gt;
&lt;p&gt;Sus puntos fuertes suelen aparecer en algunos lugares:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Su estilo de respuesta es relativamente estable.&lt;/li&gt;
&lt;li&gt;La curva de aprendizaje es baja para los usuarios generales.&lt;/li&gt;
&lt;li&gt;La mayoría de las tareas amplias no requieren muchos ajustes adicionales&lt;/li&gt;
&lt;li&gt;El producto se siente pulido y funciona bien para el uso diario frecuente&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Entonces, si tu tarea es algo como esto:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ayúdame a organizar un tema.&lt;/li&gt;
&lt;li&gt;Convertir una idea en contenido estructurado.&lt;/li&gt;
&lt;li&gt;Resumir un artículo extenso.&lt;/li&gt;
&lt;li&gt;Lluvia de ideas sobre varios enfoques&lt;/li&gt;
&lt;li&gt;Reescribir algo más claramente&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Entonces, &amp;ldquo;ChatGPT&amp;rdquo; suele ser un lugar muy natural para empezar.&lt;/p&gt;
&lt;p&gt;Eso no significa que sea siempre la opción más sólida para cada tarea profesional. Esto significa que, para un uso amplio y de propósito general, a menudo se siente más como el espacio de trabajo predeterminado.&lt;/p&gt;
&lt;h2 id=&#34;2-codificación-de-línea-de-comandos-y-tareas-largas-por-qué-mucha-gente-se-inclina-por-claude&#34;&gt;2. Codificación de línea de comandos y tareas largas: por qué mucha gente se inclina por &lt;code&gt;Claude&lt;/code&gt;
&lt;/h2&gt;&lt;p&gt;Una vez que una tarea pasa de &amp;ldquo;charlemos&amp;rdquo; a &amp;ldquo;seguiremos trabajando hasta terminar esto&amp;rdquo;, muchas personas empiezan a preferir &amp;ldquo;Claude&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Esto es especialmente cierto en escenarios como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Programación de línea de comandos&lt;/li&gt;
&lt;li&gt;Comprender el contexto de un gran proyecto.&lt;/li&gt;
&lt;li&gt;Coordinar ediciones en múltiples archivos.&lt;/li&gt;
&lt;li&gt;Depuración de largas cadenas de tareas.&lt;/li&gt;
&lt;li&gt;Leer código mientras se avanza constantemente una tarea&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En este tipo de trabajo, la clave no suele ser si una respuesta es especialmente impresionante. Se trata de si el modelo puede permanecer estable a lo largo de una cadena de trabajo más larga.&lt;/p&gt;
&lt;p&gt;La razón por la que a menudo se prefiere &amp;ldquo;Claude&amp;rdquo; no es que &amp;ldquo;diga una frase mejor que las demás&amp;rdquo;, sino que:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Se mantiene mejor en tareas de contexto prolongado.&lt;/li&gt;
&lt;li&gt;Se siente más estable al leer archivos, registros y reglas continuamente&lt;/li&gt;
&lt;li&gt;Es más adecuado para avanzar gradualmente en trabajos de codificación complejos.&lt;/li&gt;
&lt;li&gt;En los flujos de trabajo de agentes y de línea de comandos, a menudo se lo trata como el modelo de trabajo principal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si está haciendo &amp;ldquo;codificación de vibración&amp;rdquo;, corrigiendo errores en la terminal, entendiendo la estructura del proyecto o cambiando características en varios archivos, las fortalezas de &amp;ldquo;Claude&amp;rdquo; tienden a mostrarse más claramente.
En pocas palabras, &amp;ldquo;Claude&amp;rdquo; se siente más como un modelo con el que trabajas para hacer las cosas, no simplemente como uno al que haces una pregunta y obtienes una respuesta.&lt;/p&gt;
&lt;h2 id=&#34;3-géminis-a-menudo-gana-no-compitiendo-frontalmente-en-todo&#34;&gt;3. &amp;ldquo;Géminis&amp;rdquo; a menudo gana no &amp;ldquo;compitiendo frontalmente en todo&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;Cuando la gente habla de &amp;ldquo;Géminis&amp;rdquo;, a menudo formulan la pregunta de la siguiente manera: ¿es el más fuerte de los tres?&lt;/p&gt;
&lt;p&gt;Pero en el uso real, la pregunta más útil no suele ser esa. Es: &lt;strong&gt;¿en qué escenarios vale especialmente la pena sacarlo y usarlo a propósito?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El valor de &amp;ldquo;Géminis&amp;rdquo; a menudo se muestra más claramente en estas direcciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Integración con el ecosistema de Google.&lt;/li&gt;
&lt;li&gt;Búsqueda y recopilación de información.&lt;/li&gt;
&lt;li&gt;Puntos de entrada multimodales&lt;/li&gt;
&lt;li&gt;Ciertos vínculos de características del lado del producto.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si su flujo de trabajo ya está cerca de la cadena de herramientas de Google, por ejemplo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Buscar&lt;/li&gt;
&lt;li&gt;Documentos&lt;/li&gt;
&lt;li&gt;Correo electrónico&lt;/li&gt;
&lt;li&gt;Uso del lado del navegador&lt;/li&gt;
&lt;li&gt;Puntos de entrada móviles&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Entonces la conveniencia práctica de &amp;ldquo;Gemini&amp;rdquo; puede importar más que una simple comparación entre modelo y puntuación.&lt;/p&gt;
&lt;p&gt;En otras palabras, &amp;ldquo;Gemini&amp;rdquo; suele ser útil porque se integra en su flujo de trabajo de manera más natural, no solo porque puede o no vencer a otra persona en una sola respuesta.&lt;/p&gt;
&lt;h2 id=&#34;4-la-forma-útil-de-elegir-no-es-preguntar-quién-es-más-fuerte-sino-qué-tipo-de-tarea-tienes&#34;&gt;4. La forma útil de elegir no es preguntar quién es más fuerte, sino qué tipo de tarea tienes
&lt;/h2&gt;&lt;p&gt;Cuando la gente compara los tres modelos uno al lado del otro, la trampa más fácil es tratar de encontrar el “mejor” modelo.&lt;/p&gt;
&lt;p&gt;Pero las tareas reales varían demasiado:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Algunas son preguntas y respuestas únicas&lt;/li&gt;
&lt;li&gt;Algunas son conversaciones de larga duración.&lt;/li&gt;
&lt;li&gt;Algunos son proyectos de software.&lt;/li&gt;
&lt;li&gt;Algunos son recuperación de información.&lt;/li&gt;
&lt;li&gt;Algunos son procesamiento multimodal&lt;/li&gt;
&lt;li&gt;Algunos son colaboración en cadena de herramientas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por lo tanto, el enfoque más eficaz suele ser ordenar por tipo de tarea:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Si desea un asistente amplio y de alta frecuencia que funcione de inmediato, comience con &lt;code&gt;ChatGPT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Si necesita contexto extenso, trabajo en la línea de comandos, colaboración en codificación y progreso constante en tareas complejas, pruebe primero con &amp;ldquo;Claude&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;Si necesita ayuda del ecosistema de Google, búsqueda, puntos de entrada multimodal o ciertas integraciones de productos, preste especial atención a &amp;ldquo;Gemini&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ese tipo de división del trabajo está mucho más cerca del uso en el mundo real que obligar a un único campeón general.&lt;/p&gt;
&lt;h2 id=&#34;5-por-qué-muchos-usuarios-habituales-se-suscriben-a-los-tres&#34;&gt;5. Por qué muchos usuarios habituales se suscriben a los tres
&lt;/h2&gt;&lt;p&gt;Desde la perspectiva de un usuario ligero, pagar por los tres puede parecer redundante.&lt;br&gt;
Desde la perspectiva de un usuario intensivo, es más como asignar diferentes herramientas a diferentes trabajos.&lt;/p&gt;
&lt;p&gt;La razón es sencilla:&lt;br&gt;
Si las fortalezas de los tres modelos ya han comenzado a divergir claramente, entonces usarlos juntos no constituye realmente un gasto duplicado. Es una forma de reducir los costos de cambio y los costos de prueba y error.&lt;/p&gt;
&lt;p&gt;Por ejemplo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Utilice &lt;code&gt;ChatGPT&lt;/code&gt; para la organización diaria y preguntas y respuestas generales&lt;/li&gt;
&lt;li&gt;Utilice &lt;code&gt;Claude&lt;/code&gt; para el trabajo de codificación principal.&lt;/li&gt;
&lt;li&gt;Utilice &lt;code&gt;Gemini&lt;/code&gt; para ciertos flujos de trabajo de búsqueda, multimodales o relacionados con Google&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La lógica de esta configuración no es fundamentalmente diferente de la de los diseñadores que instalan múltiples herramientas creativas o los desarrolladores que usan múltiples IDE.&lt;/p&gt;
&lt;h2 id=&#34;6-cuándo-no-debes-cambiar-de-modelo-con-demasiada-frecuencia&#34;&gt;6. Cuándo no debes cambiar de modelo con demasiada frecuencia
&lt;/h2&gt;&lt;p&gt;Eso sí, tener más modelos no siempre es mejor.&lt;/p&gt;
&lt;p&gt;Si todavía estás creando un flujo de trabajo estable, saltar demasiado pronto y con demasiada frecuencia entre tres modelos puede complicar aún más las cosas. Los problemas comunes incluyen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Volver a explicar la misma tarea tres veces.&lt;/li&gt;
&lt;li&gt;Recibir diferentes sugerencias de diferentes modelos y luchar más para juzgarlas.&lt;/li&gt;
&lt;li&gt;Perder contexto y aumentar los costos de colaboración.&lt;/li&gt;
&lt;li&gt;Estancarse en la elección de herramientas antes de establecer sus propios límites de trabajo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Entonces, una forma más estable suele ser esta:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Asigne primero a cada modelo un escenario principal&lt;/li&gt;
&lt;li&gt;Úselo continuamente en ese escenario por un tiempo.&lt;/li&gt;
&lt;li&gt;Construya gradualmente sus propios hábitos de división del trabajo.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Eso hace que sea más fácil obtener experiencia reutilizable en lugar de quedarse para siempre en la etapa de &amp;ldquo;déjame probar esta hoy&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;7-una-forma-sencilla-de-recordarlo&#34;&gt;7. Una forma sencilla de recordarlo
&lt;/h2&gt;&lt;p&gt;Si solo desea una versión práctica para recordar, puede utilizar esta división en lenguaje sencillo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ChatGPT&lt;/code&gt;: más parecido al asistente de uso general predeterminado&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Claude&lt;/code&gt;: más bien la opción principal para tareas largas y colaboración en codificación&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gemini&lt;/code&gt;: más bien la herramienta con mayores ventajas en la búsqueda, el trabajo multimodal y el ecosistema de Google&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esta no es una regla absoluta y no significa que los tres no puedan reemplazarse entre sí. Es simplemente un punto de partida más realista.&lt;/p&gt;
&lt;p&gt;Lo que realmente importa no es elegir el “modelo más fuerte del universo”, sino averiguarlo lo antes posible:&lt;br&gt;
&lt;strong&gt;Para el tipo de tarea que tienes por delante, ¿qué modelo ahorra más tiempo, cuesta menos esfuerzo mental y facilita la obtención de resultados?&lt;/strong&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Aplicación de Google para escritorio: llevando la búsqueda con IA a Windows</title>
        <link>https://knightli.com/es/2026/04/18/google-app-desktop-ai-search-windows/</link>
        <pubDate>Sat, 18 Apr 2026 11:08:00 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/04/18/google-app-desktop-ai-search-windows/</guid>
        <description>&lt;p&gt;Google ha añadido un punto de entrada de búsqueda más ligero al escritorio de Windows. En lugar de abrir primero un navegador, puede presionar un acceso directo, abrir un cuadro de búsqueda, hacer preguntas, cargar imágenes, analizar archivos, seleccionar contenido en su pantalla y seguir haciendo preguntas de seguimiento.&lt;/p&gt;
&lt;p&gt;El nombre oficial es &lt;strong&gt;Aplicación de Google para escritorio&lt;/strong&gt;. No pretende reemplazar un navegador tradicional. Su propósito es reunir la búsqueda de Google, el modo AI, Google Lens, compartir pantalla, búsqueda de archivos de computadora y búsqueda de Google Drive en un cuadro de búsqueda de escritorio.&lt;/p&gt;
&lt;p&gt;Si busca información con frecuencia, resume documentos, identifica contenido de capturas de pantalla o desea una forma más rápida de buscar en su computadora, vale la pena probar esta aplicación de escritorio de Google.&lt;/p&gt;
&lt;h2 id=&#34;requisitos&#34;&gt;Requisitos
&lt;/h2&gt;&lt;p&gt;Según la página oficial de Google, los requisitos actuales son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Los usuarios deben tener 13 años o más.&lt;/li&gt;
&lt;li&gt;El dispositivo debe ejecutar Windows 10 o posterior.&lt;/li&gt;
&lt;li&gt;Actualmente, la aplicación solo está disponible en inglés.&lt;/li&gt;
&lt;li&gt;El modo AI en la Búsqueda de Google no es compatible con todas las cuentas, países e idiomas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En otras palabras, los usuarios de Windows 10 y Windows 11 pueden instalarlo primero y probarlo. La página oficial actualmente dice &lt;strong&gt;Ahora disponible en Windows&lt;/strong&gt;, por lo que este artículo se centra en la versión de Windows.&lt;/p&gt;
&lt;h2 id=&#34;características-principales&#34;&gt;Características principales
&lt;/h2&gt;&lt;h3 id=&#34;1-abrir-búsqueda-con-un-acceso-directo&#34;&gt;1. Abrir búsqueda con un acceso directo
&lt;/h3&gt;&lt;p&gt;Después de la instalación, presione:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Alt + Space
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Esto abre el cuadro de búsqueda de escritorio de Google. Presiónelo nuevamente para ocultar el cuadro.&lt;/p&gt;
&lt;p&gt;La experiencia es un poco como un iniciador de sistema. Ya sea que esté escribiendo un documento, leyendo una página web, organizando archivos o usando otra aplicación, puede acceder a la Búsqueda sin tener que volver al navegador.&lt;/p&gt;
&lt;h3 id=&#34;2-modo-ia-y-preguntas-de-seguimiento&#34;&gt;2. Modo IA y preguntas de seguimiento
&lt;/h3&gt;&lt;p&gt;La búsqueda tradicional suele proporcionar una lista de enlaces. El modo AI se acerca más a una respuesta resumida creada a partir de los resultados de búsqueda. Puede hacer una pregunta directamente, obtener una respuesta más completa y seguir abriendo enlaces útiles cuando sea necesario.&lt;/p&gt;
&lt;p&gt;La parte útil es que puedes seguir haciendo preguntas de seguimiento. Por ejemplo, comience con:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;What is this tool best used for?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Luego continúa con:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If I create written content, how can I use it to improve my workflow?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Esto evita reescribir repetidamente palabras clave o saltar entre varias páginas.&lt;/p&gt;
&lt;h3 id=&#34;3-cargar-imágenes-para-reconocimiento-y-búsqueda&#34;&gt;3. Cargar imágenes para reconocimiento y búsqueda
&lt;/h3&gt;&lt;p&gt;La aplicación de escritorio de Google permite cargar una imagen y hacer preguntas sobre ella. Los usos comunes incluyen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Identificar personas, lugares, productos u objetos en una imagen.&lt;/li&gt;
&lt;li&gt;Encontrar imágenes similares e información relacionada.&lt;/li&gt;
&lt;li&gt;Extraer una descripción del contenido de la imagen.&lt;/li&gt;
&lt;li&gt;Pedirle a la IA que genere indicaciones creativas basadas en la imagen.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por ejemplo, después de subir un retrato, podrías preguntar:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Who is the person in this image? Please provide an introduction and related references.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Para la búsqueda diaria de imágenes, la búsqueda de fuentes y el reconocimiento de objetos, esto es más conveniente que abrir manualmente una página web y cargar la imagen allí.&lt;/p&gt;
&lt;h3 id=&#34;4-seleccione-el-contenido-de-la-pantalla-con-google-lens&#34;&gt;4. Seleccione el contenido de la pantalla con Google Lens
&lt;/h3&gt;&lt;p&gt;Google Lens es una de las partes más útiles de la aplicación de escritorio. Puede seleccionar un área en su pantalla y dejar que reconozca y busque ese contenido.&lt;/p&gt;
&lt;p&gt;Es útil para:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Seleccionar un producto en una página web para encontrar artículos similares o información relacionada.&lt;/li&gt;
&lt;li&gt;Seleccionar texto en una captura de pantalla y pedir una explicación.&lt;/li&gt;
&lt;li&gt;Seleccionar una interfaz de software y preguntar qué herramienta es.&lt;/li&gt;
&lt;li&gt;Seleccionar un mensaje de error y solicitar ideas para solucionar problemas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La idea central es simple: busca lo que ves. Anteriormente, es posible que hayas necesitado tomar una captura de pantalla, guardarla y cargarla. Ahora puedes seleccionar el objetivo directamente en la pantalla.&lt;/p&gt;
&lt;h3 id=&#34;5-búsqueda-de-pantalla-compartida&#34;&gt;5. Búsqueda de pantalla compartida
&lt;/h3&gt;&lt;p&gt;Además de seleccionar una parte de la pantalla, la aplicación también admite compartir pantalla. Una vez habilitada, la IA puede ver la ventana actual o la pantalla completa, y usted puede hacer preguntas sobre lo que está visible.&lt;/p&gt;
&lt;p&gt;Por ejemplo, mientras lees un artículo, puedes preguntar:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Please summarize the key points on the current page.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;O:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;What parts of this page could be improved?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Esto puede ahorrar tiempo al leer páginas web, revisar diseños, analizar fragmentos de código o resumir páginas largas. Cuando se habilita el uso compartido de pantalla, el sistema generalmente muestra un borde claro para que pueda confirmar lo que se está compartiendo.&lt;/p&gt;
&lt;h3 id=&#34;6-buscar-archivos-de-computadora-y-google-drive&#34;&gt;6. Buscar archivos de computadora y Google Drive
&lt;/h3&gt;&lt;p&gt;La página oficial de Google también dice que la aplicación puede encontrar aplicaciones y archivos en su computadora y en Google Drive desde el mismo cuadro de búsqueda.&lt;/p&gt;
&lt;p&gt;Esto combina la búsqueda en el escritorio y la búsqueda en la nube. Si recuerda parte del nombre de un archivo, una palabra clave del contenido o desea encontrar algo rápidamente en Google Drive, no necesita abrir el Explorador de archivos y Drive por separado.&lt;/p&gt;
&lt;p&gt;Al usarla por primera vez, es posible que la aplicación le pregunte si desea habilitar la búsqueda en Google Drive o la búsqueda de archivos locales. Autorice solo las áreas que realmente necesita, especialmente cuando se trata de archivos locales y datos de la nube.&lt;/p&gt;
&lt;h2 id=&#34;instalación-y-uso&#34;&gt;Instalación y uso
&lt;/h2&gt;&lt;h3 id=&#34;1-abra-la-página-de-descarga-oficial&#34;&gt;1. Abra la página de descarga oficial
&lt;/h3&gt;&lt;p&gt;Visita:&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://search.google/google-app/desktop/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://search.google/google-app/desktop/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Haga clic en &lt;strong&gt;Descargar aplicación&lt;/strong&gt; para descargar el instalador.&lt;/p&gt;
&lt;h3 id=&#34;2-instale-la-aplicación-de-escritorio&#34;&gt;2. Instale la aplicación de escritorio
&lt;/h3&gt;&lt;p&gt;Una vez finalizada la descarga, ejecute el instalador y siga las instrucciones.&lt;/p&gt;
&lt;p&gt;Puede optar por iniciar sesión con una cuenta de Google. Iniciar sesión es más útil si desea realizar búsquedas en Google Drive, búsquedas personalizadas y algunas funciones de inteligencia artificial. Si solo desea probar la búsqueda básica, también puede comenzar con las indicaciones predeterminadas.&lt;/p&gt;
&lt;h3 id=&#34;3-abra-el-cuadro-de-búsqueda&#34;&gt;3. Abra el cuadro de búsqueda
&lt;/h3&gt;&lt;p&gt;Prensa:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Alt + Space
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Aparece un cuadro de búsqueda de Google en el escritorio. Puede escribir una pregunta directamente, cargar archivos, usar Lens o comenzar a compartir pantalla.&lt;/p&gt;
&lt;h3 id=&#34;4-habilite-el-ámbito-de-búsqueda-que-necesita&#34;&gt;4. Habilite el ámbito de búsqueda que necesita
&lt;/h3&gt;&lt;p&gt;Si desea buscar en Google Drive o archivos locales, siga las instrucciones para habilitar los permisos relevantes.&lt;/p&gt;
&lt;p&gt;Un enfoque práctico:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Habilite primero la búsqueda de Google Drive y pruebe la búsqueda de documentos en la nube.&lt;/li&gt;
&lt;li&gt;Habilite la búsqueda de archivos locales solo si la necesita.&lt;/li&gt;
&lt;li&gt;Dejar ámbitos innecesarios desactivados.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto le brinda acceso a las partes útiles mientras mantiene los permisos claros.&lt;/p&gt;
&lt;h2 id=&#34;casos-de-uso-comunes&#34;&gt;Casos de uso comunes
&lt;/h2&gt;&lt;h3 id=&#34;analizar-archivos-pdf-y-documentos&#34;&gt;Analizar archivos PDF y documentos
&lt;/h3&gt;&lt;p&gt;Puede arrastrar un PDF, una tabla o un documento y pedirle que resuma los puntos clave.&lt;/p&gt;
&lt;p&gt;Por ejemplo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Please summarize the key points of this PDF and list anything I should pay attention to.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Para archivos densos como formularios, declaraciones, materiales de solicitud o manuales, continúe con:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Please organize the key information by category.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Esto suele ser más rápido que leer un documento largo página por página.&lt;/p&gt;
&lt;h3 id=&#34;resumir-páginas-web&#34;&gt;Resumir páginas web
&lt;/h3&gt;&lt;p&gt;Después de habilitar el uso compartido de pantalla, puede pedirle que resuma la página actual.&lt;/p&gt;
&lt;p&gt;Por ejemplo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Extract the main ideas from this page and summarize them in five bullet points.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Esto es útil para artículos extensos, páginas de productos, documentación y páginas de noticias.&lt;/p&gt;
&lt;h3 id=&#34;identificar-capturas-de-pantalla-e-interfaces&#34;&gt;Identificar capturas de pantalla e interfaces
&lt;/h3&gt;&lt;p&gt;Utilice Google Lens para seleccionar una interfaz de software, un fragmento de código, un mensaje de error o un contenido de imagen en la pantalla y luego pídale que le explique lo que está viendo.&lt;/p&gt;
&lt;p&gt;Por ejemplo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Please explain what this error means and suggest a troubleshooting path.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;O:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;What tool is shown in this screenshot, and what scenarios is it likely used for?
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;ayuda-con-la-creación-de-contenido&#34;&gt;Ayuda con la creación de contenido
&lt;/h3&gt;&lt;p&gt;También puede ayudar a escribir títulos, generar esquemas y organizar puntos de venta.&lt;/p&gt;
&lt;p&gt;Por ejemplo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Write 10 article titles about AI tool recommendations, with angles for practical tips, productivity tools, and office workflows.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Después de recibir un borrador, puedes continuar:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Make these titles more suitable for a tech blog.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Este estilo de seguimiento parece más natural que pedirle todo a un motor de búsqueda de una sola vez.&lt;/p&gt;
&lt;h2 id=&#34;consejos-de-uso&#34;&gt;Consejos de uso
&lt;/h2&gt;&lt;p&gt;Si solo necesita una búsqueda diaria de información, trátela como un punto de entrada más rápido a la Búsqueda de Google. Si trabaja a menudo con imágenes, archivos PDF, páginas web y capturas de pantalla, concéntrese en Lens, la carga de archivos y el uso compartido de pantalla.&lt;/p&gt;
&lt;p&gt;Tenga en cuenta tres puntos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;La página oficial dice que la aplicación actualmente solo está disponible en inglés. Las indicaciones en chino pueden comportarse de manera diferente según su cuenta y región.&lt;/li&gt;
&lt;li&gt;El modo AI no está disponible para todas las cuentas. Si no puede verlo, verifique la configuración de su cuenta, región e idioma.&lt;/li&gt;
&lt;li&gt;La búsqueda de archivos locales, la búsqueda en Google Drive y el uso compartido de pantalla implican permisos de privacidad. Confirme a qué contenido desea que acceda la aplicación antes de habilitarlos.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;resumen-rápido&#34;&gt;Resumen rápido
&lt;/h2&gt;&lt;p&gt;El principal valor de la aplicación de Google para escritorio es que saca la búsqueda del navegador y la convierte en un cuadro de búsqueda de IA al que puedes acceder en cualquier momento.&lt;/p&gt;
&lt;p&gt;En resumen, puede:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Abra la búsqueda rápidamente con &lt;code&gt;Alt + Espacio&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Utilice el modo AI para obtener respuestas organizadas.&lt;/li&gt;
&lt;li&gt;Subir imágenes o archivos para su análisis.&lt;/li&gt;
&lt;li&gt;Seleccionar contenido de la pantalla con Google Lens.&lt;/li&gt;
&lt;li&gt;Comprenda la ventana actual o la pantalla completa compartiendo pantalla.&lt;/li&gt;
&lt;li&gt;Busque archivos locales, aplicaciones y contenido de Google Drive.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si ya confías en la Búsqueda de Google y quieres que la experiencia se parezca más a pedirle a un asistente, vale la pena probar la aplicación de Google para escritorio.&lt;/p&gt;
&lt;h2 id=&#34;referencia&#34;&gt;Referencia
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Página oficial de la aplicación de Google para escritorio: &lt;a class=&#34;link&#34; href=&#34;https://search.google/google-app/desktop/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://search.google/google-app/desktop/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Compartir un Agent Skill para recortar y normalizar imágenes de producto de e-commerce</title>
        <link>https://knightli.com/es/2026/04/09/product-cutout-normalize-agent-skill-guide/</link>
        <pubDate>Thu, 09 Apr 2026 21:43:50 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/04/09/product-cutout-normalize-agent-skill-guide/</guid>
        <description>&lt;p&gt;&lt;code&gt;product-cutout-normalize&lt;/code&gt; es un Agent Skill para imágenes de producto.&lt;/p&gt;
&lt;p&gt;Procesa imágenes originales y las convierte en imágenes cuadradas con fondo transparente y especificaciones uniformes. Sus reglas predeterminadas son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lienzo &lt;code&gt;1024x1024&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Fondo transparente&lt;/li&gt;
&lt;li&gt;Conservar el sujeto lo más completo posible&lt;/li&gt;
&lt;li&gt;Convertir automáticamente sujetos verticales a orientación horizontal&lt;/li&gt;
&lt;li&gt;Centrar el sujeto&lt;/li&gt;
&lt;li&gt;Normalizar el ancho visible del sujeto a &lt;code&gt;820px&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Es adecuado para materiales de e-commerce, bibliotecas de producto y preprocesamiento de imágenes para páginas de detalle.&lt;/p&gt;
&lt;h2 id=&#34;qué-problema-resuelve-este-skill&#34;&gt;Qué problema resuelve este skill
&lt;/h2&gt;&lt;p&gt;Después de un recorte básico, muchas imágenes de producto todavía tienen estos problemas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Restos de borde blanco o fondo gris claro&lt;/li&gt;
&lt;li&gt;Orientación horizontal/vertical del sujeto inconsistente&lt;/li&gt;
&lt;li&gt;Tamaño de lienzo inconsistente&lt;/li&gt;
&lt;li&gt;Tamaño del sujeto muy variable&lt;/li&gt;
&lt;li&gt;Pequeños puntos de ruido en áreas transparentes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Este skill procesa con un flujo fijo:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Recorte con Gemini&lt;/li&gt;
&lt;li&gt;Limpieza de fondo claro en los bordes&lt;/li&gt;
&lt;li&gt;Eliminación de pequeños fragmentos de ruido&lt;/li&gt;
&lt;li&gt;Rotación de imágenes verticales a horizontales&lt;/li&gt;
&lt;li&gt;Escalado según ancho objetivo&lt;/li&gt;
&lt;li&gt;Colocación en el centro de un lienzo transparente uniforme&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Las imágenes exportadas quedan más ordenadas y son más adecuadas para uso por lotes.&lt;/p&gt;
&lt;h2 id=&#34;escenarios-adecuados&#34;&gt;Escenarios adecuados
&lt;/h2&gt;&lt;p&gt;Encaja con estas necesidades:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Procesar fotos de producto por lotes&lt;/li&gt;
&lt;li&gt;Exportar PNG con fondo transparente de forma uniforme&lt;/li&gt;
&lt;li&gt;Unificar el tamaño visual principal&lt;/li&gt;
&lt;li&gt;Necesitar un flujo estable y repetible&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si solo procesas pocas imágenes, o si cada imagen necesita ajustar manualmente la composición, quizá no sea la herramienta más adecuada.&lt;/p&gt;
&lt;h2 id=&#34;inicio-rápido&#34;&gt;Inicio rápido
&lt;/h2&gt;&lt;p&gt;La forma más directa de ejecución:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\.venv\Scripts\python.exe&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.codex\skills\product-cutout-normalize\scripts\run_pipeline.py&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;input_dir&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dir&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-overwrite&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Antes de ejecutar necesitas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GEMINI_API_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;google-genai&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Pillow&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Instalar dependencias:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;.\.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;venv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Scripts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;python&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;exe&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-m&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;google-genai&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pillow&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Configurar variable de entorno:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env:GEMINI_API_KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your_api_key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;reglas-de-salida&#34;&gt;Reglas de salida
&lt;/h2&gt;&lt;p&gt;Salida predeterminada:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PNG&lt;/code&gt; con fondo transparente&lt;/li&gt;
&lt;li&gt;Lienzo &lt;code&gt;1024x1024&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Ancho del sujeto &lt;code&gt;820px&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Sujeto centrado&lt;/li&gt;
&lt;li&gt;Se limpian pequeños puntos de ruido&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Así que no es solo un script de quitar fondo, sino más bien un script de organización de imágenes de producto.&lt;/p&gt;
&lt;h2 id=&#34;parámetros-principales&#34;&gt;Parámetros principales
&lt;/h2&gt;&lt;p&gt;Parámetros habituales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--model&lt;/code&gt;
Predeterminado: &lt;code&gt;gemini-2.5-flash-image&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--canvas-size&lt;/code&gt;
Tamaño del lienzo cuadrado de salida, predeterminado &lt;code&gt;1024&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--target-width&lt;/code&gt;
Ancho visible del sujeto, predeterminado &lt;code&gt;820&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--min-component-pixels&lt;/code&gt;
Fragmentos transparentes con menos píxeles que este valor se eliminan, predeterminado &lt;code&gt;500&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--overwrite&lt;/code&gt;
Sobrescribe directamente si el archivo de salida ya existe&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por ejemplo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\.venv\Scripts\python.exe&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.codex\skills\product-cutout-normalize\scripts\run_pipeline.py&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\input&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\output&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-canvas-size&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1280&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-target-width&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;960&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-overwrite&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;flujo-de-procesamiento&#34;&gt;Flujo de procesamiento
&lt;/h2&gt;&lt;p&gt;El flujo es simple:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Recorte con Gemini&lt;/li&gt;
&lt;li&gt;Limpieza de fondo claro en los bordes&lt;/li&gt;
&lt;li&gt;Eliminación de pequeños fragmentos de ruido&lt;/li&gt;
&lt;li&gt;Rotación de imágenes verticales a horizontales&lt;/li&gt;
&lt;li&gt;Escalado según ancho objetivo&lt;/li&gt;
&lt;li&gt;Colocación en el centro de un lienzo transparente uniforme&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;diferencia-frente-a-scripts-comunes-de-recorte&#34;&gt;Diferencia frente a scripts comunes de recorte
&lt;/h2&gt;&lt;p&gt;Comparado con un script común de eliminación de fondo, también trata:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Orientación uniforme del sujeto&lt;/li&gt;
&lt;li&gt;Tamaño uniforme del sujeto&lt;/li&gt;
&lt;li&gt;Tamaño uniforme del lienzo&lt;/li&gt;
&lt;li&gt;Limpieza de pequeños fragmentos de ruido&lt;/li&gt;
&lt;li&gt;Resultados más adecuados para colocarse directamente en una biblioteca de materiales&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;código-fuente-de-skillmd&#34;&gt;Código fuente de SKILL.md
&lt;/h2&gt;&lt;p&gt;Abajo se conserva el código fuente completo de &lt;code&gt;SKILL.md&lt;/code&gt;, sin cambios:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;name: product-cutout-normalize
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;description: Run a reusable Gemini product-image pipeline that removes backgrounds, preserves the full subject, rotates tall products to a horizontal orientation, centers them on a 1024x1024 transparent canvas, and normalizes the visible subject width to 820px. Use when the user wants a repeatable cutout-and-normalize workflow for product photos or asks to batch-process product images into standardized square PNG assets.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gh&#34;&gt;# Product Cutout Normalize
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Use this skill when product photos need the same deterministic finishing pipeline:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; Gemini cutout from the original photo
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; border cleanup to transparent
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; preserve the full subject
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; rotate to horizontal when the subject is taller than it is wide
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; center on a &lt;span class=&#34;sb&#34;&gt;`1024x1024`&lt;/span&gt; transparent canvas
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; normalize the visible subject width to &lt;span class=&#34;sb&#34;&gt;`820px`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Quick Start
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Run the bundled script:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;```powershell
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.\.venv\Scripts\python.exe&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.codex\skills\product-cutout-normalize\scripts\run_pipeline.py&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;input_dir&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dir&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-overwrite&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;```&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Required environment:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`GEMINI_API_KEY`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`google-genai`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`Pillow`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Workflow
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;1.&lt;/span&gt; Confirm the request matches this standard pipeline. If the user asks for a different canvas size, subject width, or layout rule, pass explicit flags instead of changing the script.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;2.&lt;/span&gt; Run the bundled script on the input directory.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;3.&lt;/span&gt; If a result looks misaligned, inspect the alpha bounding box and small detached artifacts first; this pipeline already removes tiny alpha components by default.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;4.&lt;/span&gt; Report the exact input and output directories used, plus any non-default flags.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Script
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Primary entry point:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`scripts/run_pipeline.py`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Key flags:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--model`&lt;/span&gt;: Gemini image model, default &lt;span class=&#34;sb&#34;&gt;`gemini-2.5-flash-image`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--canvas-size`&lt;/span&gt;: output square size, default &lt;span class=&#34;sb&#34;&gt;`1024`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--target-width`&lt;/span&gt;: visible subject width after normalization, default &lt;span class=&#34;sb&#34;&gt;`820`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--min-component-pixels`&lt;/span&gt;: remove detached alpha specks smaller than this, default &lt;span class=&#34;sb&#34;&gt;`500`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`--overwrite`&lt;/span&gt;: replace existing outputs in the destination directory
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;gu&#34;&gt;## Repo Integration
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;If the current project already has [&lt;span class=&#34;nt&#34;&gt;`scripts/nano_banana_cutout.py`&lt;/span&gt;](&lt;span class=&#34;na&#34;&gt;/c:/Work/my_shop/scripts/nano_banana_cutout.py&lt;/span&gt;), prefer that repo script when the user wants the same pipeline inside this repository. Use the bundled skill script when the task is cross-project reuse or when you want the workflow to stay self-contained inside the skill.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;código-fuente-de-scriptsrun_pipelinepy&#34;&gt;Código fuente de scripts/run_pipeline.py
&lt;/h2&gt;&lt;p&gt;Abajo se conserva el código fuente completo de &lt;code&gt;scripts/run_pipeline.py&lt;/code&gt;, sin cambios:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;  1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 71
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 72
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 73
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 74
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 75
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 76
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 77
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 78
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 79
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 80
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 81
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 82
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 83
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 84
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 85
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 86
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 87
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 88
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 89
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 90
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 91
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 92
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 93
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 94
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 95
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 96
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 97
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 98
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 99
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;100
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;101
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;102
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;103
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;104
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;105
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;106
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;107
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;108
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;109
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;110
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;111
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;112
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;113
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;114
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;115
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;116
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;117
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;118
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;119
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;120
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;121
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;122
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;123
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;124
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;125
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;126
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;127
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;128
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;129
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;130
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;131
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;132
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;133
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;134
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;135
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;136
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;137
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;138
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;139
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;140
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;141
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;142
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;143
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;144
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;145
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;146
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;147
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;148
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;149
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;150
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;151
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;152
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;153
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;154
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;155
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;156
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;157
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;158
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;159
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;160
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;161
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;162
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;163
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;164
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;165
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;166
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;167
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;168
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;169
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;170
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;171
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;172
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;173
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;174
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;175
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;176
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;177
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;178
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;179
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;180
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;181
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;182
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;183
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;184
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;185
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;186
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;187
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;188
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;189
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;190
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;191
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;192
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;193
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;194
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;195
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;196
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;197
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;198
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;199
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;200
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;201
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;202
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;203
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;204
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;205
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;206
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;207
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;208
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;209
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;210
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;211
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;212
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;213
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;214
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;215
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;216
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;217
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;218
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;219
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;220
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;221
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;222
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;223
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;224
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;225
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;226
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;227
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;228
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;229
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;230
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;231
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;232
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;233
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;234
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;235
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;236
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;237
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;238
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;239
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;240
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;241
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;242
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;243
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;244
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;245
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;246
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;247
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;248
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;249
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;250
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;251
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;252
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;253
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;254
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;255
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;256
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;257
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;258
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;259
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;260
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;261
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;262
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;263
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;264
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;265
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;266
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;267
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;268
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;269
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;270
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;271
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;272
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;273
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;274
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;275
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;276
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;277
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;278
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;279
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;280
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;281
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;282
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;283
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;284
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;285
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;286
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;287
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;288
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;289
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;290
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;291
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;__future__&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;annotations&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;argparse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;collections&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;PIL&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ImportError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# pragma: no cover&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;Missing dependency: google-genai. Install it with &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#39;.\.venv\Scripts\python.exe -m pip install google-genai&amp;#39;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;exc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;Remove the entire background from this product photo and return only the product &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;on a fully transparent background as a PNG. Keep the full product intact, preserve &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;thin cable details, clean the inner loops and holes, and do not add any new objects &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;or shadows.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_CANVAS_SIZE&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1024&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_TARGET_WIDTH&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;820&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_MIN_COMPONENT_PIXELS&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;SUPPORTED_EXTENSIONS&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.jpg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.jpeg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.webp&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;170&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;35&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;to_pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;_pil_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;pil_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;TypeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Unsupported image object type: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;!r}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;popleft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;remove_small_components&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;alpha&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getchannel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;A&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;alpha_pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;alpha&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba_pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;alpha_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;component&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;popleft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;component&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cy&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;alpha_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;len&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;component&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;py&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;component&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;py&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;rgba_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;px&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;py&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;normalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;bbox&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getchannel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;A&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getbbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;bbox&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;90&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;expand&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;resample&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Resampling&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BICUBIC&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;rotated_bbox&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getchannel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;A&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;getbbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rotated_bbox&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;crop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rotated_bbox&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;scale&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;resize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;round&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;scale&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Resampling&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LANCZOS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;offset_x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;//&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;offset_y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;//&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;alpha_composite&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subject&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;offset_x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;offset_y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;canvas&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;finalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;transparent&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cleaned&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;remove_small_components&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;transparent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;normalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cleaned&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;save_first_image_part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;parts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;candidates&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;candidates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;RuntimeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Model returned no content parts.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;part&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;inline_data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;inline_data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;hasattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;as_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to_pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;as_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;finalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;wb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;handle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;handle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;processed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;finalize_product_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;processed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;with_suffix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unlink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;missing_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;RuntimeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Model returned text only and no edited image.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;process_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;save_first_image_part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Namespace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Cut out product images with Gemini and normalize them to square transparent PNGs.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;input_dir&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dir&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--model&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-2.5-flash-image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--canvas-size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_CANVAS_SIZE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--target-width&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_TARGET_WIDTH&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--min-component-pixels&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DEFAULT_MIN_COMPONENT_PIXELS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--overwrite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;action&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;store_true&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GEMINI_API_KEY&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Missing GEMINI_API_KEY environment variable.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_dir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Input directory does not exist: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_dir&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--canvas-size must be positive.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--target-width must be positive and no larger than --canvas-size.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--min-component-pixels must be &amp;gt;= 0.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iterdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SUPPORTED_EXTENSIONS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stem&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exists&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;overwrite&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;skip &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;process_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;canvas_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target_width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;min_component_pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Descargar adjunto:
&lt;a class=&#34;link&#34; href=&#34;product-cutout-normalize.7z&#34; &gt;product-cutout-normalize.7z&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Cómo llamar a Google Nano Banana para recortar fondos de imágenes</title>
        <link>https://knightli.com/es/2026/04/09/google-nano-banana-cutout-guide/</link>
        <pubDate>Thu, 09 Apr 2026 20:10:48 +0800</pubDate>
        
        <guid>https://knightli.com/es/2026/04/09/google-nano-banana-cutout-guide/</guid>
        <description>&lt;p&gt;Este artículo usa un script Python realmente ejecutable para demostrar cómo llamar a la capacidad de edición de imágenes &lt;code&gt;Nano Banana&lt;/code&gt; de Google y recortar fondos de imágenes de producto.&lt;/p&gt;
&lt;p&gt;El objetivo de esta implementación es muy claro:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Leer imágenes de producto desde un directorio&lt;/li&gt;
&lt;li&gt;Llamar al modelo de imagen de Google para eliminar el fondo&lt;/li&gt;
&lt;li&gt;Hacer una limpieza local adicional del fondo transparente sobre la imagen devuelta&lt;/li&gt;
&lt;li&gt;Exportar finalmente como &lt;code&gt;PNG&lt;/code&gt; con fondo transparente&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si ya tienes un lote de imágenes de producto con fondo blanco, fotos de auriculares o cables, y quieres generar rápidamente imágenes de fondo transparente aptas para e-commerce, esta forma es bastante directa.&lt;/p&gt;
&lt;h2 id=&#34;qué-hace-este-código&#34;&gt;Qué hace este código
&lt;/h2&gt;&lt;p&gt;Este script se divide principalmente en 4 partes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Definir el prompt para que el modelo sepa que debe &amp;ldquo;quitar fondo, conservar sujeto, no añadir sombras&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Llamar a la interfaz de generación de imágenes de &lt;code&gt;google-genai&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Extraer el resultado de imagen desde la respuesta del modelo&lt;/li&gt;
&lt;li&gt;Usar lógica local para convertir fondos claros de los bordes en transparencia, reduciendo restos de borde&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Es decir, no se limita a enviar una imagen al modelo y terminar, sino que encadena &amp;ldquo;edición con modelo + posprocesamiento local&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;preparación-antes-de-ejecutar&#34;&gt;Preparación antes de ejecutar
&lt;/h2&gt;&lt;p&gt;Primero instala dependencias:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;venv&lt;span class=&#34;se&#34;&gt;\S&lt;/span&gt;cripts&lt;span class=&#34;se&#34;&gt;\p&lt;/span&gt;ython.exe -m pip install google-genai pillow
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;cómo-obtener-gemini_api_key&#34;&gt;Cómo obtener GEMINI_API_KEY
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;GEMINI_API_KEY&lt;/code&gt; es la clave usada para llamar a Gemini API. Según el quickstart oficial de Google, si todavía no tienes una key, puedes crearla directamente en Google AI Studio.&lt;/p&gt;
&lt;p&gt;Pasos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Abre Google AI Studio.&lt;/li&gt;
&lt;li&gt;Inicia sesión con tu cuenta de Google.&lt;/li&gt;
&lt;li&gt;Busca la página &lt;code&gt;Get API key&lt;/code&gt; o &lt;code&gt;API keys&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Crea una nueva API key.&lt;/li&gt;
&lt;li&gt;Copia la key generada.&lt;/li&gt;
&lt;li&gt;Configúrala como variable de entorno local para que el script pueda leerla.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Si la página todavía no tiene un proyecto disponible, normalmente hay que completar primero la inicialización del proyecto y después volver a la página de API Key para crear la clave.&lt;/p&gt;
&lt;p&gt;Después de obtener la key, configura la variable de entorno:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env&lt;/span&gt;:GEMINI_API_KEY&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;your_api_key&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Si usas &lt;code&gt;cmd&lt;/code&gt;, puedes escribir:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;your_api_key
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Si configuras a la vez &lt;code&gt;GEMINI_API_KEY&lt;/code&gt; y &lt;code&gt;GOOGLE_API_KEY&lt;/code&gt;, en ejecución normalmente se leerá primero &lt;code&gt;GOOGLE_API_KEY&lt;/code&gt;, así que se recomienda conservar solo una para evitar confusión.&lt;/p&gt;
&lt;h2 id=&#34;ejemplo-de-estructura-de-directorios&#34;&gt;Ejemplo de estructura de directorios
&lt;/h2&gt;&lt;p&gt;El script recibe dos parámetros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;input_dir&lt;/code&gt;: directorio de imágenes de entrada&lt;/li&gt;
&lt;li&gt;&lt;code&gt;output_dir&lt;/code&gt;: directorio de imágenes de salida&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por ejemplo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;images/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  product1.jpg
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  product2.png
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;output/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;cómo-ejecutarlo&#34;&gt;Cómo ejecutarlo
&lt;/h2&gt;&lt;p&gt;Suponiendo que el script se llame &lt;code&gt;cutout.py&lt;/code&gt;, se ejecuta así:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;venv&lt;span class=&#34;se&#34;&gt;\S&lt;/span&gt;cripts&lt;span class=&#34;se&#34;&gt;\p&lt;/span&gt;ython.exe .&lt;span class=&#34;se&#34;&gt;\c&lt;/span&gt;utout.py .&lt;span class=&#34;se&#34;&gt;\i&lt;/span&gt;mages .&lt;span class=&#34;se&#34;&gt;\o&lt;/span&gt;utput
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Si quieres cambiar de modelo, también puedes pasar el parámetro explícitamente:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;.&lt;span class=&#34;se&#34;&gt;\.&lt;/span&gt;venv&lt;span class=&#34;se&#34;&gt;\S&lt;/span&gt;cripts&lt;span class=&#34;se&#34;&gt;\p&lt;/span&gt;ython.exe .&lt;span class=&#34;se&#34;&gt;\c&lt;/span&gt;utout.py .&lt;span class=&#34;se&#34;&gt;\i&lt;/span&gt;mages .&lt;span class=&#34;se&#34;&gt;\o&lt;/span&gt;utput --model gemini-2.5-flash-image
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;El script recorrerá estos formatos dentro del directorio de entrada:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.jpg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.jpeg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.png&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.webp&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Al terminar, generará archivos &lt;code&gt;PNG&lt;/code&gt; con fondo transparente y el mismo nombre en el directorio de salida.&lt;/p&gt;
&lt;h2 id=&#34;flujo-principal-de-llamada&#34;&gt;Flujo principal de llamada
&lt;/h2&gt;&lt;p&gt;La llamada clave a Google Nano Banana está aquí:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Aquí se pasan dos contenidos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un prompt de texto &lt;code&gt;PROMPT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Una imagen &lt;code&gt;PIL.Image&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El prompt le pide al modelo eliminar el fondo completo de la imagen de producto, conservar solo el sujeto y enfatiza varios puntos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Conservar el producto completo&lt;/li&gt;
&lt;li&gt;Conservar detalles de cables y líneas finas&lt;/li&gt;
&lt;li&gt;Limpiar huecos internos y zonas anulares&lt;/li&gt;
&lt;li&gt;No añadir objetos nuevos&lt;/li&gt;
&lt;li&gt;No añadir sombras&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Este tipo de prompt influye mucho en la calidad del recorte, especialmente en detalles como cables de auriculares, bordes transparentes y zonas huecas.&lt;/p&gt;
&lt;h2 id=&#34;por-qué-hacer-otro-posprocesamiento-local&#34;&gt;Por qué hacer otro posprocesamiento local
&lt;/h2&gt;&lt;p&gt;Después de que el modelo devuelve el resultado, el script no lo guarda directamente, sino que ejecuta &lt;code&gt;make_transparent_from_borders(image)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;La idea de este paso es:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Buscar píxeles de fondo claros desde los bordes de la imagen&lt;/li&gt;
&lt;li&gt;Usar búsqueda en anchura para marcar todas las zonas claras conectadas&lt;/li&gt;
&lt;li&gt;Convertir finalmente esas zonas en transparentes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La ventaja es que puede limpiar mejor algunos bordes blancos residuales, fondos gris claro y zonas de borde poco limpias.&lt;/p&gt;
&lt;p&gt;La condición para decidir &amp;ldquo;si es fondo&amp;rdquo; está aquí:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;170&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;35&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;En términos simples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El color debe ser suficientemente claro&lt;/li&gt;
&lt;li&gt;La diferencia entre los tres canales RGB no debe ser grande&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto encaja bien con fondos blancos, gris claro o casi de color sólido en imágenes de producto.&lt;/p&gt;
&lt;h2 id=&#34;código-fuente-completo&#34;&gt;Código fuente completo
&lt;/h2&gt;&lt;p&gt;Abajo se conserva el código fuente completo actual, para que puedas reutilizarlo o modificarlo directamente:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;  1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 71
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 72
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 73
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 74
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 75
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 76
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 77
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 78
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 79
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 80
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 81
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 82
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 83
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 84
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 85
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 86
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 87
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 88
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 89
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 90
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 91
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 92
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 93
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 94
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 95
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 96
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 97
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 98
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 99
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;100
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;101
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;102
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;103
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;104
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;105
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;106
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;107
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;108
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;109
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;110
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;111
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;112
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;113
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;114
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;115
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;116
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;117
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;118
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;119
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;120
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;121
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;122
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;123
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;124
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;125
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;126
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;127
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;128
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;129
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;130
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;131
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;132
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;133
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;134
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;135
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;136
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;137
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;138
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;139
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;140
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;141
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;142
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;143
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;144
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;145
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;146
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;147
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;148
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;149
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;150
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;__future__&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;annotations&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;argparse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;pathlib&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;collections&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;PIL&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;google&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;ImportError&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exc&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# pragma: no cover&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s2&#34;&gt;&amp;#34;Missing dependency: google-genai. Install it with &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#39;.\.venv\Scripts\python.exe -m pip install google-genai&amp;#39;.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;exc&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;Remove the entire background from this product photo and return only the product &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;on a fully transparent background as a PNG. Keep the full product intact, preserve &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;thin cable details, clean the inner loops and holes, and do not add any new objects &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;or shadows.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;brightness&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;170&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;spread&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;35&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;to_pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;_pil_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pil_image&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;pil_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;as_pil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;TypeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Unsupported image object type: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image_obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;!r}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;tuple&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;deque&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;is_light_background_pixel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;g&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;b&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;queue&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;popleft&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;width&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;height&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;push_if_bg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;nx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ny&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;visited&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;pixels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;x&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;y&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rgba&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;save_first_image_part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;parts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;candidates&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;candidates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;RuntimeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Model returned no content parts.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;part&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;inline_data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;isinstance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;dict&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;inline_data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;is&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;hasattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;as_image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to_pil_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;part&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;as_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;data&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;mime_type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;getattr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inline_data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;mime_type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mkdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exist_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;wb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;handle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;handle&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;processed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;make_transparent_from_borders&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;processed&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;save&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;with_suffix&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unlink&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;missing_ok&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;True&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;RuntimeError&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Model returned text only and no edited image.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;process_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;convert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;RGBA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;response&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;models&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PROMPT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;save_first_image_part&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Use Nano Banana / Gemini image editing to cut out product images.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;input_dir&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;output_dir&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;--model&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gemini-2.5-flash-image&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;environ&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GEMINI_API_KEY&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;raise&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;SystemExit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Missing GEMINI_API_KEY environment variable.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;genai&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;api_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;exts&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;.jpg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.jpeg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;.webp&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;sorted&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;input_dir&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;iterdir&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;or&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;suffix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;lower&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output_dir&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stem&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;process_image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;model&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dst&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;qué-conviene-optimizar-después&#34;&gt;Qué conviene optimizar después
&lt;/h2&gt;&lt;p&gt;Si quieres seguir usando este script para producción por lotes, después puedes añadir:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reintentos ante fallos, para evitar que una sola imagen rompa todo el lote&lt;/li&gt;
&lt;li&gt;Registro de logs, para localizar qué imagen falló&lt;/li&gt;
&lt;li&gt;Umbrales configurables para distintos fondos&lt;/li&gt;
&lt;li&gt;Escaneo recursivo de subdirectorios&lt;/li&gt;
&lt;li&gt;Vista previa comparativa entre imagen original y resultado&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;resumen&#34;&gt;Resumen
&lt;/h2&gt;&lt;p&gt;Si solo quieres entender rápido &amp;ldquo;cómo llamar a Google Nano Banana para recortar fondos&amp;rdquo;, el núcleo son tres pasos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Instalar &lt;code&gt;google-genai&lt;/code&gt; y &lt;code&gt;Pillow&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Configurar &lt;code&gt;GEMINI_API_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Usar &lt;code&gt;client.models.generate_content()&lt;/code&gt; pasando prompt e imagen&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;El valor de este código está en que no solo llama al modelo, sino que añade posprocesamiento de fondo transparente, por lo que sirve mejor para tareas reales de recorte de imágenes de producto.&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
