Lo Stack dell'Intelligenza Artificiale Applicata

23 gennaio 2025

Sulla via maestra non ci sono scorciatoie

Come le Macchine Comprendono il Significato

Oggi, ogni azienda tecnologica — da OpenAI ad Anthropic, da Google a startup di nicchia — costruisce applicazioni IA seguendo un pattern architetturale comune. Non è un caso. È evoluzione convergente: soluzioni simili a problemi simili. Quello che vi presento in questo post, è il pattern architetturale che tutti stanno/stiamo seguendo.

Le macchine non capiscono il linguaggio naturale. Non "pensano" come noi. Ma possono costruire rappresentazioni incredibilmente accurate del significato.

E queste rappresentazioni hanno un nome: Embeddings.


Embeddings: Tradurre il Significato in Numeri

Un embedding è una rappresentazione numerica di un concetto. Un vettore che cattura il "significato" di un testo nello spazio matematico.

La cosa interessante: testi semanticamente simili producono vettori vicini nello spazio.

"Il gatto dorme sul divano"  →  [0.23, -0.45, 0.12, ..., 0.89]
"Un felino riposa sul sofà"  →  [0.21, -0.43, 0.14, ..., 0.87]  ← VICINI!
"La pizza è buona"           →  [-0.67, 0.12, 0.78, ..., -0.23] ← LONTANO

Questa proprietà permette di cercare per significato, non solo per parole chiave. È la differenza tra "trova documenti che contengono 'automobile'" e "trova documenti che parlano di veicoli a quattro ruote".

Esistono diversi modelli di embedding sul mercato: OpenAI, Voyage AI, Cohere per soluzioni cloud; BGE, Nomic, Mixedbread per chi preferisce self-hosting. La scelta dipende da budget, requisiti di privacy e volume di dati.

Un punto importante: cambiare modello di embedding significa re-indicizzare tutto. I vettori non sono compatibili tra modelli diversi.


Ingestion: Preparare i Dati

L'ingestion è il processo che trasforma dati grezzi in vettori pronti per la ricerca: documenti, parsing, pulizia, suddivisione in frammenti, embedding, e infine memorizzazione.

La suddivisione (chunking) è critica. Frammenti troppo grandi fanno perdere contesto nella ricerca. Frammenti troppo piccoli frammentano il significato. Per il codice, la suddivisione deve essere semanticamente consapevole: una funzione non va mai spezzata a metà.

Ogni frammento dovrebbe portare con sé informazioni contestuali: da quale file proviene, quando è stato modificato, che tipo di contenuto è. Questi metadata permettono di filtrare la ricerca in modo intelligente.


Vector Database: Dove Vivono i Significati

I vector database sono database ottimizzati per memorizzare milioni o miliardi di vettori, cercare quelli più simili a una query, e filtrare per metadata. La ricerca avviene tramite algoritmi specializzati che trovano vettori simili in millisecondi anche su dataset enormi.

Le opzioni principali sul mercato:

  • ChromaDB: semplicissimo, ideale per prototipi e progetti personali
  • Qdrant: performance eccellenti, scala a miliardi di vettori, open source
  • Pinecone: fully managed, zero operazioni, ma vendor lock-in
  • Weaviate: supporta ricerca ibrida (semantica + keyword)
  • pgvector: per chi già usa PostgreSQL e ha volumi moderati

La scelta dipende dalla scala del progetto, dalle competenze del team, e dai requisiti di hosting.


RAG: Retrieval-Augmented Generation

RAG risolve un problema fondamentale degli LLM: non sanno tutto, e quello che "sanno" potrebbe essere obsoleto o sbagliato.

L'idea è semplice: invece di chiedere al modello di "ricordare", gli forniamo contesto rilevante al momento della domanda. Il flusso è:

  1. Retrieval: cerca nei vettori i documenti più pertinenti alla domanda
  2. Augmentation: costruisci un prompt che include quei documenti come contesto
  3. Generation: l'LLM genera una risposta basata su documenti reali

Esistono tecniche avanzate per migliorare la qualità: reranking per riordinare i risultati per rilevanza, hybrid search che combina ricerca semantica con keyword tradizionali, query expansion dove l'LLM riformula la domanda per catturare più risultati pertinenti.


Prompting: L'Arte della Comunicazione

Il prompting è l'interfaccia tra l'intenzione umana e la capacità del modello. Un prompt ben costruito può fare la differenza tra una risposta mediocre e una eccellente.

Le tecniche fondamentali sono:

  • System Prompt: definisce il "personaggio" e i vincoli del modello
  • Few-shot Learning: mostra esempi del comportamento desiderato prima di chiedere il risultato
  • Chain-of-Thought: chiedi al modello di "ragionare" passo passo
  • Structured Output: richiedi formati specifici come JSON

La qualità del prompt determina la qualità della risposta. È qui che l'esperienza e la sperimentazione fanno la differenza.


LLM: Il Cervello Generativo

Il panorama degli LLM è ricco e in continua evoluzione. OpenAI con GPT-4o, Anthropic con Claude, Google con Gemini, Mistral, Meta con Llama — ogni provider ha i suoi punti di forza.

Per coding assistants, Claude e GPT-4o sono tra i migliori. Per RAG e assistenti documentali, Claude e Gemini eccellono grazie al contesto lungo. Per self-hosting, Llama e Mistral offrono qualità vicina ai modelli commerciali.

La scelta dipende dal caso d'uso, dal budget, e dai requisiti di privacy. I modelli open source permettono il self-hosting completo; i modelli cloud offrono semplicità d'uso e aggiornamenti continui.


Lo Stack in Produzione

Un esempio concreto: un assistente per codebase aziendale.

I repository GitHub e la documentazione Confluence alimentano una pipeline di ingestion che suddivide e pulisce i contenuti. Gli embeddings vengono generati e memorizzati in un vector database. Quando un utente fa una domanda via Slack, la pipeline RAG cerca i documenti rilevanti e costruisce un prompt per l'LLM, che genera la risposta finale.

Ogni componente ha il suo ruolo: GitHub Actions per l'ingestion automatica, embeddings con cache per ridurre i costi, vector database cloud per semplicità operativa, LLM ottimizzato per il codice.


Conclusione

Lo stack Embeddings → Ingestion → Vector DB → RAG → Prompting → LLM non è magia. È ingegneria. È l'applicazione sistematica di tecniche a un problema antico: far "capire" le macchine.

Queste rappresentazioni numeriche del linguaggio ci permettono di costruire sistemi che rispondono in modo pertinente, che trovano informazioni rilevanti in oceani di dati.

E come ogni buona ingegneria, funziona meglio quando ne capisci i principi, non solo le API.


Serie "CodeIntel System: Dal Concetto al Codice"