Qualche tempo fa ho scritto di aver costruito un selezionatore AI per PhotoPrism, un piccolo strumento che usa modelli locali per scegliere le foto migliori e creare album automatici. Il post originale raccontava il primo prototipo: ranking estetico puro, clustering semantico, e una CLI minimale.
Da allora ho lavorato molto sul progetto, aggiungendo funzionalità, migliorando la stabilità e rendendo tutto più facile da usare.
Da Ollama a Ollama e LM Studio
Una delle richiesta più comuni che ho visto in giro per progetti simili è la possibilità di usare backend diversi. Nel primo post parlavo solo di Ollama come backend AI. Ora lo strumento supporta anche LM Studio, con API OpenAI-compatibili.
Che significa, in pratica? Se desideri avere più controllo e scelta di modelli, puoi usare LM Studio senza cambiare nulla nel flusso di lavoro. Nell’interfaccia web e nella CLI il passaggio è trasparente: basta cambiare il backend nei parametri e puntare all’URL del server corretto.
Deduplicazione tempo e spazio, non solo semantica
Nel post originale parlavo di clustering semantico: le foto venivano raggruppate per similarità di descrizione e poi selezionate a rotazione per evitare ripetizioni. Funzionava, ma a volte finivo comunque con foto troppo simili, scattate nello stesso istante e nella stessa posizione.
Ho aggiunto un secondo livello di deduplicazione temporale e geografica. Dopo la selezione iniziale, lo strumento rimuove automaticamente le foto che sono entro 30 secondi e 100 metri l’una dall’altra, tenendo sempre quella con il ranking estetico migliore.
Il risultato è un album più vario, con meno “serie di foto quasi identiche” e più momenti distinti.
Logging professionale con Logback
Il primo prototipo scriveva log in modo un po’ artigianale, spesso su stdout o in file senza gestione. Per un tool che può girare automaticamente su grandi archivi, serve qualcosa di più robusto.
Ora il progetto usa Logback con:
- logging su file (
logs/photoprism-ai.log) - rotazione giornaliera
- retention di 7 giorni
- nessun output su stdout, tranne barre di progresso essenziali
Nel log trovi:
- prompt di clustering (DEBUG)
- rimozioni per dedup temporale/spaziale (INFO)
- nomi dei cluster finali (INFO)
Prompt emozionale e descrizioni più ricche
Uno dei problemi iniziali era che il modello multimodale produceva descrizioni troppo brevi o generiche, il che rendeva il clustering meno efficace.
Ho:
- aumentato la descrizione a 30 parole per ogni foto
- introdotto un prompt emozionale più ricco, per spingere il modello a valutare anche composizione, originalità e “atmosfera”, non solo要素 tecnici
Il clustering ne beneficia molto: le categorie sono più pulite e coerenti.
Batch, thread e performance
Nel primo post parlavo di timeout e latenza come principali colli di bottiglia. Ho fatto diversi affini:
- batch da 30 richieste per il clustering
- 3 thread per il processing parallelo
- caching più intelligente di
takenAt, titolo, coordinate e luogo - retry automatico 3× per le chiamate AI in caso di errore
Questi cambiamenti hanno reso il tool più stabile e veloce, soprattutto su archivi grandi.
Barra di progresso e Web UI
La CLI funziona bene, ma per molti utenti un’interfaccia visuale è più comoda. Ho quindi sviluppato una Web UI leggera con:
- Javalin come server embedded
- HTMX per dinamicità senza scrivere JavaScript complesso
- una barra di progresso per il clustering, con conteggio batch in tempo reale
La Web UI permette di:
- scegliere mese singolo o anno intero
- specificare quante foto selezionare
- personalizzare il prompt di valutazione
- scegliere il nome dell’album
Il form è semplice, ma copre tutti i casi d’uso principali.
Modalità anno intero
Nel post originale parlavo solo di selezione per mese. Ora c’è anche una modalità anno intero: lo strumento processa tutti i 12 mesi in sequenza, accumulando le foto migliori di ogni mese in un unico album annuale.
È utile per creare album tipo “Best of 2025” o “Viaggi 2025” senza dover lanciare manualmente 12 selezioni separate.
Cache arricchita e pool temporaneo
La cache (ai-cache.json) ora conserva per ogni foto:
- score estetico
- descrizione generata dall’AI
- cluster assegnato
- titolo, coordinate,
takenAt,placeLabel,placeCity,placeState,placeCountry
Il pool temporaneo pre-dedup viene salvato in {albumName}.json, utile per debug e analisi.
CLI più flessibile
Oltre alla Web UI, la CLI è più potente:
bash# Mese singolo
java -jar target/photoprism-ai-curator-1.0.1.jar \
--no-web --mode month --month 1 --year 2026 \
--count 20 --album "Mia Selezione"
# Anno intero
java -jar target/photoprism-ai-curator-1.0.1.jar \
--no-web --mode year --year 2026 \
--count 20 --album "Best of 2026"
# Prompt personalizzato
java -jar target/photoprism-ai-curator-1.0.1.jar \
--no-web --mode month --month 1 --year 2026 \
--count 20 \
--prompt "Rate composition and originality"
Sono disponibili flag per:
- percorso del config file
- forzatura modalità CLI
- modalità mese/anno
- mese, anno, conteggio foto
- nome album
- prompt di valutazione
Struttura del progetto
Il progetto è ora più maturo e meglio organizzato:
AiBackendcome interfaccia comune per rating e clusteringOllamaClienteLmStudioClientcome implementazioni separatePhotoFetcher,AISelector,AlbumManager,ImageHashercome servizi pulitiWebServercon Javalin + HTMXJobContextper lo stato thread-safe dei job
Tutto il codice è in Java 17+, con Maven, JUnit 5 e Mockito per i test.
Perché questi aggiornamenti contano
Per me, il punto non è solo automatizzare una classifica di bellezza. Il vero valore sta nel:
- combinare giudizio estetico, varietà narrativa e vincoli pratici
- gestire cache, timeout e costi computazionali in modo intelligente
- offrire un’alternativa locale e controllabile ai servizi cloud per la selezione foto
Con LM Studio, dedup tempo/spazio, Logback, Web UI e modalità anno intero, ritengo che il progetto sia oggi molto più pronto per l’uso quotidiano.
Tutti i dettagli tecnici, commit e modifiche sono disponibili su GitHub.
La commit history è qui: https://github.com/b0sh-net/photoprism-ai-curator/commits/master/.
Lascia un commento