Technical write-up · Lingways

Teaching Spanish by construction.

Lingways is a Spanish-learning platform built on computational Construction Grammar rather than vocabulary lists. This note describes how the engine represents what a learner knows, chooses what to teach next, and measures progress — at the level of design, not implementation.

Why constructions, not words

Fluency is the ability to produce and understand form–meaning pairings, not the size of a word list. Construction Grammar (CxG) treats grammar as an inventory of such pairings, from morphemes to idioms to argument-structure patterns. A learner who knows me gusta as a construction with a dative experiencer slot can generalize to nos interesa on first contact; a learner who memorized the phrase cannot.

Most apps model the learner as a set of known words and a difficulty score. Lingways models the learner as a partial copy of a construction inventory, with a separate strength for each construction and for each of the semantic and pragmatic frames it participates in. Everything downstream — flashcard scheduling, which article the Reader surfaces, what the guide says next — reads from that representation.

The bet is that construction-level modeling gives three things word-level modeling cannot: transfer (one construction licenses many sentences), diagnosability (an error localizes to a construction, not a word), and dialect sensitivity (the same frame is realized differently in Mexico City and Madrid, and the model keeps them apart).

The construction layer

The current inventory holds 42 constructions, 26 semantic/pragmatic frames, and 5 dialect variants, hand-built and intended to grow. Each construction record carries:

FieldWhat it holdsExample
FormSlot structure with morphosyntactic constraints per slot[EXPERIENCER.dat] gustar [STIMULUS.nom]
FramesThe semantic/pragmatic frames the construction evokesLiking, Evaluation
Dialect variantsRealizations that differ by region, with register notesvosotros vs ustedes forms
DependenciesConstructions a learner should hold firstclitic pronouns, present indicative
Cost vectorPer-component difficulty across morphology, lexicon, syntax, semantics, pragmaticssee Target Model generation

Lexical grounding comes from a 794K-entry Spanish lexicon indexed in Typesense, so a construction slot can be filled with real, frequency-ranked candidates at query time. Dialect commitments were shaped in part by work alongside Tzotzil-speaking colleagues, which is why variant tracking is a first-class field rather than a flag.

The NLP service (Python, FastAPI, Stanza) parses learner input and reading material into dependency structure, then matches spans against construction form templates. A match is a signal about one construction, not about a sentence.

Target Model generation

Given a learner's current inventory and a goal — a situation, register, or dialect they want to operate in — the engine builds a Target Model: the smallest set of constructions that closes the gap, ordered so each one is learnable from what came before.

The search runs breadth-first over the construction dependency graph from the learner's frontier. Each edge carries a cost vector rather than a scalar: morphology, lexicon, syntax, semantics, and pragmatics load are tracked separately, and the learner's own component-level weaknesses weight them. The result is a distance vector between current and target competency, not a single difficulty number. Two learners with the same total distance can get different Target Models because the shape of the distance differs.

That vector drives three consumers today:

  1. The flashcard deck (three activity types, scheduled by FSRS with construction-level weighting).
  2. The Reader, which surfaces articles whose construction profile sits just beyond the frontier.
  3. The animal guides — LLM-rendered tutors that explain the next construction in the voice of one of the guide characters.

The exact edge-cost formulation and the pruning rules are the part I keep out of public write-ups. The structure — a BFS over a typed construction graph with vector costs — is the part worth discussing.

Measuring fluency

Comprehension and production are tracked as independent strengths per construction. A learner who reads se me olvidó correctly but never produces it has one score high and the other low, and the Target Model treats those as different gaps with different exercises. Collapsing them into one mastery number is the most common modeling error in language apps, and the one the construction layer makes easiest to avoid.

Every interaction writes one row to a minimal event schema:

{user_id, construction_id, frame_id, modality, source, signal, latency, timestamp}

modality is comprehension or production; source is which surface produced the event (deck, reader, guide chat); signal is the graded outcome. The schema is deliberately small so that every new activity type can emit it without a migration.

On top of the event stream, the knowledge-tracing layer is in progress. The MVP uses per-construction Bayesian updates. The next design is a hybrid: an attention-based sequence encoder over a learner's interaction history, feeding per-skill Bayesian heads, so the model keeps interpretable per-construction mastery estimates while borrowing strength across related constructions. Cross-construction propagation through the frame graph is deferred until there is enough interaction data to fit it honestly.

Architecture

One stateless Python service sits between the API and the stores React Native / Expo app Node / Express API on Renderauth, decks, reader, interaction events Python / FastAPI NLP serviceStanza parsing and construction matchingTarget Model generation (BFS, cost vectors)knowledge tracing parse, plan SupabasePostgres + pgvector Typesense794K-entry lexicon Upstash Rediscache, queues Cloudflare R2media and audio Muxvideo
Lingways architecture · client, API, engine, five stores.

The app talks only to the Node API; the API calls the Python engine for parsing and Target Model planning, and both write to the same stores. The engine is stateless per request, so it can be scaled or swapped without touching the app.

Open problems, and what I'm looking for

Three problems I'd most like to work on with someone:

  1. Frame-graph propagation. When a learner strengthens one construction, how much credit should flow to constructions that share a frame? The MVP defers this; the right answer is probably learned, not hand-set.
  2. Construction induction. The 42-construction inventory is hand-built. Mining candidate constructions from corpora (Stanza dependency patterns plus frequency) would let the inventory grow past what one linguist can curate.
  3. Agents as learners. The research program behind Yāska Labs studies how populations of LLM agents develop shared conventions. Running agent populations through the same construction engine, as synthetic learners, is a way to stress-test the Target Model before real users do — and a dataset in its own right.

I'm a solo founder with a background in archaeological science (more here), and I'm looking for an ML/NLP co-founder who wants to own the modeling side of a research-driven product company. Knowledge tracing, LLM agents, or multi-agent simulation experience would all be relevant.

If any of the three problems above made you want to argue, I'd like to hear it.