Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ScratchGrader

系統改寫來源:makishi-ops/scratch-ai-grader

ScratchGrader 是供 Scratch 教學使用的 AI 輔助批改系統。教師建立作業規則與參考解答後,學生可上傳自己的 .sb3 專案進行自評,系統會依教師規則產生分數、邏輯分析與可改進建議。

系統目的

它適合在課堂、社團或自學情境中,協助教師快速檢視學生是否完成指定的 Scratch 功能,同時讓學生在繳交前取得具體回饋。系統不取代教師判斷;教師仍可依課程目標調整題目、評分規則與 AI 回饋。

核心特色

  • 教師可設定作業主題、評分規則、初始範本與參考解答。
  • 學生以瀏覽器上傳 .sb3,不需安裝額外軟體。
  • 直接解析 Scratch 專案結構、角色、背景、音效、變數與積木流程,再交由 Gemini 依規則評量。
  • 積木名稱使用 Scratch 官方繁體中文詞彙;未知的第三方擴充會被標示,不讓 AI 任意猜測。
  • Gemini/Claude 共用結構化扣分與加分格式,後端統一計算總分;每關先盲評校正,再開放學生送件。
  • 可選擇使用 Firestore 保存教師設定與學生自評紀錄;未啟用時只儲存在目前後端環境。
  • 將教師設定的分數門檻換成 0⭐/2⭐/3⭐ 學習成果,讓學生知道是否達成任務與下一步如何修改。
  • 評分期間持續顯示已等待時間、目前工作量與實測平均時間,減少學生因誤以為系統卡住而重複送出。
  • 教師端由 ADMIN_TOKEN 保護;公開專案不含任何帳號、金鑰或既有學生資料。

操作方式

  1. 部署者:依「第一次設定」與「外部服務設定指南」建立自己的 ngrok、Gemini、ADMIN_TOKEN,以及選用的 Firestore 設定。
  2. 教師:先閱讀下方「核心操作」章節;登入教師頁,上傳範本/解答,生成並審閱規則、試評、儲存,最後完成每關的盲評校正,才能開放學生。
  3. 學生:開啟 ScratchGrader_student.html,輸入學號並上傳 .sb3,取得分數(若教師開啟)、邏輯分析與改善建議。
  4. 教師追蹤:啟用 Firestore 時,可在教師頁讀取學生自評紀錄;未啟用時不保存學生自評紀錄,教師設定則保留於本機或目前 Colab 工作階段。

核心操作:建立、試評與校正評分標準(教師必讀)

這是系統最重要的設定流程。模型、金鑰與連線設定只是讓系統能運作;真正決定評分品質的是教師的規則、樣本與反覆校正。每一關都應完成此流程,再讓學生正式送件。

準備作品 → 上傳範本/解答 → AI 生成規則草稿 → 教師審閱與一般試評 → 儲存設定 → 四種樣本盲評校正 → 不符預期則修訂、儲存、重測 → 通過後開放學生

「自動生成」是產生評分標準草稿,不是直接產生成績,也不代表標準已正確。「校正並記錄」是檢查模型分數是否符合教師事先設定的範圍,不會自動修改配分、訓練模型或替教師決定正確答案。

1. 先準備本關作品與人工判斷

在教師頁②填入自己的 API key、選擇主模型,在③設定主題、唯一的關卡識別碼與成果門檻(預設達成 75 分、優秀 90 分)。

準備以下作品,原始 .sb3 請自行保留,不要只依靠後端保存:

作品 放在哪裡 用途
初始範本 ④「初始空白範本 .sb3」 學生開始作業前的起始專案;解析結果完全未改時判為 0 分。可包含教師預先提供的角色、背景或部分程式,不一定完全空白。
教師完成解答 ④「老師參考解答 .sb3」 作為生成規則的資料;一般評分也可參考。不要把初始範本誤當完成解答。
四種校正作品 ⑥的試評檔案欄,逐份上傳 人工已確認的完整、缺一要求、未完成與邏輯錯誤作品,用來檢驗評分標準。完整樣本可用教師完成解答,其他三種須是不同作品。

初始範本與參考解答不是必填;沒有解答仍可手動寫規則,但依解答自動生成規則必須先提供完成解答。初始範本不可直接拿來充當「未完成」的模型校正樣本:完全相同時會由本機直接判為 0 分,沒有實際檢驗模型。

先親自在 Scratch 執行樣本,確認哪些要求成立、哪些不成立,再決定期望分數;不能看完 AI 分數才把期望範圍改成一定通過。

2. 上傳並確認轉換成功

在④分別選擇初始範本與完成解答,等各欄顯示「已轉換」後再進行下一步。若轉換失敗,先修正檔案或重新上傳,不要沿用畫面先前載入的舊內容。

上傳會把 .sb3 解析為供 AI 閱讀的程式文字,不等於已儲存本關設定。目前後端不長期保存原始上傳檔案;按⑤「儲存設定」後,才保存解析文字與相關設定。日後更新解析器時,仍需重新上傳原始作品。

3. 自動生成草稿,再由教師逐條審閱

按④「依參考解答自動生成主題與規則」。系統使用②的主模型產生建議,填入③的主題及規則;已有內容時會提示覆蓋,請先自行備份手動修訂的文字。生成成功後不會自動儲存,也不會自動完成校正。

教師必須確認:

  • 基本項目配分合計 100 分;額外加分總計不超過 10 分,未完成加分題不扣分。
  • 每條規則有唯一名稱、可觀察的功能與未達成時扣分;部分完成如何扣分也要事先說清楚。
  • 不強迫學生照抄教師的積木排列、角色或變數名稱;等效解法是否允許應明寫。
  • 不額外要求題目未教、未指定的防呆、特定輸入或創意;「A 或 B」是擇一,不是兩者都要。
  • 配分與達成門檻相容,且同一缺失的扣分範圍明確,避免用不同名稱重複處罰同一問題。
  • 規則來自本關教學目標,不把清單的存檔資料或變數存檔值誤當執行成果。

例如,可把「清單運作正確,100 分」改成以下可查核規則。這只是教學示例,不會寫入系統預設設定:

R1:開始處理資料前,以有效程式清空本清單,20 分;未達成扣 20 分。

R2:透過有效程式加入三筆資料,20 分;未達成扣 20 分。

R3:透過迴圈依序讀取全部三筆清單資料,40 分;若重複讀同一筆而沒有遍歷全部,扣 40 分。

R4:透過「清單 … 的長度」積木取得並顯示總筆數,20 分;未達成扣 20 分。

B1:全部資料讀取完成後,將舞台切換到另一個背景,另加 10 分;未完成不扣分。

角色、變數、清單名稱可不同;達成相同功能的等效寫法均可。

這裡的 20/20/40/20 是示例配分,不是系統替所有題目固定分配。實際配分、部分完成與替代方案由教師依本關要求調整。

4. 一般試評與儲存:先看判斷,不只看總分

在⑥選擇作品、供應商,按「一般試評」,可以用③尚未儲存的規則先檢查:

  • 分數是否依明確的扣分/加分算出。
  • 扣分證據是否指向作品真的缺少的功能,而不是模型假設的問題。
  • 講評是否與扣分互相矛盾,是否出現老師沒有訂定的要求。
  • 有效的替代寫法是否被錯扣分。

一般試評不使用正式成績快取,但不列入校正紀錄,也保留一般評分的參考解答政策。勾選「與參考解答一致即滿分」時,完成解答試評得到 100 分,不能據此認定規則已通過校正。

修訂後按⑤「儲存設定」,確認保存成功及實際保存位置。Firestore 保存成功才能跨 Colab 重啟保留;若只保存於本機,應先處理保存問題或做好自行備份。儲存後是後端使用的正式規則,但校正未通過時,仍不開放學生正式評分。

5. 以四種不同樣本做正式盲評校正

先儲存,再在⑥依序選樣本、樣本類型及事先決定的期望最低/最高分,按「校正並記錄此樣本」。

樣本類型 教師先確認的事實 期望分數如何設定
完整解答 必要要求均成立,加分項目另計 最低分不得低於優秀門檻;預設 90~110。若示例四項全做、未做加分,人工預期為 100 分。
少一條規則 明確少一項,其餘要求仍成立 依該項配分計算,不能固定套用 75~89。例如只缺示例 R4、沒有加分,人工預期為 80 分。
明顯未完成 核心任務尚未完成,且不是與初始範本完全相同的作品 最高分須低於達成門檻;預設 0~74。依實際已完成項目設定,不必一律預期 0 分。
外觀相似但邏輯錯誤 看似有積木,但必要功能未成立 最高分須低於達成門檻;預設 0~74。例如示例 R3 每次只讀第一筆、其他三項成立且無加分,人工預期為 60 分。

可把期望範圍設為相同的最低/最高分,嚴格檢查確定配分;若允許小幅差異,應事先訂定有理由的範圍。若邏輯錯誤樣本依現有配分仍能及格,先檢討關鍵功能配分或重選真正不及格的樣本,不要把它偽裝成「未完成」校正。

正式校正會暫時移除參考解答,關閉「相同即滿分」捷徑,不用快取,也不自動切換供應商。同一作品不能冒充兩種情境。

若啟用 Claude 備援,選「Claude」以同四份作品再測一次(會產生費用)。主模型與 Claude 各四項通過、同樣本的及格判定一致,且分差不超過③的「跨模型校正容許分差」(預設 10),才開放學生送件。未啟用 Claude 則只要求主模型四項。

6. 校正不符預期時,修改標準並回到儲存/重測

不要只把期望範圍放寬至包含 AI 分數。先讀扣分證據,找出是作品、規則還是模型判斷的問題:

發現的問題 建議動作
完整解答被扣了未訂定的要求 在③明確列出範圍與等效解法,刪除模糊描述;不必直接免除真正的必要要求。
缺少功能的作品仍拿滿分 補上該規則的具體檢查條件、扣分及部分完成界線;確認樣本真的只缺該項。
表面有迴圈就被判成完成 把規則改成「迴圈中每次索引須正確變動並遍歷全部項目」等本題實際要求。
兩個模型給分差異過大 比較各自扣了哪些規則,釐清措辭與配分;不要只提高容許分差掩蓋差異。
校正樣本本身與人工預期不符 回 Scratch 修正或重選樣本,再重測;更換某情境樣本時,兩個模型都要測該份新作品。
API 或回覆格式失敗 修復連線、金鑰或模型設定後重試;服務失敗不是學生 0 分,也不算校正通過。

操作循環固定為:修改③評分標準 → 按⑤儲存 → 重新完成⑥校正 → 確認狀態。修改規則、範本、解答、主模型、Claude 備援、成果門檻、容許分差或後端分析版本,會使本關原校正失效,不能只重跑先前失敗的那一項。

若只替換某一情境的樣本,而沒有修改評分政策,其他情境紀錄可保留;該情境須在所有啟用供應商上重新測同一份新作品。校正符合範圍不代表一定沒有錯誤,仍須覆核評語與扣分理由。

7. 確認可開放,並保存本關資料

只有⑥顯示所有啟用模型已通過校正,才請學生使用學生端正式評分。保留本關的原始作品、人工預期與規則文字,供後續查核及重新部署;勿把學生個資、金鑰或私人設定加入公開專案。

學生正式成績會保存第一次成功評分的結果;一般試評與校正不會覆寫它。修改規則會形成新的正式快取範圍,但既有成績紀錄不會自動重新計算,需要時應請學生重新提交,並由教師辨識新舊規則的結果。

同一後端目前只有一份正在使用的作業設定。關卡識別碼用來分別保存校正紀錄,不會自動載入各關的主題、規則與範本;切換關卡時需先載入或填入對應內容、儲存,再確認該關校正狀態。正在收學生作業時不要切換到另一關;不同班級的同時評分應使用隔離部署或設定/資料集合。

班級同時評分與排隊

學生可以同時開啟與送出學生頁面;後端會以 FIFO(先送先處理)佇列執行 AI 評分,預設同時處理 3 份,其餘等待。此設定讓約 15 位學生同時繳交時,不會同時大量佔用 Colab 與模型免費額度。

  • MAX_CONCURRENT_GRADES=3:同時進行的 AI 評分數。免費 Colab 建議維持 2~3;效能與額度充足時才提高。
  • MAX_QUEUED_GRADES=24:最多可等待的評分數;佇列已滿時,學生會收到稍後再試的訊息。
  • 後端會保存最近 20 次成功評分的實測處理時間。學生等待時會看到已等待時間、目前工作量與平均時間;剛啟動、尚未有樣本時會清楚標示為尚在累積資料,而不會假裝提供精準倒數。
  • 教師端的連線區也會顯示這次 Colab 工作階段的平均秒數、樣本數與目前佇列狀態,方便課後據以調整模型、冷卻秒數與同時評分數。此統計為執行期資料,重啟 Colab 後會重新累積。
  • 評分工作仍受模型回應時間與帳號額度影響;此佇列控制併發,不保證固定完成時間。

學習成果門檻

評分流程參考 course_115 的程式設計評分設計:AI 提供扣分與加分證據,由後端計算分數,再依教師設定的固定門檻換算成果,而不是再交給 AI 主觀決定是否通關。

  • 未達「達成門檻」:0⭐,顯示待修正與 AI 的具體建議。
  • 達成門檻以上:2⭐,表示已達成本次任務。
  • 優秀門檻以上:3⭐,表示表現優秀。

這是單次作業的成果回饋,不會鎖住學生、也不會禁止重新送件;每次送件仍會記錄,供教師追蹤修改歷程。

系統架構與檔案

後端在 Google Colab 執行 Flask,再以 ngrok 提供 HTTPS 網址;前端是兩個獨立 HTML:

檔案 用途
scratch_grader_core.py .sb3 解析、Gemini 評分、設定與 Firestore 存取
colab_server.py Flask API、教師端驗證、ngrok 連線
grading_queue.py 限制同時 AI 評分數並依送出順序排隊,保護 Colab 與模型額度
grading_scoring.py 驗證扣分/加分證據並統一計算分數
grading_policy.py 正式結果快取識別、內部分析版本與備援條件
grading_calibration.py 校正樣本類型、模型/規則/門檻的版本識別
grading_assessment.py 固定分數門檻轉換為學習成果
ngrok_recovery.py 只清理同一靜態網域的舊連線
ScratchGrader_teacher.html 教師設定與試評頁面
ScratchGrader_student.html 學生自評頁面
app-config.js 前端唯一需調整的公開 API 網址
.env.example 所有伺服器端設定的清單
scratch_official_zh_tw.json Scratch Foundation 官方繁中詞彙快照
scratch_translation.py 積木名稱渲染與專案覆蓋率檢查

請使用 ScratchGrader_Secure_Colab.ipynb 啟動;後端來源為上列 Python 模組及官方詞彙 JSON,不包含 notebook 內寫死的另一份批改程式。

本次分析更新與既有部署升級

已核對 course_115 的 2026-10-02「程式設計評分校正」更新,參考其分析原則獨立調整本專案,沒有帶入該課程的關卡內容、學生資料或服務設定。本次內部分析版本為 2026-10-03-evidence-v2。

  • 保留自訂積木的名稱、參數及呼叫順序;空的如果分支不再讓有效的「否則」分支消失。
  • 變數/清單明確標記為存檔快照,而非程式執行結果;補充分身的建立時狀態、區域變數獨立性與相同事件多段程式的啟動語意。
  • 不把 pen_stamp 等擴充指令誤認為事件起點;不憑未知擴充、截斷內容或假設的執行情況扣分。輸入超長會明確標示需人工確認。
  • 不額外要求防呆、特定命名、任意輸入或老師未列出的功能;「A 或 B」只需滿足其中一項。未完成加分題不扣分。
  • 分數由後端依 100 − 扣分總和 + 加分 計算,限制在 0~110 並四捨五入;完全相同的重複扣分合併,衝突的同規則扣分、缺少明細或非法數值會視為評分失敗,不保存為正式成績。AI 對功能的判斷仍須教師覆核,這些檢查不等於保證評分正確。
  • 初始範本完全未修改時,本機直接判為 0 分,不耗模型額度;這種本機判定不可冒充模型校正。

舊部署更新步驟:備份自己的設定與成績 → 上傳本 README「Colab 啟動」列出的全部後端檔案 → 重新啟動 Colab 工作階段並重新執行啟動器 → 在教師頁重新上傳原本的初始範本/參考解答 .sb3,讓它們使用新版解析文字 → 儲存設定 → 每關重新做盲評校正。

內部分析版本會自動讓舊快取與舊校正失效,不需手動刪除 Firestore。既有成績紀錄不會被覆寫;若需要新版成績,須重新提交評分。系統只做靜態程式分析,未在 Scratch 中實際執行作品;課堂前仍需用自己的真實樣本測試模型的扣分判斷與回覆時間。

開啟後端的 /api/health 可確認 version=2026-10-03-evidence 與 analysis_revision=2026-10-03-evidence-v2。若分析版本仍舊或顯示 outdated-restart-required,請重新啟動工作階段,不要只重新載入 colab_server。

Scratch 官方繁中積木詞彙

批改前會將 .sb3 的 opcode 轉為 Scratch 官方繁體中文積木名稱,再提供給 AI。例如 motion_movesteps 會輸出為「移動 10 點」,不會把英文技術代號當成學生可見用語。

詞彙快照來自 Scratch Foundation 的 scratch-l10n(zh-tw)與 scratch-vm,並固定記錄來源提交版本。目前涵蓋 218 個 Scratch VM 官方核心與官方擴充 opcode;常見的 project.json 內部輸入積木也有中文處理。

若學生使用未收錄的第三方/自訂擴充,系統會標出「積木詞彙覆蓋警告」。AI 被要求不得猜測這些積木的功能或因此扣分;教師可在自訂擴充規則中補充其用途。

更新官方詞彙快照時,使用 tools/sync_official_scratch_zh_tw.py 對照官方來源後重新產生 JSON。提交前請執行:

python -m unittest discover -s tests -v

第一次設定(必要)

此公開專案不含 ngrok authtoken、Gemini/Google API key、Firebase API key、服務帳戶或任何既有資料。每位使用者都必須建立並使用自己的設定:

  1. 在 ngrok 建立自己的 authtoken 與靜態網域。
  2. 為教師端產生一組長且隨機的 ADMIN_TOKEN。它只存在 Colab Secrets,不要寫進 HTML 或程式碼。
  3. 若要使用 Firestore,建立自己的服務帳戶並授予該帳戶 Firestore 存取權。把其完整 JSON 放入 Colab Secret FIREBASE_SERVICE_ACCOUNT_JSON。
  4. 將 Firestore 規則改為拒絕公開讀寫。此專案的瀏覽器不會直接讀取 Firestore,所有資料應只透過後端服務帳戶存取。

若你曾在早期的私人測試版本使用過自己的憑證,請自行到 ngrok/Google Cloud 撤銷並重建那些憑證;這與目前公開專案的內容無關。

建議的 Firestore 規則:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} { allow read, write: if false; }
  }
}

外部服務設定指南

以下帳號、專案與金鑰都應由每位部署者自行建立;不要共用、不要上傳到 GitHub,也不要貼在學生端網頁。

1. Gemini API(必要)

  1. 開啟 Google AI Studio 的 API key 頁面,使用自己的 Google 帳號/Google Cloud 專案建立 Gemini API key。
  2. 依 Gemini API key 官方說明 管理、限制與輪替 key。
  3. 啟動系統後,在教師頁面輸入 key 並按「儲存設定」;key 只會送到後端,不會寫入 app-config.js、.env 或 GitHub。

API key 會依部署方式保存在 Firestore 或目前的後端設定檔。若是共用教學環境,建議為每個班級或測試環境建立獨立 key,以便停用與用量管理。

即時線上回饋:建議使用付費 Gemini 2.5 Flash

本專案的即時學生回饋預設使用 gemini-2.5-flash 搭配付費帳號。它適合需要較快、較穩定回覆的課堂情境;模型名稱不寫死,教師仍可在頁面載入自己 API key 可用的模型後更換。

  • 課堂正式使用時,建議先選 gemini-2.5-flash,並維持評分佇列與冷卻秒數,避免全班同時送出時造成額度或等待問題。
  • Gemma 可作為成本優先、測試或非即時情境的替代方案;是否採用應以實際作業的回覆時間、評分一致性與帳號額度測試決定。
  • 後續會依實際班級的評分時間、成功率、等待佇列長度與 API 用量資料,調整模型、MAX_CONCURRENT_GRADES 與每份冷卻秒數。

Claude 付費備援與同作品一致性(選用)

本系統預設不會呼叫 Claude。只有部署者在 Colab Secrets/自己的 .env 同時設定 ANTHROPIC_FALLBACK_ENABLED=true 與 ANTHROPIC_API_KEY 後,才會在 Gemini 回傳 503,或連續兩次 500 時改由 claude-haiku-4-5-20251001 備援評分;429 額度限制及一般錯誤不會自動花費 Claude 額度。

  • 學生正式送出的作品,會依「作品邏輯 + 作業規則 + 範本/參考解答 + 評分政策版本」保存第一次完成的結果。同一份作品重送時會回傳該正式結果,不因 Gemini/Claude 切換而重新抽分。
  • 教師「單檔試評」刻意不使用快取,方便反覆修正規則與校準;因此不應把試評分數當作學生正式成績。
  • 教師可指定主模型或 Claude 分別試評;指定主模型不會悄悄切換備援。Claude 試評需先啟用備援,頁面會提示費用並要求確認。
  • 兩個供應商使用相同規則、官方繁中解析及扣分格式,後端統一算分;這能消除計算差異,但不能保證兩個模型的功能判斷完全相同,因此還有跨模型樣本校正與首次結果快取。
  • 教師成績紀錄與單檔試評會標示評分引擎、是否使用 Claude 備援、是否命中首次結果快取,便於人工覆核。
  • 修改評分規則、主題、範本或參考解答會自動形成新的快取範圍;若需刻意讓所有舊結果失效,將 GRADING_POLICY_VERSION 加一後重啟後端。

Claude 備援會產生費用。請先確認 Anthropic 帳號的額度與預算,並僅將 ANTHROPIC_API_KEY 放入部署端 Secret,絕不可填入教師頁、學生頁或 app-config.js。

每一關的試評與校正(正式課堂必做)

完整步驟、樣本配分示例與失敗修訂方法請看前段的 核心操作:建立、試評與校正評分標準。流程原則參考 course_115 的程式設計評分說明。

正式課堂請維持 CALIBRATION_REQUIRED=true:主模型需通過四種樣本盲評;啟用 Claude 時兩模型各測同四份作品,且跨模型分差與及格判定通過比較。修改評分政策或 GRADING_PROMPT_VERSION 後需重新校正。校正紀錄依實際保存位置顯示「已保存到 Firestore」或「僅保存於本機」。

2. ngrok 公開網址(必要)

  1. 註冊並登入 ngrok Dashboard。
  2. 在 Dashboard 取得自己的 authtoken;ngrok 將此視為可讓 agent 代表帳號連線的祕密,不可公開。官方說明
  3. 在你的方案可用範圍內建立或保留一個靜態網域(static domain)。
  4. 將值填入環境變數/Colab Secrets:
NGROK_AUTHTOKEN=你的_ngrok_authtoken
NGROK_STATIC_DOMAIN=你的靜態網域

啟動後,程式會印出 https://... API 網址。將該網址填入 app-config.js,供教師端與學生端連線。靜態網域本身可以公開;authtoken 不可以。

避免「網域已被 Agent 使用」

若 Colab 非正常中斷,舊 agent 可能還在線並佔用同一靜態網域,導致 ERR_NGROK_334。本專案會先清除目前 Colab runtime 的 ngrok 程序;若要連其他 runtime/裝置的舊 tunnel 一併安全釋放,請在 ngrok Dashboard 建立 API key,並額外設定:

NGROK_API_KEY=你的_ngrok_API_key
NGROK_REMOTE_RECOVERY=true

啟動器會透過 ngrok API 列出 active endpoints,僅比對 NGROK_STATIC_DOMAIN 完全相符的項目,然後停止其 tunnel session;不會停止帳號下其他網域的 agent。ngrok 的 API key 是管理 API 用途,與 agent 連線所需的 authtoken 不同。ngrok Agent 設定說明 ERR_NGROK_334 官方說明

若你正確在另一個 runtime 執行同一個正式服務,請把 NGROK_REMOTE_RECOVERY=false,避免新啟動的 Colab 中斷那個服務。

3. Firebase Firestore(選用,但建議用於保留設定與紀錄)

  1. 到 Firebase Console 建立自己的 Firebase 專案,並建立 Firestore 資料庫。請選擇正式/Production mode,不要使用允許公開讀寫的 Test mode。
  2. 到 Google Cloud Service Accounts 為同一專案建立服務帳戶,僅授予可讀寫 Firestore 所需的角色(例如 Cloud Datastore User)。採用最小權限原則。Firestore IAM 官方說明
  3. 為該服務帳戶建立 JSON 私鑰。此檔案等同後端身分憑證,不能上傳 GitHub、不能寄給學生。
  4. 在 Colab 將完整 JSON 放入 FIREBASE_SERVICE_ACCOUNT_JSON Secret;在自己的電腦/伺服器則將 JSON 存在未被版控的檔案,並設定:
FIREBASE_ENABLED=true
FIREBASE_PROJECT_ID=你的_firebase_專案_ID
FIREBASE_SERVICE_ACCOUNT_FILE=service-account.json
  1. 將 Firestore Rules 保持為上方的 allow read, write: if false;。本系統後端使用服務帳戶 OAuth 存取,權限由 IAM 控制;瀏覽器不會直接讀取 Firestore。Firestore REST 驗證官方說明

本專案不需要 Firebase Web API key。請不要建立或填寫 FIREBASE_API_KEY。

4. Google Colab Secrets(Colab 部署時必要)

開啟 Google Colab 後,在左側 Secrets 面板建立下列項目,並允許此 notebook 存取它們:

Secret 名稱 必要性 填入內容
NGROK_AUTHTOKEN 必要 ngrok 的祕密 authtoken
NGROK_STATIC_DOMAIN 必要 你的 ngrok 靜態網域
NGROK_API_KEY 建議 自動釋放同網域舊 tunnel session 的管理 API key
NGROK_REMOTE_RECOVERY 選用 true 時啟用精準的遠端復原,預設為 true
ANTHROPIC_FALLBACK_ENABLED 選用 設為 true 才允許 Gemini 容量/內部錯誤時使用 Claude 付費備援
ANTHROPIC_API_KEY Claude 備援時必要 Anthropic API key;只放在 Colab Secret,不可放在網頁或 Git
ANTHROPIC_MODEL 選用 備援模型,預設 claude-haiku-4-5-20251001
ADMIN_TOKEN 必要 自行產生的長隨機教師管理密碼
FIREBASE_ENABLED 選用 使用 Firestore 時填 true
FIREBASE_PROJECT_ID Firestore 時必要 Firebase 專案 ID
FIREBASE_SERVICE_ACCOUNT_JSON Firestore 時必要 完整服務帳戶 JSON 內容
CORS_ALLOWED_ORIGINS 正式網站建議 前端網址,例如 https://example.github.io
MAX_CONCURRENT_GRADES 選用 同時評分數,預設 3
MAX_QUEUED_GRADES 選用 最多等待中的評分數,預設 24

將 ScratchGrader_Secure_Colab.ipynb、scratch_grader_core.py 與 colab_server.py 上傳到同一個 Colab 工作階段,依序執行 notebook 儲存格。缺少必要 Secret 時,啟動器會直接提示缺少的名稱,不會使用預設祕密值。

5. 前端網址與 CORS

在 app-config.js 填入 ngrok 啟動後顯示的網址:

window.SCRATCH_GRADER_API_URL = 'https://你的靜態網域.ngrok-free.app';
  • 直接以本機檔案開啟 HTML(file://)時,CORS_ALLOWED_ORIGINS=* 可供測試使用。
  • 正式將 HTML 放到 GitHub Pages、學校網站等 HTTPS 網域時,請將 CORS_ALLOWED_ORIGINS 改成該確切來源;多個來源以半形逗號分隔。
  • app-config.js 只能放公開 API 網址,不能放 ADMIN_TOKEN、Gemini key、ngrok authtoken 或服務帳戶 JSON。

Colab 啟動

先將下列檔案上傳到同一個 Colab 目錄(通常 /content);不能只傳兩個主要 Python 檔:

scratch_grader_core.py
colab_server.py
scratch_translation.py
scratch_official_zh_tw.json
grading_queue.py
grading_assessment.py
grading_policy.py
grading_calibration.py
grading_scoring.py
ngrok_recovery.py
ScratchGrader_Secure_Colab.ipynb

可先安裝相依套件:

!pip install -q flask flask-cors pyngrok pandas google-genai anthropic google-auth python-dotenv

在 Colab 的 Secrets 設定下列值:

import os
from google.colab import userdata

for name in [
    'NGROK_AUTHTOKEN', 'NGROK_STATIC_DOMAIN', 'ADMIN_TOKEN',
    'FIREBASE_ENABLED', 'FIREBASE_PROJECT_ID',
    'FIREBASE_SERVICE_ACCOUNT_JSON',
    'ANTHROPIC_FALLBACK_ENABLED', 'ANTHROPIC_API_KEY', 'ANTHROPIC_MODEL',
]:
    try:
        value = userdata.get(name)
        if value:
            os.environ[name] = value
    except Exception:
        pass

接著啟動:

import colab_server
colab_server.serve_background()

前端連線

只需編輯 app-config.js 的一行,把空字串改成此次 Colab 顯示的 HTTPS 網址。兩個 HTML 會自動讀取它:

window.SCRATCH_GRADER_API_URL = 'https://your-domain.ngrok-free.app';

此檔可隨前端一起公開,因為它只能包含 API 網址;絕不可放入 Gemini key、Firebase key 或 ADMIN_TOKEN。

也可在開啟 HTML 時帶入網址,例如:

ScratchGrader_teacher.html?api=https://your-domain.ngrok-free.app

首次開啟教師端會要求輸入 ADMIN_TOKEN;只保存在該瀏覽器分頁的工作階段內。學生端不需要也不會取得這個密碼。

環境變數

完整清單見 .env.example。在一般電腦或伺服器上,將它複製成 .env 並填入值即可;程式會自動讀取。Colab 請使用 Secrets 與安全啟動 notebook,不要上傳 .env。

copy .env.example .env

每次修改環境變數或 Colab Secret 後,都要重新啟動 Colab 後端;不要把 .env、服務帳戶 JSON 或任何 token 上傳到 GitHub。

後端與部署參數

參數 預設值 放置位置/如何調整 用途與建議
NGROK_AUTHTOKEN 無 .env 或 Colab Secret 必填。ngrok 帳號的 agent 認證,不可公開。
NGROK_STATIC_DOMAIN 無 .env 或 Colab Secret 必填。ngrok 指派的固定 HTTPS 網域。更換網域後,也要更新 app-config.js。
NGROK_API_KEY 空白 .env 或 Colab Secret 選用。只用於解除同一靜態網域被舊 Colab Agent 佔用的狀況。
NGROK_REMOTE_RECOVERY true .env 或 Colab Secret 設為 false 可避免新啟動的 Colab 停止另一個正在使用相同網域的部署。
PORT 5000 .env Flask 本機連接埠;通常不必改。若已被其他程式占用才改,ngrok 會自動跟隨。
ADMIN_TOKEN 無 .env 或 Colab Secret 必填。教師端管理密碼,請使用長且隨機的值;更換後需在教師頁重新輸入。
CORS_ALLOWED_ORIGINS * .env 或 Colab Secret 可呼叫 API 的前端網址,多個網址以逗號分隔。正式發布務必填入確切的 HTTPS 網址;本機 file:// 測試才使用 *。
MAX_CONCURRENT_GRADES 3 .env 或 Colab Secret 同時 AI 評分數。15 人班級和免費 Colab 建議 2~3;提高會加快處理,但更容易碰到模型額度與 Colab 資源限制。
MAX_QUEUED_GRADES 24 .env 或 Colab Secret 最多等待中的 AI 評分數。15 人班級可維持 24;超過時學生會收到稍後再試。
GRADE_RESULT_CACHE_ENABLED true .env 或 Colab Secret 學生正式評分是否保存同作品的首次完成結果。正式教學建議維持 true,避免重送改分。教師試評不受此設定影響。
GRADE_RESULT_CACHE_PATH grading_result_cache.json .env 未啟用/無法連線 Firestore 時,本機首次結果快取位置;已被 Git 忽略。Colab 重啟後是否保留取決於 runtime。
GRADING_POLICY_VERSION 1 .env 或 Colab Secret 手動提升此值可讓所有既有正式評分重新計算;通常只要改規則,系統已會自動使用新的快取範圍。
CALIBRATION_REQUIRED true .env 或 Colab Secret 正式課堂應維持 true。每關主模型需通過四份盲評校正;啟用 Claude 時兩模型各四份及跨模型比較都須通過。
GRADING_PROMPT_VERSION 1 .env 或 Colab Secret 自行修改提示詞後提升以要求重新校正;專案內部分析版本更新也會自動使校正/正式快取失效。若修改會影響正式評分,請同時提升 GRADING_POLICY_VERSION。
ANTHROPIC_FALLBACK_ENABLED false .env 或 Colab Secret 設 true 且存在有效 Anthropic key 後,才允許 Claude 付費備援。預設關閉。
ANTHROPIC_API_KEY 空白 僅 Colab Secret/本機 .env Claude 備援的祕密金鑰;不可填在教師頁、HTML、app-config.js 或 Git。
ANTHROPIC_MODEL claude-haiku-4-5-20251001 .env 或 Colab Secret Claude 備援模型。修改後應重做四份校準作品。
CONFIG_PATH grader_config.json .env 未使用或無法連線 Firestore 時的本機設定檔位置。此模式隨 Colab 重啟可能遺失。

Firestore 資料保存參數

參數 預設值 放置位置/如何調整 用途與建議
FIREBASE_ENABLED false .env 或 Colab Secret 設為 true 才保存教師設定與學生紀錄到 Firestore。未啟用時僅保存在當前工作階段。
FIREBASE_PROJECT_ID 空白 .env 或 Colab Secret 啟用 Firestore 時必填,填入自己的 Firebase/Google Cloud 專案 ID。
FIREBASE_CONFIG_COLLECTION scratchgrader .env 教師共用設定所在集合名稱。多班級共用同一個 Firestore 時可改為不同名稱以隔離資料。
FIREBASE_CONFIG_DOCUMENT config .env 教師共用設定文件名稱。不同班級應使用不同名稱,避免最後儲存者覆蓋其他班級設定。
FIREBASE_SUBMISSIONS_COLLECTION scratchgrader_submissions .env 學生自評紀錄集合名稱;可依班級改名隔離。
FIREBASE_RESULTS_COLLECTION scratchgrader_results .env 正式評分首次結果快取集合;啟用 Firestore 時可跨 Colab 重啟保留,避免同作品重送改分。
FIREBASE_SERVICE_ACCOUNT_JSON 空白 僅 Colab Secret 完整服務帳戶 JSON。不可寫入 .env、HTML 或 GitHub。
FIREBASE_SERVICE_ACCOUNT_FILE 空白 本機 .env 服務帳戶 JSON 的本機路徑;檔案必須保留在版控之外。
GOOGLE_APPLICATION_CREDENTIALS 空白 本機 .env FIREBASE_SERVICE_ACCOUNT_FILE 的替代方案,填入服務帳戶 JSON 路徑。

教師頁面可調整的評分設定

這些不是環境變數;由教師登入教師頁填寫並儲存。FireStore 可用時會永久保存,否則僅保留目前 Colab 工作階段。

設定 如何調整 影響範圍
API Key 1/2 在教師頁輸入自己的付費 Generative AI API key 用於取得模型清單與進行即時評分。請勿公開或放入前端程式。
評分模型 按「載入可用模型」後選擇 預設、建議值為 gemini-2.5-flash,適合課堂即時回饋;Gemma 可作為成本優先的替代方案。
每份冷卻秒數 教師頁調整,預設 13 秒 全系統每次開始呼叫 AI 前至少間隔的秒數。付費 gemini-2.5-flash 先維持 5~13 秒,之後依實際成功率與用量資料調整。
達成門檻/優秀門檻 教師頁調整,預設 75/90 分 分別換算為 2⭐/3⭐;低於達成門檻為 0⭐。優秀門檻不得低於達成門檻。
跨模型校正容許分差 教師頁調整,預設 10 分,範圍 0~110 對應後端設定 calibration_score_tolerance,不是 Secret。啟用 Claude 時,同樣本的分差不得超過此值且及格判定必須一致;修改會使本關校正失效。
關卡識別碼與四份校正樣本 每關填入唯一識別碼,儲存後依序上傳四份樣本試評 每關必做四種情境;Claude 啟用時需兩模型各通過四項且跨模型比較通過。未通過時學生端會拒絕正式評分。
試評/校正供應商 在⑥選擇主模型或已啟用的 Claude 只控制本次教師試評,不改變學生主模型;指定主模型遇 503/連續 500 不會自動轉 Claude。
作業主題與評分規則 直接編輯,或用參考解答產生後再審閱 決定 AI 依據什麼標準評分;教師修改後必須按「儲存設定」才會提供給學生。
初始範本與參考解答 .sb3 上傳後轉成虛擬碼並儲存 可讓評分依指定範本/解答比較。
是否依標準答案評分 教師頁勾選 勾選時重視是否符合參考解答;取消時較著重教師規則與創意。
是否向學生顯示分數 教師頁勾選 取消後仍會記錄真實分數(Firestore 啟用時),但學生只看到分析與建議。
是否向學生顯示任務成果 教師頁勾選 可獨立決定是否顯示 0⭐/2⭐/3⭐ 與是否達成;即使隱藏分數,也可保留明確的學習成果回饋。
最大 .sb3 解析大小 教師頁調整,預設 10 MB 限制 Scratch 專案內 project.json 的解析大小;一般作業維持預設即可。

Gemini/Gemma API key 不放在 .env,而是由教師登入教師頁面後輸入並保存於後端設定。請使用新的 key,並在 Google Cloud Console 限制其 API 與使用來源。

前端網址參數

app-config.js 只調整下列公開網址,不得放入任何密碼或 API key:

window.SCRATCH_GRADER_API_URL = 'https://你的-ngrok-靜態網域.ngrok-free.app';

也可在開啟教師/學生 HTML 時附加 ?api=https://你的網域 暫時覆蓋網址,適合測試;正式發布時仍建議修改 app-config.js。

轉移給其他使用者

  1. 複製整個專案資料夾。
  2. 新使用者自行建立 ngrok、Firebase/服務帳戶及 Gemini 憑證,絕不沿用你的憑證。
  3. 填寫他自己的 .env,或在 Colab 建立同名 Secrets。
  4. 只修改 app-config.js 中的公開 API 網址。
  5. 使用 ScratchGrader_Secure_Colab.ipynb 啟動並測試教師、學生兩個頁面。

授權與開源宣言 (License)

本專案基於「共創共好」的教育精神,採用 GNU GPLv3 授權條款。

開放與自由:我們歡迎任何人、學校或商業機構自由使用、複製與修改本專案。我們相信,只要能讓這個教育工具變得更好,就不該限制它的發展。

開源傳染性限制:若您修改了本系統並重新發布(包含將其包裝為付費服務或商業軟體),您必須以相同的 GPLv3 授權,公開您修改後的完整原始碼。我們期盼取之於社群的成果,最終能回饋給所有的第一線教師。

免責聲明:本系統批改之評語與分數由 AI 自動生成,僅供教學輔助參考。請教師於正式登錄成績前,務必進行最終之確認與人工抽測。

About

支援繁體中文 Scratch 積木解析、Gemma/Gemini AI 回饋與班級排隊評分的 Scratch 教學輔助批改系統。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages