AI幫幫忙-4:題庫工具功能設計與思路:多題型、簡答、模擬考試、計時與還原
上一篇《如何結合AI 及 IM BOT》是規劃文章。這一篇有兩個任務:一是把計畫逐項對照現況(進度對照),二是把這一輪「長出來」的功能,怎麼設計、為什麼這樣設計、中間改過什麼一次寫清楚。 主角是五件事:多題型的判分模型、簡答題的出題方式、模擬考試的保存與重考、計時器、未交卷的作答還原。
V2 保留不動,V3 測試版在這裡:https://blog.coins2ex.com/info-test/v3/info-test.html。誠實聲明:本文依我上傳的最新版
info-test.html逐項對照寫成。文中的「完成」只代表我讀過程式、做過語法檢查與部分模擬測試,我還沒有在真實瀏覽器與手機上逐項實測;IM 機器人與 Quiz API 那一半依然只是規劃。
前言:需求把順序改了
第 3 篇的里程碑是 M0、M1、M2……,先契約、再多題型、再 Quiz API。實際發生的事完全不是這個順序。我手上多了四門空大課程的自我評量與期中考簡答題,逼得工具先回答幾個很實際的問題:
- 題目不只有單選,有是非、複選,還有「請至少寫出三點」的簡答題,怎麼作答、怎麼評分?
- 題庫從資安擴大到 AI 應用與空大課程,單一下拉選單塞不下,怎麼分類?
- 想練「像考試」的卷子:選擇加簡答、有時間壓力、做到一半關掉頁面還能接著做、同一份試卷可以重考。
所以這一篇先看版本差異與進度對照,再講設計原則,接著逐項拆解功能,最後講資料與流程、驗證到哪裡。
V2 與 V3 測試版:先看差異
兩個版本我同時保留,網址不同。V2 是穩定版;V3 是同一個工具往多題型與課程題庫延伸的測試版。
| 項目 | V2(穩定版,保留) | V3(測試版) |
|---|---|---|
| 題型 | 單選 | 單選、是非、複選、簡答(自評) |
| 簡答題 | 無 | 最少 N 點加提示,或提示加填空,每次隨機 |
| 模擬考試 | 無 | 同科目客觀題加簡答,依占分配分;試卷與結果完整保存,可重載重考 |
| 計時 | 無 | 作答後開始計時,靜止、切換或關閉頁面即停止 |
| 未交卷還原 | 無 | 自動保存草稿,重開頁面詢問是否繼續 |
| 題庫選擇 | 年度 / 科目單層選單 | 先選題庫大分類,再選年度 / 科目 |
| 選項與分析文字 | 過長時截斷 | 完整顯示、自動折行 |
| 綜合題庫題數 | 10 / 25 / 50 | 10 / 20 / 25 / 50 / ALL |
| 作答紀錄 | 作答、錯題、備註 | 另記各題得分、用時,模擬考試另存試卷與總分 |
| IM 機器人、Quiz API | 無 | 尚未實作 |
保留 V2 的理由很單純:V3 新增的欄位(得分、用時、試卷、簡答文字答案)伺服器端是否保存,我還沒驗證。穩定版不動,測試版才敢放手改。
需求對照:最新版 info-test.html 做到哪裡
這一段是我拿「要求清單」逐項核對上傳的最新版程式(約 59 KB)的結果。標記沿用下方進度對照的五種。
| 需求 | 現況 | 實際做法與差異 |
|---|---|---|
| 1. 計時器:出題並開始答題後計時;靜止超過 10 分鐘或關閉頁面即停止 | ✔ 完成 | 出題後先不計時,第一次在題目區輸入或選取才開始。超過 10 分鐘沒有任何操作就停止,並扣掉靜止那段時間;切換分頁、關閉頁面也暫停,回來後有動作即恢復。交卷後停止,檢視舊作答時不計時。用時寫入每次作答紀錄 |
| 2. 答題狀態紀錄:cookie 保留未交卷答案;重開頁面詢問是否繼續,並提示科目與上次時間 | △ 修改 | 提示內容符合:顯示考試種類、題庫標題(含科目)、最後儲存時間、已作答題數、已用時,可選「繼續」或「放棄並刪除」。但答案存在 localStorage,不是 cookie:cookie 容量約 4 KB,放不下整份答案;cookie 只寫一份摘要(draftmeta),而且目前程式沒有讀它 |
| 3. 「模擬考試卷(期中 / 期末)」改名為「模擬考試」 | ✔ 完成 | 區塊標題、按鈕「產生模擬考試」、試卷標題都已改;紀錄檔 id 仍是 exam-能力-科目 |
| 4. 考試設定不須選擇期中 / 期末 | ✔ 完成 | 已移除考試類型選單與預設表;產生試卷時預設客觀題為 20 題與題庫題數取小者、簡答 4 題與題庫題數取小者,客觀占 60%(沒有簡答題庫時 100%),都可手動改 |
| 5. 同科目沒有選擇 / 是非以外的題型,就不顯示簡答 / 填空設定 | ◐ 部分完成 | 模擬考試卡片會依「該科目有沒有簡答題庫」隱藏簡答題數與占分欄位,並把簡答題數歸零、客觀占 100%。填空題尚未實作,所以沒有填空設定可顯示。但「② 出題設定」裡的「簡答題作答方式」選單不分科目,永遠顯示 |
| 6. 試卷題目與測試結果完整保存,可選擇重載題目重複測試 | ✔ 完成 | 見功能三:試卷快照、歷次結果、重載重考、檢視作答、匯出匯入、刪除都有 |
另外有三個我讀程式時發現、需求沒提到、但值得知道的行為:
- 草稿只有一個欄位。 同時做兩份卷,後面的會蓋掉前面的。
- 產生或重載模擬考試會直接清掉未完成的草稿,沒有先詢問。 這是目前最容易讓人吃虧的地方。
- 草稿至少要作答一題才會存,什麼都沒填就離開不會有提示。
進度對照:計畫與現況
我用五種標記,避免把「做了一半」寫成「完成」:
| 標記 | 意思 |
|---|---|
| ✔ 完成 | 程式或資料已做完,並在沙盒驗證過(語法檢查、模擬測試);仍未實機 |
| ◐ 部分完成 | 一部分做了,其餘沒做,或關鍵環節無法驗證 |
| ○ 未完成 | 沒有動 |
| + 新增 | 原計畫沒有,因需求產生 |
| △ 修改 | 原計畫有,但做法或決定被改掉 |
里程碑
| 里程碑 | 計畫內容 | 現況 | 說明 |
|---|---|---|---|
| M0 契約定稿 | 題庫 v3 欄位、API 規格、狀態機、資料表 | ◐ 部分完成 | 題庫欄位與題型已落地(寫進題庫並整理成規則 V4 的第 3 節);API 規格、狀態機、資料表仍只是草案 |
| M1 是非與複選 | grade()、render 分支、records.php 放寬 |
◐ 部分完成 | 前端完成,且擴及簡答題;records.php 沒有上傳,是否保存新欄位無法確認;正式的單元與回歸測試沒有做 |
| M2 Quiz API 基礎 | 資料庫、角色、綁定、稽核 | ○ 未完成 | 沒有動 |
| M3 匯入與審核 | 驗證器、管理後台、上架 | ○ 未完成 | 程式沒有;但我用人工流程先頂著(見下方「+ 爭議檢查」) |
| M4 Telegram 做題 | 外掛、工作階段、按鈕 | ○ 未完成 | 沒有動 |
| M5 LINE 做題 | Reply only | ○ 未完成 | 沒有動 |
| M6 對話式匯入 | /匯入 指令與閉環 |
○ 未完成 | 沒有動 |
| M7 網站聊天窗做題 | 中轉層帶入 uid |
○ 未完成 | 沒有動 |
| M8 填空與簡答自評 | 判分與介面 | ◐ 部分完成 | 簡答自評前端完成(含自動比對與出題方式);填空(fill)沒有做,仍被略過並提示 |
| M9 QQ(可選) | 官方機器人適配 | ○ 未完成 | 沒有動 |
計畫外的新增與修改
| 項目 | 標記 | 內容 |
|---|---|---|
| 題庫資料層 v1.1 欄位 | + 新增 | schemaVersion: 2、visibility、owner、source、aiMeta、answerSource、simulatedFields,每題 type、grading,先寫進題庫,工具暫不讀 |
| 題庫大分類 | + 新增 | 單一題庫先選大分類,再選年度與科目;group 欄位可覆寫 |
| 選項與分析完整顯示 | + 新增 | 不再用「…」截斷,改為自動折行 |
| 綜合題庫題數 | △ 修改 | 由 10、25、50 改成 10、20、25、50、ALL |
| 簡答題出題 | + 新增 | 最少 N 點加提示,或提示加填空,每次隨機 |
| 模擬考試 | + 新增 | 同科目客觀題與簡答題,依占分比例配分 |
| 空大課程題庫 | + 新增 | 新分類 ou,4 份選擇與是非題庫(共 340 題)、3 份簡答題庫(共 22 題) |
| 標準答案升級流程 | + 新增 | 題庫匯出成純文字,我標 *,AI 回填並回報差異 |
| 爭議檢查 | + 新增 | 每題都檢查誤植、答案唯一性與時效,有疑問寫進 note |
visibility 預設值 |
△ 修改 | 計畫寫預設 private;現況未標示視為 public,新匯入題庫預設才是 private |
| V2 保留、V3 另立測試網址 | + 新增 | V2 穩定版不動;V3 測試版放在獨立路徑 |
| 計時器 | + 新增 | 作答後開始計時,靜止、切換或關閉頁面即停止,用時存入紀錄 |
| 未交卷草稿與還原 | + 新增 | 作答中自動保存,重開頁面詢問是否繼續;答案存 localStorage,cookie 只放摘要 |
| 模擬考試試卷保存與重考 | + 新增 | 試卷快照、歷次結果、重載重考、檢視作答、匯出與匯入 |
| 模擬考試改名、不分期中期末 | △ 修改 | 原「模擬考試卷(期中 / 期末)」改為「模擬考試」,取消考試類型選單 |
| 系列文章與索引頁 | + 新增 | 第 3 篇補上 V3 測試網址與上下篇連結;索引頁新增第 4 篇與 V2 / V3 差異表 |
| 簡答 AI 評分 | ○ 未完成 | 依原計畫排在最後,沒有動 |
設計原則:三條規則撐住所有改動
1. 最小修改,不整份重寫。 每次改動都在上傳的 info-test.html 上做,保留元素 id、class 與 JSON 欄位名,改完列出差異。大分類那一輪只動約 35 行;簡答與試卷那一輪,原有程式碼只改了 11 處,其餘都是新增。
2. 得分統一用 0 到 1。 單選與是非是 0 或 1,複選可以按比例給分,簡答是命中比例,自評則是 1、0.5、0。「錯題」的定義也統一成「得分小於 1」。於是錯題統計、備註、歷史錯題練習、綜合題庫、模擬考試計分,完全不用為新題型各寫一套。
3. 資料層先行,執行層後做。 欄位(type、grading、visibility、group……)先寫進題庫,工具只讀它需要的。我把狀態拆成兩層:資料層是欄位已定義、已寫進題庫;執行層是工具或 API 是否讀取並改變行為。visibility、owner、aiMeta 現在資料層都有,但工具只用 visibility 決定「更新 index.json」要不要收錄。這代表私有題庫放在可下載的資料夾裡,一樣會被下載到,真正的保護要等 Quiz API。沒有真實資料的欄位用模擬值,並列入 simulatedFields。
功能一:多題型的判分模型
判分入口只有一個 grade(q, userAns),依題型分流,回傳一致的結果(得分、是否完全正確、訊息):
| 題型 | 作答 | 得分 | 備註 |
|---|---|---|---|
single |
radio | 0 或 1 | 沒寫 type 的舊題一律當單選 |
tf |
radio(是 Y / 否 N) | 0 或 1 | 視為兩個選項的單選 |
multi |
checkbox | all:全對才 1;partial:依對錯比例 |
partial 未滿分仍算錯題 |
short |
文字輸入 | 關鍵字比對得 0 到 1,可自評覆寫 | 見功能二 |
fill |
— | — | 尚未實作,載入時略過並提示 |
三個細節:
- 綜合題庫的去重鍵要加題型。 是非題的選項都是「是、否」,不加題型會把不同題誤併成一題。單選不加前綴,舊鍵完全不變。
- 重排選項只用於選擇類。 簡答沒有選項,自然不參與。
- 未支援的題型寧可略過並提示,也不要壞掉。 這讓題庫可以先含
fill,而不影響舊工具。
功能二:簡答題為什麼要「提示加隨機」
簡答題最常見的場景是:題目寫「請至少寫出三點」,教材卻有六項。只給一個空白輸入框,壓力大,而且每次背同一組答案。設計目標是讓同一題重複練習時,看到的線索不一樣。
兩種作答方式
| 模式 | 適用 | 呈現 |
|---|---|---|
| A:最少 N 點加提示 | 題目有「至少 N 點」 | 隨機給 0 到 2 個提示(提示算入 N 點),再填其餘點數 |
| B:提示加填空 | 題目沒有指定點數 | 給 1 到 2 個提示,另指定 2 到 3 項要點讓你填空 |
預設依題意自動選;設定裡可以強制一律 A 或一律 B。每次出題(包含「重新作答」)提示與填空位置都重新抽;但同一份模擬考試重考時,預設沿用原本的提示,勾選「重考時重新隨機」才重抽。
把出題結果集中在一個函式
出題邏輯只放在 shortSetup 一處,畫面和評分共用同一份結果:
// 概念示意(非完整程式)
function shortSetup(q){
const items = shortItems(q); // 要點:items → 由 reference 拆 → 關鍵字
const need = q.answer.need ?? Math.ceil(q.answer.pass * items.length);
const mode = pickMode(need, items.length); // A 或 B
if (mode === 'A') {
const h = rand(0, Math.min(2, need - 1, items.length - 1));
return { mode, hints: pick(items, h), reqA: need - h };
}
const hints = pick(items, items.length >= 3 ? rand(1, 2) : 1);
const blanks = pick(rest(items, hints), rand(2, 3));
return { mode, hints, blanks };
}
如果畫面和評分各自抽一次,就會出現「畫面給了提示,評分卻以為沒給」。而且這份結果現在還要一起存進草稿與試卷快照,才能在還原或重考時畫面一致,所以集中成一份資料格外重要。邊界條件也在這裡處理,例如 A 模式提示上限是 N 減 1,避免使用者「一個都不用寫」。
評分:關鍵字先比,自評最後定
要點資料格式沿用 reference 與 keywords,每個要點一組同義詞:
{"type":"short","question":"…請至少寫出三點?",
"answer":{"reference":"(1) … (2) … (3) …",
"keywords":[{"any":["遷移","關廠","歇業"],"w":1}],
"pass":0.5,"items":["…"],"need":3},
"grading":{"mode":"self"}}
A 看「命中點數 ÷ 需要點數」,B 看「填對格數 ÷ 總格數」。顯示答案後,使用者可以按「對、部分、錯」覆寫得分。我刻意不一開始就交給 AI 評分:關鍵字比對一定會誤判,必須有人工自評當最後一道防線;AI 評分要經過伺服器、金鑰、額度,屬於第四期。
功能三:模擬考試——從「出一張卷」到「可保存、可重考」
配對與配分
簡答題庫的科目代碼是「對應科目加 short」(如 hrs 對 hrsshort),模擬考試靠這個約定把客觀題庫和簡答題庫配成同一科目。優點是不必改任何既有題庫;缺點是改錯一個字就配不上,我標成「待確認」。
| 項目 | 規則 |
|---|---|
| 客觀題每題 | 滿分 × 客觀占分 ÷ 客觀題數 |
| 簡答題每題 | 滿分 × 其餘占分 ÷ 簡答題數 |
| 預設 | 客觀 20 題、簡答 4 題(都不超過題庫題數)、客觀占 60%、滿分 100;沒有簡答題庫時客觀占 100% |
| 版面 | 一、是非題 二、選擇題 三、簡答題,區標題標示每題分數與小計 |
| 計分 | 得分 = Σ(配分 × 該題得分),另記滿分 |
模擬測試時抓到過一個小錯:3 題簡答、每題 13.33 分,如果先四捨五入再相加,總分變成 99.99。修正是內部保留完整精度,只在顯示時四捨五入。
為什麼不分期中、期末
原本我把「期中 / 期末」做成選單,只是兩組不同的預設題數。實際用起來,題數本來就會依科目題庫大小調整,選單沒有帶來新資訊,反而多一個決定。現在拿掉,預設值依題庫大小自動取小。
試卷是一份「快照」
這是這一輪最重要的設計決定:模擬考試產生之後,存的不是「抽題規則」,而是整份試卷的內容。快照包含:題目全文(含選項、解析、配分、分區)、選項順序、簡答的提示與填空位置、產生時間、設定。理由很實際:
- 題庫之後可能被我修改(改答案、補備註),如果只存題號,重考時題目就不是當時那份了。
- 選項順序與簡答提示是隨機的,不存下來就無法重現。
每次測試的結果另存為一筆作答紀錄,包含各題答案與得分、總分、用時,以及用到的試卷代號。於是一份試卷底下可以累計多次測試。介面上對每份試卷提供:
| 操作 | 作用 |
|---|---|
| 重載重考 | 以同一份試卷重新作答;可勾選「重考時重新隨機選項順序與簡答提示」 |
| 檢視作答 | 以唯讀方式還原某一次的作答與結果 |
| 匯出 / 匯入 | 試卷加歷次結果存成一個 JSON 檔,可備份或換機器 |
| 刪除 | 刪除試卷題目內容,但歷次成績仍保留在作答紀錄 |
紀錄檔是 exam-能力-科目.records.json,試卷放在 papers,成績放在 attempts。合併時以試卷代號去重,刪除用「墓碑」標記,避免多個裝置合併時把已刪除的試卷又帶回來。
這個設計的代價:試卷帶整份題目文字,紀錄檔會隨試卷數量變大,目前沒有保存份數上限;而 Web 模式的 api/records.php 我沒有看過,不確定它會不會保留 papers、elapsed 等新欄位。在確認之前,把試卷「匯出」備份是比較穩的做法。
功能四:計時器——怎麼算才算「用時」
需求很直覺,但「用時」其實有幾個容易算錯的地方:
- 何時開始。 出題的瞬間不計時,第一次在題目區輸入或選取才開始。這樣「看一下題目要不要做」不會被算進去。
- 什麼叫靜止。 我用滑鼠移動、點擊、按鍵、捲動、觸控都算活動。超過 10 分鐘沒有任何活動,就視為離開。
- 離開時怎麼扣。 偵測到靜止超過 10 分鐘時,不是「從第 10 分鐘開始扣」,而是把最後一次活動之後的整段時間都扣掉。也就是用時只算到最後一次操作為止。
- 暫停與恢復。 切換分頁或關閉頁面(
visibilitychange、pagehide)立刻暫停;回來後只要有操作就自動恢復,畫面顯示「已暫停,繼續作答即恢復」。 - 何時結束。 交卷後停止並顯示「已交卷」;檢視舊作答時不計時。
實作很小:一個狀態物件(累計毫秒、是否執行、最後活動時間)、一個每秒執行的 timerTick,以及活動事件。我用模擬時鐘驗證過核心邏輯:未作答不開始、第一次作答開始、靜止超過 10 分鐘會停止並扣除靜止時段、再操作會恢復、關閉頁面會暫停。真實瀏覽器的背景分頁節流與手機休眠,我沒有實測。
功能五:未交卷還原——為什麼答案不放 cookie
需求寫的是「用 cookie 保留未交卷的答案」。我讀完實作後發現這裡改了做法:答案存 localStorage,cookie 只放摘要。理由是容量:cookie 單筆約 4 KB,而且每次請求都會送到伺服器;一份 40 題的作答加上簡答文字、選項順序、簡答提示、模擬考試的整份試卷,很容易超過。
| 項目 | 做法 |
|---|---|
| 存什麼 | 題庫或試卷代號、題號清單、各題答案、選項順序與簡答提示、已用時、最後儲存時間;模擬考試連整份試卷快照一起存 |
| 何時存 | 每次輸入後約 0.5 秒、計時進行中每秒、切換分頁與關閉頁面時;至少作答一題才存 |
| 何時清 | 交卷、按「重新作答」、選擇「放棄並刪除」,以及產生或重載模擬考試時 |
| 重開頁面 | 頂端出現提示:題庫標題(含科目)、最後儲存時間、已作答題數、已用時,按鈕「繼續上次的考試」或「放棄並刪除」 |
| 還原後 | 題目順序、選項順序、簡答提示和用時都回到中斷時的狀態,繼續作答即恢復計時 |
這個做法有三個已知缺點,我寫在這裡而不是藏起來:
- 只有一個草稿欄位,同時做兩份會互相覆蓋。
- 產生或重載模擬考試會直接清掉未完成的草稿,沒有確認。 這應該改成先詢問。
- 不能跨裝置。 要跨裝置就必須把草稿存到伺服器,牽涉到
api/records.php,目前沒有。
功能六:題庫分類與完整顯示
- 題庫大分類。 單一題庫改成先選大分類(初級資訊安全工程師、AI 應用、空大課程),再選年度與科目。分類依
ability對照,題庫可用選填欄位group覆寫。 - 完整顯示。 選項與分析文字原本過長會被「…」截斷;改成自動折行。
- 綜合題庫題數。 由 10、25、50 改成 10、20、25、50、ALL。
命名的坑:空大課程原本用 ability: ec,後來統一改成 ou。內建的大分類對照沒有 ou,所以這些題庫必須帶 group: 空大課程 才會歸對;題庫 id 一改,舊的作答紀錄就對不上。命名要一次想清楚,事後改名的成本還在使用者累積的紀錄。
題庫整理:標準答案與 AI 判斷分開
| 來源格式 | 處理 |
|---|---|
選項前 * |
標準答案 |
CHx 單獨一行 |
章節,寫入 category |
題號前 Y 或 N |
是非題 |
| 沒有選項的題目 | 是非題(依詳解判定) |
詳解: 後面的字母 |
該題答案 |
| 沒有任何答案標示 | AI 判斷,並查證條文 |
標準答案可以覆蓋 AI 判斷。 舊題庫的答案全是 AI 判斷,我把題庫匯出成純文字、在標準答案前加 *,再貼回去重新生成。結果有 6 題 AI 原本判斷錯了(112 年資安技術概論第 23、24 題、113 年資安管理概論第 45 題、113 年資安技術概論第 35、38 題、114 年資安管理概論第 27 題)。重點不是 AI 會錯,而是有一個機制讓我的答案能直接蓋過去,而且一眼看得出每題答案是誰給的。
懷疑標準答案有誤時,只標註,不擅自改。 例如跨境電子商務 CH5 第 5 題標「否」、第 6 題標「是」,兩題描述的卻是同一件事;就業服務管理 CH1 第 13、14 題的答案與課程資料對不上。AI 在備註寫「標準答案疑有問題」與理由,由我對照教材決定。有意思的是,有些疑慮後來被簡答題原文解開:簡答題寫明阿里巴巴的四個經營理念是「找商機、建立公司、交商友、看商情」,所以選擇題的「以上皆非」其實成立。同一門課的不同題型,可以互相驗證。
查證會推翻記憶。 就業服務管理 CH4(25 題)沒有標準答案,我要求先搜尋條文再判斷,結果幾個數字與記憶不同:身心障礙者就業基金撥交就業安定基金的比率是 30%、勞保滯納金上限是應納費額的 20%。沒查證的部分,備註一律寫「依記憶,未經本次搜尋查證」。
目前累積的空大課程題庫:選擇與是非題 340 題(電子商務導論 92、跨境電子商務 77、就業服務管理 71、人工智慧導論 100),簡答題庫 22 題(就業服務管理 9、電子商務導論 6、跨境電子商務 7)。
驗證:我做了什麼,做不到什麼
這一輪對最新版檔案做的:
- 通讀程式,逐項對照需求清單(上面的「需求對照」)。
- 用
node --check做語法檢查,通過。 - 用模擬時鐘驗證計時核心邏輯(開始、靜止扣除、恢復、暫停)。
之前對簡答與試卷做過、但這次沒有重跑的:
- 簡答題抽題與評分各跑 300 次,輸入格數與提示數量符合規則,標準答案得滿分、亂答得 0 分。
- 試卷配分總和、科目配對、成績計算。
做不到的,也是我最擔心的:
- 排版、手機版、按鈕互動、背景分頁節流,都沒有在真實瀏覽器看過。
- 未交卷還原的端對端流程(作答、關閉、重開、繼續)我沒有實際操作過,只讀了程式。
api/records.php沒有上傳,不確定它是否保存papers、elapsed、paperId、簡答文字答案。本地模式與瀏覽器備份不受影響。- 新題庫還沒進
index.json,要用「更新 index.json」重建,並移除末尾的空字串元素。
還沒做、也不想誇大的地方
- IM 與 Quiz API 那一半完全沒動。 外掛、後台、角色與綁定仍是草案。
- 填空題沒做;簡答 AI 評分也沒做。
- 草稿改成先詢問再覆蓋、支援多份草稿、跨裝置還原都還沒做。
- 試卷沒有保存份數上限,也沒有「一份卷子正式計時倒數」的考試模式(目前是累計用時,沒有限時)。
- 可見範圍沒有真正的保護。 題庫目前都標
public,但空大教材題目的著作權地位我沒有確認;若要公開分享,請先評估來源授權。 - 簡答題的關鍵字需要持續維護,同義詞太少就會誤判。
這一輪和 AI 協作的心得
1. 叫 AI 拿「上傳的檔案」去對照,而不是憑記憶說進度。 這次我把需求清單丟給它,請它對照最新版程式。結果它抓出一個我自己沒意識到的偏差:答案其實存在 localStorage,不是 cookie;還有一個風險:產生新試卷會默默清掉草稿。進度文件最怕憑印象。
2. 先把「判分模型」想清楚,再談介面。 得分統一成 0 到 1 之後,新題型和模擬考試計分幾乎是「接上去」而不是「改下去」。
3. 需求寫「怎麼做」之前,先問「為什麼」。 「用 cookie 保存」背後的目的是「重開頁面能接著做」;換成 localStorage 一樣達成,而且不會撞到容量。只要目的達成、差異寫清楚,實作可以調整。
4. 把「標準答案」和「AI 判斷」分開,並讓前者可以覆蓋後者;AI 可以指出疑點,但不要讓它改你的答案。
5. 查證會推翻記憶,所以要記錄「查過」與「沒查」。 條文的數字,AI 憑記憶寫的和搜尋到的不一樣至少有三處,備註寫明查證狀態,下次回頭看才知道哪些可以信。
6. 模擬測試抓邏輯,抓不到畫面。 它抓得到配分與計時的錯,但抓不到排版與按鈕。所以我要求 AI 明講「沒有實測的部分」,那些才是我要自己點開瀏覽器確認的。
7. 需求會把計畫打亂,但文件要跟著更新。 這次我沒有照 M0 到 M9 走,而是被期中考推著做簡答、模擬考試、計時與還原。計畫不必假裝照走,但要定期回頭對照、標清楚誰完成誰沒完成。這就是「進度對照」和「需求對照」兩節的由來。
下一步
| 順序 | 事項 | 為什麼 |
|---|---|---|
| 1 | 在真實瀏覽器與手機實測簡答、模擬考試、計時與還原 | 目前最大的未知 |
| 2 | 產生或重載模擬考試前,先詢問是否覆蓋未完成的草稿 | 避免默默丟掉作答 |
| 3 | 取得並放寬 api/records.php |
讓 Web 模式保存試卷、用時等新欄位 |
| 4 | 用「更新 index.json」重建索引,移除空字串 | 新題庫才會被載入 |
| 5 | 「簡答題作答方式」選單也依科目隱藏 | 完成需求 5 |
| 6 | 補填空題(fill) |
完成 M8 |
| 7 | 評估簡答題庫的明確配對欄位,取代命名約定 | 降低改錯字就配不上的風險 |
| 8 | 回到 M2:Quiz API 與角色 | 真正的私有題庫保護與對話功能的前提 |
IM 做題與對話式匯入,我依然認為值得做,但在上面幾件事有結果之前,不會動。
結語
這個系列的做法一直沒變:把重複的事拆成資料和工具,讓 AI 做機械性的整理,我負責決定方向和驗收。這一輪多了一個體會:判分模型、資料格式與流程的品質,比功能數量更決定這個工具好不好用。 能把答案的來源標清楚、能發現教材的矛盾、能誠實說出沒驗證的部分,比多一個按鈕重要。
如果你也在做自己的題庫工具,建議先決定「每一題的得分怎麼表示」和「答案是誰給的」,再談題型與介面。