Blog
AI/Voice
22 febbraio 20269 min

Generazione di immagini IA in un'app di produttività

Permettere agli utenti di generare immagini per le loro attività, direttamente dall'app, tramite la voce. "Crea un'immagine per la mia attività" e voilà, appare un'illustrazione pertinente. Dietro questa semplicità si nasconde una pipeline tecnica con due fornitori di immagini AI, un sistema di prompt engineering automatizzato, quattro stili visivi, un fallback automatico e una gestione dei costi per piano di abbonamento.

La generazione di immagini AI in un'app di produttività non è un gadget. È una risposta a un'osservazione: le attività con un'immagine sono più memorabili, più coinvolgenti e più facili da trovare in un feed. E se l'utente può ottenere questa immagine con una frase, senza lasciare il suo flusso di lavoro vocale, l'adozione è naturale.

Punti chiave
  • Due fornitori di immagini AI integrati: Gemini 2.5 Flash Image per la qualità e Runware HiDream-I1-Fast per l'economia (~0,003 euro/immagine).
  • Il LLM conversazionale genera automaticamente un prompt ottimizzato analizzando il titolo, la descrizione e i tag dell'attività.
  • Quattro stili predefiniti (flat, minimalista, realistico, acquerello) modificano il prompt inviato al modello.
  • Fallback automatico da Gemini a Runware con retry e backoff esponenziale, gestito dall'amministratore dalla dashboard.
Schermo diviso che mostra due immagini generate dall'IA affiancate con stili visivi diversi, fotorealistico e acquerello, che fluttuano sopra uno smartphone

Perché integrare due fornitori di immagini AI?

Un solo fornitore è un single point of failure. Se l'API cade, se le quote vengono superate, se la qualità si degrada: l'utente non ha più immagini. Due fornitori significano resilienza e flessibilità.

Gemini 2.5 Flash Image (tramite OpenRouter) è il fornitore predefinito. La qualità è eccellente, la velocità è buona (2-4 secondi per immagine). È il miglior rapporto qualità/velocità che ho testato. Il modello comprende bene i prompt complessi con più soggetti, stili artistici specifici e composizioni dettagliate.

Runware HiDream-I1-Fast è l'alternativa economica. A circa 0,003 euro per immagine, è 5-10 volte più economico di Gemini a seconda del prompt. La qualità è leggermente inferiore sui prompt complessi, ma perfettamente sufficiente per le illustrazioni delle attività. E la velocità è paragonabile.

L'amministratore passa da uno all'altro dalla dashboard di amministrazione. È un toggle nella tabella app_config di Supabase. Perché un toggle admin e non una scelta dell'utente? Perché il costo è a carico del servizio, non dell'utente. Spetta a me decidere quale fornitore ottimizza il rapporto qualità/costo in base al volume di utilizzo.

Come il LLM genera il prompt perfetto?

Chiedere a un utente di scrivere un buon prompt per un'immagine è irrealistico. I modelli di generazione di immagini sono sensibili alla formulazione. "Un gatto" dà un risultato generico. "Un gatto domestico a pelo corto seduto su un davanzale, luce del tramonto, profondità di campo ridotta, fotorealistico, toni caldi" dà un'immagine professionale.

La differenza tra i due? Prompt engineering. Ed è esattamente il compito del LLM conversazionale di TAMSIV.

Quando l'utente richiede un'immagine, il LLM analizza tre fonti di contesto:

  1. Il titolo dell'attività: "Preparare la presentazione cliente Q2" → il LLM capisce che è necessaria un'immagine professionale.
  2. La descrizione: "Includere i dati di vendita e il grafico di crescita" → il LLM aggiunge elementi di visualizzazione dati al prompt.
  3. I tag/cartella: se l'attività è nella cartella "Marketing", il LLM orienta lo stile verso il branding.

Il prompt è sempre generato in inglese, anche se l'utente parla in italiano. Perché? Perché i modelli di immagini sono addestrati principalmente su dati in lingua inglese. Un prompt in inglese dà sistematicamente risultati migliori. È la stessa osservazione che avevo fatto per il sistema i18n in 6 lingue: la lingua di lavoro interna non è necessariamente la lingua dell'utente.

Il LLM aggiunge anche modificatori tecnici automaticamente: risoluzione, illuminazione, composizione. Questi modificatori sono calibrati per il fornitore attivo. Gemini e Runware non interpretano i prompt allo stesso modo, quindi il LLM adatta la sua formulazione. Secondo le buone pratiche di OpenAI sul prompting di immagini, i modificatori di stile e composizione sono i fattori che influenzano maggiormente la qualità del risultato.

Quali sono i quattro stili visivi disponibili?

Diagramma di flusso che mostra la pipeline di generazione di immagini AI: input vocale al trattamento LLM al fornitore di immagini allo storage cloud, nodi luminosi interconnessi

Ogni stile modifica il prompt inviato al modello aggiungendo suffissi e modificatori specifici:

Stile Flat (illustrazioni vettoriali)

Aggiunge: "flat vector illustration, clean lines, solid colors, minimal shading, modern graphic design style". Ideale per attività professionali e presentazioni. Il rendering è pulito e stampabile.

Stile Minimalista

Aggiunge: "minimalist, simple composition, lots of white space, single focal point, clean aesthetic". Perfetto per le attività personali. Il rendering è pulito e rilassante.

Stile Realistico

Aggiunge: "photorealistic, high detail, natural lighting, shallow depth of field, 4K quality". Il rendering più vicino a una foto. Ideale quando vuoi un'immagine concreta di ciò che immagini.

Stile Acquerello

Aggiunge: "watercolor painting, soft edges, flowing colors, artistic, hand-painted look". Il rendering più creativo. Ideale per progetti artistici o attività creative.

La scelta dello stile è opzionale. Se l'utente non specifica, il LLM sceglie lo stile più adatto al contesto dell'attività. Un'attività "Preparare la spesa" sarà in stile minimalista. Un'attività "Progettare il logo del nuovo prodotto" sarà in stile flat. È una decisione contestuale, non casuale. La stessa filosofia della personalizzazione vocale: l'IA si adatta senza che le venga chiesto.

Come funziona la pipeline tecnica end-to-end?

La pipeline completa, dalla richiesta dell'utente alla visualizzazione dell'immagine, si articola in 6 fasi con potenziali punti di fallimento ad ogni transizione:

  1. Richiesta utente → trascrizione STT → testo inviato al backend tramite WebSocket.
  2. Analisi LLM → il LLM conversazionale rileva l'intenzione di generare un'immagine e chiama il function tool create_task con un flag generate_image: true.
  3. Prompt engineering → il backend passa il contesto dell'attività al LLM che genera un prompt ottimizzato.
  4. Chiamata fornitore → il backend invia il prompt al fornitore configurato (Gemini o Runware).
  5. Upload Storage → l'immagine ricevuta (base64 o URL) viene caricata su Supabase Storage nel bucket dedicato. Viene creato un record in privat.task_attachments con type: 'ai_generated', storage_path e i metadati.
  6. Visualizzazione → il frontend riceve la conferma tramite WebSocket, genera un URL firmato e visualizza l'immagine nella scheda dell'attività.

Ogni fase può fallire. Lo STT può trascrivere male. Il LLM può non rilevare l'intenzione. Il fornitore può andare in timeout. L'upload può fallire. La strategia: retry con backoff esponenziale ad ogni fase, e fallback automatico tra i fornitori se il fornitore principale fallisce 3 volte consecutive.

Il fallback da Gemini a Runware (o viceversa) è automatico e trasparente per l'utente. Non vede che il fornitore è cambiato. Vede solo la sua immagine apparire, forse con 2 secondi in più. È la stessa filosofia di resilienza del sistema STT nativo vs Deepgram: avere sempre un piano B.

Come vengono controllati i costi per piano di abbonamento?

Dashboard di amministrazione che mostra grafici di analisi dei costi per la generazione di immagini AI, tema scuro con colori blu e verdi

La generazione di immagini AI ha un costo diretto per immagine. Anche a 0,003 euro per immagine con Runware, se 10.000 utenti generano 3 immagini al giorno, sono 900 euro al mese. Servono dei guardrail.

Il sistema di limiti per piano utilizza RevenueCat e i piani di abbonamento:

  • Piano Free: nessun accesso alla generazione di immagini. È una funzionalità premium che giustifica l'upgrade.
  • Piano Pro: quota giornaliera di N immagini al giorno (configurabile lato admin).
  • Piano Team: quota giornaliera più elevata, condivisa tra i membri del gruppo.

Il contatore è gestito lato backend, non lato frontend (per evitare frodi). Ogni generazione incrementa un contatore nel DB con un reset giornaliero tramite un cron job. Se la quota viene raggiunta, il backend restituisce un errore esplicito e il frontend visualizza un messaggio chiaro: "Quota immagini raggiunta per oggi. Riprova domani o passa al piano Team."

La dashboard admin mostra le statistiche di consumo in tempo reale: numero di immagini generate al giorno, costo medio per immagine, rapporto Gemini/Runware, tasso di fallimento per fornitore. Queste metriche sono cruciali per regolare le quote e scegliere il fornitore ottimale. Avevo già implementato questo tipo di monitoraggio nella dashboard admin analytics.

Perché gli utenti adorano questa funzionalità?

Il feedback più frequente dei tester: "Non ho l'impressione di usare l'IA, è semplicemente naturale." Questo è il miglior complimento possibile. L'IA è invisibile. L'utente dice "crea un'attività per il barbecue di sabato con un'immagine" e ottiene un'attività con un'illustrazione di barbecue. Nessuna selezione di modello. Nessuna regolazione dei parametri. Nessun prompt da scrivere.

Un'attività con un'immagine è immediatamente più coinvolgente di un'attività solo testuale. Nel feed con gamification, le attività illustrate attirano l'attenzione. È un principio di design ben documentato: i contenuti con immagini generano, secondo Social Media Examiner, 2 o 3 volte più engagement rispetto ai contenuti solo testuali.

Ed è anche un fattore di differenziazione. Nessuna app di gestione delle attività offre la generazione di immagini AI integrata nel flusso vocale. Questo è un vantaggio competitivo concreto rispetto ad alternative come Todoist o TickTick, che avevo confrontato nell'articolo comparativo.

Qual è il futuro della generazione di immagini in TAMSIV?

Il sistema attuale è una base solida. Ma sono previste diverse evoluzioni. L'estensione ai memo, innanzitutto: la tabella privat.memo_attachments esiste già con la stessa struttura di privat.task_attachments, come dettagliato nell'articolo sugli allegati.

L'editing di immagini poi: poter dire "cambia lo sfondo in blu" o "aggiungi testo" su un'immagine esistente. Le API di Gemini e Runware supportano già l'image-to-image. E la generazione collaborativa: in un gruppo, un membro genera un'immagine e gli altri la vedono in tempo reale tramite il canale Realtime.

L'obiettivo rimane lo stesso: rendere l'IA invisibile. Più la tecnologia è potente, più deve essere semplice da usare.

Domande frequenti

Quali formati di immagine vengono generati?

Le immagini sono generate in JPEG con una qualità del 95%. La risoluzione standard è di 1024x1024 pixel. Le immagini sono ottimizzate per la visualizzazione mobile ma rimangono di qualità sufficiente per l'uso desktop tramite la dashboard web.

È possibile rigenerare un'immagine se il risultato non è soddisfacente?

Sì. L'utente può richiedere una nuova generazione in qualsiasi momento. L'immagine precedente viene conservata nello storage e la nuova la sostituisce nella visualizzazione. La quota giornaliera viene decrementata ad ogni generazione.

L'immagine generata è archiviata in modo permanente?

Sì. L'immagine viene caricata in Supabase Storage e collegata all'attività tramite privat.task_attachments. Rimane disponibile finché l'attività esiste. La cancellazione dell'attività comporta la cancellazione a cascata dell'immagine.

Il prompt generato dal LLM è visibile all'utente?

No, per impostazione predefinita. Il prompt è tecnico e in inglese, il che non sarebbe utile per la maggior parte degli utenti. Tuttavia, il prompt viene registrato lato backend per il debugging e il miglioramento continuo del sistema.

La generazione di immagini funziona offline?

No. La generazione richiede una chiamata API al fornitore di immagini (Gemini o Runware) e un caricamento su Supabase Storage. È indispensabile una connessione internet. L'app visualizza un messaggio di errore chiaro se la connessione è assente.