L'AI dove vivono i dati aziendali (parte 1): Preparare i dati per la ricerca semantica

Introduzione

Molto del valore informativo di un’azienda è già nei suoi database: dati relazionali, contenuti testuali, documentazione, ticket e knowledge base. Non sempre, però, filtri, relazioni e ricerche testuali sono sufficienti per trovare informazioni simili per significato.

Con SQL Server 2025, Microsoft porta funzionalità di intelligenza artificiale direttamente nel motore database: nuovo tipo di dato VECTOR, funzioni per lavorare con embeddings, vector search, external model e integrazione con servizi come Azure OpenAI. Queste funzionalità permettono di costruire scenari di ricerca semantica usando T-SQL, accanto al dato relazionale e senza dover ripensare completamente l’architettura dati.

La stessa direzione si ritrova anche in Azure SQL, dove alcune funzionalità legate alla ricerca vettoriale sono già disponibili con caratteristiche più evolute rispetto a quelle dell’ambiente on-premises. In questo modo è possibile lavorare sia in locale che nel cloud, mantenendo continuità con l’ecosistema SQL Server esistente.

In questa serie di articoli costruiremo passo dopo passo una soluzione di ricerca semantica. L’obiettivo è mostrare come valorizzare dati aziendali esistenti mantenendo governance, modello relazionale e controllo vicino al motore database.

In questo primo articolo configureremo l’istanza SQL Server per consentire chiamate ad API esterne e prepareremo le tabelle che ospiteranno la base semantica su cui effettueremo le ricerche.

Configurazioni server-level

Prima di lavorare con modelli esterni, chiamate REST ed endpoint AI, è necessario verificare che l’istanza SQL Server consenta di invocare endpoint esterni. In SQL Server 2025 questa configurazione viene gestita a livello di server tramite la stored procedure di sistema sp_configure.

Il seguente frammento di codice T-SQL abilita l’opzione “external rest endpoint enabled” necessaria per interagire con servizi esterni, in particolare con Azure OpenAI.

USE [master];
GO

EXEC sp_configure 'external rest endpoint enabled', 1;
RECONFIGURE WITH OVERRIDE;
GO

Questa impostazione consente all’Engine di SQL Server di effettuare chiamate verso endpoint REST esterni. Si tratta di una funzionalità necessaria quando si vogliono integrare servizi AI o usare procedure come sys.sp_invoke_external_rest_endpoint.

Si tratta di una configurazione a livello di istanza. Deve quindi essere eseguita da un utente con privilegi adeguati, tipicamente un sysadmin o un utente con permessi equivalenti per modificare le impostazioni server. Per verificare il valore configurato è possibile usare il seguente comando:

USE [master];
GO

EXEC sp_configure 'external rest endpoint enabled';
GO

Preparare i dati per la ricerca semantica con SQL Server 2025 e Azure SQL

Useremo il database StackOverflowMini, una versione ridotta del database pubblico di StackOverflow. Sarà il nostro esempio di knowledge base aziendale: contiene domande, risposte, tag, punteggi e contenuti testuali, cioè lo stesso tipo di patrimonio informativo che molte aziende accumulano nel sistema interno di ticketing, su portali interni e nella documentazione tecnica. Ci concentreremo sulla tabella dbo.Posts che contiene sia le domande poste che le risposte della community.

La tabella dbo.Posts, però, non è ottimizzata per la ricerca semantica, che necessita di un contesto più ricco per funzionare al meglio: un documento che combini, ad esempio, il titolo della domanda, eventuali tag, il corpo della domanda, la risposta accettata e i punteggi. Da qui nasce la tabella ai_demo.PostSearchDocuments che verrà creata nel database StackOverflowMini, nello schema dedicato ai_demo.

Il seguente frammento di codice T-SQL crea lo schema ai_demo e la tabella PostSearchDocuments nel database StackOverflowMini.

USE [StackOverflowMini];
GO

CREATE SCHEMA [ai_demo];
GO

CREATE TABLE [ai_demo].[PostSearchDocuments]
(
  DocumentId INT IDENTITY(1, 1) NOT NULL CONSTRAINT PK_PostSearchDocuments PRIMARY KEY CLUSTERED
  ,QuestionId INT NOT NULL
  ,AcceptedAnswerId INT NOT NULL
  ,Title NVARCHAR(500) NOT NULL
  ,Tags NVARCHAR(300) NOT NULL
  ,QuestionScore INT NOT NULL
  ,AcceptedAnswerScore INT NOT NULL
  ,ViewCount INT NOT NULL
  ,AnswerCount INT NULL
  ,QuestionCreationDate DATETIME NOT NULL
  ,QuestionBody NVARCHAR(4000) NOT NULL
  ,AcceptedAnswerBody NVARCHAR(4000) NOT NULL
  ,DocumentText NVARCHAR(MAX) NOT NULL
  ,Embedding VECTOR(1536) NULL
  ,CreatedAt DATETIME2(0) NOT NULL CONSTRAINT DF_PostSearchDocuments_CreatedAt DEFAULT SYSUTCDATETIME()
  ,EmbeddedAt DATETIME2(0) NULL
  ,CONSTRAINT UQ_PostSearchDocuments_QuestionId UNIQUE (QuestionId)
);

Questo è il significato delle colonne:

  • QuestionId: ID del post che rappresenta la domanda originale
  • AcceptedAnswerId: ID della risposta accettata
  • Title, Tags, QuestionBody, AcceptedAnswerBody: Contenuti testuali
  • QuestionScore, AcceptedAnswerScore, ViewCount: Metadati utili al contesto
  • DocumentText: Testo composto da mandare al modello LLM di embedding
  • Embedding VECTOR(1536): rappresentazione vettoriale di DocumentText
  • EmbeddedAt: Riferimento temporale relativo alla creazione dell’embedding

Il tipo di dato VECTOR permette di memorizzare all’interno del database matrici di numeri a virgola mobile. Nel contesto dell’AI, questi numeri rappresentano un embedding, cioè una rappresentazione numerica del significato di un testo.

I database tradizionali sono ottimizzati per trovare corrispondenze esatte, non per comprendere il contesto e il significato dei valori. La ricerca vettoriale abilita la comprensione semantica nel database, ovvero la possibilità di trovare elementi concettualmente simili anche quando non condividono parole chiave esatte.

La colonna Embedding di tipo VECTOR è stata dimensionata a 1536 perché il modello LLM che useremo genera embedding con 1536 dimensioni. Ovviamente il tipo di dato VECTOR non è pensato per essere letto manualmente: serve per calcolare la similarità o la distanza tra due testi. Un embedding, quindi, trasforma un testo in un vettore numerico. Testi simili per significato producono vettori vicini nello spazio vettoriale.

I vettori vengono archiviati in un formato binario ottimizzato, ma esposti come matrici JSON per facilitarne l’uso e la compatibilità. Ogni elemento del vettore può essere archiviato come valore a virgola mobile a precisione singola (4 byte) oppure a metà precisione (2 byte), consentendo di bilanciare accuratezza ed efficienza di archiviazione. SQL Server 2025 supporta vettori con un massimo di 1998 dimensioni per la precisione singola e 3996 dimensioni per la precisione dimezzata, garantendo il supporto a un’ampia gamma di modelli di embedding.

La colonna DocumentText di tipo NVARCHAR(MAX) è quella a partire dalla quale verrà generato l’embedding. Non vogliamo embeddare soltanto il titolo o la risposta alla domanda, ma l’intero contesto semantico, composto da informazioni quali titolo, tag, domanda e risposta accettata. Così facendo saremo agevolati nelle attività di debug. L’eventuale rigenerazione degli embedding potrà essere eseguita in modo ripetibile e lo stesso contenuto potrà essere utilizzato anche in scenari RAG.

Conclusioni

In questo primo articolo abbiamo definito il contesto della demo: il database StackOverflowMini, la tabella dbo.Posts come sorgente dei contenuti e la nuova tabella ai_demo.PostSearchDocuments come base per la ricerca semantica. Abbiamo introdotto il tipo di dato VECTOR, il concetto di embedding e il ruolo della colonna DocumentText come rappresentazione testuale del documento da trasformare in vettore.

Nel prossimo articolo vedremo come creare un external model verso Azure OpenAI e come generare gli embedding direttamente da T-SQL, salvandoli nella tabella che abbiamo appena descritto.