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
| Livello | Che cos'è | Servono dati etichettati? | Predefinito |
|---|---|---|---|
| 1. Regole | Sei segnalazioni con nome, soglie esplicite e prove visibili | No | Attivo |
| 2. Calibrazione | Soglie ritarate sugli annotatori del tuo progetto | No | Disattivo |
| 3. Supervisionato | Un classificatore che addestri sulle tue etichette | Sì | Disattivo |
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 metronomicorevision_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
| Livello | Significato |
|---|---|
ok | Nessuna segnalazione scattata |
review | Almeno una segnalazione di gravità review |
suspect | Almeno una segnalazione di gravità suspect |
Scavalcare le soglie
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: 1000Le 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.
# 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.yamlkeystroke_logging:
detection:
calibrate: true # use the saved fitLa 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:
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.
| Situazione | A quale regola somiglia | Come la gestisce Potato |
|---|---|---|
| Citare il passaggio in annotazione | paste_dominant, silent_insertion, offscreen_composition | Soppressa tramite paste_source: instance_text |
| Spostare la propria bozza | Le stesse | Soppressa tramite paste_source: self |
| Digitare su telefono o tablet | silent_insertion | Soppressa tramite virtual_keyboard |
| Input non latino tramite IME | silent_insertion | Soppressa tramite composition_events |
| Dattilografo veloce e sciolto, stesura pulita | transcription_rhythm, implausible_speed | Regole congiuntive; review e non suspect; calibrazione |
| Risposte molto brevi | transcription_rhythm | Saltata sotto gli 80 caratteri / 40 battute |
| Dettatura o riconoscimento vocale | silent_insertion | Non gestita. Farà scattare la segnalazione. Escludi quegli annotatori o alza la soglia. |
| Screen reader e alcune tecnologie assistive | synthetic_input | Non del tutto gestita. Alcuni strumenti producono eventi non attendibili. |
| Correzione automatica su mobile | silent_insertion | In parte. insertReplacementText conta come esterno. |
| Estensioni del browser come gli strumenti grammaticali | silent_insertion, synthetic_input | Non 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:
keystroke_logging:
enabled: true
detection:
enabled: falseLe regole basate su soglia si possono rendere irraggiungibili impostando un valore assurdo, per esempio implausible_speed.chars_per_min: 1000000.
Intervento in tempo reale
keystroke_logging:
detection:
on_external_insert: flag # allow | warn | block | flag| Valore | Comportamento |
|---|---|
allow | Non fa nulla oltre a registrare |
warn | Avviso non bloccante sugli incollaggi esterni, ma non sulle citazioni proprie o del passaggio |
block | Impedisce incollaggio e drop nei campi strumentati |
flag | Predefinito. 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- Registrazione dei tasti - che cosa viene catturato e come
- Etica della registrazione dei tasti - IRB, consenso, diritti dei partecipanti
- Controllo della Qualità - verifiche di attenzione e standard gold
- Dashboard di Amministrazione - il pannello Processo di scrittura
Per i dettagli di implementazione, consulta la documentazione sorgente.