Liigu sisu juurde

Kaaslane — MATx (Tom Kabel)

matx-hack õpetab modelleerimist — kuidas tekstülesandest saada võrrand. MATx (github.com/tomkabel/MATx) õpetab seda võrrandit lahendama tehniliselt. Kaks naabrit ühes ahelas, mis sobivad loomulikult kokku.

tekst ──▶ mudel (matx-hack) ──▶ võrrand ──▶ lahendus (MATx)

Täielik ülemineku-kaart mikrooskuste vahel — lehel Sild MATx-i.

Kes MATx-i taga seisab

Jaotis «Kes MATx-i taga seisab»

Tom Kabel — autor ja arendaja. Eesti projekt põhikoolile (7.–9. klass). Stack: TypeScript + React (frontend) + Express (API) + Postgres + Drizzle ORM. Hostitud enda taristul aadressil matxdev.duckdns.org.

Koostöö staatus. Kirjutamise hetkel on repositoorium avalik, aga ilma LICENSE-failita. Ekraanitõmmiste ja kirjelduste kasutamine selles õpikus on autoriga Slackis kooskõlastatud. Iga tehniline integratsioon (vt allpool Phase 3) nõuab eraldi PR-i selgesõnalise nõusolekuga.

Tegelikud slug’id andmebaasis on saadud GET /api/topics kaudu — matxdev.duckdns.org/api/topics (avalik endpoint, autentimiseta).

1. abivalemid — Korrutamise abivalemid

Jaotis «1. abivalemid — Korrutamise abivalemid»

Õpi ja harjuta kolme abivalemit: summa ruut, vahe ruut ja ruutude vahe.

Competency (id, nimi)Valem
1 — Summa ruut(a+b)2=a2+2ab+b2(a + b)^2 = a^2 + 2ab + b^2
2 — Vahe ruut(ab)2=a22ab+b2(a - b)^2 = a^2 - 2ab + b^2
3 — Ruutude vahea2b2=(a+b)(ab)a^2 - b^2 = (a + b)(a - b)

Ava topic →

2. protsendid — Protsentarvutus

Jaotis «2. protsendid — Protsentarvutus»

Lahenda protsentülesandeid ristkorrutise meetodil.

Competency (id, nimi)Mida teeb
4 — Osa leidmineLeia osa, kui tervik ja protsent on teada
5 — Terviku leidmineLeia tervik, kui osa ja protsent on teada
6 — Protsendi leidmineLeia protsent, kui tervik ja osa on teada

Ava topic →

3. vorrandid — Ühe tundmatuga võrrandid

Jaotis «3. vorrandid — Ühe tundmatuga võrrandid»

Lahenda võrrandeid samm-sammult, kirjutades välja iga teisenduse.

Competency (id, nimi)Vorm / kirjeldus
7 — Lihtsad võrrandidax+b=cax + b = c
8 — Sulgudega võrrandidVõrrandid, kus tuleb esmalt sulud avada
9 — Murdudega võrrandidVõrrandid, kus tuleb esmalt murrud kaotada

Ava topic →

Lisaks: docs/06-math-topics.md Tom-i juures (teoreetiline kirjeldus); tabelite formaalne skeem — shared/schema.ts.

matx-hack (meie)MATx (Tom)
DomeenModelleerimineArvutamine
Mikrooskused9 (defining T1–T3 × kolm tüüpi suhteid)9 (3 topicut × 3 competency)
Mida õpilane vastabSuuruste avaldised läbi xxNumbriline/sümbolne vastus
Mida jälgibBKT 9 defining-oskuse järgiPer-question results + error categories
StackAstro + React + Next.js (web/)React + Express + Postgres
SihtgruppEesti kool, 7. klassEesti kool, 7.–9. klass
SisukeelET / RU / ENET

Kognitiivselt — meie õpilane lõpetab faasi “saa aru ülesandest ja kirjuta võrrand”, misjärel läheb loomulikult faasi “lahenda võrrand numbrini”. Ilma MATx-ita jääb teine faas meie raamatus sõnaliseks; ilma meieta eeldab MATx, et võrrand on juba kuidagi saadud.

Live dev-instants: matxdev.duckdns.org. Avalikke lehti pole — kasutajakontoga (õpetaja/õpilane) sisselogimine on vajalik. Tom kasutab demo-kontot päringu peale.

Kõige olulisemad vaated (pärast sisselogimist)

Jaotis «Kõige olulisemad vaated (pärast sisselogimist)»
  • /dashboard — Sinu õpitee Õpilase kodu. Kolm teemakaarti (Korrutamise abivalemid / Protsentarvutus / Ühe tundmatuga võrrandid), igal oma oskus% ja edenemine. Soovitatud-tag märgib käesolevat ZPD-eesmärki. Pärast PR-1-e hakkab seda tagi tagant juhtima student_skill_state posterior — praegu on see lihtne % õigeid.
  • /teacher/analytics — Pädevuste soojuskaart Õpetaja hot map: iga rida õpilane, iga veerg mikrooskus, värvid <50% / 50-74% / 75-89% / 90%+. Praegu tuleneb % otse results-tabelist. Pärast PR-1-e on iga lahter Bayesi posterior pKnown, mis on stabiilsem (ei kõigu üksikute attempt’ide peale) ja auditeeritav (igal hetkel saab (prior, isCorrect, params) log’ist taasesitada). Tabid Soojuskaart / Õpilased / Hoiatused katavad erinevaid analüütika-rakurse.
  • /topic/3/practice-flow — praktika-tutorial Step-by-step ülesannete lahendus murdude eemaldamisest võrrandist. See annab tunde, kuidas ülesanne ekraanil välja näeb enne kui õpilane vastust sisestab. PR-1-i createResult on just see endpoint, kus vastus salvestatakse ja BKT-update toimub.

Otselingid topic-lehtedele

Jaotis «Otselingid topic-lehtedele»

Avalik API ilma autentimiseta

Jaotis «Avalik API ilma autentimiseta»

Integratsiooni roadmap

Jaotis «Integratsiooni roadmap»

Phase 1 — raamatu lehed (selles releases tehtud)

Jaotis «Phase 1 — raamatu lehed (selles releases tehtud)»
Jaotis «Phase 2 — cross-links ja deep-links (tehtud)»
  • Inline-kaardid “Companion: MATx” võtmelehetel: pealeht, Multi-skill, Simulaator, Q&A
  • Otselingid kolmele topicule slug’i kaudu + avalik API
  • iframe-embed otsustasime mitte teha: connect.sid läheb SameSite=Lax-iga, seega sisselogitud flow iframe-is ei tööta — ilma selleta on embed kasutu. Parem avada uues vahekaardis.

Phase 3 — BKT-mudel MATx-i submit-handleris (PR-ide plaan)

Jaotis «Phase 3 — BKT-mudel MATx-i submit-handleris (PR-ide plaan)»

Idee. Tõsta meie BKT-matemaatika pure-TypeScript paketti bkt-core (zero runtime deps), Tom lisab selle ühe sõltuvusega ja ühe kutsega storage.createResult-i. Mingit võrgukutset, mingit ML-taristut. Mergitav kahes iseseisvas PR-is.

Mida portime bkt-core-i

Jaotis «Mida portime bkt-core-i»
Allikas matx-hack-isMisMaht
web/lib/microskills.tsTüübid BktParams, MicroSkill, Task, StudentState + konstant DEFAULT_BKT~25 rida, ilma deps-ita
web/lib/bkt.tsbktUpdate, pSolve, ensureMastery, applyAttempt, scoreTaskForStudent, recommend~150 rida, impordib ainult tüüpe

Paketi package.json sisaldab ainult name, main, types, tsc. Mitte ühtegi production-sõltuvust — see on puhas matemaatika.

PR 1 — bookkeeping (miinimum, ~70 rida, UI-d ei muuda)

Jaotis «PR 1 — bookkeeping (miinimum, ~70 rida, UI-d ei muuda)»

Iga vastusekatse uuendab vastava competency BKT suletud valemiga. MATx-i nähtav käitumine ei muutu — andmebaasis ilmub uus väli.

1. Drizzle migration — uus tabel:

CREATE TABLE student_skill_state (
user_id text NOT NULL REFERENCES users(id) ON DELETE CASCADE,
competency_id integer NOT NULL REFERENCES competencies(id) ON DELETE CASCADE,
p_known double precision NOT NULL DEFAULT 0.2,
attempts integer NOT NULL DEFAULT 0,
last_updated timestamp DEFAULT now(),
PRIMARY KEY (user_id, competency_id)
);

Zero-downtime (uus tabel, midagi ei blokeerita). Rakendatakse olemasoleva npm run db:push-iga.

2. shared/schema.ts — lisa tabeli definitsioon (~15 rida):

export const studentSkillState = pgTable("student_skill_state", {
userId: text("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
competencyId: integer("competency_id").notNull().references(() => competencies.id, { onDelete: "cascade" }),
pKnown: doublePrecision("p_known").notNull().default(0.2),
attempts: integer("attempts").notNull().default(0),
lastUpdated: timestamp("last_updated").defaultNow(),
}, (t) => ({ pk: primaryKey({ columns: [t.userId, t.competencyId] }) }));

3. server/storage.ts.createResult (praegune, read 150–152) — lisa upsert pärast insert (~20 rida):

import { bktUpdate, DEFAULT_BKT } from "@matx-hack/bkt-core";
import { studentSkillState } from "@shared/schema";
async createResult(result: CreateResultRequest) {
const [savedResult] = await db.insert(results).values(result).returning();
// — BKT update —
const q = await this.getQuestion(result.questionId);
if (q?.competencyId) {
const [cur] = await db.select().from(studentSkillState).where(and(
eq(studentSkillState.userId, result.userId),
eq(studentSkillState.competencyId, q.competencyId),
)).limit(1);
const prior = cur?.pKnown ?? DEFAULT_BKT.pInit;
const posterior = bktUpdate(prior, result.isCorrect, DEFAULT_BKT);
await db.insert(studentSkillState).values({
userId: result.userId, competencyId: q.competencyId,
pKnown: posterior, attempts: 1, lastUpdated: new Date(),
}).onConflictDoUpdate({
target: [studentSkillState.userId, studentSkillState.competencyId],
set: { pKnown: posterior, attempts: sql`${studentSkillState.attempts} + 1`, lastUpdated: new Date() },
});
}
return savedResult;
}

server/routes.ts (submit-handler readadel 292–345) jääb puutumata — uuendus on inkapsuleeritud storage-kihti.

PR 2 — nutikam soovitus (~80 rida, vabatahtlik)

Jaotis «PR 2 — nutikam soovitus (~80 rida, vabatahtlik)»

Asenda heuristika getNextRecommendedQuestion-is (praegune, read 878–940) BKT-põhise valikuga ZPD-sihtmärgi P(solve)0.7P(solve) \approx 0.7 kaudu.

Praegune loogika — kolm bucketit notStarted / needsWork (mastery < 60%) / progressing (60–90%) valikuga mastery asc järgi — säilib mapping-kihina tagasi Tom-i eestikeelseteks selgitusteks (Harjuta..., Kinnista..., Korda...), et UI/UX ei muutuks. Kapoti all — meie recommend(state, tasks):

import { recommend } from "@matx-hack/bkt-core";
async getNextRecommendedQuestion(userId, topicId) {
const skillStates = await db.select().from(studentSkillState)
.innerJoin(competencies, eq(studentSkillState.competencyId, competencies.id))
.where(eq(competencies.topicId, topicId));
const state = {
student_id: userId,
mastery: Object.fromEntries(skillStates.map(s => [String(s.competency_id), s.p_known])),
history: [],
};
const qs = await db.select().from(questions).where(eq(questions.topicId, topicId));
const tasks = qs.map(q => ({
id: String(q.id),
topic: String(topicId),
microskills: q.competencyId ? [String(q.competencyId)] : [],
difficulty: 0.5, prompt_et: q.text, answer: "",
}));
const top = recommend(state, tasks, 1)[0];
// … map score+pSolve back to existing reason buckets for UX continuity
}

Mis on tehtud, mis on järel

Jaotis «Mis on tehtud, mis on järel»
TükkStaatus
bkt-core paketiks ekstraheerimine✅ Tehtud
tomkabel/MATx-i submodule lisamine✅ Tom tegi ise
PR-1 BKT bookkeeping✅ Mergitud + deploy’tud
PR-2 ZPD-targeted soovitus✅ Mergitud + deploy’tud
PR-3 Defineerimine + 28 ülesannet✅ Mergitud + deploy’tud
PR-4 UI: heatmap pKnown, “Miks soovitatud?”, 10 mock-õpilast✅ Mergitud + deploy’tud
PR-5 audit_trace + sparkline + sortimine✅ Mergitud + deploy’tud
PR-6 õpilase detailvaade + BKT-teavitused + mikrooskuse bookkeeping✅ Mergitud + deploy’tud
PR-7 mikrooskuse UI (detailvaade sektsioon + uus heatmap-tab + mock-seed)✅ Mergitud + deploy’tud
Õpetaja tagasiside-iteratsioon⏳ Käes

Audit-trail EU AI Act jaoks

Jaotis «Audit-trail EU AI Act jaoks»

bktUpdate on suletud analüütiline valem. See tähendab: igal hetkel saab audiitor võtta logist (prior, observation, params) ja iseseisvalt taasesitada posterior. Mingit “black-box” põhjendust pole vaja.

Vabatahtlik: lisa audit_trace JSONB veerg student_skill_state-i — sinna kogunes uuenduste ajalugu (timestamp, prior, isCorrect, posterior) tuplitena. See katab Annex III nõuded traceability + explainability ilma eraldi compliance-taristuta.

Education / vocational training — high-risk Annex III kategooria Regulation (EU) 2024/1689 järgi. Nõuded traceability’le, dokumentatsioonile, human oversight’ile ja explainability’le jõustuvad etapiviisiliselt augustist 2026 kuni augustini 2027.

Meie konveier on juba praegu täielikult deterministlik — production- teel pole ühtegi LLM-kutset:

  • BKT-uuendus — suletud analüütiline avaldis Bayesi järgi.
  • Selgitused — mallimootor (web/lib/explain.ts) fikseeritud fraaside komplektiga.
  • Selektor — argmax mudeli kindluse järgi + topology reeglid (skill-graph).

Pärast Phase 3-e pärib MATx sama profiili automaatselt: üks rida bktUpdate(...) submit-handleris — ja audit-trail järgmise küsimuse otsuse kohta tekib ilma eraldi compliance-taristuta.

Lisaks saab katuse peale lisada eatf.eu — model attestation, response signing, audit ühe API-kutsega — artefaktide tsentraliseeritud salvestamiseks.

  • Progressioonimaatriks — meie 9-mikrooskuse defining-skills mudel.
  • Sild MATx-i — vastavustabel microskill ↔ MATx-competency ja Mermaid-graafik üleminekutest.
  • Selektori simulaator — kuidas BKT valib järgmise defining-mikrooskuse; pärast Phase 3-e viitab ka MATx-competencies’idele.
  • Sõnastik — terminid (microskill, competency, BKT jne).