A VERNACULAR VITALS PROJECT
ClinicalTypingLab

How AI Mode works

AI Mode is a statistical model of your typing, not a black box. It estimates what each key transition should cost you, measures what it actually costs, and drills the difference. This page shows the equations and the choices behind them.

keystrokesvalidity filter aggregatestransitions · starts · errors personal fitgeometry + key effects residualsshrunk, ranked by lane drill setreweights the sampler the next session updates the model; old evidence fades (×0.92 per session)
Everything runs in the browser, after every session.

Is it AI?

It is adaptive and it learns from your data, which is what the name is meant to convey, but there is no neural network. The engine is a regularized linear model plus Bayesian-style shrinkage, chosen deliberately: with a few thousand keystrokes per person the honest thing to do is to be explicit about prior knowledge and to report uncertainty, and a linear model can be read back to you line by line. The Progress tab is the model printed out.

1. What gets measured

Every keystroke the trainer processes is time-stamped. For a keystroke to count as a transition u = (previous character, this character), it must be correct, follow a correct keystroke that immediately precedes it in the stream, and arrive between 30 and 2000 ms after it. Anything faster is not a human keystroke; anything slower is a pause, not a transition cost. Retries after an error in Block mode and keystrokes after a backspace are excluded, so error recovery does not contaminate speed. The first keystroke of a term after the separator dot is recorded separately as recall time, because it mixes reading and retrieval with motor speed. Mistypes are recorded as (expected, typed) pairs together with the preceding character and the word they occurred in.

Only aggregates are stored: for each transition, the count nu, the sum of log latencies, and the sum of squared log latencies. Log latency is used throughout because keystroke intervals are right-skewed and multiplicative: a 20 percent slowdown means the same thing at 150 ms as at 400 ms. When a session closes, every count is multiplied by 0.92, so evidence has a half-life of about eight sessions: a weakness you fix stops being drilled within a few sessions instead of haunting you for months, and the counts behave as effective sample sizes in everything below.

2. Expected cost: keyboard geometry as a prior

The central idea is that a hard transition is not a weakness. Reaching to the number row, typing a shifted symbol, or moving the same finger across two rows is slow for everyone. So each transition gets an expected cost from a small feature model:

E[lnLu]=b+xu·β

where b is your own median log transition time and xu is a vector of geometry features on a US QWERTY layout: same finger, same key, same hand, rows travelled, same-finger reach, shift required, digit, symbol, previous key was a digit or symbol, space bar involved, and the familiarity of the pair as an English digraph. The coefficients β0 start from values that encode well-replicated regularities of transcription typing (same-finger transitions are slow, hand alternation is fast, shifted and top-row keys are slow, familiar digraphs such as th and er are fast). Because b is your own median, the model is normalized within you: a slow typist and a fast typist get the same structure scaled to their own speed.

3. Personal fit

Your data then pulls the coefficients toward your own technique with a ridge penalty:

β^=argminβuwu(y¯ubxu·β)2+λββ02

The weights wu are the observation counts, capped at 30 so that one very common pair cannot steer the whole fit, and λ = 40 sets how much evidence it takes to move a coefficient away from the prior. With little data the fit is essentially the prior; with a few thousand transitions it is essentially yours. The fitted coefficients are shown in the Progress tab as "Technique," for example that same-finger transitions cost you 48 percent extra where the prior expected 38.

The same fit carries one effect per physical key, for the key being reached and for the key being left, each shrunk toward zero with its own penalty (λkey = 60). This is partial pooling: a slow reach into p is learned from every transition that ends on p, so it can be detected after a couple of thousand keystrokes even though any single pair ending on p has been typed only a handful of times. Simulations with a planted slow key found it first in ten of ten runs at 2,500 keystrokes; isolated slow pairs need more exposure, which is why key-level findings usually appear before pair-level ones.

4. Residuals, shrinkage, and lanes

4 → 5r → tt → h observed 310 ms · expected 300 msdeficit +3%: slow, but normal for digits observed 260 ms · expected 190 msdeficit +37%: a personal weakness observed 150 ms · expected 160 msdeficit −6%: a strength lighter bar: what you did · darker bar: what the model expects for you on that pair
Only the gap between the bars counts. Hard keys are expected to be slow.

The residual of a transition is what is left after the model has explained it. It is then shrunk toward zero in proportion to how much evidence supports it:

ru=y¯ubxu·β^,r^u=nunu+kru,deficit %=100(er^u1)
012 (= k)2436n 1.00.50 at n = k the residual counts half
Shrinkage keeps a lucky (or unlucky) handful of keystrokes from becoming a "weakness."

With k = 12, a transition seen 12 times keeps half of its raw residual, and one seen 60 times keeps five sixths. A pair you have typed four times cannot become a "weakness" on the strength of one bad moment. Before ranking, any lane-wide offset the coefficients did not absorb is subtracted (it is reported as technique instead), and a pair enters the drill set only if its raw residual is at least 1.5 standard errors above zero. Residuals are ranked within lanes (letter transitions, numbers, symbols, capitals, recall, mistypes) and the Progress tab shows the top of each lane rather than one global list, so digits and symbols, which carry larger residual variance, cannot fill the screen. Each entry states the observed and the expected time, the percentage, and the sample size.

5. Mistypes

For each (expected, typed) pair the engine tracks the count, the conditional rate, the most common preceding character, and example words. Pairs are ranked by count and by lift over your overall error rate:

lift(et)=P(typedt|expectede)P(any error)

A lift of 3 means you make that particular substitution three times as often as you make errors in general. When a mistype has a clear preceding context and a lift above 2, the transition (preceding character → expected character) joins the drill set even if its timing is fine, because accuracy and speed are separate problems. Error recovery cost, the time from the first wrong key until the cell is typed correctly, is reported separately.

6. Recall versus motor speed

The first keystroke of a term is compared with your typical transition time inside words. A large gap on a particular term means you were retrieving its spelling rather than fumbling keys; a large gap on a whole category (say, brand drugs) suggests vocabulary practice, not key drills. Terms whose start is at least 25 percent slower than your own typical start, over at least three occurrences, can enter the drill set as recall targets.

7. The drill set and the stream

After each session the engine selects at most eight transitions with a shrunk residual above 0.08 (about 8 percent slower than expected), at least five observations, and a t-statistic of at least 1.5, with lane caps of four letters, two numbers, two symbols, and one capital, plus up to two keys whose reach costs at least 13 percent extra and up to three recall targets. A transition drilled in two consecutive sessions is rested for two sessions and then retested, so improvement is verified by spacing rather than assumed.

Each item in the corpus gets a density di, the fraction of its transitions that are drilled (or that land on a drilled key), and a sampling multiplier proportional to it:

mi=1+c·di,f(c)=iwimidiLiiwimiLi

The constant c is solved per category by bisection so that the expected fraction of typed transitions that land on a drilled unit, f, rises from its natural value f0 to min(0.25, max(3 f0, f0 + 0.03)), with every multiplier capped at 8. Items that contain none of the drilled units keep a multiplier of exactly 1, so the trainer still generates fresh text from the whole corpus rather than repeating a few words; the strip above the trainer shows the natural and the achieved fraction. In the live app, turning AI Mode on roughly doubles the rate at which the drilled transitions appear (for example 1.4 percent of keystrokes to 3.1 percent in an end-to-end test).

8. Session quality

Each session is screened for the signatures of human typing before it counts toward anything shared: a median interval above 60 ms, realistic variance, slower keystrokes after errors, hesitation at word starts, a plausible words-per-minute range, and keydown events that match input events (which rules out pasting). Sessions that fail are flagged in the Progress tab and would be excluded from a shared baseline; they still count locally, because the person typing is the only one they could mislead.

9. Cohort baseline (when accounts arrive)

With enough consenting users, the structural prior for each transition is blended with what other people actually do:

du=k·su+j=1nuzu,jk+nu

where su is the structural prediction, zu,j is user j's within-user normalized mean for that transition (each person counts once, regardless of how many sessions they upload), and k is a pseudo-count. With five contributors the baseline is mostly the structural model; with five hundred it is mostly observed. Units with fewer than eight distinct contributors are not used. The baseline is a prior only: your own data always drives your own drill set, so a bad contributor can nudge the reference but cannot steer anyone's practice. Contribution is on by default for signed-in users and can be turned off in the Progress tab.

Limitations

The geometry model assumes a US QWERTY layout; on other layouts the prior is wrong in places and the personal fit has to do more work. Latency is measured between keydown events in the browser and includes rendering delay on slow devices, which is why comparisons are always within you. The prior coefficients are informed starting points, not measurements from this site, until enough users contribute to recalibrate them. And the tool measures transcription typing of synthetic clinical text; it does not measure the composition of a real note.

Source for all of this is served unminified under /ai/ on this site: geometry.js, engine.js, and progress.js.

More from ClinicalTypingLab