Write your own bank as a .json file (UTF-8) and import it on the catalog page — or skip the file entirely and paste an AI’s reply straight into the catalog’s “📋 Paste the AI’s reply” box. Nothing is uploaded; it stays in your browser. / 可以写成 .json 文件导入,也可以完全不碰文件——把 AI 的回复直接粘进目录页的「📋 直接粘贴 AI 的回复」。内容不上传,只存在你的浏览器里。
No paid plan, no file download needed. Free ChatGPT / Gemini can do this — you just copy their reply. / 不需要付费、不需要下载文件,免费版 ChatGPT / Gemini 就够——把它的回复复制过来即可。
=== MATERIAL === line at the very end. / 粘进 AI,再把你的题目(或贴截图)接在最后那行 === MATERIAL === 后面。MORE AVAILABLE. Type more, then paste that batch too with “add to the same bank” ticked. Repeat until it prints DONE. / 提示词会让 AI 每 15 题停一次并打印 MORE AVAILABLE。回一句 more,把这批也粘进去(勾上「并入同名题库」),直到它打印 DONE。Why batches: a free account’s reply gets cut off partway through a long bank. Fifteen at a time never hits the limit — and if one does get cut off, the importer still recovers every complete question and tells you to ask for the rest. / 为什么分批:免费账号的回复在长题库上会被截断。每次 15 题不会触顶;万一还是被截断,导入器也会把已完整的题全部抢救出来并提示你去要剩下的。
Tip: cheap models read pasted text and screenshots far better than a raw saved .mhtml (those are huge and encoded — that’s usually why an AI just echoes the prompt back). Open the page and copy the visible questions, or screenshot them. / 提示:便宜模型对粘贴的文字、截图的识别远好于直接丢原始 .mhtml(又大又是编码——AI 复读提示词多半就是这个原因)。打开网页复制可见题目,或截图即可。
Turn the material at the bottom into a question-bank JSON array. Reply with JSON only — do not restate these instructions.
BATCHES (important — free ChatGPT/Gemini cut long replies off): give me AT MOST 15 questions per reply. Stop after 15, and end that reply with the single line: MORE AVAILABLE. When I type "more", continue with the NEXT questions in the same format, never repeating ones you already gave. If everything fits in 15, end with: DONE.
FORMAT — a bare JSON array, one object per question:
[
{"id":"q1","question":"Which fabric is approved for aircraft covering?","choices":["Polyester","Cotton bedsheet","Nylon tarp"],"answer":0},
{"id":"q2","question":"Select ALL tools required. (multiple answers)","choices":["Punch tester","Hammer","Maule tester"],"answers":[0,2]},
{"id":"q3","type":"fill","question":"A hole smaller than ____ inches may be patched.","blanks":[["8","eight"]]}
]
RULES
1. "id": unique short string. "question": the stem as plain text.
2. One correct answer: "choices" (2 or more strings) + "answer" = the 0-based index (first choice = 0). A plain integer, not [2], not the answer text, not 1-based.
3. Several correct answers: use the plural key "answers" = array of indexes, e.g. [0,2].
4. Fill in the blank: "type":"fill", put ____ in the question where the blank goes, and "blanks" = one array per blank listing every accepted answer, e.g. [["8","eight"]].
5. Optional: "explanation" (one short sentence of why), "source" (where it came from).
6. Include every question in this batch. Use the answer the material marks correct; if none is marked, pick the best-supported one and add "source":"answer unverified".
7. Straight ASCII quotes. No trailing commas. Do not wrap the array in an object.
You may put the JSON in a code block and write a sentence before it — the importer strips that. Just never split one batch across two replies.
=== MATERIAL ===
The importer auto-handles a few common AI slips (code fences, an outer {"questions":[…]} wrapper, a missing id) — but the rules below still matter. / 导入器会自动兜底几种常见小毛病(代码围栏、外层 {"questions":[…]} 包裹、缺 id),但下面的规则仍需遵守。
section grouping (passage first, then its questions — never shuffled), and how each IELTS task type maps onto the fields below. / 雅思式阅读题库:阅读文章、section 分组(先文章再作答、不打乱),以及各雅思题型怎么落到下面的字段上。
A bank is a JSON array of question objects. Three graded question types are supported: single-choice, multiple-answer, and fill-in-the-blank. Any question can also carry an image, an explanation, and a section (for reading-passage banks).
| Field | Required | Meaning |
|---|---|---|
id | ✅ every question | Unique string within the file, e.g. "ch3-12". Progress (wrong/star records) is keyed on it. |
question | ✅ (unless image present) | The stem, plain text. \n makes a line break. |
choices | ✅ for choice questions | Array of at least 2 strings. |
answer | single-choice | 0-based index into choices (first choice = 0). |
answers | multiple-answer | Array of 0-based indexes, e.g. [0,2]. Player switches to checkboxes automatically; all must match. |
type | fill-in only | Set "fill" (or just provide blanks). |
blanks | fill-in | One array per blank, each listing the accepted answers: [["8","eight"]] = 1 blank with 2 accepted spellings; [["a"],["b"]] = 2 blanks. |
question_html | optional (fill-in) | HTML stem with <input data-blank="1"> placed where blanks belong (1-based). Omit it and inputs are appended below the stem. |
answer_sets | optional (fill-in) | Alternative whole-row combinations; any ONE set matching counts as correct. |
image | optional | Image URL or base64 data:image/... string — or an array of them. Shown above the choices. |
source | optional | Where the question came from; shown small under the card. May also be an array of strings (a merged question keeps every origin; they render joined by |). |
explanation | optional | Why the answer is right. Shown with a 💡 only after the learner submits and then taps Show Correct Answers — it shares one reveal gate with the correct answer, so it can never leak the answer early. Plain text (HTML is escaped, not rendered). |
section | optional | Group name, e.g. a reading passage title. Turns the bank into a section bank: questions keep their array order (never shuffled) and the filter panel lists sections instead of id prefixes. See the IELTS page. |
passage | optional | The reading text for this section, shown in a collapsible “Reading Passage” box above the section’s first question. Read from the first question of each section. See the IELTS page. |
banks | optional | Array of filter-group keys this question belongs to. Defaults to the part of id before the first -. Use it when one question should appear under several groups. |
Anything else you add is ignored, so extra bookkeeping fields are harmless. type:"essay" renders as an ungraded free-text card in the player, but the importer drops it (a record needs choices or blanks) — so don’t put essay questions in a bank you plan to import.
check list = checklist). It also normalizes typography before comparing: curly quotes → straight, en/em dashes → -, non-breaking space → space, and a trailing . , ; : ! ? is dropped (8. = 8).1,000 = 1000, 8 RPM = 8, 8% = 8. No unit conversion — 1 ft ≠ 12 in.blanks matches each blank independently. answer_sets instead matches whole rows: any one set matching all blanks counts as correct. Every blank must be filled before the answer is graded.answer, fill-in without accepted answers, neither choices nor blanks…).These common slips (mostly from cheap AI output) are repaired rather than rejected — but a clean file is still safer:
{"questions":[…]} wrapper, are stripped.id is auto-filled (auto-1, auto-2…). Give real ids anyway: wrong/star history is keyed on them, so auto ids shift if you re-order the file.id becomes a string; index written as a string ("2") becomes a number.answer:[2] becomes answer:2; answer:[0,2] becomes answers:[0,2].| Symptom | Fix |
|---|---|
| Whole file rejected (“Not valid JSON”) | It must be valid JSON. Remove markdown code fences, comments, and trailing commas; use straight " quotes. |
| “No valid questions found” | Top level must be a bare array […]. Don’t wrap it as {"questions":[…]}. (The importer tries to unwrap, but a bare array is safest.) |
| Every question skipped | Usually a missing id or a bad answer. Give each a unique id; make answer a 0-based integer in range (not the text, not 1-based). |
| One question skipped | Choice Q needs choices (2+) and a valid answer/answers; fill-in needs blanks with at least one accepted answer; or give it an image if there’s no stem text. |
题库就是一个 JSON 数组,每个元素是一道题。可判分的题型有三种:单选、多选、填空;任何题都还能带图片、解析、以及 section(阅读文章型题库用)。
id:文件内唯一(错题/收藏记录靠它存)。缺了会自动补 auto-1…,但仍建议自己给——自动 id 会随文件顺序变动,历史就断了。question:题干纯文本(有 image 时可留空);\n 换行。choices(≥2 个选项)+ answer(正确选项的下标,从 0 开始)。answers: [0,2] 数组代替 answer,播放器自动变复选框,需全对(无部分分)。type:"fill" + blanks——每个空一个数组,列出全部可接受答案,如 [["8","eight"]]。explanation(解析):提交后再点卡片上的「Show Correct Answers」才以 💡 显示——与正确答案共用同一道揭示闸,绝不会提前泄题;纯文本(写 HTML 会被转义)。section + passage:阅读文章型题库(雅思等)。带 section 的库不打乱、筛选面板按篇分组;passage 是该篇的文章,显示在该篇第一题上方的可折叠框里。详见 雅思专页。image(图片 URL 或 base64 data-URI,可数组)、source(来源,可为数组)、question_html(题干内嵌输入框 <input data-blank="1">)、answer_sets(多组合答案,任一组全匹配即对)、banks(自定义筛选分组,默认取 id 第一个 - 之前的部分)。check list = checklist);比较前统一弯引号/破折号/不换行空格,去掉句尾标点(8. = 8);期望答案本身是数字时才按数值比(1,000=1000、8 RPM=8、8%=8),但不做单位换算。{"questions":[…]}、缺 id、数字 id、answer:[2] 这类常见毛病会自动兜底修好。type:"essay"(问答题)播放器能显示但不判分,且导入时会被剔除——要导入的题库别放问答题。[
{
"id": "demo-1",
"question": "Which fabric is approved for aircraft covering?",
"choices": ["Polyester", "Cotton bedsheet", "Nylon tarp", "Canvas drop cloth"],
"answer": 0,
"source": "Chapter 3 – Coverings"
},
{
"id": "demo-2",
"question": "Select ALL tools required for fabric testing. (multiple answers)",
"choices": ["Punch tester", "Hammer", "Maule tester", "Torque wrench"],
"answers": [0, 2]
},
{
"id": "demo-3",
"type": "fill",
"question": "A hole smaller than ____ inches may be repaired with a doped-on patch.",
"blanks": [["8", "eight"]]
},
{
"id": "demo-4",
"question": "Identify the part shown in the image.",
"image": "https://example.com/part-diagram.png",
"choices": ["Rib", "Spar", "Longeron"],
"answer": 1,
"explanation": "The vertical member running spanwise along the wing is the spar; ribs give the airfoil its shape.",
"source": "Chapter 5 – Structures"
}
]
Save as e.g. my-bank.json → catalog page → “Import your own bank”. The Extractor's “导出全部合并 JSON” produces exactly this format. / 保存为 .json 后到目录页导入即可;提取器导出的合并 JSON 就是这个格式。