init: edu-content 内容库骨架(L1-L4 四层数据模型 + B类迁移 + lint/CI 工具)
这个提交包含在:
@@ -0,0 +1,44 @@
|
||||
# 题库 INDEX — 数据总览与使用指南
|
||||
|
||||
> 更新:2026-08-21 | 格式规范见 [SCHEMA.md](SCHEMA.md)(qb-1.0)
|
||||
|
||||
## 一、现有数据
|
||||
|
||||
| 文件 | 级别 | 套数 | 空格/小题 | 多答案小题 | 来源 | 许可 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| `cepoc-a2-key.jsonl` | A2 Key | 6 | 68 | 14 | CEPOC(剑桥 ALTA 官方开源) | `cc-nc-education` |
|
||||
| `cepoc-b1-preliminary.jsonl` | B1 Preliminary | 21 | 150 | 24 | CEPOC | `cc-nc-education` |
|
||||
| `p2/out/*.jsonl`(6 份) | A2+B1 | 6 卷 | 131 | — | 剑桥官方 2022 样卷 | `official-free` |
|
||||
| **合计** | | **33** | **349** | | | |
|
||||
|
||||
> P2 详情(成功率 112/112 对账、token 成本、风险点)见 [p2/P2-REPORT.md](p2/P2-REPORT.md)。解析器:pymupdf4llm。
|
||||
|
||||
## 二、待入库(已规划)
|
||||
|
||||
| 优先级 | 数据 | 预估规模 | 许可 |
|
||||
|---|---|---|---|
|
||||
| ~~P3~~ | ~~官方词表 → 词库~~ **已完成** → 见 [../vocab/INDEX.md](../vocab/INDEX.md)(A2 1740 + B1 3172 词条) | — | `official-free` |
|
||||
| ~~P3.5~~ | ~~词库中文释义+音标~~ **已完成** → 见 [../vocab/INDEX.md](../vocab/INDEX.md) §三·五(ECDICT 4804 + LLM 98,音标覆盖 93.3%) | 4902 条 | ECDICT `CC-BY-SA-4.0` / LLM 生成 |
|
||||
| P4 | tape script + mp3 精听语料 | 2 套对齐文本 | `official-free` |
|
||||
| P5 | SkoolPlus 教材(ECS 下载后) | 20+ 套模拟题 | `restricted`(仅本地) |
|
||||
|
||||
## 三、下游 agent 使用须知
|
||||
|
||||
1. **读库**:JSONL 逐行 `json.loads`;一条记录 = 一个任务(语篇+多小题),不是单题
|
||||
2. **判题**:必须按 SCHEMA.md 第二节规则——`strip` + 大小写不敏感 + `answers_accept` 集合匹配;38 个空有多个可接受答案(如 `["because","as","since"]`),字符串全等会误判
|
||||
3. **许可红线**(按 `license` 字段过滤):
|
||||
- `official-free` → 可进部署的英语门户
|
||||
- `cc-nc-education`(CEPOC 全部数据)→ 自用/练习工具可以,**禁止商业化与再分发**
|
||||
- `restricted` → 任何对外输出都不允许出现
|
||||
4. **完形上下文切分**:`passage.split(blank_token)`,段数 = 空数 + 1
|
||||
5. **CEPOC 的 `part` 为 null**:数据混有 2020 改版前真题(KET 11-12 空/套、PET 6-8 空/套),与新版题型空数不符,见记录内 `note` 字段
|
||||
6. **P2 记录的媒体引用**:`meta.media[].path` 与 `meta.audio` 为相对路径(前者相对 question-bank 目录,后者相对 english-site 目录);图片选项题(听力 Part 1)`options=null`,必须渲染 `meta.media` 图片作答
|
||||
|
||||
## 四、复现
|
||||
|
||||
```bash
|
||||
cd data/question-bank
|
||||
python3 scripts/convert_cepoc.py <cepoc-main 绝对路径> .
|
||||
```
|
||||
|
||||
转换脚本内置校验:空格数与小题数一致、题号不重复、答案非空、id 唯一。2026-08-21 校验全部通过。
|
||||
@@ -0,0 +1,6 @@
|
||||
{"schema": "qb-1.1", "id": "a2k-cepoc-0001", "exam": "A2 Key", "cefr": "A2", "paper": "reading_writing", "part": null, "type": "open_cloze", "task_prompt": "For each gap, write ONE word which best completes the text.", "title": null, "passage": "Dear Melissa\n\nHow are things _ London? I had a great time staying with you. Thank you for looking after _ . You are _ great cook and your family were really kind to me. And my English is much better now _ it was before. \n\nMy flight home was fine – there were _ delays at all. It’s good to be back, but I miss you all very _ !\n\n_ you remember my friend Jenny? I think she came _ visit me at your house once _ twice. Well, she took some great photos _ us on our last day at the language school. I’m sending you one with this email. I hope you like \n\n_ .\n\nRosario", "blank_token": "_", "items": [{"no": 1, "stem": null, "options": null, "answers_accept": ["in"], "answer_official": "in", "explain": null, "tags": []}, {"no": 2, "stem": null, "options": null, "answers_accept": ["me"], "answer_official": "me", "explain": null, "tags": []}, {"no": 3, "stem": null, "options": null, "answers_accept": ["a"], "answer_official": "a", "explain": null, "tags": []}, {"no": 4, "stem": null, "options": null, "answers_accept": ["than"], "answer_official": "than", "explain": null, "tags": []}, {"no": 5, "stem": null, "options": null, "answers_accept": ["no"], "answer_official": "no", "explain": null, "tags": []}, {"no": 6, "stem": null, "options": null, "answers_accept": ["much"], "answer_official": "much", "explain": null, "tags": []}, {"no": 7, "stem": null, "options": null, "answers_accept": ["Do"], "answer_official": "Do", "explain": null, "tags": []}, {"no": 8, "stem": null, "options": null, "answers_accept": ["to"], "answer_official": "to", "explain": null, "tags": []}, {"no": 9, "stem": null, "options": null, "answers_accept": ["or"], "answer_official": "or", "explain": null, "tags": []}, {"no": 10, "stem": null, "options": null, "answers_accept": ["of"], "answer_official": "of", "explain": null, "tags": []}, {"no": 11, "stem": null, "options": null, "answers_accept": ["it"], "answer_official": "it", "explain": null, "tags": []}], "source": {"origin": "cepoc", "file": "assets/open-source/cepoc-main/KET.json", "orig_id": 1, "url": "https://github.com/CambridgeALTA/cepoc", "retrieved": "2026-08-21", "source_id": "cepoc", "source_item_id": "cepoc-ket-json"}, "license": "cc-nc-education", "tags": ["cloze", "open_cloze"], "note": "CEPOC 未标注套题年份与卷内 Part 号;空格数与 2020 版题型不完全对应(KET 11-12空/套、PET 6-8空/套),推断混有 2020 改版前真题。完形题型本身对应 A2 Key Reading & Writing / B1 Preliminary Reading 的 open cloze 题型。", "meta": {"multi_answer_items": 0}}
|
||||
{"schema": "qb-1.1", "id": "a2k-cepoc-0002", "exam": "A2 Key", "cefr": "A2", "paper": "reading_writing", "part": null, "type": "open_cloze", "task_prompt": "For each gap, write ONE word which best completes the text.", "title": null, "passage": "Dear Aunt Fabienne,\n\nMum asked _ to let you know that I arrived home okay. I enjoyed travelling back _ the train, and I was surprised that _ only took me three hours to get home. Thank you very _ for looking after me _ I was in France. \n\nI’m going back to school _ week. My French is a lot better _ it was before, so I hope my marks will improve!\n\nI _ like to keep practising French and I’m looking _ a pen friend. I thought of your friend’s son Elian. We could email each _ once a week. Let me know _ you think.\n\nI hope _ see you soon. \n\nDaniel", "blank_token": "_", "items": [{"no": 1, "stem": null, "options": null, "answers_accept": ["me"], "answer_official": "me", "explain": null, "tags": []}, {"no": 2, "stem": null, "options": null, "answers_accept": ["on"], "answer_official": "on", "explain": null, "tags": []}, {"no": 3, "stem": null, "options": null, "answers_accept": ["it"], "answer_official": "it", "explain": null, "tags": []}, {"no": 4, "stem": null, "options": null, "answers_accept": ["much"], "answer_official": "much", "explain": null, "tags": []}, {"no": 5, "stem": null, "options": null, "answers_accept": ["when", "while"], "answer_official": "when", "explain": null, "tags": []}, {"no": 6, "stem": null, "options": null, "answers_accept": ["next", "this"], "answer_official": "next", "explain": null, "tags": []}, {"no": 7, "stem": null, "options": null, "answers_accept": ["than"], "answer_official": "than", "explain": null, "tags": []}, {"no": 8, "stem": null, "options": null, "answers_accept": ["would", "'d"], "answer_official": "would", "explain": null, "tags": []}, {"no": 9, "stem": null, "options": null, "answers_accept": ["for"], "answer_official": "for", "explain": null, "tags": []}, {"no": 10, "stem": null, "options": null, "answers_accept": ["other"], "answer_official": "other", "explain": null, "tags": []}, {"no": 11, "stem": null, "options": null, "answers_accept": ["what"], "answer_official": "what", "explain": null, "tags": []}, {"no": 12, "stem": null, "options": null, "answers_accept": ["to", "I'll", "we'll"], "answer_official": "to", "explain": null, "tags": []}], "source": {"origin": "cepoc", "file": "assets/open-source/cepoc-main/KET.json", "orig_id": 2, "url": "https://github.com/CambridgeALTA/cepoc", "retrieved": "2026-08-21", "source_id": "cepoc", "source_item_id": "cepoc-ket-json"}, "license": "cc-nc-education", "tags": ["cloze", "open_cloze"], "note": "CEPOC 未标注套题年份与卷内 Part 号;空格数与 2020 版题型不完全对应(KET 11-12空/套、PET 6-8空/套),推断混有 2020 改版前真题。完形题型本身对应 A2 Key Reading & Writing / B1 Preliminary Reading 的 open cloze 题型。", "meta": {"multi_answer_items": 4}}
|
||||
{"schema": "qb-1.1", "id": "a2k-cepoc-0003", "exam": "A2 Key", "cefr": "A2", "paper": "reading_writing", "part": null, "type": "open_cloze", "task_prompt": "For each gap, write ONE word which best completes the text.", "title": null, "passage": "Hi Marta,\n\nI hope _ are well. I was trying _ call you yesterday but you didn’t answer. Is your phone broken, _ have you lost it again? \n\nAnyway, I wanted to ask _ you can come to my birthday party next Saturday. My birthday was actually two weeks _ , but I couldn’t have the party then _ lots of people were _ holiday. \n\nI’ve invited _ few people from our swimming club, as well as my friends from school. _ you think your brother _ free that day? Please invite _ to come too. The party’s at my house and starts at 8p.m. \n\nParveen", "blank_token": "_", "items": [{"no": 1, "stem": null, "options": null, "answers_accept": ["you"], "answer_official": "you", "explain": null, "tags": []}, {"no": 2, "stem": null, "options": null, "answers_accept": ["to"], "answer_official": "to", "explain": null, "tags": []}, {"no": 3, "stem": null, "options": null, "answers_accept": ["or"], "answer_official": "or", "explain": null, "tags": []}, {"no": 4, "stem": null, "options": null, "answers_accept": ["if", "whether"], "answer_official": "if", "explain": null, "tags": []}, {"no": 5, "stem": null, "options": null, "answers_accept": ["ago"], "answer_official": "ago", "explain": null, "tags": []}, {"no": 6, "stem": null, "options": null, "answers_accept": ["because", "as"], "answer_official": "because", "explain": null, "tags": []}, {"no": 7, "stem": null, "options": null, "answers_accept": ["on"], "answer_official": "on", "explain": null, "tags": []}, {"no": 8, "stem": null, "options": null, "answers_accept": ["a"], "answer_official": "a", "explain": null, "tags": []}, {"no": 9, "stem": null, "options": null, "answers_accept": ["Do"], "answer_official": "Do", "explain": null, "tags": []}, {"no": 10, "stem": null, "options": null, "answers_accept": ["is"], "answer_official": "is", "explain": null, "tags": []}, {"no": 11, "stem": null, "options": null, "answers_accept": ["him"], "answer_official": "him", "explain": null, "tags": []}], "source": {"origin": "cepoc", "file": "assets/open-source/cepoc-main/KET.json", "orig_id": 3, "url": "https://github.com/CambridgeALTA/cepoc", "retrieved": "2026-08-21", "source_id": "cepoc", "source_item_id": "cepoc-ket-json"}, "license": "cc-nc-education", "tags": ["cloze", "open_cloze"], "note": "CEPOC 未标注套题年份与卷内 Part 号;空格数与 2020 版题型不完全对应(KET 11-12空/套、PET 6-8空/套),推断混有 2020 改版前真题。完形题型本身对应 A2 Key Reading & Writing / B1 Preliminary Reading 的 open cloze 题型。", "meta": {"multi_answer_items": 2}}
|
||||
{"schema": "qb-1.1", "id": "a2k-cepoc-0004", "exam": "A2 Key", "cefr": "A2", "paper": "reading_writing", "part": null, "type": "open_cloze", "task_prompt": "For each gap, write ONE word which best completes the text.", "title": null, "passage": "Hi Marcia, \n\nDo you remember I wanted _ invite you, Sasha and John to my new house? Well, _ about next Saturday evening? We _ a beautiful garden with lots _ trees. We may have a barbeque outside _ it doesn’t rain. My mother is _ really good cook and I _ going to help her make the food. \n\nAfterwards, _ don’t we watch a film? _ you bring a DVD with you as I haven’t got many here? \n\nJohn’s coming _ bike and Sasha is getting a lift _ her father. I hope you’ll be able to come too. \n\nLet me know soon!\n\nConny", "blank_token": "_", "items": [{"no": 1, "stem": null, "options": null, "answers_accept": ["to"], "answer_official": "to", "explain": null, "tags": []}, {"no": 2, "stem": null, "options": null, "answers_accept": ["what", "how"], "answer_official": "what", "explain": null, "tags": []}, {"no": 3, "stem": null, "options": null, "answers_accept": ["have"], "answer_official": "have", "explain": null, "tags": []}, {"no": 4, "stem": null, "options": null, "answers_accept": ["of"], "answer_official": "of", "explain": null, "tags": []}, {"no": 5, "stem": null, "options": null, "answers_accept": ["if"], "answer_official": "if", "explain": null, "tags": []}, {"no": 6, "stem": null, "options": null, "answers_accept": ["a"], "answer_official": "a", "explain": null, "tags": []}, {"no": 7, "stem": null, "options": null, "answers_accept": ["am", "'m"], "answer_official": "am", "explain": null, "tags": []}, {"no": 8, "stem": null, "options": null, "answers_accept": ["why"], "answer_official": "why", "explain": null, "tags": []}, {"no": 9, "stem": null, "options": null, "answers_accept": ["Can", "Could"], "answer_official": "Can", "explain": null, "tags": []}, {"no": 10, "stem": null, "options": null, "answers_accept": ["by"], "answer_official": "by", "explain": null, "tags": []}, {"no": 11, "stem": null, "options": null, "answers_accept": ["from", "with"], "answer_official": "from", "explain": null, "tags": []}], "source": {"origin": "cepoc", "file": "assets/open-source/cepoc-main/KET.json", "orig_id": 4, "url": "https://github.com/CambridgeALTA/cepoc", "retrieved": "2026-08-21", "source_id": "cepoc", "source_item_id": "cepoc-ket-json"}, "license": "cc-nc-education", "tags": ["cloze", "open_cloze"], "note": "CEPOC 未标注套题年份与卷内 Part 号;空格数与 2020 版题型不完全对应(KET 11-12空/套、PET 6-8空/套),推断混有 2020 改版前真题。完形题型本身对应 A2 Key Reading & Writing / B1 Preliminary Reading 的 open cloze 题型。", "meta": {"multi_answer_items": 4}}
|
||||
{"schema": "qb-1.1", "id": "a2k-cepoc-0005", "exam": "A2 Key", "cefr": "A2", "paper": "reading_writing", "part": null, "type": "open_cloze", "task_prompt": "For each gap, write ONE word which best completes the text.", "title": null, "passage": "How _ you? I’m writing to you _ I need your help.\n\nI’m starting a business course at college _ term. The teacher has asked us to do some office work during _ summer. Your Dad’s _ manager, isn’t he? Can you ask him _ I can work with him? I only need to work _ a few weeks, and he will _ have to pay me anything.\n\nAlso, can I stay _ you while I’m working? Mum says it’s much _ far to go by bike _ day. Tell your mum that I can make _ own meals, so she won’t have to cook for me.\n\nThanks.", "blank_token": "_", "items": [{"no": 1, "stem": null, "options": null, "answers_accept": ["are"], "answer_official": "are", "explain": null, "tags": []}, {"no": 2, "stem": null, "options": null, "answers_accept": ["because", "as", "since"], "answer_official": "because", "explain": null, "tags": []}, {"no": 3, "stem": null, "options": null, "answers_accept": ["this", "next"], "answer_official": "this", "explain": null, "tags": []}, {"no": 4, "stem": null, "options": null, "answers_accept": ["the"], "answer_official": "the", "explain": null, "tags": []}, {"no": 5, "stem": null, "options": null, "answers_accept": ["a"], "answer_official": "a", "explain": null, "tags": []}, {"no": 6, "stem": null, "options": null, "answers_accept": ["if"], "answer_official": "if", "explain": null, "tags": []}, {"no": 7, "stem": null, "options": null, "answers_accept": ["for"], "answer_official": "for", "explain": null, "tags": []}, {"no": 8, "stem": null, "options": null, "answers_accept": ["not"], "answer_official": "not", "explain": null, "tags": []}, {"no": 9, "stem": null, "options": null, "answers_accept": ["with"], "answer_official": "with", "explain": null, "tags": []}, {"no": 10, "stem": null, "options": null, "answers_accept": ["too"], "answer_official": "too", "explain": null, "tags": []}, {"no": 11, "stem": null, "options": null, "answers_accept": ["each", "every"], "answer_official": "each", "explain": null, "tags": []}, {"no": 12, "stem": null, "options": null, "answers_accept": ["my"], "answer_official": "my", "explain": null, "tags": []}], "source": {"origin": "cepoc", "file": "assets/open-source/cepoc-main/KET.json", "orig_id": 5, "url": "https://github.com/CambridgeALTA/cepoc", "retrieved": "2026-08-21", "source_id": "cepoc", "source_item_id": "cepoc-ket-json"}, "license": "cc-nc-education", "tags": ["cloze", "open_cloze"], "note": "CEPOC 未标注套题年份与卷内 Part 号;空格数与 2020 版题型不完全对应(KET 11-12空/套、PET 6-8空/套),推断混有 2020 改版前真题。完形题型本身对应 A2 Key Reading & Writing / B1 Preliminary Reading 的 open cloze 题型。", "meta": {"multi_answer_items": 3}}
|
||||
{"schema": "qb-1.1", "id": "a2k-cepoc-0006", "exam": "A2 Key", "cefr": "A2", "paper": "reading_writing", "part": null, "type": "open_cloze", "task_prompt": "For each gap, write ONE word which best completes the text.", "title": null, "passage": "Welcome _ my blog! My name’s Lauren and I’m 22 years old. I come from\n\nIllinois in the USA, but _ the moment I’m studying in Florence, in Italy.\n\nI’m living _ a friend of mine from university. Our apartment _ in the centre of town, so we don’t _ to use the buses – we can walk everywhere. I have classes most days, but in _ afternoon, I explore the city or _ swimming. When _ is sunny I visit the Boboli Gardens. _ are beautiful views of Florence from here.\n\nI _ you enjoy my blog. _ you have any questions, please leave me a message.", "blank_token": "_", "items": [{"no": 1, "stem": null, "options": null, "answers_accept": ["to"], "answer_official": "to", "explain": null, "tags": []}, {"no": 2, "stem": null, "options": null, "answers_accept": ["at"], "answer_official": "at", "explain": null, "tags": []}, {"no": 3, "stem": null, "options": null, "answers_accept": ["with"], "answer_official": "with", "explain": null, "tags": []}, {"no": 4, "stem": null, "options": null, "answers_accept": ["is"], "answer_official": "is", "explain": null, "tags": []}, {"no": 5, "stem": null, "options": null, "answers_accept": ["have", "need"], "answer_official": "have", "explain": null, "tags": []}, {"no": 6, "stem": null, "options": null, "answers_accept": ["the"], "answer_official": "the", "explain": null, "tags": []}, {"no": 7, "stem": null, "options": null, "answers_accept": ["go"], "answer_official": "go", "explain": null, "tags": []}, {"no": 8, "stem": null, "options": null, "answers_accept": ["it"], "answer_official": "it", "explain": null, "tags": []}, {"no": 9, "stem": null, "options": null, "answers_accept": ["There"], "answer_official": "There", "explain": null, "tags": []}, {"no": 10, "stem": null, "options": null, "answers_accept": ["hope"], "answer_official": "hope", "explain": null, "tags": []}, {"no": 11, "stem": null, "options": null, "answers_accept": ["If"], "answer_official": "If", "explain": null, "tags": []}], "source": {"origin": "cepoc", "file": "assets/open-source/cepoc-main/KET.json", "orig_id": 6, "url": "https://github.com/CambridgeALTA/cepoc", "retrieved": "2026-08-21", "source_id": "cepoc", "source_item_id": "cepoc-ket-json"}, "license": "cc-nc-education", "tags": ["cloze", "open_cloze"], "note": "CEPOC 未标注套题年份与卷内 Part 号;空格数与 2020 版题型不完全对应(KET 11-12空/套、PET 6-8空/套),推断混有 2020 改版前真题。完形题型本身对应 A2 Key Reading & Writing / B1 Preliminary Reading 的 open cloze 题型。", "meta": {"multi_answer_items": 1}}
|
||||
在新工单中引用
屏蔽一个用户