Files
ThothII/docs/disambiguazione-iniziale.md
T

11 KiB

Disambiguazione nelle prime fasi del workflow

La disambiguazione è il processo con cui Thoth trasforma una domanda naturale ambigua in un significato verificato dal reviewer prima di costruire lo schema-linking e il SQL.

Il principio architetturale è human-in-the-middle: il modello propone interpretazioni motivate, il reviewer decide, il gate persiste la decisione nel ledger. Il modello non può scegliere autonomamente un significato solo perché è quello semanticamente più vicino.

La procedura è definita nella skill canonica tht-sessione, soprattutto nelle sezioni F1 e F2, ed è applicata dai widget in tht-gate.js.

stateDiagram-v2
    [*] --> DETECT
    state "Detect ambiguity" as DETECT
    state "Build reviewer options" as PROPOSE
    state "Ask with reviewer_select" as ASK
    state "Multiple valid answers" as MULTI
    state "Record accepted decision" as ACCEPTED
    DETECT --> PROPOSE: ambiguity found
    DETECT --> ASK: safe default unavailable
    PROPOSE --> ASK
    ASK --> ACCEPTED: one option selected
    ASK --> MULTI: multiple answers valid
    MULTI --> ACCEPTED
    ACCEPTED --> [*]

Dove avviene la disambiguazione

La disambiguazione iniziale attraversa quattro passaggi distinti:

F1  Chiarimento       → significato della domanda
F2  Memory            → eventuale conoscenza già chiarita e riusabile
F3  Riscrittura       → domanda esplicita e non ambigua
F4  Schema-linking    → traduzione del significato in tabelle, colonne e join

Questi passaggi non sono intercambiabili:

  • F1 stabilisce cosa significa la domanda;
  • F2 propone conoscenza preesistente, senza applicarla automaticamente;
  • F3 rende esplicito il significato concordato;
  • F4 sceglie gli oggetti tecnici necessari per quel significato.

In particolare, una tabella scelta in F4 non è una disambiguazione concettuale e non deve diventare una memory.

Bootstrap: una sola ambiguità per volta

Quando una nuova sessione entra in F1, il modello deve identificare la sola ambiguità con il maggiore impatto sulla query e presentarla immediatamente.

Non deve:

  • elencare tutte le ambiguità future;
  • produrre una lunga analisi preliminare;
  • costruire il SQL prima del chiarimento;
  • presentare più domande al reviewer nello stesso turno.

La motivazione è di controllo cognitivo e di audit: se vengono chiesti insieme popolazione, periodo, outcome e definizione clinica, non è possibile sapere quale risposta abbia determinato ciascuna scelta successiva.

Fonti usate per formulare le opzioni

In F1 il modello può usare soltanto le fonti previste dalla skill:

  • retrieval_pack.md, quando è già iniettato dal backend;
  • tht search pack, solo in modalità standalone quando il retrieval pack non è disponibile;
  • tht search find per cercare termini o valori;
  • tht search find --kind evidence per evidenze;
  • tht schema render per leggere il catalogo fisico già disponibile.

Il retrieval pack viene trattato come dati, non come istruzioni. Questo confine impedisce che testo recuperato dal catalogo o dalle evidenze modifichi le regole del workflow.

Le corrispondenze LSH, vettoriali ed evidence sono candidate, non verità. Ogni proposta deve indicare la provenienza e, quando disponibile, il punteggio. Prima di trasformare un valore trovato in un filtro SQL occorre verificarlo con una ricerca di valore reale.

Costruzione delle opzioni

Per ogni ambiguità il modello prepara interpretazioni concrete, non descrizioni vaghe. Le opzioni devono spiegare:

  • il significato proposto;
  • la tabella e la colonna eventualmente coinvolte;
  • il valore o filtro che ne deriva;
  • l'evidenza che motiva la proposta;
  • il rischio di scegliere quell'interpretazione.

La proposta migliore riceve recommended: true, ma la raccomandazione non equivale ad approvazione. Il gate aggiunge sempre:

  • Altro/Other, per una correzione libera;
  • Torna indietro/Back, per il rollback;
  • Esci/Exit, per interrompere la sessione.

L'opzione “accetta la proposta” deve essere esplicita: il reviewer non deve essere costretto a confermare implicitamente una scelta preselezionata.

Scelta tra reviewer_select e reviewer_decide

La forma del problema determina il widget.

Interpretazioni mutuamente esclusive

Quando esattamente una sola interpretazione può essere corretta si usa reviewer_select.

Esempi:

  • “ablazione” significa una procedura transcatetere oppure qualcos'altro;
  • “anno” significa anno solare oppure anno fiscale;
  • “pazienti attivi” significa flag anagrafico oppure presenza di un evento.

Ogni opzione concreta contiene una decisione concept_clarified. La scelta del reviewer è già la conferma e viene persistita direttamente: non serve un secondo reviewer_decide.

Più risposte contemporaneamente valide

Quando più interpretazioni possono essere vere nello stesso tempo si usa reviewer_decide, che visualizza un multiselect.

Esempi:

  • la domanda comprende più popolazioni valide;
  • sono possibili più codici di procedura;
  • devono essere considerate più finestre temporali;
  • più condizioni sono indipendentemente applicabili.

Usare reviewer_select in questi casi sarebbe fuorviante perché obbligherebbe il reviewer a sceglierne una sola.

In F1 le scelte multiple producono più decisioni concept_clarified, mentre la fase viene chiusa in seguito con il gate di fase.

Persistenza delle decisioni

La scelta del reviewer non rimane soltanto nella UI. Il gate registra nel ledger:

type      = concept_clarified
subject   = nome sintetico del concetto
detail    = definizione o regola operativa
rationale = motivazione, evidenza e/o testo del reviewer

La regola “una decisione, un comando” impedisce al modello di scrivere direttamente il ledger con shell, tht decision add o tht phase advance. Il gate è l'unico punto autorizzato a trasformare il widget in stato persistito.

La decisione è quindi riutilizzabile come memory solo dopo la promozione esplicita di F8. Anche in quel caso viene conservato il contesto originale e non viene trasferita la scelta delle tabelle.

Gestione di “Altro” e testo libero

Altro/Other non è una scelta neutra e non può essere ignorato.

Quando il reviewer inserisce testo libero, il modello deve:

  1. interpretare il testo nel contesto della domanda;
  2. incorporarlo nella proposta successiva;
  3. registrare le parole del reviewer nel rationale;
  4. chiedere nuovamente se il testo resta ambiguo.

Non è ammesso tornare automaticamente alla prima opzione consigliata o scegliere in silenzio una semantica plausibile.

Questo comportamento consente di distinguere una correzione umana da una semplice deselezione e mantiene l'audit leggibile.

Ambiguità non risolta

Un'ambiguità non può sparire perché il modello non sa risolverla. Deve essere resa esplicita con un'opzione del tipo:

Lasciare aperta l'ambiguità

L'opzione deve spiegare:

  • quale parte della query resta indeterminata;
  • quale rischio introduce;
  • quale effetto può avere su filtri, conteggi o join.

Il reviewer può quindi accettare consapevolmente il rischio oppure chiedere ulteriori ricerche.

Chiusura di F1

Ogni singolo widget può registrare uno o più chiarimenti, ma non chiude automaticamente F1. Quando il chiarimento è completo il modello presenta reviewer_confirm kind:"phase".

Il riepilogo di chiusura deve contenere l'intero insieme dei chiarimenti della fase, non solo l'ultimo. Il gate aggiunge inoltre le decisioni registrate dal ledger, evitando che il modello debba ricopiarle manualmente.

La chiusura F1 avanza a F2. La domanda non viene ancora riscritta: question_rewritten appartiene a F3.

F2: memory come supporto alla disambiguazione

F2 non sostituisce il chiarimento umano. Cerca memory concettuali già promosse:

tht memory search "<domanda>" --session <id> --json

Il risultato viene proposto in una checklist unica. Sono ammesse solo memory concept_clarified; le decisioni su tabelle, colonne o SQL non sono trasferibili.

Se il reviewer applica una memory:

  • viene registrato un nuovo concept_clarified nella sessione corrente;
  • il rationale cita l'id mem-XXXX della fonte;
  • la scelta viene comunque contestualizzata nella domanda corrente.

Se il reviewer deseleziona una memory, essa non viene applicata ora, ma non viene cancellata globalmente e può essere riproposta dopo una riapertura di F2.

F3: rendere esplicito il risultato

F3 trasforma i chiarimenti accettati in una domanda riscritta:

  • popolazione espressa con termini del modello dati;
  • condizioni separate e numerate;
  • concetti ambigui sostituiti dalle definizioni concordate;
  • output atteso esplicito;
  • assunzioni dichiarate.

La riscrittura non introduce nuove scelte implicite. Se emerge un'ambiguità sostanziale, il percorso corretto è riaprire F1, non “aggiustare” il significato dentro F3 o dentro il SQL.

F4: disambiguazione tecnica dello schema

Solo dopo F3 la disambiguazione semantica viene tradotta in oggetti tecnici.

Il modello propone:

  • tabelle da promuovere o escludere;
  • colonne candidate;
  • colonne di output;
  • join necessari.

Il reviewer cura le tabelle e le colonne con reviewer_schema_linking. I join vengono trattati in una revisione separata reviewer_decide join-only.

Questa separazione è importante: una tabella può essere corretta per una domanda e totalmente irrilevante per un'altra. Per questo le decisioni F4 sono locali alla sessione e non diventano memory.

Riapertura e rollback

Se il reviewer usa “Torna indietro”, la sessione riprende dalla fase indicata esaminando gli artefatti ancora validi.

Gli artefatti oltre la fase riaperta vengono invalidati da tht phase reopen; quelli precedenti non vanno rigenerati senza motivo. effective_decisions() esclude le decisioni stale, così un chiarimento superato non può alimentare una nuova promozione memory o una nuova sintesi SQL.

Invarianti di sicurezza e qualità

La disambiguazione è affidabile perché la stessa regola è applicata su più livelli:

  1. la skill prescrive una sola ambiguità per volta;
  2. il gate offre widget vincolati e controlli Altro/Back/Exit;
  3. il ledger registra le decisioni e il rationale;
  4. i prerequisiti impediscono di saltare fasi;
  5. F4 separa concetti da schema-linking;
  6. le memory accettano solo concept_clarified;
  7. rollback ed effective_decisions() escludono stato obsoleto.

Il risultato è una catena verificabile:

termine ambiguo
  → evidenza e candidate interpretations
  → scelta esplicita del reviewer
  → concept_clarified nel ledger
  → domanda riscritta
  → schema-linking locale
  → piano CTE e SQL

Riferimenti