Cosa sono gli incorporamenti? Vettori e somiglianza del coseno spiegati in modo semplice
Gli incorporamenti consentono ai computer di confrontare il significato invece di abbinare le parole esatte. Alimentano la ricerca semantica, le raccomandazioni e il RAG. Scopri cosa sono, come viene misurata la somiglianza e dove ti deludono.
- Un incorporamento è un elenco di numeri che rappresenta il significato di un testo, un’immagine o altri dati.
- Elementi simili finiscono con numeri simili, quindi il significato può essere confrontato con la matematica.
- La Somiglianza del coseno confronta la direzione ed è un modo comune per valutare quanto sono simili due incorporamenti.
- Confronta solo gli incorporamenti dello stesso modello e testa i risultati sui tuoi dati.
Cerca “come riavere i miei soldi” e un buon sistema dovrebbe trovare una pagina intitolata “Politica di rimborso”, anche se i due non condividono parole importanti. Questa capacità deriva dagli embedding, una delle idee più utili dell’intelligenza artificiale moderna.
Questa guida spiega gli incorporamenti senza calcoli pesanti. Abbiamo eseguito un piccolo esempio in Python 3.13 e il suo output è mostrato di seguito. I vettori in esso contenuti sono quelli che abbiamo creato a mano, con solo tre numeri ciascuno, per rendere l’idea facile da capire. Gli incorporamenti reali provengono da un modello addestrato e spesso hanno centinaia o migliaia di numeri.
Cos’è un incorporamento?
Un incorporamento è una rappresentazione di qualcosa come un elenco di numeri, chiamato vettore. Un modello viene addestrato in modo che gli elementi con significati correlati ricevano vettori vicini tra loro.
"kitten" -> [0.9, 0.8, 0.1]
"cat" -> [0.9, 0.7, 0.2]
"invoice" -> [0.0, 0.1, 0.9]
Una volta che il testo è in questa forma, un computer può calcolare quanto sono simili due parti di testo, cosa che non può fare direttamente con le parole. Anche gli incorporamenti non si limitano alle parole. È possibile incorporare frasi, interi documenti, immagini, audio e prodotti.
Perché non abbinare semplicemente le parole chiave?
| Interrogare e documentare | Ricerca per parole chiave | Incorporamento della ricerca |
|---|---|---|
| “rimborso” e “politica di rimborso” | Mi manca, nessuna parola condivisa | Posso trovarlo |
| “laptop” e “computer notebook” | Mi manca | Posso trovarlo |
| “errore E1042” e una pagina con “E1042” | Lo trova esattamente | Potrebbe mancarlo |
| “banca” (fiume) e “banca” (denaro) | Li tratta allo stesso modo | Può separarli, dato il contesto |
La nostra guida a RAG lo mostra nella pratica. Una semplice ricerca basata sul conteggio delle parole ha ottenuto zero per “Quando posso riavere i miei soldi?” contro un documento di rimborso, poiché non hanno condiviso parole. Nota anche la terza riga: gli identificatori esatti sono un punto debole degli incorporamenti, quindi la ricerca per parole chiave ha ancora un posto.
Pensa a una mappa
Immagina di posizionare ogni parola su un’enorme mappa, dove la posizione riflette il significato. “Gatto” e “gattino” sono seduti quasi uno accanto all’altro, “cane” è nello stesso quartiere e “fattura” è in una città diversa. Per trovare parole correlate, guarda semplicemente nelle vicinanze.
Un vero e proprio incorporamento funziona allo stesso modo, tranne per il fatto che la mappa ha centinaia di dimensioni anziché due. Le persone non possono immaginarlo, ma i conti funzionano lo stesso. I singoli numeri generalmente non hanno un significato chiaro, come “pelosità”. Ciò che conta è la posizione complessiva.
Un piccolo esempio funzionante
Ecco come confrontare i nostri vettori fatti a mano:
import math
def cosine(a, b):
dot = sum(x * y for x, y in zip(a, b))
return dot / (math.sqrt(sum(x * x for x in a)) *
math.sqrt(sum(y * y for y in b)))
vectors = {
"kitten": [0.9, 0.8, 0.1],
"cat": [0.9, 0.7, 0.2],
"dog": [0.8, 0.3, 0.2],
"invoice": [0.0, 0.1, 0.9],
}
for word in ("kitten", "dog", "invoice"):
print(word, round(cosine(vectors["cat"], vectors[word]), 3))
# kitten 0.994
# dog 0.955
# invoice 0.238
Contro “gatto”, “gattino” ottiene il punteggio più alto, “cane” dopo e “fattura” molto più basso. Abbiamo scelto questi vettori per produrre quel modello, quindi la classifica non prova nulla sul linguaggio reale. Mostra solo come si comporta il calcolo. Una ricerca semantica fa la stessa cosa in tre passaggi: incorpora la query, assegna un punteggio a ogni elemento memorizzato e ordina.
query = [0.85, 0.75, 0.15]
sorted(vectors, key=lambda w: cosine(query, vectors[w]), reverse=True)
# ['kitten', 'cat', 'dog', 'invoice']
Spiegazione della somiglianza del coseno
Ogni vettore può essere pensato come una freccia che punta dall’origine. La somiglianza del coseno misura l’angolo tra due frecce, ignorando quanto sono lunghe. Abbiamo confermato i valori chiave:
cosine([1, 2, 3], [2, 4, 6]) # 1.0 same direction
cosine([1, 0], [0, 1]) # 0.0 unrelated (at right angles)
cosine([1, 0], [-1, 0]) # -1.0 opposite directions
| Punteggio | Significato |
|---|---|
| Vicino a 1 | Puntano quasi nella stessa direzione, quindi molto simili |
| Vicino a 0 | Non correlato |
| Vicino a -1 | Puntare in direzioni opposte |
Guarda la prima riga. [2, 4, 6] è lungo il doppio di [1, 2, 3], ma il punteggio è un perfetto 1,0, perché la direzione è tutto ciò che conta. Ciò è utile per il testo, dove la lunghezza può riflettere aspetti come la dimensione del documento piuttosto che il significato. Fai attenzione anche alle soglie. Non esiste un punteggio universale che significhi “simile”, poiché gli intervalli utili differiscono da modello a modello, quindi esegui il test sui tuoi dati.
Altre misure di distanza
| Misurare | Cosa guarda | Note |
|---|---|---|
| Somiglianza del coseno | Solo angolo | Un’impostazione predefinita comune per il testo |
| Prodotto scalare | Angolo e lunghezza | Veloce ed è uguale al coseno sui vettori normalizzati |
| Distanza euclidea | Distanza in linea retta | Più piccolo significa più simile |
La differenza è facile da vedere. Quegli stessi due vettori con un punteggio coseno di 1,0 hanno una distanza euclidea di 3,742, poiché uno è più lungo dell’altro. Molti sistemi normalizzano i vettori, ridimensionandoli ciascuno a una lunghezza pari a 1. Successivamente, il prodotto scalare e il coseno danno la stessa risposta, e lo abbiamo confermato: entrambi hanno dato 0,955 per “gatto” e “cane”. Controlla la documentazione del tuo modello per vedere quale misura consiglia.
Come vengono appresi gli incorporamenti
Nessuno assegna questi numeri manualmente nei sistemi reali. Una rete neurale li apprende durante l’addestramento. Un’idea iniziale e influente è che le parole che appaiono in contesti simili tendono ad avere significati simili, come “ho dato da mangiare al mio gatto” e “ho dato da mangiare al mio cane”. Modelli come Word2Vec e GloVe hanno imparato i vettori di parole da questi modelli.
Successivamente, modelli basati su trasformatori come BERT hanno reso gli incorporamenti sensibili al contesto, quindi “banca” potrebbe ottenere un vettore diverso in “riva del fiume” e “prestito bancario”. Molti modelli moderni incorporano intere frasi o passaggi contemporaneamente. La nostra guida ai modelli linguistici di grandi dimensioni spiega come i trasformatori gestiscono il contesto.
Dove vengono utilizzati gli incorporamenti
| Utilizzare | Come aiuta |
|---|---|
| Ricerca semantica | Trova i risultati in base al significato, anziché alle parole esatte |
| RAG | Recupera passaggi rilevanti per un modello linguistico |
| Raccomandazioni | Suggerisce articoli simili a quelli che ti sono piaciuti |
| Raggruppamento | I gruppi supportano ticket o recensioni per argomento |
| Rilevamento duplicati | Individua domande o elenchi simili |
| Classificazione | Fornisce funzionalità per modelli semplici |
| Rilevamento anomalie | Contrassegna gli elementi lontano da tutto il resto |
Ricerca su larga scala
Nel nostro esempio abbiamo confrontato una query con ogni elemento, operazione nota come ricerca esatta. Funziona bene per migliaia di articoli, ma diventa lento con molti milioni. Gli indici Approssimati del vicino più vicino (ANN) come HNSW risolvono questo problema. Trovano rapidamente partite molto ravvicinate, rinunciando a una piccola possibilità di perdere quella migliore in assoluto.
I database vettoriali e le estensioni, come pgvector per PostgreSQL, forniscono questi indici insieme al filtraggio e all’archiviazione. La nostra guida al database vettoriale copre le opzioni. Per un progetto di piccole dimensioni, potresti non averne affatto bisogno e una ricerca in memoria è un ottimo modo per iniziare.
Suggerimento: considera in anticipo la ricerca ibrida. La combinazione della somiglianza di incorporamento con la corrispondenza delle parole chiave spesso fornisce risultati migliori rispetto a entrambi i risultati presi singolarmente, in particolare quando gli utenti cercano codici prodotto, nomi o messaggi di errore.
Scelta di un modello di incorporamento
- Lingua. Se il tuo contenuto è in hindi o tamil, ad esempio, controlla che il modello lo gestisca bene.
- Dominio. I modelli generali possono avere difficoltà con termini legali o medici specialistici.
- Dimensioni. Più dimensioni possono acquisire più dettagli, ma costano più spazio di archiviazione e memoria.
- Costi e hosting. Confronta un’API ospitata con un modello aperto che puoi eseguire tu stesso, soprattutto per i dati privati.
- Lunghezza di input. I modelli hanno un limite, quindi i documenti lunghi devono essere prima divisi in blocchi.
Il miglior test sono i tuoi dati. Raccogli circa 20 domande reali insieme ai documenti che dovrebbero trovare e confronta il modo in cui ciascun modello le classifica. I benchmark pubblicati potrebbero non riflettere i tuoi contenuti.
Limitazioni
- Blocco del modello. I vettori di modelli diversi non possono essere confrontati. Se cambi modello, devi incorporare di nuovo tutto.
- Termini esatti. ID, codici e nomi rari potrebbero non essere abbinati in modo affidabile.
- Negazione. “Rimborsi consentiti” e “rimborsi non consentiti” possono essere vicini, nonostante abbiano significati opposti.
- Simile non significa corretto. Una corrispondenza ravvicinata potrebbe essere obsoleta o semplicemente sbagliata.
- Bias. Gli incorporamenti possono assorbire gli stereotipi dai dati di addestramento.
- Il coseno non è magico. I ricercatori si sono chiesti quanto sia significativo su alcuni incorporamenti appresi, quindi tratta i punteggi come un segnale utile e non come una misura della verità.
Errori comuni
- Mixing di modelli. Incorpora query e documenti con lo stesso modello e versione.
- Utilizzo di una soglia di somiglianza ovunque. Ottimizzala per ogni modello e attività.
- Incorporare documenti enormi. Il significato viene diluito, quindi dividili prima.
- Saltare la valutazione. Senza query di prova, non puoi dire se una modifica ha aiutato.
- Utilizzo degli incorporamenti per tutto. Se gli utenti cercano ID esatti, un normale indice del database è migliore.
Considerazioni finali
Un incorporamento trasforma il significato in numeri, in modo che il software possa confrontare idee anziché stringhe. Il concetto è semplice, mentre il lavoro pratico consiste nella scelta di un modello, nella suddivisione dei dati e nel test su query reali. Per provarlo tu stesso, incorpora qualche dozzina dei tuoi documenti con qualsiasi modello di incorporamento, cercali con domande reali e vedi dove i risultati ti sorprendono.
Domande frequenti
Cosa sono gli incorporamenti in termini semplici?
Gli incorporamenti sono elenchi di numeri che rappresentano il significato. Elementi con significato simile ottengono numeri simili, il che consente a un computer di confrontarli matematicamente.
Cos’è la somiglianza del coseno?
Misura l’angolo tra due vettori, da -1 a 1. Un punteggio vicino a 1 significa che puntano quasi nella stessa direzione, il che suggerisce contenuti simili.
Qual è la differenza tra incorporamenti e token?
Un token è una porzione di testo elaborata da un modello. Un incorporamento è un vettore numerico che rappresenta il significato di un token, una frase o un documento.
Quante dimensioni dovrebbe avere un incorporamento?
Dipende dal modello e sono comuni centinaia o poche migliaia. Di più puoi acquisire più dettagli, ma costa più spazio di archiviazione, quindi prova ciò di cui ha bisogno il tuo caso d’uso.
Ho bisogno di un database vettoriale per utilizzare gli incorporamenti?
No. È possibile effettuare ricerche in piccole raccolte in memoria. I database vettoriali diventano utili con raccolte più grandi, aggiornamenti frequenti o esigenze di filtraggio.
Continua a imparare
Hai bisogno di aiuto con test, WordPress o SEO?
Aiutiamo i team a fornire software migliore e a far crescere i loro siti. Raccontaci a cosa stai lavorando e ti suggeriremo chiaramente il prossimo passo.
Altre guide su test, intelligenza artificiale e sviluppo moderno
Ti è piaciuto questo articolo? Scegli un argomento e passa direttamente ai nostri tutorial più recenti.
Spiegazione delle allucinazioni dell'intelligenza artificiale: perché i modelli linguistici inventano le cose e come ridurle
Spiegazione delle allucinazioni dell'intelligenza artificiale: cosa sono, perché i modelli linguistici le producono, tipi comuni, come ridurle con b…
Leggi l'articolo →DevOpsSpiegazione delle variabili d'ambiente: file .env, segreti e configurazione eseguiti correttamente
Variabili d'ambiente spiegate con esempi Python che abbiamo eseguito: lettura e impostazione, perché ogni valore è una stringa, file .env, ereditari…
Leggi l'articolo →Sviluppo softwareSpiegazione della limitazione della velocità API: algoritmi, intestazioni e gestione degli errori 429
La limitazione della velocità dell'API spiegata con una simulazione che abbiamo eseguito: bucket di token, finestra fissa, finestra scorrevole, risp…
Leggi l'articolo →Automazione dei testDerisione in Python: unittest.mock, patch e gli errori che fanno mentire i test
Mocking in Python con unittest.mock, testato: Mock e return_value, side_effect, patch dove viene utilizzato un nome, specifiche e autospec, date moc…
Leggi l'articolo →Test del softwareSpiegazione della copertura del codice: copertura di linea o di filiale e cosa significa realmente il 100%.
Copertura del codice spiegata con una vera esecuzione di cover.py: copertura di linea, ramo e condizione, lettura di un rapporto, perché la copertur…
Leggi l'articolo →Database e SQLDELETE vs TRUNCATE vs DROP in SQL: differenze, rollback e quando utilizzarli
DELETE vs TRUNCATE vs DROP spiegato con SQL testato: cosa rimuove, rollback, trigger, reimpostazione dell'identità, velocità e come differiscono Pos…
Leggi l'articolo →Database e SQLSpiegazione delle visualizzazioni SQL: crea, utilizza ed evita le insidie, con esempi
Viste SQL spiegate con le query che abbiamo eseguito: creazione di una vista, risultati in tempo reale, nascondere colonne, prestazioni, viste aggio…
Leggi l'articolo →Sviluppo softwareInterfaccia TypeScript e tipo: differenze reali, testate con il compilatore
Interfaccia TypeScript vs tipo, verificata con il vero compilatore: cosa possono fare entrambi, cosa può fare solo uno, fusione delle dichiarazioni,…
Leggi l'articolo →Sviluppo softwareSpiegazione di Python *args e **kwargs: funzioni flessibili con esempi chiari
Python *args e **kwargs spiegati con il codice che abbiamo eseguito: compressione e decompressione, ordine dei parametri, argomenti solo per parole …
Leggi l'articolo →Sviluppo softwareFunzioni Lambda Python: sintassi, usi reali e quando non usarli
Funzioni lambda Python spiegate con il codice che abbiamo eseguito: sintassi, ordinamento con chiave, mappa e filtro, chiusure, trap dell'associazio…
Leggi l'articolo →Intelligenza artificialeCosa sono gli agenti AI? Come funzionano, con un semplice ciclo di agenti che puoi eseguire
Cosa sono gli agenti IA? Una semplice guida al ciclo dell'agente, agli strumenti, alla memoria e ai guardrail, con un piccolo ciclo Python che abbia…
Leggi l'articolo →DevOpsMonitoraggio vs osservabilità: la vera differenza, con log, metriche e tracce
Spiegazione del monitoraggio e dell'osservabilità: errori noti e sconosciuti, log, metriche e tracce, una procedura dettagliata sugli incidenti di p…
Leggi l'articolo →DevOpsVolumi Docker e montaggi di associazione: mantenere i dati del contenitore nel modo giusto
Volumi Docker e montaggi di collegamento spiegati: perché i dati del contenitore scompaiono, volumi denominati, montaggi di collegamento, tmpfs, ese…
Leggi l'articolo →Automazione dei testTDD vs BDD: differenze chiave, una caratteristica costruita in entrambi i modi e quando utilizzarli ciascuno
TDD vs BDD spiegato con una funzione di sconto costruita in entrambi i modi: refactoring rosso-verde con il codice che abbiamo eseguito, scenari "Da…
Leggi l'articolo →Test del softwareTest di accettazione da parte dell'utente (UAT): processo, lista di controllo ed esempi reali
Spiegazione del test di accettazione dell'utente: chi lo esegue, in cosa differisce dal QA, un processo in sette fasi, un modello di test case UAT, …
Leggi l'articolo →Database e SQLSpiegazione dei valori SQL NULL: IS NULL, COALESCE, NULLIF e le trappole da evitare
Valori SQL NULL spiegati con le query che abbiamo eseguito: logica a tre valori, IS NULL, COALESCE, NULLIF, come aggregazioni, join e ordinamento tr…
Leggi l'articolo →Database e SQLIstruzione SQL CASE WHEN: sintassi, esempi reali ed errori comuni
SQL CASE WHEN spiegato con le query che abbiamo eseguito: moduli semplici e cercati, ordine delle condizioni, pivot con SUM, trucchi COUNT, ordiname…
Leggi l'articolo →Sviluppo softwareCos'è il JWT? Token Web JSON spiegati con un esempio funzionante
Cos'è il JWT? Spiegazione dei token Web JSON: le tre parti, un token creato e manomesso nel codice che abbiamo eseguito, JWT e sessioni, archiviazio…
Leggi l'articolo →Sviluppo softwareSpiegazione del loop di eventi JavaScript: stack di chiamate, microtask e timer con esempi
Il ciclo di eventi JavaScript spiegato con il codice che abbiamo eseguito: stack di chiamate, code di attività e microtask, perché setTimeout 0 non …
Leggi l'articolo →Sviluppo softwareSpiegazione dei generatori Python e del rendimento: risparmia memoria con esempi reali
Generatori Python e rendimento spiegati con il codice che abbiamo eseguito: come vengono messi in pausa e ripresi, misurato il risparmio di memoria,…
Leggi l'articolo →Intelligenza artificialeCosa sono gli incorporamenti? I vettori e la somiglianza del coseno spiegati semplicemente
Cosa sono gli incorporamenti? Una guida in linguaggio semplice ai vettori, alla similarità del coseno e alla ricerca semantica, con un piccolo esemp…
Leggi l'articolo →DevOpsDistribuzione blu-verde rispetto a quella canaria: differenze, compromessi e come scegliere
Spiegazione della distribuzione blu-verde e canary: come funziona ciascuna, costi, rischi e rollback, bucket utente stabile che abbiamo testato, mig…
Leggi l'articolo →Automazione dei testTest instabili: quali sono le cause e come risolverli definitivamente
Test instabili spiegati con demo che abbiamo eseguito: le cause principali, come confermarne e diagnosticarne uno, soluzioni adeguate per tempistich…
Leggi l'articolo →Test del softwareTest di carico e test di stress: differenze, metriche ed esempi k6
Spiegazione del test di carico e dello stress test: cosa dimostra ciascuno, test di picco e di assorbimento, le metriche che contano, perché le medi…
Leggi l'articolo →Test del softwareCaso di test e scenario di test: differenze chiave, esempi e quando utilizzarli
Spiegazione del caso di test e dello scenario di test: definizioni chiare, una tabella affiancata, una funzione di reimpostazione della password pre…
Leggi l'articolo →Database e SQLOttimizzazione delle query SQL: leggi i piani di esecuzione e correggi query lente, con tempistiche
Ottimizzazione delle query SQL testata su un milione di righe: leggi i piani di esecuzione, aggiungi gli indici corretti, correggi filtri non aggior…
Leggi l'articolo →Database e SQLSQL UNION vs UNION ALL: differenze, esempi e prestazioni testate
SQL UNION vs UNION ALL spiegati con le query che abbiamo eseguito: duplicati, regole seguite da entrambi, un vero bug di dati, prestazioni misurate,…
Leggi l'articolo →Sviluppo softwareTutorial sull'API di recupero JavaScript: GET, POST, gestione degli errori e timeout
Un tutorial sull'API JavaScript Fetch testato su un server locale: GET e POST, perché 404 non genera eccezioni, un helper riutilizzabile, stringhe d…
Leggi l'articolo →Sviluppo softwareGestione dei file Python: lettura, scrittura, CSV, JSON e pathlib con esempi
Gestione dei file Python spiegata con il codice che abbiamo eseguito: modalità aperte, con, lettura di file di grandi dimensioni, CSV, JSON, pathlib…
Leggi l'articolo →Sviluppo softwareClassi e oggetti Python: tutorial OOP con esempi reali
Classi e oggetti Python spiegati con il codice che abbiamo eseguito: __init__, metodi, attributi di classe e istanza, ereditarietà, proprietà, metod…
Leggi l'articolo →Intelligenza artificialeChe cos'è un modello linguistico di grandi dimensioni? Come funzionano i LLM, spiegato senza esagerazioni
Cos’è un modello linguistico ampio? LLM spiegati in un linguaggio semplice: token, incorporamenti, attenzione, formazione, finestre di temperatura e…
Leggi l'articolo →DevOpsComandi Linux per principianti: la guida essenziale del terminale con esempi
Comandi Linux per principianti, raggruppati per attività: navigazione, file, visualizzazione log, grep, pipe, permessi, processi e archivi, con un e…
Leggi l'articolo →Automazione dei testSelenio vs drammaturgo: differenze chiave, codice a confronto e quale scegliere
Selenium vs Playwright a confronto: architettura, attesa, supporto per browser e linguaggio, debug, lo stesso test in entrambi gli strumenti, consig…
Leggi l'articolo →Test del softwarePartizionamento di equivalenza: tecnica di progettazione dei test spiegata con esempi pratici
Spiegazione del partizionamento di equivalenza: come trovare partizioni valide e non valide, esempi funzionanti per età, password e coupon, test che…
Leggi l'articolo →Test del softwareGravità vs priorità nel test del software: differenze, matrice ed esempi reali
Spiegazione della gravità e della priorità nei test del software: definizioni chiare, una matrice a quattro vie con esempi, scale di livello, chi im…
Leggi l'articolo →Database e SQLEsercitazione sulle sottoquery SQL: tipi, sottoquery correlate ed EXISTS con esempi
Un tutorial sulle sottoquery SQL con le query che abbiamo eseguito: sottoquery scalari, IN, FROM e SELECT, sottoquery correlate, EXISTS, trap NOT IN…
Leggi l'articolo →Database e SQLSpiegazione di transazioni SQL e ACID: COMMIT, ROLLBACK e livelli di isolamento
Transazioni SQL e ACID spiegate con un bonifico bancario eseguito: COMMIT, ROLLBACK, punti di salvataggio, blocchi, livelli di isolamento, letture s…
Leggi l'articolo →Sviluppo softwareGit merge vs rebase: differenze, esempi e quando usare ciascuno
Git merge vs rebase spiegato con output reale del log, una tabella di confronto, la regola d'oro del rebase e un flusso di lavoro sicuro per i team.
Leggi l'articolo →Sviluppo softwareList comprehension in Python: sintassi, esempi e quando evitarla
List comprehension in Python spiegata: sintassi, filtri, if-else, cicli annidati, tempi misurati e i casi in cui un normale ciclo for è meglio.
Leggi l'articolo →Database e SQLSQL JOIN spiegati con esempi (Inner, Left, Right, Full)
Capisci i JOIN SQL passo dopo passo con tabelle e query di esempio: INNER, LEFT, RIGHT, FULL, CROSS e SELF, con errori comuni e consigli sulle prest…
Leggi l'articolo →