Skip to content

Rilevamento del processo di scrittura

Trasforma i log dei tasti di Potato in segnalazioni verificabili per le risposte a testo libero incollate, trascritte o generate da una macchina, con soglie che puoi leggere e scavalcare.

Il rilevamento del processo di scrittura legge le dinamiche di digitazione catturate dalla Registrazione dei tasti e produce segnalazioni con nome corredate dalle prove, così puoi vedere quali valori delle caratteristiche hanno fatto scattare ciascuna e scartare quelle su cui non sei d'accordo.

Richiede Potato 2.7.2 o successivo e funziona solo dove la registrazione dei tasti è già attiva. Poiché keystroke_logging.enabled vale false per impostazione predefinita, un progetto che non l'ha mai attivata non ha nulla su cui rilevare.

Attenzione: le segnalazioni sono indizi per una revisione umana. Non sono prove di scorrettezza e non devono mai essere collegate a rifiuti automatici, trattenute di pagamento o blocchi dei partecipanti. Un dattilografo veloce e sciolto che produce una prima stesura pulita somiglia davvero a una trascrizione. Un annotatore al telefono somiglia davvero a qualcuno che incolla. Le regole qui sotto sono costruite per ridurre al minimo queste sovrapposizioni, e le sovrapposizioni continuano a esserci. La sezione sui falsi positivi fa parte della funzionalità, non è una clausola di esclusione.

Tre livelli

LivelloChe cos'èServono dati etichettati?Predefinito
1. RegoleSei segnalazioni con nome, soglie esplicite e prove visibiliNoAttivo
2. CalibrazioneSoglie ritarate sugli annotatori del tuo progettoNoDisattivo
3. SupervisionatoUn classificatore che addestri sulle tue etichetteDisattivo

Con Potato non viene distribuito alcun modello pre-addestrato. Nel repository non c'è un corpus etichettato, quindi qualsiasi coefficiente distribuito arriverebbe con un numero di validazione inventato da noi. Al suo posto ricevi sei regole che puoi leggere e contestare. Se hai etichette vere, il livello 3 è la strada che riproduce le accuratezze riportate in letteratura.

Livello 1: le regole

Ogni segnalazione restituisce i valori delle caratteristiche che l'hanno fatta scattare, così puoi difendere o scartare ciascuna singolarmente.

paste_dominant

Gravità: sospetto. Scatta quando pasted_fraction >= 0.5, cioè metà o più del testo finale è arrivata per incollaggio.

Soppressa quando ogni incollaggio è stato classificato come self (riorganizzare la propria bozza) o instance_text (citare il passaggio in annotazione).

silent_insertion

Gravità: sospetto. Scatta quando external_insert_ratio >= 0.3, cioè quasi un terzo dei caratteri inseriti è comparso senza una battuta corrispondente.

È il singolo segnale di maggior valore. Incollaggio, riempimento automatico, dettatura e iniezione programmatica compaiono tutti qui, anche quando l'evento di incollaggio in sé è soppresso dalla pagina. È un'operazionalizzazione diretta del «conteggio dei tasti anomalmente basso rispetto alla lunghezza della risposta» di Asher et al.

Soppressa sulle tastiere software (virtual_keyboard) e durante la composizione IME, dove keydown non viene emesso in modo affidabile e altrimenti ogni inserimento sembrerebbe silenzioso. La regola usa il rapporto che tiene conto della provenienza, quindi le citazioni legittime non contano.

transcription_rhythm

Gravità: da rivedere. Scatta quando valgono tutte e tre queste condizioni:

  • iki_log_cv <= 0.06, un ritmo di digitazione metronomico
  • revision_ratio <= 0.02, in pratica nessuna cancellazione
  • meno di 0,5 pause di 2 secondi o più ogni 100 caratteri

Congiuntiva per scelta. Ciascuna presa da sola ha una lettura innocente. Insieme sono la firma della copiatura a macchina descritta da Crossley et al.: lineare, a raffiche, con varianza bassa.

Saltata del tutto per le risposte sotto gli 80 caratteri o le 40 battute, dove non c'è un ritmo di cui parlare.

offscreen_composition

Gravità: sospetto. Scatta quando un inserimento consistente di provenienza esterna (80 caratteri o più) segue immediatamente 10 secondi o più trascorsi fuori dalla pagina. È il pattern «sono passato a ChatGPT, sono tornato, ho incollato».

Soppressa quando la provenienza dell'inserimento era il passaggio o il testo dell'annotatore stesso, dato che allontanarsi e poi citare il passaggio è un comportamento ordinario.

implausible_speed

Gravità: da rivedere. Scatta sopra i 900 caratteri al minuto (circa 180 wpm) mantenuti per un'intera risposta.

synthetic_input

Gravità: sospetto. Scatta su qualsiasi evento con isTrusted === false, cioè quando il browser riporta che l'input è stato generato da uno script anziché da una persona. L'automazione del browser, gli script iniettati e alcuni strumenti di accessibilità producono tutti questo effetto.

Livelli di verdetto

LivelloSignificato
okNessuna segnalazione scattata
reviewAlmeno una segnalazione di gravità review
suspectAlmeno una segnalazione di gravità suspect

Scavalcare le soglie

yaml
keystroke_logging:
  detection:
    thresholds:
      paste_dominant.pasted_fraction: 0.4
      silent_insertion.ratio: 0.25
      transcription_rhythm.iki_log_cv: 0.05
      transcription_rhythm.revision_ratio: 0.02
      transcription_rhythm.pause_2s_per_100_chars: 0.5
      offscreen_composition.blur_ms: 15000
      offscreen_composition.insert_chars: 100
      implausible_speed.chars_per_min: 1000

Le soglie sono valutate lato server e non vengono mai inviate al browser. Pubblicarle direbbe a un annotatore con quanta lentezza esattamente incollare per restare sotto la segnalazione.

Livello 2: calibrazione sul progetto

Le caratteristiche dei tasti variano molto a seconda del compito di scrittura (Conijn et al. 2019), e soglie fisse su una quantità distribuita come miscela sono distorte (Roeser et al. 2021). Una soglia che funziona per una motivazione di una frase è sbagliata per un saggio di cinque paragrafi.

La calibrazione fissa ogni soglia su un percentile di coda delle sessioni del tuo progetto.

bash
# Inspect the fit without saving it
python -m potato.typing_detect calibrate config.yaml --dry-run
 
# Save it
python -m potato.typing_detect calibrate config.yaml
yaml
keystroke_logging:
  detection:
    calibrate: true    # use the saved fit

La calibrazione richiede almeno 30 sessioni utilizzabili (80 caratteri o più, non da mobile). Al di sotto restituisce insufficient_data e restano in vigore i valori predefiniti.

Attenzione: una soglia percentilica è una definizione relativa di valore anomalo. Per costruzione segnala all'incirca tail_fraction (5% per impostazione predefinita) delle sessioni anche in una popolazione dove nessuno sta facendo niente di male. Ti dice dove guardare per primo. Non è una prova. Le soglie calibrate sono inoltre limitate entro 3x i valori predefiniti incorporati, così una popolazione omogenea non può trascinare una soglia sulla propria mediana e cominciare a segnalare annotatori onesti.

Un thresholds: esplicito prevale sempre su un valore calibrato, che a sua volta prevale sempre sul valore predefinito incorporato.

Livello 3: classificatore supervisionato

Se hai sessioni etichettate, addestra un modello vero:

python
from potato import typing_store
from potato.typing_detect import fit_supervised
 
rows = typing_store.feature_matrix(task_dir, project)
labels = [...]   # 1 = non-composed, 0 = composed
 
result = fit_supervised(rows, labels, model="random_forest")
print(result["cv_accuracy_mean"], result["feature_importances"])

Richiede scikit-learn, che viene importato in modo lazy e non è una dipendenza di Potato.

Ottenere etichette senza uno studio esterno

La fase di addestramento di Potato può generarle per te. Chiedi agli annotatori di copiare un passaggio fornito come compito di riscaldamento. Le loro sessioni di copiatura sono esempi genuini di trascrizione e le loro risposte normali sono esempi di composizione: ne esce un insieme etichettato dall'interno del tuo progetto, sul tuo compito, con i tuoi annotatori. È lo stesso modo in cui Crossley et al. hanno costruito il loro corpus, e l'esempio di calibrazione lo imposta dall'inizio alla fine.

Falsi positivi

Il modo in cui questa funzionalità fallisce è accusare un annotatore onesto. Questi sono i casi che somigliano legittimamente ai pattern descritti sopra.

SituazioneA quale regola somigliaCome la gestisce Potato
Citare il passaggio in annotazionepaste_dominant, silent_insertion, offscreen_compositionSoppressa tramite paste_source: instance_text
Spostare la propria bozzaLe stesseSoppressa tramite paste_source: self
Digitare su telefono o tabletsilent_insertionSoppressa tramite virtual_keyboard
Input non latino tramite IMEsilent_insertionSoppressa tramite composition_events
Dattilografo veloce e sciolto, stesura pulitatranscription_rhythm, implausible_speedRegole congiuntive; review e non suspect; calibrazione
Risposte molto brevitranscription_rhythmSaltata sotto gli 80 caratteri / 40 battute
Dettatura o riconoscimento vocalesilent_insertionNon gestita. Farà scattare la segnalazione. Escludi quegli annotatori o alza la soglia.
Screen reader e alcune tecnologie assistivesynthetic_inputNon del tutto gestita. Alcuni strumenti producono eventi non attendibili.
Correzione automatica su mobilesilent_insertionIn parte. insertReplacementText conta come esterno.
Estensioni del browser come gli strumenti grammaticalisilent_insertion, synthetic_inputNon gestita. Farà scattare la segnalazione.

Gli ultimi quattro sono limiti reali, non sviste. Se il tuo gruppo di partecipanti comprende persone che usano la dettatura, tecnologie assistive o estensioni per la scrittura, o togli quelle regole dai tuoi criteri di revisione, o tratti ogni segnalazione come un invito a chiedere all'annotatore anziché ad agire.

Accessibilità

synthetic_input si basa su isTrusted, che anche alcune tecnologie assistive fanno scattare. Segnalare un annotatore con disabilità perché usa gli strumenti di cui ha bisogno per lavorare è un esito inaccettabile.

Quella regola non ha soglia, quindi non c'è alcun valore che tu possa impostare per renderla irraggiungibile. Se il tuo studio è aperto a chi usa tecnologie assistive, o escludi synthetic_input dai criteri di revisione che metti per iscritto, o disattivi del tutto il rilevamento e analizzi da te le caratteristiche esportate:

yaml
keystroke_logging:
  enabled: true
  detection:
    enabled: false

Le regole basate su soglia si possono rendere irraggiungibili impostando un valore assurdo, per esempio implausible_speed.chars_per_min: 1000000.

Intervento in tempo reale

yaml
keystroke_logging:
  detection:
    on_external_insert: flag   # allow | warn | block | flag
ValoreComportamento
allowNon fa nulla oltre a registrare
warnAvviso non bloccante sugli incollaggi esterni, ma non sulle citazioni proprie o del passaggio
blockImpedisce incollaggio e drop nei campi strumentati
flagPredefinito. Registra in silenzio; decidi dopo

block è uno strumento grossolano. Blocca anche le citazioni legittime, e un partecipante determinato può sempre ridigitare. Usare flag e poi rivedere di solito è meglio.

Dashboard di amministrazione

Il pannello Processo di scrittura, sotto la scheda Comportamentale della Dashboard di Amministrazione, mostra mediane per annotatore, tassi di incollaggio, tassi di inserimento silenzioso e ogni sessione segnalata con le relative prove.

Riporta writing_process_risk, la quota di sessioni di un utente che hanno fatto scattare ciascuna segnalazione, pesata verso i segnali con la spiegazione innocente meno plausibile. È un ausilio all'ordinamento, tenuto deliberatamente separato dal suspicion_score esistente, così che nessuno dei due numeri cambi in silenzio il significato dell'altro.

Basi di ricerca

Ogni citazione qui sotto è verificata sul registro Crossref o DataCite.

Crossley, Tian, Choi, Holmes e Morris (2024) hanno raccolto 500 saggi argomentativi, li hanno fatti trascrivere da altri lavoratori e hanno separato l'autentico dal trascritto con un'accuratezza del 99% usando una random forest (96-98% per altri modelli). Le loro famiglie di caratteristiche sono ciò che Potato cattura: tempi di pausa prima delle frasi e delle parole, conteggi di inserimenti e cancellazioni, rapporti prodotto/processo, raffiche, revisione e varianza del processo. Il loro risultato è l'obiettivo di progetto. La scrittura autentica mostra pause più lunghe, più inserimenti e cancellazioni e una varianza maggiore; la trascrizione è lineare e procede a raffiche.

Deane, Zhang, Hao e Li, e separatamente Zhang, Feng, He, Li e Zhu, confermano in modo indipendente la separazione fra copiatura a macchina e scrittura naturale, i secondi con un modello di deep learning. Asher, Gold, Chen e Carvalho è il caso specifico del crowdsourcing: uno strumento di registrazione dei tasti su Prolific che segnala i partecipanti che incollano nei campi di risposta o il cui conteggio di battute è anomalamente basso rispetto alla lunghezza della risposta.

Per le misure di processo sottostanti, vedi Leijten e Van Waes (Inputlog) per le misure di log standard, Chenoweth e Hayes per il costrutto di raffica, Conijn, Roeser e van Zaanen per la dipendenza dal compito delle caratteristiche dei tasti, e Roeser, De Maeyer, Leijten e Van Waes per il motivo per cui le soglie di pausa fisse sono distorte.

References

  1. Crossley, S., Tian, Y., Choi, J. S., Holmes, L., & Morris, W. (2024). Plagiarism Detection Using Keystroke Logs. EDM 2024 (Short Papers). doi:10.5281/zenodo.12729864
  2. Deane, P., Zhang, M., Hao, J., & Li, C. Using Keystroke Dynamics to Detect Nonoriginal Text. Journal of Educational Measurement, 63(1). doi:10.1111/jedm.12431
  3. Asher, M. W., Gold, G., Chen, E., & Carvalho, P. F. (2026). Chatbots Are Undermining Crowdsourced Research in the Behavioral Sciences: Detecting Artificial Intelligence-Assisted Cheating With a Keystroke-Based Tool. Advances in Methods and Practices in Psychological Science, 9(1). doi:10.1177/25152459261424723
  4. Zhang, M., Feng, L., He, X., Li, C., & Zhu, M. (2026). Disentangling copy typing and natural writing behaviors using keystroke logs and deep learning model. Assessing Writing. doi:10.1016/j.asw.2026.101070
  5. Leijten, M., & Van Waes, L. (2013). Keystroke Logging in Writing Research: Using Inputlog to Analyze and Visualize Writing Processes. Written Communication, 30(3), 358-392. doi:10.1177/0741088313491692
  6. Chenoweth, N. A., & Hayes, J. R. (2001). Fluency in Writing: Generating Text in L1 and L2. Written Communication, 18(1), 80-98. doi:10.1177/0741088301018001004
  7. Conijn, R., Roeser, J., & van Zaanen, M. (2019). Understanding the keystroke log: the effect of writing task on keystroke features. Reading and Writing, 32(9), 2353-2374. doi:10.1007/s11145-019-09953-8
  8. Roeser, J., De Maeyer, S., Leijten, M., & Van Waes, L. (2021). Modelling typing disfluencies as finite mixture process. Reading and Writing. doi:10.1007/s11145-021-10203-z
  9. Lee, M., Liang, P., & Yang, Q. (2022). CoAuthor: Designing a Human-AI Collaborative Writing Dataset for Exploring Language Model Capabilities. CHI 2022. doi:10.1145/3491102.3502030

Ulteriori Letture

Per i dettagli di implementazione, consulta la documentazione sorgente.