Case study · RAG · PostgreSQL
RAG su corpus normativo: pipeline reale con PostgreSQL, embedding e ricerca semantica
Da ingest automatico a query intelligenti: modellazione di articoli e documenti ufficiali in .NET con EF Core e pgvector. Nota: descrizione di software di supporto alla ricerca documentale, non consulenza legale.
In sintesi
- Pipeline scrape → enrich → embed su PostgreSQL con tipo
vector(pgvector). - Worker embedding in batch con
FOR UPDATE SKIP LOCKEDper istanze parallele. - Microsoft.Extensions.AI (
IEmbeddingGenerator) e SDK OpenAI. - Ricerca orchestrata con agenti e tool sul corpus.
Problema
Serve trovare relazioni tra articoli e versioni oltre la keyword search, con tracciabilità, pipeline aggiornabile e costi prevedibili su storage e API LLM.
Approccio
- Ingest strutturato con scraper dedicati.
- Enrichment con worker (LLM dove previsto).
- Embedding batch su righe senza vettore.
- Query semantica (L2/cosine su pgvector) + orchestrazione agenti.
Architettura
Worker .NET (Hosted Services), PostgreSQL + pgvector (indici HNSW/IVFFlat a volumi alti), runner/API per ricerca multi-step.
Stack
| Componente | Tecnologia |
|---|---|
| Runtime | .NET, EF Core |
| Database | PostgreSQL + pgvector |
| Embedding | OpenAI / Azure via Microsoft.Extensions.AI |
| Concorrenza | FOR UPDATE SKIP LOCKED |
Esempio (pattern codice)
// Batch + FOR UPDATE SKIP LOCKED (multi-worker)
var articoli = await dbContext.ArticoliCodicePenale
.FromSqlRaw(@"
SELECT * FROM articoli_codice_penale
WHERE embedding IS NULL AND article_content != ''
ORDER BY index ASC LIMIT {0}
FOR UPDATE SKIP LOCKED", batchSize)
.ToListAsync(cancellationToken);
Risultati
Coda embedding resiliente a riavvii; separazione costi enrich vs embed; qualità RAG dipende da chunking, metadati e filtri SQL.
FAQ
È un prodotto pronto per studi legali?
Architettura di riferimento e implementazioni su misura; compliance per cliente.
Che database usate?
PostgreSQL con estensione pgvector.
Sostituisce un avvocato?
No. Supporta ricerca e organizzazione documentale.
Fonti
Contesto normativo e tracciabilità
Nei corpus di testi ufficiali ogni versione di articolo può avere efficacia diversa nel tempo. La pipeline deve versionare documenti, conservare hash o timestamp di ingest e collegare ogni risposta utente alle fonti recuperate. Questo non sostituisce un giurista ma consente audit interni su cosa ha letto il sistema quando ha prodotto una sintesi.
Chunking e sovrapposizione
La segmentazione del testo influenza recall e precisione: chunk troppo grandi diluiscono il segnale semantico; troppo piccoli perdono contesto. Spesso si usa sovrapposizione controllata tra chunk adiacenti e metadati (numero articolo, rubrica, data di pubblicazione) per filtri SQL pre-vector.
Enrichment controllato
Gli worker di enrichment possono estrarre entità o riassunti con LLM. Va definito cosa resta persistito e cosa è volatile, per costi e privacy. Separare job di enrich da job di embed consente di ricalcolare vettori senza ripagare arricchimenti già validati.
Indici e prestazioni
Con volumi elevati, IVFFlat o HNSW su pgvector richiedono tuning di liste e parametri di costruzione. Monitorate tempi di build indice durante finestre di manutenzione. Query ibride (filtro relazionale + top-k vettoriale) devono usare piani verificati con dati realistici.
Orchestrazione agenti
Gli agenti possono scomporre domande complesse in sotto-query su sotto-corpus. Serve limite di passi, timeout e budget token per evitare loop costosi. I tool esposti agli agenti devono essere idempotenti dove possibile e loggati.
Allucinazioni e mitigazione
Anche con buon retrieval, il modello può sintetizzare oltre il testo recuperato. Tecniche includono citazioni obbligate, temperature basse, refusal templates e validazione post-gen su presenza di span nei chunk. Il business deve accettare che “non so” sia risposta legittima.
Costi operativi
Embed in batch ammortizzano chiamate rispetto a embed on-the-fly su ogni aggiornamento minore. Cache di query ripetute e deduplica documenti identici riducono storage. Confrontate costo storage vettoriale vs costo re-indicizzazione frequente.
Sicurezza e segregazione
Database dedicati o schema separati per ambienti dev/staging/prod. Ruoli PostgreSQL limitati ai soli comandi necessari per worker e API. Backup crittografati e test di restore periodici.
Test e qualità
Set di domande golden con risposta attesa e fonti attese. Regressioni dopo cambio modello embedding o LLM. Valutazione umana campionata su nuovi tipi di domanda prima di ampliare utenza.
Estensibilità
Nuove fonti documentali richiedono mapping schema e policy di aggiornamento. Prevedete adapter per formati (HTML, PDF testo, DOCX) e normalizzazione Unicode.
Handover
Documentate come rilanciare worker, come verificare lunghezza code, come invalidare cache semantica. Il cliente deve poter operare in emergenza anche senza il fornitore in videochiamata.
Multi-tenant e isolamento
Se più clienti condividono piattaforma, isolamento logico per schema o database è preferibile a semplice filtro applicativo. Ogni tenant ha quote storage e rate limit distinti per evitare effetto noisy neighbor su indici vettoriali.
Localizzazione contenuti
Documenti bilingui richiedono strategia di lingua nel retrieval: stesso embedding multilingue o modelli separati per lingua con routing esplicito nella domanda.
Disaster recovery
Backup PostgreSQL includono estensione pgvector. Testate restore in ambiente isolato e tempo di ricostruzione indici grandi. Pianificate finestra di manutenzione per rebuild dopo disaster.
Osservabilità e operatività
Metriche su latenza p50/p95, tasso errore, profondità code e costo stimato per richiesta dovrebbero essere visibili in dashboard dedicate prima che il business se ne accorga per telefono. Alert su soglie anomale devono avere runbook: chi guarda, cosa riavviare, quando escalation. Includete exporter compatibili con lo stack già usato dal cliente (Prometheus, Azure Monitor, altro).
Gestione segreti e rotazione
Chiavi API, stringhe di database e certificati restano in vault o variabili d’ambiente gestite, mai in repository. Pianificate rotazione periodica e procedure d’emergenza in caso di leak. Documentate quali servizi terzi ricevono quali segreti e con quali scope minimi.
Test di carico e caos controllato
Prima del go-live, simulare picchi di richieste e timeout di dipendenze esterne. Verificate degradazione controllata: code, circuit breaker, messaggi utente comprensibili. Il caos in produzione arriva da sé; meglio provarlo in staging.
Conformità e dati personali
Mappate flussi PII attraverso embedding, log e backup. Allineate retention a policy aziendale e GDPR. Se usate fornitori extra-UE, verificate SCC e trasferimenti. Il reparto legale del cliente deve ricevere diagramma semplificato dei flussi.
Documentazione e formazione handover
Consegnate architettura logica, istruzioni di deploy, checklist incident e contatti escalation. Una sessione di training registrata (se consentita) riduce dipendenza da singole persone. Aggiornate documentazione quando cambiate versione modello o schema DB.
Evolutività
Prevedete punti di estensione: nuovi template, nuovi corpus, nuovi tool per agenti. Evitate fork non mergeabili del codice core. Usate feature flag per abilitare gradualmente capacità a sottoinsiemi di utenti.
Collaborazione con il cliente
Coinvolgete early il team operations del cliente: conoscono finestre di deploy, blackout e vincoli di change management. Una roadmap condivisa evita sorprese quando il fornitore LLM annuncia deprecation o quando il cliente deve congelare rilasci per audit.
Chiusura e lesson learned
Dopo go-live, tenete retrospettiva su cosa ha funzionato in discovery e cosa no. Documentate debiti tecnici accettati e pianificate paydown. Questo materiale alimenta miglioramento continuo e proposte commerciali successive credibili.
Integrazione con toolchain esistente
CI/CD, code review e policy di branch del cliente vanno rispettate: consegnate pipeline coerenti con repository interni, evitando “isole” che solo il fornitore può buildare. Automatizzate test funzionali minimi su componenti AI così un refactor non rompe silenziosamente il retrieval o i template SQL.
Formazione e handover
Prevedete sessioni di handover con documentazione operativa: runbook, contatti escalation, metriche da monitorare e procedure di rollback. Così il team interno può gestire incidenti di routine senza dipendere dal fornitore per ogni piccolo aggiustamento.