---
url: https://docs.nemo12.com/architecture/sdd-014-exam-acquisition.md
description: >-
  Bản nháp thu thập đề thi (SDD-014): registry trường chuyên toàn quốc, mục tiêu
  crawl, độ phủ và quy trình nhập đề.
---

# SDD-014 — Exam Acquisition (khu vực crawl đề thi)

**Khu vực riêng** để thu thập đề thi thật ở quy mô toàn quốc (SRC-035): quản lý **mục tiêu thu thập** (trường nào, từ năm nào tới năm nào, các chuyên nào), registry **mọi trường chuyên tại mọi tỉnh thành** + **các lớp chuyên từng trường**, và pipeline crawl **AI-first** gom tất cả đề về một chỗ — đầu vào của Real Exam Bank ([SDD-012](sdd-012-real-exam-bank.md) §7/WF-13). Surface quản lý: khu vực "Thu thập đề" trong Coral ([SDD-013](sdd-013-coral-content-plane.md)).

## 1. Nguyên tắc

1. **AI First / AI Native** (REQ-PLT-12): toàn pipeline chạy end-to-end không cần human step bắt buộc — crawl, extract, tách bài, metadata, lời giải, đánh giá chất lượng đều bằng AI (multi-evaluator SDD-003 §8 thay human review mặc định; owner spot-check theo ngưỡng rủi ro). Ngoại lệ giữ human: an toàn trẻ em/moderation nội dung public (QG-008).
2. **Chỉ nguồn công khai, tôn trọng robots.txt/ToS**, rate-limit lịch sự; ưu tiên nguồn chính thức (Sở GD&ĐT, trường) rồi mới báo chí/site học liệu. Đề thi công lập là văn bản công bố; **lời giải của site ngoài không sao chép** (SDD-012 §1.6) — chỉ lưu URL tham chiếu; lời giải do AI tự biên soạn.
3. **Provenance từng bản ghi**: source_url, fetched_at, content hash (không lưu file — Q-069 ✅); mọi artifact AI sinh mang {model, prompt_version} (QG-010, SDD-003 §13).
4. **Acquisition tách khỏi publish**: crawl đổ vào staging (`raw → extracted → problemized`); chỉ khi qua gate QG-011 (AI checks) mới thành đề published của exam bank.

## 2. Registry trường chuyên toàn quốc (REQ-EXAM-11)

Mở rộng `target_schools` (SDD-011 §3) + kế thừa thiết kế legacy `schools/specialized_programs` (FEAT-035):

```text
target_schools (mở rộng): id, name, province, kind[chuyen|chon|thuong],
  managed_by[so|dai_hoc], website?, source, status
specialized_programs: id, school_id → target_schools, subject_code,   -- lớp chuyên: Toán, Tin, Anh…
  name_vi, intake_size?, notes, source, status
```

* Mục tiêu phủ: **mọi tỉnh thành** — danh sách trường chuyên (THPT chuyên thuộc Sở + trường chuyên thuộc đại học) + danh sách lớp chuyên từng trường.
* Seed bằng AI research (WebSearch/crawl nguồn công khai) → AI cross-check ≥2 nguồn → ghi provenance; refresh định kỳ theo mùa tuyển sinh.

## 3. Acquisition targets & coverage (REQ-EXAM-12)

```text
acquisition_targets: id, school_id|exam_system, year_from, year_to,
  rounds[dieu_kien|chuyen|both], subjects[], specialized_subjects[],  -- "các chuyên nào"
  priority, status[active|paused|done]
crawl_coverage (derived): school/hệ × year × round × subject →
  {found_exam?, found_official_answer?, extracted?, problemized?, published?}
```

* Coverage matrix là màn hình chính của khu vực "Thu thập đề" trong Coral: thấy ngay còn thiếu gì so với mục tiêu; gaps sinh crawl tasks tự động.
* Mục tiêu hiện tại (Q-063 ✅): Sư phạm → KHTN → Ams 2024–2026 trước; SRC-035 nâng tầm nhìn lên **tất cả trường chuyên, tất cả các năm có thể tìm được**.

## 4. Crawl pipeline (REQ-EXAM-13) — WF-16

```text
acquisition_target → resolve nguồn ứng viên (search index + registry site đã biết)
  → Cloudflare Workflow `exam-crawl`: fetch (robots-aware, rate-limited; xử lý trong bộ nhớ — Q-069 ✅ KHÔNG lưu file đề, chỉ lưu source_url + hash)
  → AI extract (OCR/PDF→text, nhận diện đề/đáp án chính thức)
  → AI tách bài (label theo đề gốc) → metadata + dạng bài + node links
  → AI soạn lời giải 3 tầng (SDD-012 §3) → AI multi-evaluator (SDD-003 §8) chấm theo rubric
  → đạt ngưỡng → publish vào exam bank (exams source='authentic' + exam_problems)
  → không đạt/variance cao → review queue (Coral §6) — AI retry trước, owner spot-check sau
```

* Queue `nemo12-content` fan-out per (đề × bước); DLQ + idempotent theo (source_url, hash) — QG-009; **không cron-poll** (RISK-018).
* `crawl_runs {id, target_id, status, progress, stats_json, started_at, finished_at}` — hiển thị trong Coral Hoạt động (SDD-013 §4).
* Nguồn seed ban đầu: research report 2026-08-14 (URL hanoi.edu.vn + các nguồn đã xác minh cho Sư phạm/KHTN/Ams).

## 5. AI-first quality (REQ-PLT-12)

* Gate publish = **deterministic checks + AI multi-evaluator đạt ngưỡng** (thay "human review bắt buộc" trước đây của QG-011 — amend theo SRC-035); variance cao giữa evaluators → giữ ở review queue.
* Owner (dac2205@gmail.com) chỉ **spot-check**: mẫu ngẫu nhiên theo tỷ lệ + mọi item bị learner report sai (learner evidence là trọng tài cuối — SDD-003 §11).
* Toàn bộ AI qua gateway `nemo12`, cost dashboard, prompt registry versioned (QG-010).

## 6. Source Registry & Scoring (REQ-EXAM-14, SRC-039)

Mọi nguồn đề được **lưu lại và xem lại được** — kế thừa ý tưởng `exam_sources` legacy (FEAT-034), làm mới:

```text
exam_sources: id, name, kind[so_gddt|truong|bao_chi|site_hoc_lieu|khac], base_url,
  robots_ok, provenance_notes, status[active|blocked], created_at
source_evaluations: id, source_id → exam_sources, run_id?, rubric_scores_json,
  -- các chiều: đúng-đủ đề, có đáp án chính thức?, chất lượng scan/OCR, độ tươi (đăng sớm?),
  -- độ ổn định link, phạm vi phủ (trường/năm)
  score 0–1, evaluator (AI model + prompt_version), evaluated_at
```

* **Workflow chấm nguồn** (bước trong WF-16): sau mỗi crawl run, AI đánh giá nguồn theo rubric trên → cập nhật `score` (trung bình trượt); mọi đề/bài giữ `source_id` → truy ngược được đề nào từ nguồn nào.
* **Ưu tiên tái dùng**: resolver của WF-16 xếp nguồn theo `score DESC` khi tìm đề mới — nguồn tốt được dùng nhiều hơn; nguồn kém/chết link tự tụt hạng; `blocked` khi vi phạm robots/bản quyền.
* Coral khu "Thu thập đề" có tab **Nguồn**: danh sách + score + lịch sử đánh giá + đề đã lấy từ nguồn.

## Trace

| REQ | Section |
| --- | --- |
| REQ-EXAM-11 | §2 |
| REQ-EXAM-12 | §3 |
| REQ-EXAM-13 | §4, §5 |
| REQ-EXAM-14 | §6 |
| REQ-PLT-12 | §1, §5 |

Liên quan: SDD-012 (exam bank đích), SDD-013 (Coral UI + runs), SDD-003 §8/§11 (multi-evaluator, learner arbiter), QG-011 (amended), Q-103..Q-106 (Đợt 6).
