Skip to content

Modalità Think-Aloud

Gli annotatori parlano mentre lavorano e Potato conserva la trascrizione verbatim come motivazione. Il riconoscimento vocale gira interamente in locale con faster-whisper, quindi nessun audio lascia la macchina e nella pipeline non c'è né un'API cloud né un LLM.

Novità della v2.7.0

Prima degli LLM lo standard di riferimento per capire come si forma un giudizio era il protocollo think-aloud, che però non è mai sopravvissuto all'incontro con gli strumenti di annotazione. La modalità Think-Aloud lascia semplicemente che gli annotatori parlino mentre lavorano.

La trascrizione verbatim viene conservata come motivazione, deliberatamente non riassunta, perché parafrasare un protocollo think-aloud contamina proprio l'artefatto che stai cercando di raccogliere. Le etichette possono essere confermate a voce usando frasi fissate, rilevate da un parser basato su regole, senza alcun LLM in nessun punto della pipeline.

Il riconoscimento vocale gira interamente in locale tramite faster-whisper, che sul modello tiny.en da 39 MB lavora in tempo reale su CPU. L'audio non lascia mai la macchina, non c'è nessuna API cloud da chiamare né alcuna bolletta per token da pagare.

Nota: Think-Aloud trascrive i tuoi annotatori. Se vuoi annotare trascrizioni che hai già, prodotte da Whisper, da un'API ASR nel cloud o scaricate come sottotitoli, quella è una funzionalità diversa: vedi Formati di trascrizione. Le due vengono confuse perché entrambe hanno a che fare con Whisper.

Una trascrizione verbatim del ragionamento parlato con un'etichetta vocale rilevata: la catena di pensiero umana, da confrontare con quella del modello.

Registrare la catena di pensiero umana

Il punto non è soltanto raccogliere motivazioni. Think-Aloud cattura come una persona ragiona davvero fino a un'etichetta, così puoi mettere quella catena di pensiero umana a confronto con la catena di pensiero di un modello sullo stesso elemento.

L'annotazione della process reward di Potato segmenta come ragiona un modello, passo per passo. Think-Aloud cattura come lo fa una persona. Sono entrambe superfici di cattura, ed è mettendole affiancate sullo stesso elemento che emergono le divergenze interessanti.

Come funziona

  1. L'annotatore tocca 🎤 Pensa ad alta voce e parla liberamente.
  2. L'audio viene catturato in chunk completi da sei secondi e trascritto in locale.
  3. Per confermare un'etichetta a voce, usa una delle frasi accettate:
    • "I label this Polite" / "I'd call it neutral"
    • "My answer is impolite"
    • "Final answer: polite" / "I go with neutral"
  4. Il rilevamento seleziona automaticamente l'opzione corrispondente nell'interfaccia, parte la normale pipeline di salvataggio e la pill conferma: Sentito: Impolite ✓. Pronunciare più tardi una nuova frase cambia l'etichetta, quindi vince l'ultima conferma.
  5. Con require_spoken_label: true, premere Avanti senza avere confermato un'etichetta fa scattare un promemoria una tantum che mostra la frase attesa. Un secondo Avanti lascia passare, e cliccare le etichette funziona sempre.

Tutto quello che viene detto mentre si pensa è ignorato. "This seems polite, but…" non conferma nulla. Confermano solo le frasi fissate, ed è questo che rende sufficiente un parsing basato su regole. Gli ascolti sbagliati sono assorbiti dal matching fuzzy delle etichette, quindi "in polite" si risolve in Impolite.

Preparazione

bash
pip install faster-whisper   # local STT; first recording downloads the model (~39 MB)

Il browser ha bisogno del permesso per il microfono. localhost conta come contesto sicuro.

Configurazione

yaml
thinkaloud:
  enabled: true
  schema: politeness          # scheme whose labels can be spoken (default: first radio)
  stt: auto                   # faster_whisper | mock | auto
  model: tiny.en              # tiny.en is CPU real-time; base.en is sturdier
  chunk_seconds: 6            # recording chunk length
  require_spoken_label: true  # nudge on Next without a committed label
  # stems:                    # override accepted phrasing regexes (advanced)
  # fillers: [um, uh, hmm, i guess, maybe]
  # language: en
OpzionePredefinitoDescrizione
sttautofaster_whisper (locale), mock (test e sviluppo) oppure auto, che sceglie faster-whisper e segnala un errore utile se manca.
modeltiny.enQualsiasi id di modello faster-whisper.
chunk_seconds6Ogni chunk è un file audio completo.
stemsintegratiStem regex per le frasi accettate; ciascuno cattura le parole che seguono.
fillersum, uh, hmm, …Lessico per il contatore delle esitazioni.
require_spoken_labeltruePromemoria una tantum sul pulsante Avanti quando non è stato confermato nulla.

Che cosa ottieni

  • Flussi di motivazioni verbatim allineati a ciascuna coppia (annotatore, istanza), con la frase dell'etichetta tenuta a parte. La trascrizione meno la frase di conferma è la motivazione.
  • Segnali di esitazione deterministici: conteggi dei chunk silenziosi e delle parole riempitive su un lessico configurabile, calcolati con l'aritmetica invece che con i modelli.
  • Una pagina di revisione su /thinkaloud/review (amministratore) con la trascrizione di ogni sessione, l'etichetta confermata a voce, la confidenza e le statistiche di esitazione.
  • Annotazione a mani libere come effetto collaterale, con benefici reali in termini di accessibilità e di sollievo dalla RSI.

Dati e API

Le trascrizioni vengono salvate in {output_annotation_dir}/thinkaloud/transcripts.jsonl (solo in append, un record per chunk).

EndpointMetodoAuthScopo
/thinkaloud/api/chunkPOSTsessioneChunk audio multipart → trascrizione + rilevamento
/thinkaloud/api/textPOSTsessioneChunk di testo (percorso senza audio)
/thinkaloud/api/stateGETsessioneAggregato di sessione per un'istanza
/thinkaloud/reviewGETamministratorePagina di revisione delle trascrizioni
/thinkaloud/api/exportGETamministratoreTutte le sessioni in JSON

Note di progettazione

  • Il parser lavora su una finestra scorrevole degli ultimi due chunk, così anche le frasi a cavallo tra due chunk vengono rilevate.
  • Il matching delle etichette è prima esatto, poi per prefisso, poi con difflib a una soglia di 0.8, preferendo le corrispondenze esatte. «polite» non collide mai in modo fuzzy con «Impolite».
  • Aggiungere un backend STT significa creare una sottoclasse di STTBackend in potato/thinkaloud/stt.py e registrarla in create_stt.

Ulteriori letture