Guida all'uso
Due guide: una pratica per l'uso quotidiano, una tecnica per capire il funzionamento
Opus Meum (latino: "la mia opera") è uno strumento che analizza testi in italiano per determinare se sono stati scritti da un umano o generati da un'AI.
Cos'è Opus Meum
Uno strumento che analizza un testo e dice se è stato scritto da un umano o generato da un'intelligenza artificiale. Funziona per testi in italiano, analizzando oltre 90 caratteristiche linguistiche e stilistiche combinate in 6 modelli ensemble.
1. Creare un Autore
Prima di analizzare, crea un autore. Usa nome e cognome separati:
- Vai su Autori
- Clicca Nuovo Autore
- Inserisci nome, cognome, e opzionalmente data/luogo di nascita, nazionalità, biografia e note
Ogni autore ha i propri testi di riferimento, cronologia analisi e profilo separati.
2. Aggiungere Testi di Riferimento
I testi di riferimento migliorano l'accuratezza. Più ne aggiungi (almeno 3-5), più la perplessità e il profilo autore diventano precisi:
- Entra nella pagina dell'autore cliccando sul suo nome
- Incolla un testo nella sezione Aggiungi Testo e salva
- Il testo viene automaticamente usato come riferimento per le analisi successive
3. Analizzare un Testo
Due modalità:
Analisi Rapida (Dashboard)
- Vai sulla Dashboard
- Incolla il testo e clicca Analizza
- Il risultato viene mostrato subito ma non viene salvato
Analisi Completa (pagina Autore)
- Entra nella pagina dell'autore
- Incolla il testo nella casella in basso e clicca Analizza
- Il testo viene salvato come riferimento e l'analisi archiviata nella cronologia
4. Leggere il Risultato
Ogni analisi mostra:
- Verdetto — "Umano" o "AI" con percentuale di confidenza
- Relazione sintetica — 3-5 punti generati dall'AI: modello più influente, indizi principali, bilanciamento indicatori umani/AI, attendibilità
- Barra confidenza — verde/rosso visivo del rapporto umano/AI
- Modelli ensemble — contributo di ciascuno dei 6 modelli con peso dinamico e punteggio
- Criteri di valutazione — lista dettagliata di ogni feature analizzata con osservazione e contributo
La relazione sintetica è il punto di partenza: riassume i motivi principali del verdetto. I dettagli sotto servono per un'analisi approfondita.
5. Cronologia e CSV
Le analisi salvate sono visibili in:
- Pagina dell'autore — tabella cronologia + grafico a torta umano/AI
- Sezione Analisi — elenco globale di tutte le analisi
- Dashboard — ultime 10 analisi e grafico distribuzione
Usa il pulsante Esporta CSV per scaricare tutte le analisi in formato tabellare.
6. CLI (Linea di Comando)
Se hai accesso al server, puoi usare il comando ai-analyze:
ai-analyze authors # Elenca autori
ai-analyze add-autore Mario Rossi # Crea autore (nome cognome)
ai-analyze texts Mario # Elenca testi di Mario
ai-analyze analyze Mario "testo..." # Analizza e salva
ai-analyze analyze-text "testo..." # Analisi rapida
ai-analyze analyses # Cronologia analisi
Limitazioni pratiche
- Testi brevi (< 50 parole): confidenza ridotta. Il sistema adatta i pesi (stilometrico ×1.5, ML ×0.8). Per risultati affidabili usa almeno 100 parole.
- Testi formali/saggistici: umani e AI scrivono in modo simile nei registri formali. Il verdetto potrebbe cadere in zona grigia.
- AI moderne: GPT-4, Claude sanno imitare bene lo stile umano. Il margine di separazione si riduce.
- Testi di riferimento: più ne aggiungi (almeno 3-5 per autore), più l'analisi è accurata.
- Lunghezza massima: 100.000 caratteri per analisi. L'analisi stilometrica processa i primi 10.000 caratteri.
Architettura Ensemble
Il sistema usa 7 modelli indipendenti che analizzano il testo da prospettive diverse. Ogni modello produce un punteggio (positivo = umano, negativo = AI). Il punteggio finale è una media pesata:
score = w_stat×Stat + w_perp×Perplex + w_stylo×Stylo + w_prof×Profile + w_ref×RefDist + w_ml×ML + w_gpt2×GPT2
prob_umano = 1 / (1 + e^(-score)) ← sigmoide
soglie: prob_umano > 0.7 → "umano"
prob_umano < 0.3 → "AI"
0.3 ≤ prob_umano ≤ 0.7 → "incerto" (zona grigia)
I pesi base sono: Stat 0.25, Perplex 0.15, Stylo 0.15, Profile 0.10, RefDist 0.10, ML 0.15, GPT2 0.10. Per testi brevi i pesi vengono ricalcolati dinamicamente (vedi sezione Pesi Dinamici).
La sigmoide mappa qualsiasi score reale in [0,1]. Score=0 → 50% (incerto), score=+2 → ~88%, score=-2 → ~12%. Score ±4+ → satura a >98%.
1. Modello Statistico — peso base 25%
71 feature quantitative raggruppate in categorie. Ogni feature contribuisce con delta ±0.5–2.5. Il punteggio cumulativo è diviso per 2.0 per normalizzazione:
- CV lunghezza frasi: coefficiente di variazione delle lunghezze delle frasi. CV>0.7→+2.5 (umano), CV<0.2→−2.0 (AI). Per testi con meno di 3 frasi la penalità è ridotta (CV inaffidabile).
- TTR vs atteso: Type-Token Ratio corretto per lunghezza testo: atteso = min(0.9, 0.55 + 15/parole). Deviazione >0.08→−1.2 (AI).
- Hapax ratio: proporzione di parole usate una sola volta. Atteso = min(0.80, 0.35 + 10/parole). Deviazione >0.12→−1.0 (AI).
- Parole funzione: articoli, preposizioni, congiunzioni, pronomi. >42%→+1.5 (umano), <28%→−1.2 (AI).
- Lunghezza parole: media e std. Media >5.1 → AI (parole lunghe = registro formale che l'AI predilige). Std <0.7 → AI (uniformità innaturale).
- Punteggiatura espressiva: !/?. >1.5%→+1.0. L'AI tende a evitare la punteggiatura emotiva.
- Entropia inizio frase: varietà delle prime parole delle frasi. >0.85→+1.2, <0.4→−1.2.
- Entropia bigrammi punteggiatura: varietà delle sequenze di 2 segni. L'AI usa pattern di punteggiatura più ripetitivi.
- Connettivi discorsivi: "inoltre", "pertanto", "tuttavia". >4%→−0.8 (abuso AI).
- Gulpease: 89 + 300×frasi/parole − 10×lettere/parole. >60→+0.6, <40→−0.6.
- Autocorrelazione lunghezza frasi: misura quanto la lunghezza di una frase è prevedibile dalla precedente. L'AI ha sequenze più regolari (autocorrelazione alta).
- Rapporto aggettivi/avverbi: gli umani usano più aggettivi descrittivi; l'AI usa più avverbi per modificare.
- Ratio "si" impersonale: l'AI abusa della costruzione "si + verbo" ("si può notare", "si considera").
- Aperture formulaiche: frasi che iniziano con "inoltre", "è importante", "pertanto" — pattern tipici AI.
2. Modello Perplessità — peso base 20%
Misura la prevedibilità statistica del testo usando modelli n-gram con smoothing Laplace. Richiede testi di riferimento dell'autore per costruire i modelli. Tre metriche:
- Perplessità caratteri interpolata (n=2..6): media pesata delle perplessità ai vari ordini n-gram. Perplessità >6 → umano (sequenze imprevedibili, tipiche della scrittura umana); <3.5 → AI (sequenze troppo regolari).
- Perplessità parole (unigram+bigram+trigram): stesso principio a livello lessicale. >150 → umano, <50 → AI.
- OOV rate: percentuale di parole non presenti nei testi di riferimento. >15% → umano (vocabolario creativo e vario); <2% → AI (aderenza stretta al lessico di riferimento).
Senza testi di riferimento il punteggio è 0 (neutro, non contribuisce). Più testi (≥3) migliorano la stima. Il modello si costruisce al primo utilizzo con un autore specifico.
3. Modello Stilometrico — peso base 20%
Analisi grammaticale e sintattica con spaCy (it_core_news_sm). Processa i primi 10.000 caratteri per performance. Estrae 24 feature:
- POS tag (14 categorie): frequenze relative di NOUN, VERB, ADJ, ADV, PRON, DET, ADP, CCONJ, SCONJ, PROPN, INTJ, NUM, PART, AUX. Marcatori umani: verbi >18%, aggettivi >9%, pronomi >8%, interiezioni >0.5%, nomi propri >6%. Marcatori AI: nomi >30% + pochi pronomi → fraseggio nominale piatto.
- Profondità sintattica: massima profondità dell'albero delle dipendenze. >6 → sintassi complessa (umano, specialmente letteratura classica). <2 + testo >30 parole + nessun colloquialismo → AI (sintassi piatta).
- Clausole per frase: subordinate (csubj, ccomp, advcl, acl, relcl). >1.5 → struttura ipotattica umana. Letteratura classica ha ≥2.0 clausole per frase.
- Densità entità nominate: persone, luoghi, organizzazioni per parola. >3% → umano (ricchezza referenziale). <0.5% + testo >30 parole → AI.
- Diversità POS: entropia Shannon della distribuzione POS. >2.8 → umano. <1.5 → AI (poverà morfologica).
- Rapporto articoli: >16% → umano (testi descrittivi). <6% → AI.
- Rapporto preposizioni: >14% → AI (accumulo di complementi). <7% → umano.
Rilevamento letteratura classica: Se profondità ≥7 E clausole ≥2.0 E diversità POS >2.5 E zero interiezioni → bonus +0.8 (Manzoni, Dante, letteratura alta). Se sintassi complessa ma senza marcatori colloquiali → penalità −0.3 (AI che copia stile formale).
Correttivo AI fiction: Alti nomi (>30%) + bassi pronomi (<3%) + nessun colloquialismo → penalità −0.5 (pattern tipico di narrativa generata da AI, che descrive senza coinvolgimento personale).
4. Modello Profilo — peso base 10%
Confronta il testo con la distribuzione statistica dei testi di riferimento dell'autore su 25 feature chiave:
- Calcola media (μ) e deviazione standard (σ) per ogni feature dai testi di riferimento dell'autore (minimo 2 testi per feature).
- Per il nuovo testo calcola lo z-score:
z = (x − μ) / σ. Feature con |z| > 2 sono statisticamente anomale. - La deviazione media (media di |z| su tutte le feature) indica quanto il testo si discosta dal profilo storico dell'autore: >2σ → anomalo, probabile contraffazione AI.
- Il punteggio finale pesa ogni feature in base al suo z-score con segno: positivo se prossimo alla media umana dell'autore, negativo se deviante.
Senza testi di riferimento (≥2), punteggio = 0. È il modello più specifico per autore ma anche quello con più requisiti dati.
5. Distribuzione di Riferimento — peso base 10%
Confronta il testo con un corpus pre-calcolato di 42 testi umani + 40 testi AI (Manzoni, Dante, Boccaccio, Leopardi, Foscolo, Verga, Pirandello, Svevo, Deledda, De Amicis, Collodi, Goldoni, Ariosto, Tasso, Machiavelli, Petrarca, Serao, Fogazzaro, Salgari, Pascoli, Carducci, De Sanctis, Settembrini, Pellico, Nievo, D'Annunzio):
- Per ogni feature, calcola media e std separatamente per il corpus umano e AI.
- Il testo riceve due z-score per ogni feature:
z_h = (x − μ_h) / σ_h(quanto si discosta dalla media umana) ez_ai = (x − μ_ai) / σ_ai(quanto si discosta dalla media AI). - Punteggio feature =
sign(z_h) × (|z_ai| − |z_h|): positivo se più vicino alla distribuzione umana, negativo se più vicino a quella AI. - Lo score finale è la media dei punteggi di tutte le feature, ciascuna pesata per la sua capacità discriminativa umano/AI.
Funziona sempre, anche senza testi di riferimento dell'utente. È il modello baseline su cui si innestano gli altri.
6. ML Classifier — peso base 15%
Layer di machine learning che combina tutte le feature (71 statistiche + 24 stilometriche = 95) in un unico classificatore calibrato:
- Logistic Regression + CalibratedClassifierCV (isotonic, cv=3): la regressione logistica L2 bilanciata viene addestrata e poi ricalibrata con isotonic regression su 3 fold. Questo produce probabilità ben calibrate, eliminando la distorsione sistematica del modello base.
- Fallback composito (se sklearn non installato):
0.3×Stat + 0.3×RefDist + 0.25×Stylo + 0.15×Perplex.
La calibrazione isotonica garantisce che una previsione all'80% sia effettivamente corretta nell'80% dei casi, rendendo la soglia a 3 zone affidabile.
7. GPT-2 Perplexity — peso base 10%
Usa il modello GroNLP/gpt2-small-italian (124M parametri, addestrato su Wikipedia italiana e CommonCrawl) per calcolare la perplessità reale del testo:
- GPT-2 Perplexity globale: perplessità dell'intero testo calcolata dal transformer. Perplessità >50 indica testo imprevedibile (umano); <10 indica testo troppo prevedibile (AI).
- Burstiness GPT-2: variabilità della perplessità tra frasi consecutive (CV delle perplessità per frase). >0.5 = alta variabilità (umano); <0.15 = uniformità sospetta (AI).
- A differenza del modello n-gram (che misura regolarità superficiali), GPT-2 cattura la prevedibilità semantica a lungo raggio: l'AI tende a generare sequenze che il modello stesso troverebbe "facili".
Richiede transformers + torch (CPU). Se il modello non è disponibile, il peso viene ridistribuito sugli altri modelli senza impatto.
Pesi Dinamici per Testi Brevi
I pesi base vengono automaticamente adattati in base alla lunghezza del testo (parole):
| Lunghezza | Stat | Perplex | Stylo | ML | Profile | RefDist |
|---|---|---|---|---|---|---|
| < 50 parole | ×0.70 | ×0.70 | ×1.50 | ×0.80 | 0 | invariato |
| 50–99 parole | ×0.90 | ×0.90 | ×1.20 | ×0.90 | 0 | invariato |
| ≥ 100 parole | invariato | invariato | invariato | invariato | attivo | invariato |
Logica: i testi brevi hanno poche frasi → le statistiche sulla variabilità (CV, TTR, hapax) sono inaffidabili → si riduce il peso statistico/perplessità e si aumenta quello stilometrico (che analizza la struttura sintattica anche su poche frasi). Il profilo autore richiede ≥100 parole per un confronto significativo.
Feature Engineering
Il sistema estrae 71 feature testuali (extract_all_features) + 24 feature stilometriche (spaCy) = 95 feature totali. Le 71 feature estrattive si suddividono in:
| Categoria | # | Feature |
|---|---|---|
| Struttura frasi | 8 | word_count, sent_count, avg_sentence_len, sentence_len_cv, sentence_len_std, sentence_len_skew, sentence_len_entropy, sentence_len_autocorr |
| Lessico | 6 | ttr, hapax_ratio, hapax_dis_ratio, lexical_density, content_func_ratio, repetition_score |
| Lunghezza parole | 5 | avg_word_len, word_len_std, word_len_cv, word_len_skew, word_len_entropy |
| Parole funzione/discorso | 18 | func_word_ratio, pronoun_ratio, self_ref_ratio, conjunction_ratio, transition_ratio, emotive_ratio, temporal_ratio, filler_ratio, colloquial_ratio, hedging_ratio, certainty_ratio, personal_exp_ratio, contrastive_ratio, noisy_markers, meta_narrative_ratio, si_impersonal_ratio, formulaic_opening_ratio, adj_adv_ratio |
| Punteggiatura | 11 | comma_ratio, exclamation_ratio, period_ratio, semicolon_ratio, colon_ratio, ellipsis_ratio, dash_ratio, complex_punct_ratio, punctuation_entropy, punctuation_variety, punctuation_density, punctuation_bigram_entropy |
| Ripetizione/varietà | 6 | bigram_entropy, sent_start_entropy, sent_end_entropy, trigram_rep_score, word_repeat_ratio, self_bleu, burstiness, burstiness_pos_std |
| Leggibilità | 1 | gulpease |
| Strutture speciali | 5 | list_ratio, digit_ratio, cap_mid_ratio, uppercase_ratio, quote_ratio |
| Entropia caratteri | 4 | char_entropy_2, char_entropy_3, char_entropy_4, char_entropy_5 |
| Avanzate (pattern frasali) | 5 | consecutive_short_ratio, short_sentence_ratio, sentence_len_autocorr_abs, noun_verb_ratio, burstiness |
Feature stilometriche (spaCy, 24): pos_diversity, verb_ratio, noun_ratio, adj_ratio, adv_ratio, pronoun_ratio_pos, adp_ratio, cconj_ratio, sconj_ratio, det_ratio, propn_ratio, intj_ratio, num_ratio, aux_ratio, max_dep_depth, avg_dep_depth, dep_depth_var, avg_clauses_per_sent, clause_var, avg_np_per_sent, avg_tokens_per_sent, entity_density, article_ratio, preposition_ratio.
Calcolo dei Punteggi: Dettaglio
Ogni modello ha una sua logica di calcolo interna:
Modello Statistico
Il punteggio grezzo è la somma dei delta di tutte le feature (range tipico −15..+15). Viene divido per 2.0 per portarlo nello stesso range degli altri modelli: score = max(-15.0, min(15.0, score / 2.0)). Questo evita che un singolo outlier domini l'ensemble.
Modello Stilometrico
Il punteggio è la somma di contributi binari/ternari (es. verb_ratio >0.18 → +0.6, <0.08 → −0.2). Include un sistema di marcatori: conteggia quanti indicatori umani (human_markers) e AI (ai_markers) sono attivi. Se gli indicatori AI superano di +1 quelli umani, applica una penalità extra di −0.3 per marcatore in eccesso. Il totale è diviso per 2.5 e clampato in [−3, +3].
Modello ML (fallback composito)
Senza sklearn, il punteggio ML è calcolato come: 0.3 × stat_score + 0.3 × ref_score + 0.25 × stylo_score + 0.15 × perp_score. Questo fallback è progettato per essere più informato di un semplice rifscore: combina 4 prospettive diverse con pesi calibrati per minimizzare la perdita di accuratezza rispetto al modello con sklearn.
Modello Perplessità
I modelli n-gram sono costruiti lazy (al primo utilizzo con un autore specifico). Usano conteggi di n-grammi di caratteri (n=2..6) con smoothing di Laplace per evitare probabilità zero. La perplessità è 2^H dove H è l'entropia incrociata tra il modello e il testo. Senza testi di riferimento il punteggio è 0 (neutro).
Interpretazione dello Score
| Score | Prob. umano | Significato |
|---|---|---|
| +4 a +15 | 98-100% | Molto probabilmente umano |
| +1 a +4 | 73-98% | Probabilmente umano |
| -1 a +1 | 27-73% | Zona grigia — incerto |
| -4 a -1 | 2-27% | Probabilmente AI |
| -15 a -4 | 0-2% | Molto probabilmente AI |
La zona grigia è normale per testi <50 parole o registri formali. Aggiungere testi di riferimento migliora la separazione. Il sistema segnala quando la confidenza è bassa nella relazione sintetica.
Perché 6 modelli sono meglio di 1
- Statistico: efficace su testi informali e narrativi; debole su formali (umani e AI si assomigliano)
- Perplessità: potente rilevatore di pattern statistici; richiede dati di riferimento; senza è neutro (20% di peso sprecato)
- Stilometrico: coglie sfumature grammaticali e sintattiche indipendentemente dal contenuto semantico; non richiede riferimenti esterni
- Profilo: specifico per autore; coglie deviazioni dallo stile personale; fragile con <2 testi di riferimento
- Distribuzione rif.: baseline robusta, funziona sempre su qualsiasi testo, basata su 82 testi pre-calibrati (42 umani + 40 AI)
- ML: combina tutte le 95 feature in un modello ottimizzato; con sklearn fa Platt scaling per probabilità calibrate; fallback composito senza sklearn
L'ensemble è progettato per essere gracefully degrading: ogni modello può fallire o essere neutro senza compromettere l'intero sistema. L'accuratezza misurata con Leave-One-Out sul corpus di riferimento è ~92% con sklearn, ~87% senza.
Sicurezza e Limiti
- Rate limiting: 30 richieste/minuto alle API, 5 tentativi di login/minuto con ban automatico di 5 minuti dopo il superamento.
- Validazione input: massimo 100.000 caratteri per il testo, 200 KB per il corpo JSON. Username ≥3 caratteri, password ≥6 caratteri.
- Headers sicurezza: HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy attivi su tutte le risposte.
- Health endpoint:
/api/healthrestituisce{"status":"ok","version":"1.0.0"}per monitoraggio.
Corpus di Riferimento
Il corpus pre-calcolato contiene 82 testi (42 umani + 40 AI), selezionati per coprire un'ampia varietà di stili e registri:
- Manzoni, Dante, Boccaccio, Leopardi, Foscolo
- Verga, Pirandello, Svevo, Deledda, De Amicis
- Collodi, Goldoni, Ariosto, Tasso, Machiavelli
- Petrarca, Serao, Fogazzaro, Salgari, Pascoli
- Carducci, De Sanctis, Settembrini, Pellico, Nievo
- D'Annunzio, Serao, Salgari (opere pubblico dominio)
- Testi generati da GPT-2 Italian (GroNLP/gpt2-small-italian)
- Varietà di temi: tecnologia, società, politica, scienza, arte, cucina
- Testi brevi e frammentari, tipici della generazione automatica
Il corpus è bilanciato per coprire register formali e informali, narrativa e saggistica, dialogo e monologo — per evitare bias verso un particolare genere testuale.