init: edu-content 内容库骨架(L1-L4 四层数据模型 + B类迁移 + lint/CI 工具)
这个提交包含在:
50
schemas/qb-1.1.md
普通文件
50
schemas/qb-1.1.md
普通文件
@@ -0,0 +1,50 @@
|
||||
# 题库统一 Schema(qb-1.1)
|
||||
|
||||
`qb-1.1` 是 `qb-1.0` 的**向后兼容升级**:保留全部旧字段,仅新增血缘字段。每行一条 JSON(JSONL),一条记录 = 一个**完整任务**(一个语篇 + 若干小题)。
|
||||
|
||||
> 升级点(相对 qb-1.0):`source` 对象新增 `source_id`(必填)与 `source_item_id`(可选),指向 `sources/` 登记的根 id。旧字段 `origin`/`file`/`url`/`retrieved` 保留用于迁移期兼容。
|
||||
|
||||
## 记录级字段
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `schema` | string | ✅ | 固定 `"qb-1.1"` |
|
||||
| `id` | string | ✅ | 全局唯一 `{考试缩写}-{来源缩写}-{序号4位}` |
|
||||
| `exam` | string | ✅ | `A2 Key`/`A2 Key for Schools`/`B1 Preliminary`/`B1 Preliminary for Schools` |
|
||||
| `cefr` | string | ✅ | `A2`/`B1` |
|
||||
| `paper` | string | ✅ | `reading_writing`/`reading`/`writing`/`listening`/`speaking`/`vocabulary` |
|
||||
| `part` | int\|null | ✅ | 卷内 Part 号;未标注为 `null` |
|
||||
| `type` | string | ✅ | 题型枚举(见下表) |
|
||||
| `task_prompt` | string | ❌ | 完整作答指令 |
|
||||
| `title` | string\|null | ❌ | 语篇标题 |
|
||||
| `passage` | string\|null | ❌ | 语篇正文;空格用 `blank_token` 占位 |
|
||||
| `blank_token` | string | ❌ | 默认 `"_"` |
|
||||
| `items` | array | ✅ | 小题数组(见 §2) |
|
||||
| `source` | object | ✅ | **溯源 + 血缘**(见 §3) |
|
||||
| `license` | string | ✅ | 许可枚举(见 `../LICENSES.md`);对外许可 = 引用 source 的最严格者 |
|
||||
| `tags` | array | ❌ | 自由标签 |
|
||||
| `note` | string | ❌ | 备注 |
|
||||
| `meta` | object | ❌ | 扩展位(音频/图片路径、评分量表引用等) |
|
||||
|
||||
## `type` 题型枚举
|
||||
|
||||
`mcq`/`matching`/`open_cloze`/`gap_fill`/`word_formation`/`writing_task`/`speaking_prompt`/`word_entry`/`other`(含义与判题方式同 qb-1.0)。
|
||||
|
||||
## `source` 对象(§3,含血缘)
|
||||
|
||||
```json
|
||||
{
|
||||
"source_id": "cepoc", // [新增·必填] 指 sources/ 中的 source id
|
||||
"source_item_id": "cepoc-ket-json", // [新增·可选] 精确到文件
|
||||
"origin": "cepoc", // [保留] 旧字段,迁移期兼容
|
||||
"file": "assets/questions/CEPOC_KET.json",
|
||||
"url": "https://github.com/CambridgeALTA/cepoc",
|
||||
"retrieved": "2026-08-21"
|
||||
}
|
||||
```
|
||||
|
||||
`source_id` 必须存在于 `sources/`;lint 据此校验血缘完整性并推导该记录的对外 `license`。
|
||||
|
||||
## 机器校验
|
||||
|
||||
`../schemas/qb-1.1.schema.json` 为该格式 JSON Schema。CI 用 `tools/lint_structured.py` 校验:每条记录 `source.source_id` 必须存在、`license` 必须是合法枚举且 = 引用 source 的最严格许可。
|
||||
37
schemas/qb-1.1.schema.json
普通文件
37
schemas/qb-1.1.schema.json
普通文件
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "qb-1.1 question bank record",
|
||||
"description": "题库记录。qb-1.0 向后兼容升级:新增 source.source_id(必填)与 source.source_item_id(可选)。",
|
||||
"type": "object",
|
||||
"required": ["schema", "id", "exam", "cefr", "paper", "part", "type", "items", "source", "license"],
|
||||
"properties": {
|
||||
"schema": { "const": "qb-1.1" },
|
||||
"id": { "type": "string" },
|
||||
"exam": { "type": "string", "enum": ["A2 Key", "A2 Key for Schools", "B1 Preliminary", "B1 Preliminary for Schools"] },
|
||||
"cefr": { "type": "string", "enum": ["A2", "B1"] },
|
||||
"paper": { "type": "string", "enum": ["reading_writing", "reading", "writing", "listening", "speaking", "vocabulary"] },
|
||||
"part": { "type": ["integer", "null"] },
|
||||
"type": { "type": "string", "enum": ["mcq", "matching", "open_cloze", "gap_fill", "word_formation", "writing_task", "speaking_prompt", "word_entry", "other"] },
|
||||
"task_prompt": { "type": ["string", "null"] },
|
||||
"title": { "type": ["string", "null"] },
|
||||
"passage": { "type": ["string", "null"] },
|
||||
"blank_token": { "type": "string" },
|
||||
"items": { "type": "array", "items": { "type": "object" } },
|
||||
"source": {
|
||||
"type": "object",
|
||||
"required": ["source_id"],
|
||||
"properties": {
|
||||
"source_id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
||||
"source_item_id": { "type": ["string", "null"] },
|
||||
"origin": { "type": "string" },
|
||||
"file": { "type": ["string", "null"] },
|
||||
"url": { "type": ["string", "null"] },
|
||||
"retrieved": { "type": ["string", "null"] }
|
||||
}
|
||||
},
|
||||
"license": { "type": "string", "enum": ["official-free", "cc-by", "cc-by-sa", "cc-nc-education", "restricted", "internal-only", "llm-generated", "unknown"] },
|
||||
"tags": { "type": "array", "items": { "type": "string" } },
|
||||
"note": { "type": ["string", "null"] },
|
||||
"meta": { "type": ["object", "null"] }
|
||||
}
|
||||
}
|
||||
57
schemas/vocab-1.1.md
普通文件
57
schemas/vocab-1.1.md
普通文件
@@ -0,0 +1,57 @@
|
||||
# 词库统一 Schema(vocab-1.1)
|
||||
|
||||
`vocab-1.1` 在原有 vocab 记录上新增 `source.source_id` 血缘字段(记录级 license 标注模式原样继承,这是现有设计最好的部分)。每行一条 JSON(JSONL),一条记录 = 一个单词条目。
|
||||
|
||||
## 记录级字段
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|---|---|---|---|
|
||||
| `id` | string | ✅ | 全局唯一 `{cefr缩写}{考试}-{来源}-{序号4位}`,如 `a2k-vocab-0001` |
|
||||
| `level` | string | ✅ | `A2`/`B1` |
|
||||
| `headword` | string | ✅ | 词头 |
|
||||
| `pos` | array | ✅ | 词性,如 `["det","adj"]`;无则 `[]` |
|
||||
| `pos_notes` | string\|null | ❌ | 词性说明 |
|
||||
| `examples` | array\|null | ❌ | `[{text}]` |
|
||||
| `phrases` | array\|null | ❌ | 短语 |
|
||||
| `topics` | array\|null | ❌ | 主题标签 |
|
||||
| `origin` | string | ✅ | 来源分类,如 `main_list` |
|
||||
| `source` | object | ✅ | **溯源 + 血缘**(见下) |
|
||||
| `gloss` | object | ✅ | 释义对象(见下) |
|
||||
|
||||
## `source` 对象(含血缘)
|
||||
|
||||
```json
|
||||
{
|
||||
"source_id": "cambridge-official", // [新增·必填] 指 sources/ 的 source id
|
||||
"source_item_id": "a2-key-vocab", // [新增·可选] 精确到文件
|
||||
"file": "assets/vocab/a2-key-vocabulary-list.pdf",
|
||||
"url": "https://www.cambridgeenglish.org/Images/506886-a2-key-2020-vocabulary-list.pdf",
|
||||
"publisher": "Cambridge English / UCLES",
|
||||
"licence": "official-free" // 记录级 license 标注,原样保留
|
||||
}
|
||||
```
|
||||
|
||||
> 注意:现有 vocab 用 `licence`(英式)字段名;迁移时**保留不改**,新增 `source_id`。`licence` 取值遵循 `../LICENSES.md` 枚举。
|
||||
|
||||
## `gloss` 释义对象
|
||||
|
||||
```json
|
||||
{
|
||||
"zh": "几个, 少数, 一些",
|
||||
"phonetic": "/ə/ 或 /eɪ/",
|
||||
"phonetic_source": "..." ,
|
||||
"source": "ecdict",
|
||||
"licence": "CC-BY-SA-4.0" // 释义来源 license,记录级标注
|
||||
}
|
||||
```
|
||||
|
||||
- `zh`:中文释义;`phonetic`:音标;`phonetic_source`:音标来源;`source`:释义来源(如 `ecdict`);`licence`:释义 license。
|
||||
- 若释义为 LLM 生成,`source: "llm"`、`licence: "llm-generated"`。
|
||||
|
||||
## 机器校验
|
||||
|
||||
`../schemas/vocab-1.1.schema.json` 为该格式 JSON Schema。`tools/lint_structured.py` 校验:每条 `source.source_id` 必须存在于 `sources/`;词条的对外 license = 词表 source 与 gloss.licence 的最严格者。
|
||||
|
||||
## 词集
|
||||
|
||||
`word-sets.json`:数字/星期/月份等主题词集,引用 vocab 的 `id`。与 vocab JSONL 同目录。
|
||||
41
schemas/vocab-1.1.schema.json
普通文件
41
schemas/vocab-1.1.schema.json
普通文件
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "vocab-1.1 word entry",
|
||||
"description": "词库条目。在原有 vocab 记录上新增 source.source_id(必填)血缘字段;保留 licence(英式)记录级标注。",
|
||||
"type": "object",
|
||||
"required": ["id", "level", "headword", "pos", "origin", "source", "gloss"],
|
||||
"properties": {
|
||||
"id": { "type": "string" },
|
||||
"level": { "type": "string", "enum": ["A2", "B1"] },
|
||||
"headword": { "type": "string" },
|
||||
"pos": { "type": "array", "items": { "type": "string" } },
|
||||
"pos_notes": { "type": ["string", "null"] },
|
||||
"examples": { "type": ["array", "null"], "items": { "type": "object" } },
|
||||
"phrases": { "type": ["array", "null"] },
|
||||
"topics": { "type": ["array", "null"] },
|
||||
"origin": { "type": "string" },
|
||||
"source": {
|
||||
"type": "object",
|
||||
"required": ["source_id"],
|
||||
"properties": {
|
||||
"source_id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
|
||||
"source_item_id": { "type": ["string", "null"] },
|
||||
"file": { "type": ["string", "null"] },
|
||||
"url": { "type": ["string", "null"] },
|
||||
"publisher": { "type": ["string", "null"] },
|
||||
"licence": { "type": "string", "enum": ["official-free", "cc-by", "cc-by-sa", "cc-nc-education", "restricted", "internal-only", "llm-generated", "unknown"] }
|
||||
}
|
||||
},
|
||||
"gloss": {
|
||||
"type": "object",
|
||||
"required": ["zh", "source", "licence"],
|
||||
"properties": {
|
||||
"zh": { "type": "string" },
|
||||
"phonetic": { "type": ["string", "null"] },
|
||||
"phonetic_source": { "type": ["string", "null"] },
|
||||
"source": { "type": "string" },
|
||||
"licence": { "type": "string", "enum": ["official-free", "cc-by", "cc-by-sa", "cc-nc-education", "restricted", "internal-only", "llm-generated", "unknown"] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户