---
url: https://docs.nemo12.com/architecture/sdd-022-experience-formats.md
description: >-
  Experience Formats (SDD-022): năm dạng câu hỏi ngoài trắc nghiệm, cách chấm,
  lưu blueprint và sức nặng bằng chứng của mỗi dạng.
---

# SDD-022 — Experience Formats

Câu hỏi tài liệu này trả lời: **một câu hỏi trên Nemo12 được phép có những hình dạng nào, mỗi hình dạng chấm ra sao, và bằng chứng từ mỗi hình dạng nặng bao nhiêu.**

## 1. Vì sao không dừng ở trắc nghiệm 4 đáp án

Trước SRC-531, bảng `items` chỉ chứa được đúng một hình dạng: `prompt + options_json + correct_index`. Mọi bề mặt (Luyện tập, Đo giữa/cuối, Học vượt, Diagnosis, Luyện đề) đều chạy trên khuôn đó. Bốn hệ quả, xếp theo độ nặng:

1. **Cây năng lực hứa những thứ 4 đáp án không đo được.** Package tên là *Lập luận và chứng minh*, *Mô hình hoá toán học*, *Giải bài chưa từng gặp* — không ai chứng minh một mệnh đề bằng cách chọn A/B/C/D. Hệ trả "đã vững" cho năng lực chưa từng đo là một lời khẳng định sai, vi phạm nguyên tắc con số đếm từ bằng chứng (REQ-MEN-08 cùng tinh thần).
2. **Nhận ra ≠ làm được.** Kỳ thi vào 10 là tự luận. Trắc nghiệm đo khả năng *chọn trong tập cho sẵn*; khoảng cách giữa "chọn đúng" và "tự viết ra" hệ không nhìn thấy vì chưa bao giờ yêu cầu learner sản xuất.
3. **Sàn đoán mò 25%.** Lớp justification (SRC-070) đỡ một phần nhưng là tự khai.
4. **Khuôn câu hỏi định hình ngược chương trình.** Kỹ năng không nhét vừa 4 phương án dần biến mất khỏi nội dung dù Pearl vẫn ghi tên chúng.

## 2. Năm dạng, và ranh giới cố ý

| `answer_kind` | Dạng | Đo được cái MCQ không đo | Learner làm gì |
| --- | --- | --- | --- |
| `mcq` | Trắc nghiệm (mặc định, mọi item cũ) | — | chọn 1 trong N |
| `numeric` | Nhập đáp số | tự tính ra kết quả, không đoán mò | gõ số / phân số / biểu thức ngắn |
| `estimate` | Ước lượng trong khoảng | cảm nhận độ lớn | gõ một số, đúng khi nằm trong khoảng |
| `order_steps` | Sắp lại các bước lời giải | cấu trúc lập luận | xếp các bước bị xáo về đúng thứ tự |
| `find_error` | Tìm chỗ sai trong bài giải mẫu | soi được lỗi ở lời giải người khác | chọn dòng sai trong một lời giải có chủ ý sai |

Dạng **thao tác trên hình** (yêu cầu thứ năm của chủ dự án) KHÔNG phải một `answer_kind` riêng: nó là `numeric`/`estimate` có `figure` tương tác — engine hình (SDD-010, `apps/learn/src/figures`, `explore/`) đã vẽ được, learner kéo hình rồi hệ đọc giá trị ra thành đáp số. Tách kind riêng sẽ tạo hai đường chấm cho cùng một loại bằng chứng.

**Cố ý không làm đợt này:** chấm văn tự do bằng LLM. Đắt, sai âm thầm, và một lời chấm sai của máy in lên hồ sơ năng lực của trẻ. Khi cần phần viết, làm dạng *tự viết → so lời giải mẫu → tự đánh giá* và ghi evidence mức self-report (SDD-002 §18), không gọi là "đã đo".

## 3. Lưu trữ và blueprint

* Migration `0073_item_answer_kinds.sql`: `items.answer_kind TEXT NOT NULL DEFAULT 'mcq'` + `items.answer_spec_json TEXT`.
* `answer_spec_json` theo kind:
  * `numeric`: `{"answer":"7","accept":["7","7.0","14/2"],"tolerance":0.001,"unit":"cm"}` — `accept` là các cách viết cùng một đáp số; `tolerance` cho đáp số thập phân.
  * `estimate`: `{"min":40,"max":60}`.
  * `order_steps`: không cần spec — `options_json` chính là các bước theo THỨ TỰ ĐÚNG, client xáo khi hiển thị; đáp đúng là hoán vị `0,1,…,n-1`.
  * `find_error`: không cần spec — `options_json` là các dòng của lời giải mẫu, `correct_index` là dòng sai, `misconception` giải thích vì sao dòng đó sai.
* Hai dạng cuối tái dùng cột cũ có chủ ý: chúng vẫn là "chọn/xếp trong một tập cho sẵn", chỉ khác cách bày. Không thêm cột khi cột cũ nói đủ.
* Mỗi dạng là một **Assessment Blueprint** trong registry `content_blueprints` (SDD-013 §3): `numeric-input-v1`, `estimate-range-v1`, `order-steps-v1`, `find-error-v1`. Item seed tay đợt đầu vẫn ghi provenance về blueprint tương ứng; WF-14 sinh hàng loạt là việc chờ (SDD-013 §8).
* **Nhược điểm chấp nhận**: với `order_steps`, thứ tự đúng nằm trong payload gửi xuống client (client xáo). Learner mở devtools đọc được. Chấp nhận ở K12 vì chi phí chống (ký hoán vị per-delivery, server giữ state) không đáng với rủi ro; ghi lại để không ai tưởng là sơ suất.

## 4. Chấm

Toàn bộ trong `workers/api/src/modules/learning/grade.ts` — hàm thuần, unit test được, không đụng D1:

* `gradeAnswer(kind, spec, {selected_index, answer_value}, correct_index) → {correct, expected}`.
* `numeric`: chuẩn hoá rồi so — bỏ khoảng trắng, phẩy thập phân thành chấm, so trực tiếp với `answer`/`accept`, rồi so số học trong `tolerance`. "1/2" và "0.5" và "0,5" là một đáp số.
* `estimate`: parse số, đúng khi `min ≤ x ≤ max`.
* `order_steps`: `answer_value` là dãy chỉ số gốc theo thứ tự learner xếp; đúng khi bằng `0,1,…,n-1`.
* `find_error`/`mcq`: `selected_index === correct_index` như cũ.
* Route `POST /v1/practice/{sessionId}/answer` nhận thêm `answer_value?: string`; "Chưa biết" (`selected_index = -1`) giữ nguyên nghĩa cho mọi dạng.
* `expected` (đáp số đúng dạng chữ) chỉ trả về SAU khi chấm, để màn feedback nói được "đáp số đúng là 7" — trắc nghiệm không cần vì đáp án đã nằm trên màn.

## 5. Sức nặng bằng chứng (REQ-PED-07)

Evidence từ practice hiện ghi reliability `0.8 × attemptReliability` (SDD-002 §5). Hệ số 0.8 tồn tại vì MCQ có sàn đoán mò 25%. Dạng learner **tự sản xuất** đáp án không có sàn đó:

| Nhóm | Kind | Hệ số nguồn |
| --- | --- | --- |
| Tự sản xuất | `numeric`, `estimate`, `order_steps` | **0.95** |
| Chọn trong tập | `mcq`, `find_error` | 0.8 (giữ nguyên) |

`order_steps` xếp vào nhóm tự sản xuất vì không gian hoán vị n! làm xác suất mò đúng nhỏ hơn hẳn 25% từ n=4. `find_error` vẫn là chọn 1 trong N dòng nên giữ mức MCQ. Mọi cách tính khác (mastery update, retention, justification hạ reliability khi tự khai "đoán") giữ nguyên — thay đổi duy nhất là hệ số nguồn của một lượt.

## 6. Trải nghiệm trong app học

Màn làm bài (`apps/learn/src/Learning.tsx`) rẽ theo `answer_kind` của item, mọi thứ khác (confidence, justification, bong bóng, hàng-đợi-sai-làm-lại REQ-LRN-17) giữ nguyên:

* `numeric`/`estimate`: một ô nhập thay cho bốn nút; Enter = Kiểm tra.
* `order_steps`: danh sách các bước với nút lên/xuống — không kéo-thả, vì kéo-thả trên màn cảm ứng nhỏ dễ trượt và cần thư viện; nút mũi tên là thao tác một ngón chắc chắn.
* `find_error`: các dòng lời giải đánh số "Dòng 1…", bày như một bài giải (căn trái, đường kẻ trái) chứ không như bốn phương án.
* Ước lượng hiện khoảng chấp nhận SAU khi trả lời ("từ 40 tới 60 đều tính là đúng") — nói trước thì bài mất nghĩa.

## 7. Nội dung đợt đầu

Toán trước (quyết định chủ dự án 2026-08-23), seed tay qua script như các đợt item cũ, mỗi dạng mới phủ các unit đã có node. WF-14 generation cho các môn còn lại là việc chờ. Câu soạn theo blueprint nào ghi provenance blueprint đó.

## Trace

| REQ | Section |
| --- | --- |
| REQ-PED-06 | §2 (năm dạng), §3 (lưu trữ + blueprint), §4 (chấm), §6 (trải nghiệm), §7 (nội dung) |
| REQ-PED-07 | §5 (sức nặng bằng chứng) |
