Skip to main content

Developer blog

How the AI Model Works, and the Work That Went Into It

A 1.38M-parameter System-1 workflow executor that runs entirely in the browser, how it was trained on 526 scripted-teacher steps, and what its evaluation numbers do and do not prove.

ShareLinkedIn
AImachine learningONNXworkflow automationprivacy techin-browser ML
On this page
  1. A reflex, not a reasoner
  2. What the model actually does
  3. Where the training data came from
  4. The training run
  5. The evaluation gates
  6. The build around it
  7. Why this matters beyond one tool

Key takeaways

  • A 1,382,017-parameter transformer encoder picks the next workflow action from a valid-action menu, running fully client-side via ONNX in the browser. The request counter reads 0 cross-origin requests at inference; the weights ship with the page.
  • It was trained on 526 labeled steps generated by a scripted teacher (deterministic code, not an LLM), including adversarial recovery steps that teach the model to recover from corrupted state.
  • The reported gates: 0.9561 in-domain (319 steps), 0.9420 out-of-domain (207 steps), menu-permutation drift 0.00. Read the evaluation section before citing these numbers: what they measure, and what they do not, matters more than the digits.

A reflex, not a reasoner

Here is the architectural bet behind the data-mapping assistant. The job of guiding someone through a data-mapping workflow does not need System-2 reasoning. Nobody is asking the model to debate privacy law or weigh competing interpretations. The job is: given the current state of the workflow and a menu of valid next actions, pick one. That is a reflex. For a client-side tool, a small, fast, well-trained reflex has real advantages on the axes that matter: latency, cost, and privacy. (No latency or cost measurements are published for this build; the privacy property is architectural and stated as such below.)

Most “AI features” reach for the biggest model available and ship an API call. The assistant does the opposite. The model behind it is a tiny transformer encoder, 4 layers, d_model 128, 4 attention heads, plus a pointer head over the action menu. Total: 1,382,017 parameters. It is exported to ONNX (opset 17, no control-flow or custom ops) and runs in the browser with onnxruntime-web. The weights are vendored with the page (same-origin model.onnx plus its .data sidecar, fetched once at load); the live request counter on the page counts cross-origin requests and reads 0 from the first tap to the final Excel download, because nothing leaves the machine. A phone can run it. A laptop with the Wi-Fi off can run it. Your workflow data never leaves your machine, which is the only defensible posture for a tool aimed at privacy professionals.

What the model actually does

One thing at a time, and it does exactly one thing. The model never sees a fixed action list. At each step it receives the tokenized workflow state plus the valid-action menu, encoded per the frozen token schema (encoding version 1.0.0): token ids (16-bit id width, not a 65k vocabulary; the effective vocabulary is far smaller) paired with per-token field objects (canonical JSON describing each token’s role), plus the menu with variable-length masking so only valid slots can win. It outputs a distribution over menu slots. The argmax is the chosen action.

The part that makes this interesting: action names arrive in the input. They are embedded through a stable string hash, not looked up in a fixed vocabulary. Be precise about what that buys. It does not teach the model the meaning of a name it has never seen; a hash preserves no semantics. What it buys is architectural: there is no fixed output layer to retrain when the vocabulary changes. New recipes, new action names, same weights. The model never learned “slot 3 means add-vendor” as a position or an id, because the pointer-head design makes position-learning impossible: permuting the menu permutes the output distribution identically, so the argmax is preserved by construction. That is worth stating plainly because it cuts both ways, as the evaluation section shows.

It is also worth stating the limits plainly, because a reflex that pretends to be a planner is how demos turn into incidents. The model picks among the actions it is given; it cannot invent actions. It is one step at a time, no lookahead, no plan. Its recovery behavior is only as good as the corrupted sessions in training. And any change to the token encoding version requires retraining from scratch. These are not footnotes. They are the reason the executor is paired with a frozen spec and a verified menu, and the reason the chatbot narrates what is happening instead of silently executing.

Where the training data came from

No LLM labels anything in this pipeline. The teacher is deterministic code, and “reasoning” is the wrong word for what it does: it amortizes the state-to-action mapping once, before training, by generating demonstrations of correct workflow behavior.

The full dataset is public at huggingface.co/datasets/movahedi-ca/ai-data-map-teacher: 526 labeled steps in 33 shards (one shard per recipe scenario, 33 recipes). Three hundred nineteen of those steps are data-mapping demonstrations. Two hundred seven are spread across 10 out-of-domain domains, which exists so that generalization can be measured rather than asserted. The model card reports 152 steps, 29 percent of the set, as adversarial recovery sessions: flag, undo, skip, abort. Corrupted states are fed in on purpose so the model learns the recovery moves, not just the happy path. (One provenance note: the dataset card states corrupted steps carry no separate flag, so treat the 152 as the model card’s accounting, not as something you can recount from the shards.) Anyone who has watched a workflow tool fail has watched it fail on the mess, not on the clean case. The training data reflects that.

 state + action menu          tokenized (schema 1.0.0)
─────────────────────  ──►  ─────────────────────────
 token ids (16-bit width)       4-layer encoder
 per-token field objects        d_model 128, 4 heads
 action names in the input      pointer head over
 embedded via stable            menu slots (masked)
 string hash
                                ──► argmax = next action

The training run

The model is small enough that the training story is almost comical. The plan was a Kaggle GPU; the Kaggle account required phone verification to enable GPU, so training ran on CPU instead. It finished in under a minute: 12 epochs, batch size 256, learning rate 3e-4. That is at most 36 optimizer steps on 526 examples, which tells you something honest about the task: the scripted teacher’s mapping is highly regular, bordering on memorizable. Cheap retraining is a virtue (you can re-run after every spec change without a budget meeting), but fast convergence also tempers any grand story about what was learned. Both things are true.

Final train loss 0.2145 (reported without a baseline; treat it as a training diagnostic, not a quality claim). Validation accuracy 0.9375 on 48 held-out steps, split by recipe id so the model cannot memorize its way across the split. The ONNX export was verified against the PyTorch original in Python runtimes: max absolute difference of 1.19e-06 on a sample batch. That check ran torch against Python onnxruntime, not onnxruntime-web in a browser, so do not read it as a claim about every phone’s WASM backend. What matters for correctness is argmax parity, and the deployed behavior is what the page’s own testing covers.

The evaluation gates

The public model card reports three gates, all passed. Here they are with denominators, and then what they do and do not prove.

First, in-domain menu-choice accuracy: 0.9561 on 319 steps (305 correct), gate 0.85.

Second, out-of-domain accuracy: 0.9420 on 207 steps (195 correct), gate 0.60, described as unseen domains with unseen action names.

Third, menu-permutation drift: 0.00 (tolerance 0.10), where drift is the absolute accuracy change when the menu order is shuffled. As noted above, a pointer head is permutation-equivariant by construction, so treat this as an implementation check (the code does what the architecture promises), not as evidence the model learned restraint.

Now the honest reading, because the counts invite it: 319 and 207 are exactly the training split sizes (319 + 207 = 526). The model card labels these “held-out results” and points to a public eval-report.json, but the public artifacts do not fully specify the eval split, and a careful reader will notice the coincidence. The unambiguous held-out number in this build is the 48-step recipe-split validation at 0.9375. So cite the gates as the project’s reported results, and cite 0.9375 as the clean generalization number; do not present 0.9561/0.9420 as independent generalization proof without that qualification. The eval harness and report are public for anyone who wants to check.

Two more qualifications the article owes you. The “unseen action names” claim is softer than it sounds: the shared recovery vocabulary (flag, undo, skip, abort) appears across domains by design, so some OOD names were seen in training under other domains. And the hashed-name mechanism explains why the architecture runs on new vocabularies, not why it picks correctly: the accuracy comes from regularities the model learned in the state encoding across the teacher family, not from the hash. Ten domains from one scripted teacher family is real evidence of vocabulary substitution inside a structural family, not of transfer across genuinely different workflow styles. The gates were set before the runs (0.85, 0.60, 0.10 tolerance are in the frozen spec), which is good practice, but pre-registered gates do not rescue an underspecified eval split. All of this is checkable from the public artifacts, which is exactly why it is stated here.

The build around it

The model is one part of a phased build plan (Phase 0 through Phase 7), and the surrounding work is why any of these numbers mean anything. Phase 0 froze the specs. Before a single training step, there was a 427-entry vendor knowledge base and a subprocessor graph with 87 companies, 1,499 nodes, and 2,518 edges. Phase 4 built the scripted teacher and the dataset. Phase 5 trained. Phase 6 put the executor in the browser. Phase 7 wrapped it in the chatbot and the MCP server, the execute_mapping_workflow tool that lets other agents drive the same workflows the model executes.

Everything the model depends on is pinned. The token schema is versioned at 1.0.0. Change the encoding and you retrain; there is no silent drift. The ONNX graph has no control flow and no custom ops, so onnxruntime-web runs it anywhere without surprises. The weights are public under the MIT license at huggingface.co/movahedi-ca/s1-workflow-tiny, and the code is at github.com/movahedi-ca/AI-data-map, also MIT.

Why this matters beyond one tool

The interesting question is not whether a 1.38M-parameter model can drive a data-mapping workflow. The evaluation says it can, with the qualifications above. The interesting question is how many other workflows are reflex-shaped.

Think about what an agentic workflow actually spends its tokens on. A large model reads the state, reads the menu, reasons about which action is right, and outputs a token that names it. Most of that reasoning is overhead for a task with a bounded answer set. The System-1 design inverts it: the menu is part of the input, the choice is a pointer, and the state-to-action mapping is amortized once, in the scripted teacher, before training. At runtime there is no reasoning step because there is nothing to reason about. The valid actions are enumerated. The state is encoded. The answer is an argmax.

That does not replace large models. It scopes them. Use the big model where the answer set is unbounded: drafting, explaining, handling the genuinely novel case. Use the reflex where the answers are a menu and the state is structured. The privacy properties follow from the architecture: nothing to send, nothing to log, nothing to leak, because there is no server in the loop at all.

There is an open thread I am leaving on the table on purpose. The out-of-domain result covers ten domains, all generated by the same scripted teacher family. That is evidence of generalization across action vocabularies within one structural family, not across teacher styles, and nobody has published a number for how far the hashed-menu trick stretches before it breaks. The weights are public, the dataset is public, the eval report is public, and a full training run costs less than a minute of CPU time. Somebody should find out.