← Back to catalog / 返回目录

Question Bank JSON Format / 题库 JSON 格式说明

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 的回复」。内容不上传,只存在你的浏览器里。

🤖 Using an AI to extract questions? / 用 AI 提取题目?

No paid plan, no file download needed. Free ChatGPT / Gemini can do this — you just copy their reply. / 不需要付费、不需要下载文件,免费版 ChatGPT / Gemini 就够——把它的回复复制过来即可。

  1. Copy the prompt below. / 复制下面的提示词。
  2. Paste it into the AI, then put your questions (or attach screenshots) right after the === MATERIAL === line at the very end. / 粘进 AI,再把你的题目(或贴截图)接在最后那行 === MATERIAL === 后面。
  3. Select the AI’s whole reply, copy it, and paste it into “📋 No file? Paste the AI’s reply instead” on the catalog page. No saving, no .json file, works on a phone. / 把 AI 的整段回复选中复制,粘进目录页的「📋 没有文件?直接粘贴 AI 的回复」。不用存文件、不用弄 .json,手机上也行。
  4. The prompt makes the AI stop every 15 questions and print 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),但下面的规则仍需遵守。

📖 Building an IELTS-style reading bank? Read the IELTS page →
Reading passages, section grouping (passage first, then its questions — never shuffled), and how each IELTS task type maps onto the fields below. / 雅思式阅读题库:阅读文章、section 分组(先文章再作答、不打乱),以及各雅思题型怎么落到下面的字段上。

English

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).

Fields

FieldRequiredMeaning
id✅ every questionUnique 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 questionsArray of at least 2 strings.
answersingle-choice0-based index into choices (first choice = 0).
answersmultiple-answerArray of 0-based indexes, e.g. [0,2]. Player switches to checkboxes automatically; all must match.
typefill-in onlySet "fill" (or just provide blanks).
blanksfill-inOne array per blank, each listing the accepted answers: [["8","eight"]] = 1 blank with 2 accepted spellings; [["a"],["b"]] = 2 blanks.
question_htmloptional (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_setsoptional (fill-in)Alternative whole-row combinations; any ONE set matching counts as correct.
imageoptionalImage URL or base64 data:image/... string — or an array of them. Shown above the choices.
sourceoptionalWhere 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 |).
explanationoptionalWhy 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).
sectionoptionalGroup 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.
passageoptionalThe 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.
banksoptionalArray 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.

Grading rules

Fixed for you automatically on import

These common slips (mostly from cheap AI output) are repaired rather than rejected — but a clean file is still safer:

If it says “invalid / no valid questions” — why a record is skipped, and the fix

SymptomFix
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 skippedUsually 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 skippedChoice 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(阅读文章型题库用)。

Complete example / 完整示例

[
  {
    "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 就是这个格式。