Prep|開始前先準備好
- 強烈建議用桌機或筆電;若能準備雙載具,邊看邊操作會更方便。
- 選一篇你想拿來操作的英文課文/教材;若已經有 AI 教學網頁,先準備好 HTML 程式碼。
- Google 個人帳號通常最容易操作。學校帳號也可以,但每校管理設定不同;操作時盡量只登入一個帳號。
Warm-up|先看看我們現在在哪裡
開場調查
Sylvia’s Data Flow Wall|開場彈幕
開場彈幕 QR Code
開始之前
不是每堂課都需要網頁。如果紙筆能更快、更好,就用紙筆。
Presentation|Experience the why
先當一次學生
先體驗學生端,再看教師端。
Goodbye, John|示範課程
Goodbye, John 示範課程 QR Code
先問自己:好不好玩?如果到這裡就結束,老師其實知道了什麼?
三個教學轉變
| 轉變 | 真正的價值 |
|---|---|
| Every student responds. | 從少數幾位主動學生的聲音,變成每個人都留下思考痕跡。 |
| The teacher sees the whole class. | Dashboard 不是代替老師,而是先把 30–40 位學生的訊號整理給老師看。 |
| Data tells you what NOT to teach. | 數據不只是告訴你要補教什麼,也能告訴你哪些內容可以不用重教。 |
Behind the magic
學生操作
固定資料通道
留下資料
看見全班
你不需要自己會寫這些程式。今天真正要學的是:先決定什麼 Learning Evidence 值得留下,再讓 AI 幫我們把前端、後端與資料接起來。
Practice|Learn the CARE workflow
From Play to Proof is the goal; CARE is how we get there.
Technical Prep|先把固定後台準備好
為了降低現場除錯風險,我們先把全場共用、已驗證的資料通道準備完成。這一步只是先把技術底座準備好;真正的 R,會在 A 階段確認資料後才發生。
Prep.1|建立 Google Sheet
- 在 Google Drive 新增一份 Google 試算表。
- 不需要先設計表頭;Universal GAS 會依前端送來的資料自動建立/擴充 Responses 欄位。
- 從試算表上方選單開啟:擴充功能 → Apps Script。
Prep.2|貼上 Universal GAS Backend
- 刪除 Apps Script 內的預設程式碼。
- 複製下方完整 Universal GAS Backend。
- 貼上後儲存。
Universal GAS Backend本場研習標準後端
// ======================================================
// From Play to Proof|CARE 萬用 GAS 後台
// 功能:
// 1. doPost() 接收學生資料,自動建立 / 擴充表頭
// 2. doGet() 讀取 Responses 工作表,供 Teacher Dashboard 使用
// 3. 使用 LockService,降低多人同時提交造成資料衝突的風險
// ======================================================
const SHEET_NAME = 'Responses';
// ======================================================
// 1. 接收前端寫入請求(POST)
// ======================================================
function doPost(e) {
const lock = LockService.getScriptLock();
try {
// 最多等待 30 秒取得鎖,避免多人同時修改表頭或寫入資料
lock.waitLock(30000);
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// 固定使用 Responses 工作表
let sheet = spreadsheet.getSheetByName(SHEET_NAME);
// 若尚未存在,則自動建立
if (!sheet) {
sheet = spreadsheet.insertSheet(SHEET_NAME);
}
// 檢查是否真的收到 POST 資料
if (!e || !e.postData || !e.postData.contents) {
throw new Error('未收到 POST 資料');
}
const data = JSON.parse(e.postData.contents);
// 自動加入時間戳記
data.Timestamp = Utilities.formatDate(
new Date(),
Session.getScriptTimeZone(),
'yyyy-MM-dd HH:mm:ss'
);
// --------------------------------------------------
// 將陣列 / 物件轉成 JSON 字串,方便存進 Sheet
// --------------------------------------------------
Object.keys(data).forEach(function (key) {
const value = data[key];
if (value !== null && typeof value === 'object') {
data[key] = JSON.stringify(value);
}
});
// --------------------------------------------------
// 讀取現有表頭
// --------------------------------------------------
const lastCol = sheet.getLastColumn();
let headers = [];
if (lastCol > 0) {
headers = sheet
.getRange(1, 1, 1, lastCol)
.getValues()[0]
.map(function (header) {
return String(header).trim();
})
.filter(function (header) {
return header !== '';
});
}
// --------------------------------------------------
// 自動加入尚未存在的新欄位
// --------------------------------------------------
Object.keys(data).forEach(function (key) {
if (headers.indexOf(key) === -1) {
headers.push(key);
}
});
// 若目前完全沒有表頭,或增加了新欄位,就重新寫入第一列
if (headers.length > 0) {
sheet.getRange(1, 1, 1, headers.length).setValues([headers]);
}
// --------------------------------------------------
// 依照表頭順序建立學生資料列
// --------------------------------------------------
const rowData = headers.map(function (header) {
return data[header] !== undefined && data[header] !== null
? data[header]
: '';
});
sheet.appendRow(rowData);
return ContentService
.createTextOutput(
JSON.stringify({
status: 'success',
message: '資料已接收'
})
)
.setMimeType(ContentService.MimeType.JSON);
} catch (error) {
return ContentService
.createTextOutput(
JSON.stringify({
status: 'error',
message: error.toString()
})
)
.setMimeType(ContentService.MimeType.JSON);
} finally {
// 只有真的取得 lock 時才釋放
if (lock.hasLock()) {
lock.releaseLock();
}
}
}
// ======================================================
// 2. 接收前端讀取請求(GET)
// 供 Teacher Dashboard 使用
// ======================================================
function doGet(e) {
try {
const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadsheet.getSheetByName(SHEET_NAME);
// 沒有 Responses 工作表時,直接回傳空陣列
if (!sheet) {
return ContentService
.createTextOutput(JSON.stringify([]))
.setMimeType(ContentService.MimeType.JSON);
}
const lastRow = sheet.getLastRow();
const lastCol = sheet.getLastColumn();
// 尚無學生資料
if (lastRow < 2 || lastCol < 1) {
return ContentService
.createTextOutput(JSON.stringify([]))
.setMimeType(ContentService.MimeType.JSON);
}
const values = sheet
.getRange(1, 1, lastRow, lastCol)
.getValues();
const headers = values[0];
const result = [];
// --------------------------------------------------
// 將每一列學生資料轉成 JSON object
// --------------------------------------------------
for (let i = 1; i < values.length; i++) {
const rowObject = {};
let hasData = false;
for (let j = 0; j < headers.length; j++) {
const key = String(headers[j]).trim();
if (!key) continue;
const value = values[i][j];
rowObject[key] = value;
if (value !== '' && value !== null) {
hasData = true;
}
}
// 避免把完全空白列送到 Dashboard
if (hasData) {
result.push(rowObject);
}
}
return ContentService
.createTextOutput(JSON.stringify(result))
.setMimeType(ContentService.MimeType.JSON);
} catch (error) {
return ContentService
.createTextOutput(
JSON.stringify({
error: error.toString()
})
)
.setMimeType(ContentService.MimeType.JSON);
}
}
Prep.3|部署 GAS,先拿到自己的 GAS URL
- 點右上角「部署」→「新增部署作業」。
- 類型選「網頁應用程式」。
- 執行身分選「我」;誰可以存取務必選「所有人 (Anyone)」。
- 完成授權後,複製 Web App URL,先留在記事本備用。
完成後,今天後面通常不需要再回 Apps Script 改程式;接下來主要都在 AI 與 HTML 中操作。
C — Create|先有一份能正常操作的 HTML
已經有自己的 HTML 就直接使用,不需要重做。沒有的話,可以用講師 Starter HTML、把紙本學習單交給 AI,或從 8 個 Starter Prompts 挑一個快速生成。
Starter HTML|Animal Sleep
一份刻意保持簡單、尚未加入身分/資料提交/Learning Report/Dashboard 的演練起點。
Starter HTML_B1L3_Animal_Sleep完整 HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Do Animals Sleep like You and Me? — Starter Activity</title>
<style>
:root{
--navy:#20304a;--blue:#6ec6e8;--pink:#ef6f9a;--yellow:#ffd86b;
--green:#66c7a6;--purple:#8b7ed8;--ink:#263238;--muted:#60717b;
}
*{box-sizing:border-box}
body{margin:0;font-family:"Segoe UI",Arial,sans-serif;color:var(--ink);
background:linear-gradient(180deg,#dff4ff 0%,#f8fcff 50%,#fffaf4 100%);min-height:100vh}
.wrap{max-width:960px;margin:auto;padding:28px 18px 56px}
header{background:linear-gradient(135deg,var(--navy),#324d78);color:#fff;border-radius:28px;padding:30px;
box-shadow:0 14px 40px rgba(32,48,74,.18);position:relative;overflow:hidden}
header:after{content:"💤";position:absolute;right:28px;top:14px;font-size:74px;opacity:.16;transform:rotate(-10deg)}
.eyebrow{font-weight:800;letter-spacing:.12em;text-transform:uppercase;font-size:.78rem;color:#bfeaff}
h1{margin:.25rem 0 .45rem;font-size:clamp(2rem,5vw,3.5rem);line-height:1.05}
header p{max-width:720px;margin:0;color:#e6f6ff;font-size:1.05rem}
.pillrow{display:flex;gap:8px;flex-wrap:wrap;margin-top:18px}
.pill{background:rgba(255,255,255,.12);padding:8px 12px;border-radius:999px;font-size:.88rem}
.card{background:#fff;border-radius:22px;padding:24px;margin-top:20px;box-shadow:0 10px 30px rgba(55,84,103,.10);
border:1px solid rgba(95,145,175,.16)}
.section-title{display:flex;align-items:center;gap:12px;margin:0 0 8px;font-size:1.45rem}
.num{width:38px;height:38px;border-radius:12px;display:grid;place-items:center;color:#fff;font-weight:900;background:var(--pink);flex:none}
.hint{margin:.25rem 0 1rem;color:var(--muted);line-height:1.6}
.fact-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
.fact{padding:16px;border-radius:18px;min-height:135px;display:flex;flex-direction:column;justify-content:space-between}
.fact strong{font-size:1.04rem}.fact span{font-size:2rem}.fact small{line-height:1.45;color:#42515b}
.f1{background:#fff4c9}.f2{background:#e8fff6}.f3{background:#edf0ff}.f4{background:#ffeaf1}
.question{padding:16px 0;border-top:1px dashed #ccd8df}.question:first-of-type{border-top:none}
.qtext{font-weight:800;margin-bottom:10px;line-height:1.5}.options{display:grid;gap:9px}
.option{display:flex;gap:10px;align-items:flex-start;border:1px solid #d8e3e9;border-radius:14px;padding:12px 14px;
cursor:pointer;transition:.18s;background:#fbfdff}
.option:hover{transform:translateY(-1px);border-color:#9ccfe3;background:#f3fbff}
input[type=radio]{margin-top:4px;accent-color:var(--pink)}
select,textarea{width:100%;border:1.5px solid #cbdbe4;border-radius:14px;padding:12px;font:inherit;background:#fff;color:var(--ink)}
textarea{min-height:100px;resize:vertical;line-height:1.5}
.cause-grid{display:grid;grid-template-columns:180px 1fr;gap:10px 14px;align-items:center}
.animal-label{font-weight:800;background:#f4f8fb;border-radius:12px;padding:12px}
.actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:18px}
button{border:0;border-radius:14px;padding:13px 18px;font:inherit;font-weight:800;cursor:pointer;transition:.18s}
button:hover{transform:translateY(-1px)}.primary{background:var(--navy);color:#fff}.secondary{background:#eef4f7;color:var(--navy)}
#result{display:none;margin-top:16px;padding:16px;border-radius:16px;background:#f0fbf7;border:1px solid #bde9d8}
.feedback{font-size:.92rem;margin-top:8px;font-weight:700}.correct{color:#1f9d68}.incorrect{color:#d9534f}
.footer-note{margin-top:18px;color:#6c7b85;font-size:.86rem;text-align:center;line-height:1.5}
@media(max-width:760px){.fact-grid{grid-template-columns:repeat(2,1fr)}.cause-grid{grid-template-columns:1fr}}
</style>
</head>
<body>
<div class="wrap">
<header>
<div class="eyebrow">Lesson 3 · Starter HTML</div>
<h1>Do Animals Sleep like You and Me?</h1>
<p>A short interactive reading check about four surprising animal sleeping habits.</p>
<div class="pillrow">
<span class="pill">🦒 Giraffe</span><span class="pill">🦦 Sea Otter</span>
<span class="pill">🐬 Dolphin</span><span class="pill">🐦 Alpine Swift</span>
</div>
</header>
<section class="card">
<h2 class="section-title"><span class="num">1</span>Quick Facts</h2>
<p class="hint">Read these short clues before you answer.</p>
<div class="fact-grid">
<div class="fact f1"><span>🦒</span><strong>Giraffe</strong><small>Some giraffes sleep only about 30 minutes a day and avoid long naps when predators are nearby.</small></div>
<div class="fact f2"><span>🦦</span><strong>Sea otter</strong><small>Sea otters may float on their backs and hold paws so they do not drift away from one another.</small></div>
<div class="fact f3"><span>🐬</span><strong>Dolphin</strong><small>Only half of a dolphin's brain sleeps at one time so it can keep swimming, breathing, and watching for danger.</small></div>
<div class="fact f4"><span>🐦</span><strong>Alpine swift</strong><small>These migratory birds can take short naps while flying, helping them avoid danger on the ground.</small></div>
</div>
</section>
<section class="card">
<h2 class="section-title"><span class="num" style="background:var(--green)">2</span>Reading Check</h2>
<p class="hint">Choose the best answer. Then click <strong>Check My Answers</strong>.</p>
<div class="question">
<div class="qtext">1. Which animal sleeps very little and avoids long naps because it may need to escape predators quickly?</div>
<div class="options">
<label class="option"><input type="radio" name="q1" value="A">A. Sea otter</label>
<label class="option"><input type="radio" name="q1" value="B">B. Giraffe</label>
<label class="option"><input type="radio" name="q1" value="C">C. Dolphin</label>
<label class="option"><input type="radio" name="q1" value="D">D. Alpine swift</label>
</div><div class="feedback" id="fb-q1"></div>
</div>
<div class="question">
<div class="qtext">2. Why do sea otters hold their paws together while sleeping?</div>
<div class="options">
<label class="option"><input type="radio" name="q2" value="A">A. To keep warm in the air</label>
<label class="option"><input type="radio" name="q2" value="B">B. To avoid floating away</label>
<label class="option"><input type="radio" name="q2" value="C">C. To help them dive faster</label>
<label class="option"><input type="radio" name="q2" value="D">D. To hide from birds</label>
</div><div class="feedback" id="fb-q2"></div>
</div>
<div class="question">
<div class="qtext">3. What is special about a dolphin's sleep?</div>
<div class="options">
<label class="option"><input type="radio" name="q3" value="A">A. It sleeps only in groups.</label>
<label class="option"><input type="radio" name="q3" value="B">B. It sleeps only on land.</label>
<label class="option"><input type="radio" name="q3" value="C">C. Half of its brain stays awake.</label>
<label class="option"><input type="radio" name="q3" value="D">D. It never sleeps.</label>
</div><div class="feedback" id="fb-q3"></div>
</div>
<div class="question">
<div class="qtext">4. What common idea best explains these animals' unusual sleeping habits?</div>
<div class="options">
<label class="option"><input type="radio" name="q4" value="A">A. They want to sleep longer than humans.</label>
<label class="option"><input type="radio" name="q4" value="B">B. They are trying to survive and avoid danger.</label>
<label class="option"><input type="radio" name="q4" value="C">C. They all live in the same environment.</label>
<label class="option"><input type="radio" name="q4" value="D">D. They all eat the same food.</label>
</div><div class="feedback" id="fb-q4"></div>
</div>
</section>
<section class="card">
<h2 class="section-title"><span class="num" style="background:var(--purple)">3</span>Cause → Effect</h2>
<p class="hint">Choose the effect that matches each animal's situation.</p>
<div class="cause-grid">
<div class="animal-label">🦒 Giraffe</div>
<select id="ce1"><option value="">Choose an effect...</option><option value="A">It avoids long naps.</option><option value="B">It locks paws with others.</option><option value="C">Half of its brain stays awake.</option><option value="D">It takes short naps in flight.</option></select>
<div class="animal-label">🦦 Sea otter</div>
<select id="ce2"><option value="">Choose an effect...</option><option value="A">It avoids long naps.</option><option value="B">It locks paws with others.</option><option value="C">Half of its brain stays awake.</option><option value="D">It takes short naps in flight.</option></select>
<div class="animal-label">🐬 Dolphin</div>
<select id="ce3"><option value="">Choose an effect...</option><option value="A">It avoids long naps.</option><option value="B">It locks paws with others.</option><option value="C">Half of its brain stays awake.</option><option value="D">It takes short naps in flight.</option></select>
<div class="animal-label">🐦 Alpine swift</div>
<select id="ce4"><option value="">Choose an effect...</option><option value="A">It avoids long naps.</option><option value="B">It locks paws with others.</option><option value="C">Half of its brain stays awake.</option><option value="D">It takes short naps in flight.</option></select>
</div>
<div class="feedback" id="fb-ce"></div>
</section>
<section class="card">
<h2 class="section-title"><span class="num" style="background:var(--pink)">4</span>Think & Reflect</h2>
<p class="hint">There is no single correct answer here.</p>
<label for="reflection"><strong>Which animal sleeping habit surprised you the most? Why?</strong></label>
<textarea id="reflection" placeholder="I was most surprised by... because..."></textarea>
</section>
<section class="card">
<h2 class="section-title"><span class="num" style="background:var(--yellow);color:#5d4c00">5</span>Finish</h2>
<div class="actions">
<button class="primary" onclick="checkAnswers()">✅ Check My Answers</button>
<button class="secondary" onclick="resetActivity()">↻ Reset</button>
</div>
<div id="result"></div>
</section>
<div class="footer-note">Workshop starter page — intentionally simple: no student identity, no cloud submission, no learning report, and no teacher dashboard yet.</div>
</div>
<script>
const answerKey={q1:"B",q2:"B",q3:"C",q4:"B"};
const causeEffectKey={ce1:"A",ce2:"B",ce3:"C",ce4:"D"};
function getRadioValue(name){
const s=document.querySelector(`input[name="${name}"]:checked`);
return s?s.value:"";
}
function checkAnswers(){
let correct=0,answered=0;
Object.entries(answerKey).forEach(([q,key])=>{
const value=getRadioValue(q),fb=document.getElementById(`fb-${q}`);
if(value) answered++;
if(value===key){correct++;fb.textContent="✓ Correct";fb.className="feedback correct";}
else if(!value){fb.textContent="Please choose an answer.";fb.className="feedback incorrect";}
else{fb.textContent=`Not quite. The best answer is ${key}.`;fb.className="feedback incorrect";}
});
let ceCorrect=0;
Object.entries(causeEffectKey).forEach(([id,key])=>{
const value=document.getElementById(id).value;
if(value) answered++;
if(value===key){ceCorrect++;correct++;}
});
const ceFb=document.getElementById("fb-ce");
if(ceCorrect===4){ceFb.textContent="✓ Great! All four matches are correct.";ceFb.className="feedback correct";}
else{ceFb.textContent=`${ceCorrect}/4 matches are correct. Review the facts and try again.`;ceFb.className="feedback incorrect";}
const reflection=document.getElementById("reflection").value.trim();
const result=document.getElementById("result");
result.style.display="block";
result.innerHTML=`<strong>Objective score: ${correct} / 8</strong><br>Answered objective items: ${answered} / 8`+
(reflection?"":"<br><small>Tip: add your reflection before you finish.</small>");
result.scrollIntoView({behavior:"smooth",block:"center"});
}
function resetActivity(){
document.querySelectorAll('input[type="radio"]').forEach(el=>el.checked=false);
document.querySelectorAll('select').forEach(el=>el.value="");
document.getElementById("reflection").value="";
document.querySelectorAll('.feedback').forEach(el=>{el.textContent="";el.className="feedback";});
const result=document.getElementById("result");result.style.display="none";result.innerHTML="";
window.scrollTo({top:0,behavior:"smooth"});
}
</script>
</body>
</html>
8 個高中英文網頁 Starter Prompts
沒有現成 HTML 時,挑一個最接近你課堂需求的起點(已精選高穩定度題型)。
① 單字複習網頁Starter Prompt
請根據我提供的英文教材,製作一個適合高中生使用的互動式單字複習網頁。
請包含:
1. 重要單字與中文解釋
2. 單字例句
3. 點擊可查看意思
4. 10 題單字選擇或配對活動
5. 作答後立即顯示正確答案與簡短回饋
請產生完整單一 HTML 程式碼,CSS 與 JavaScript 都包含在同一份檔案中。
網頁需適合電腦、Chromebook 與平板操作。
② 閱讀理解互動學習單Starter Prompt
請將我提供的英文文章製作成高中英文互動閱讀網頁。
請保留原文,並加入:
1. 重要單字或片語點擊提示
2. 段落重點提示
3. 5–8 題閱讀理解題
4. 包含主旨、細節、推論等不同層次
5. 學生作答後立即看到回饋
6. 最後加入一題簡短 Reflection
請產生完整、可直接使用的單一 HTML 程式碼。
③ 文法練習網頁Starter Prompt
請根據我提供的文法教材,製作一個高中英文文法互動練習網頁。
流程為:
文法重點簡短說明
→ 範例
→ 引導練習
→ 獨立練習
→ 即時回饋
請避免只有大量選擇題,可以混合:
- 選擇
- 填空
- 句型改寫
- 找錯
- 造句
請產生完整單一 HTML 程式碼,適合學生自行操作。
④ Exit Ticket|離場卷Starter Prompt
請根據今天的課程內容,設計一個 5 分鐘可以完成的英文課 Exit Ticket 網頁。
內容包含:
1. 2 題知識理解題
2. 1 題應用題
3. 1 題「今天最清楚的是什麼?」
4. 1 題「還有什麼地方不懂?」
畫面簡潔,不需要複雜動畫。
學生完成後請在畫面上整理出他的回答摘要。
請產生完整單一 HTML 程式碼。
⑤ Vocabulary Mission|單字任務Starter Prompt
請把我提供的高中英文單字與課文內容設計成一個「Vocabulary Mission」互動任務網頁。
學生需要完成 3 個小任務:
Mission 1:單字配對
Mission 2:情境選字
Mission 3:用線索破解最後密碼
難度適合高中生,不要太幼稚。
每完成一關立即給簡短英文或中文回饋。
請產生完整單一 HTML 程式碼。
⑥ Choose Your Response|情境選擇Starter Prompt
請根據我提供的英文主題,設計一個情境式英文互動網頁。
學生會遇到 4–6 個情境,每個情境需要選擇最適合的英文回應。
選完後:
- 告訴學生這個回答是否恰當
- 解釋語氣或用法
- 讓學生進入下一個情境
最後顯示學生的選擇結果與簡短回顧。
請產生完整單一 HTML 程式碼。
⑦ Speaking Warm-up|口說前情境鷹架Starter Prompt
請根據我提供的英文單元主題,製作一個高中英文口說前暖身網頁。
學生先選擇或輸入自己想說的內容,再透過網頁完成簡短的英文情境任務。
請提供:
1. 情境說明
2. 2–3 個 sentence starters
3. 可使用的關鍵字
4. 一個簡短任務
5. 最後請學生整理出自己準備對真人同學說的英文
目的不是讓 AI 取代真人口說,而是作為真人 pair work 前的鷹架。
請產生完整單一 HTML 程式碼。
⑧ What Would You Do?|沒有標準答案的討論型Starter Prompt
請根據我提供的英文文本或主題,製作一個「What Would You Do?」互動網頁。
學生閱讀 3–5 個與文本相關的情境後,需要做選擇並簡短說明原因。
部分題目可以沒有唯一正確答案。
目標是讓學生:
- 理解文本
- 做出判斷
- 表達個人觀點
- 為後續小組討論做準備
最後整理學生所有選擇與文字回答。
請產生完整單一 HTML 程式碼。
A — Augment|先規劃,再讓 AI 動手
這一步先不要寫程式。如果您使用一般 AI,把以下三樣材料放進同一個 AI 對話,並搭配 12 字黃金指令:
- 自己的 HTML 網頁程式碼(例如 Starter HTML 或您自製的單元網頁)
- CARE Universal Upgrade Prompt(下方核心提示詞)
- 剛才取得的自己的 GAS Web App URL(第二步複製的網址)
(💡 備註:萬用後台 Code.gs 已經在第二步部署完成,升級前端時完全不需要再貼給 AI,省去繁瑣代碼複製!)
這份 Prompt 會幫你做什麼?
| 功能 | 白話版 |
|---|---|
| 保留原本活動 | 不會為了加新功能,就把你好不容易做好的網頁整個重做。 |
| 判斷哪些學習資料值得留下 | AI 先幫你想:哪些學生表現真的值得記錄,而不是什麼都收。 |
| 老師先確認 | AI 第一回合只提規劃;你說「可以,照這個做」之後才開始改。 |
| 產生學生個人學習報告 | 學生做完不只看到分數,也能回顧自己的作答與學習。 |
| 沒有後台也能完成 | 即使資料暫時送不出去,學生仍可完成活動、看到報告並下載成果。 |
| 有後台時自動收資料 | 學生作答可送進 Google Sheet,老師不用逐份整理。 |
| 整理全班學習狀況 | 建立 Teacher Dashboard,快速看出哪些題目或觀念需要處理。 |
| 自動檢查與防呆 | 盡量保護原本已成功的功能;出錯時只修必要部分。 |
途徑 A:直接使用 Sylvia 專屬客製化 Gem(最推薦、零代碼)
講師已將完整的 CARE 3.0 規範與萬用後台邏輯封裝進專屬 Gemini Gem!老師完全不需要複製長篇 Prompt 或後台代碼,直接點開專用 Gem,把 HTML 丟給它,一秒完成升級!
萬一以後不用 Gem、或習慣使用 ChatGPT / Claude / 一般 Gemini,只要在對話框貼上以下「12 字黃金指令」,並附上 (1) 你的 HTML (2) CARE Prompt (3) 你的 GAS URL 三樣材料,AI 就會完全按照 CARE 規範嚴謹升級:
請依照 CARE 規範,幫我升級這份教學網頁。
CARE Universal Upgrade Prompt
可直接貼給一般 AI,也可日後自行封裝成 Gem、Custom GPT、Skill 或交給 Agent。
CARE Universal Upgrade Prompt核心 Prompt
用途:把既有教學 HTML 升級成能留下 Learning Evidence、產生個人 Learning Report、選擇性寫入 Google Sheet,並支援 Teacher Dashboard 的「雙棲智慧教學網頁」。這份 Prompt 不依賴 Gem,可直接貼給 ChatGPT、Gemini、Claude 等一般 AI,也可自行封裝成 Gem/Skill 或交給 AI Agent 使用。
# From Play to Proof|CARE 教學網頁升級助手
## 1. 角色與任務
你是一位專精於教育科技、高中教學活動設計、HTML/CSS/JavaScript、Google Apps Script、Google Sheets、Google Sites、Learning Analytics、Formative Assessment 與 Teacher Dashboard 設計的教育網頁升級助手。
你的主要服務對象是:沒有程式設計背景、但已經使用 AI 產生教學網頁的老師。
你的任務不是從零重新設計另一個網站,而是在盡量保留原始教學網頁的教學目標、核心玩法、題目內容、活動流程與視覺風格的前提下,把它升級成能留下 Learning Evidence 的雙棲智慧教學網頁。
## 2. 核心升級目標
所有新增功能都必須服務於:留下有意義的學習證據,並支援教師做下一步教學判斷。不要為了蒐集資料而蒐集資料。
## 3. 雙棲架構|沒有 GAS 也能完成
同一個網頁必須保留兩條使用路徑:
A|沒有 GAS/GAS 暫時失敗:學生仍可完成活動 → 看到個人 Learning Report → 下載 PNG 學習成果 → 上傳 Google Classroom/LMS。
B|有 GAS:學生完成活動 → 資料送至 Google Sheet → 老師由右上角 🔒 進入 Teacher Dashboard → 讀取全班 KPI、圖表與 Student Response Wall → 調整下一步教學。
原則:GAS 是即時資料回收路徑,不是學生完成活動的入場券。
## 4. Preserve First|Augment, don't replace
除非原本功能明顯故障,否則不要刪除原活動、任意改寫題目、改變正確答案、改變主要流程、重做成完全不同的活動、破壞既有遊戲/配對/拖曳/閱讀/作答/計時/回饋/動畫,也不要任意改變原本視覺風格。
## 5. 前端與發布原則
最終學生網頁原則上維持一個完整、可直接使用的 self-contained HTML;HTML、CSS、JavaScript 放在同一份檔案中。預設要能在 Google Sites iframe/一般學校網路/Chromebook/Windows/平板/手機中合理運作。不要建立必須使用 Node.js、npm 或 build 才能執行的架構。
核心操作不要依賴瀏覽器原生 prompt()、alert()、confirm();請使用 HTML Modal、Toast、Notice Box、Inline Message 或 Inline Validation。Teacher Login 必須使用自訂 HTML Modal。
## 6. 固定兩階段工作流程
不要一收到 HTML 就直接輸出新版程式碼。
第一階段:只分析與規劃。即使使用者已同時提供 Universal GAS Backend 與 GAS Web App URL,也不得因此提前修改程式。
第二階段:老師確認後才正式產生完整 HTML。
## 7. 第一階段|先理解原網頁
先分析:學習目標、學生實際操作、可自動評分與不適合自動評分的內容、值得留下的學生行為、能幫教師做教學判斷的資料、適合的 KPI/圖表,以及值得進入 Student Response Wall 的質性回答。
請主動做教育判斷。除非真的無法判斷,不要把資料欄位設計工作全部丟回給老師。
## 8. 第一階段固定回覆格式
請依序回覆:
1. 原本值得保留的設計
2. 建議留下的 Learning Evidence
3. 個人 Learning Report 應呈現什麼
4. Teacher Dashboard 建議的 3~6 個 KPI
5. 建議圖表,以及每張圖回答的教學問題
6. Student Response Wall:哪些質性回答值得保留,順序必須依學生前端實際出現順序
7. Google Sheet 最後大致會留下哪些資料
最後只問老師:「如果這份規劃可以,請回覆『可以,照這個做。』;若要增刪資料,請現在告訴我。」
第一階段不要輸出完整 HTML,也不要修改我提供的 Universal GAS Backend。
## 9. Teacher Checkpoint
只有老師明確確認後,才進入第二階段。若老師提出增刪需求,先更新規劃並再次確認。
## 10. 第二階段|正式升級 HTML
老師確認後,請產生完整、可直接使用的單一 HTML,而不是零散修改片段。
升級內容至少包括:必要的學生身分欄位、Learning Evidence 收集、適合的自動評量、個人 Learning Report、PNG 下載備援、Teacher Dashboard、KPI、必要圖表、Student Response Wall、Refresh/Close,以及安全的錯誤狀態。
## 11. 自動評量原則
單選、多選、是非、配對、拖曳、填空、具明確答案的文法/句型題可依需要自動評量;可記錄總分、正確率、各區塊得分、各題正誤、選項分布、作答時間與有教學價值的 retryCount。
Reflection、SEL、個人意見、創意寫作、開放式閱讀回答等沒有單一標準答案的內容,不要硬判正誤;保留學生原文,呈現在 Learning Report、Google Sheet 與 Student Response Wall。
## 12. 個人 Learning Report
Learning Report 不可只顯示一個總分。可依活動包含班級、座號、姓名、日期、作答時間、總分、正確率、各區塊表現、答題摘要、參考答案、自評、Reflection、開放式回答及其他重要 Learning Evidence。
Learning Report 必須支援下載 PNG;即使 GAS 未設定或提交失敗,學生仍能完成活動、看到 Learning Report 並下載成果。
## 13. Payload 與 Universal GAS 相容
請依活動建立結構清楚的 JSON payload,並讓同一資料概念使用一致的 canonical key。前端送出的欄位名稱,必須和 Teacher Dashboard 讀取時使用的名稱一致。
本研習會提供一份 Universal GAS Backend。請把它視為固定的標準後端:不要重寫、不要改造,也不要自行另外產生 Code.gs。使用者也可能在一開始就提供自己的 GAS Web App URL;第一階段只保留這個資訊,不要動程式。老師確認後,第二階段才把該 URL 正確寫入完整 HTML。你的工作是調整前端 HTML,使 payload 可以被該後端接收,並使 Dashboard 能正確使用 doGet() 回傳的資料。
Universal GAS 會依收到的 JSON key 自動建立/擴充 Responses 表頭,array/object 會以 JSON 字串保存;活動決定收什麼,Universal GAS 負責穩定接收與讀出。
## 14. 質性資料
若活動有多個質性回答,請保留各自清楚的欄位;若原架構適合,也可額外建立 textResponses 作為 Dashboard 的質性回答備援。Student Response Wall 的題目順序必須和學生端實際出現順序完全一致。
## 15. 提交與 no-cors
若前端使用 fetch + mode:'no-cors' 送資料,請記住前端無法可靠驗證伺服器 response status/body,因此可以顯示『資料已送出』,不要在未驗證時宣稱『已成功寫入 Google 試算表』。
Submit 後要防止重複連點,顯示送出中/完成狀態;提交失敗不得破壞學生端既有活動與 Learning Report。
## 16. Teacher Dashboard
右上角固定提供清楚可辨識的 🔒 Teacher 入口,不藏在 footer 或漢堡選單。
點擊後立即顯示自訂 Teacher Login Modal;預設示範密碼為 teacher。這只是防止學生誤觸的輕量入口,不要宣稱是真正的後端 authentication。
登入後先打開 Dashboard 外框並顯示『正在讀取資料……』,再呼叫資料;若讀取失敗,Dashboard 仍保持開啟並顯示錯誤,不要讓老師以為按鈕壞了。
Dashboard 至少具備 Refresh Data 與 Close Dashboard。
## 17. Dashboard 內容原則
KPI 只選 3~6 個真正有教學意義的指標,例如提交人數、平均得分/正確率、平均自評、平均作答時間、核心題型正確率或完成率;不要為了湊數量增加無意義 KPI。
圖表只畫能回答實際教學問題的內容,例如各題正確率、錯誤選項分布、區塊表現、自評分布;不要為了視覺效果畫圖。
Student Response Wall 讓老師不用逐格讀 Sheet;顯示名稱要用老師看得懂的題目標籤,不要只顯示 q1Rewrite 之類的底層 key。
## 18. Dashboard 容錯
部分資料錯誤不等於整個 Dashboard 故障。某 KPI 沒資料顯示 —;某題沒有文字顯示『目前無資料』;圖表資料不足顯示『資料不足』;doGet() 失敗則顯示『資料讀取失敗』。其他可用部分仍應正常。
避免 undefined/null 因 .trim() 等操作造成整頁 crash;Chart.js 重畫前先 destroy 舊 instance。
## 19. End-to-End Self Check
輸出前請逐項內部檢查:學生題目 → 前端取得答案 → payload → Universal GAS doPost() → Google Sheet → doGet() → Teacher Dashboard。
至少確認:學生基本資料存在;原活動與自動評量仍正常;Learning Report 正常;PNG 可下載;沒有 GAS 時仍能完成;payload 包含 Dashboard 未來要讀的資料;GAS_URL 有清楚設定位置;Submit 防連點;🔒、Login Modal、teacher 密碼、Dashboard、Refresh、Close 都可運作;空資料不產生 NaN/undefined;每一個質性回答都能從前端一路對到 Sheet 與 Text Wall。
## 20. JavaScript 健全性
確認所有 getElementById() 對應 id 都存在、沒有重複 id、按鈕都有 handler、沒有呼叫不存在的函式、沒有變數重複宣告;Modal/Dashboard 可開關;Google Sites 不會因原生 Dialog 阻塞核心功能。
## 21. 除錯原則|Minimum Necessary Change
若後續故障,不要立刻整份重寫。先定位問題在 UI → JavaScript event → payload → POST → GAS → Sheet → GET → mapping → Dashboard render 哪一層,再做最小必要修改。
已成功的功能不要重寫;若 Sheet 已收到資料,不要優先重寫提交流程;若 GAS URL 已設定好,不得任意移除或換回 placeholder;若只要求修 Dashboard,不要順便重新設計整個網站。
## 22. 第二階段輸出規則
正式輸出完整單一 HTML。不要輸出新的 Code.gs,因為本研習使用提供的 Universal GAS Backend。
完成後只給沒有程式背景老師真正需要的下一步,且一次一個步驟;不要一次塞成工程教科書。
## 23. GAS URL 串接規則
如果老師在一開始就已提供 GAS Web App URL:第一階段不要使用它修改程式;Teacher Checkpoint 確認後,第二階段直接把它放到正確位置。如果老師是在第二階段後才補上 URL,再進行最小必要修改。無論哪種情況,其他已成功內容不要改;重新輸出完整 HTML,並再次檢查前端 payload 能被 Universal GAS 接收、Teacher Dashboard 能正確讀取 GET 回傳資料。
## 24. 最終品質標準
最終成果要讓沒有程式背景的老師只需要處理:先部署一次 Universal GAS 並取得 GAS URL、把 HTML+CARE Prompt+Universal GAS+GAS URL 交給 AI、確認 AI 的 Learning Evidence 規劃、測試一筆資料、最後把完成版 HTML 放到 Google Sites;不需要自行理解或修改其他程式碼。
學生端仍應像正常的教學活動,而不是在填資料庫;Dashboard 只呈現真正有助於教學判斷的資料;沒有 GAS 時仍能完成活動與取得 Learning Report/PNG;有 GAS 時則進一步支援全班即時 Learning Evidence 分析。
## 25. 可攜與封裝
這份 CARE Universal Prompt 是核心規則,不依賴任何單一 AI 產品。使用者未來可直接貼給一般 AI,也可以自行封裝成 Gem、Custom GPT、Skill,或交給具備檔案/終端機/部署能力的 AI Agent。
若使用 AI Agent,也不得跳過第一階段與 Teacher Checkpoint;Agent 能自動執行更多工程步驟,不代表可以跳過老師對 Learning Evidence 的確認。
一句話版本:先看懂 → 先規劃 → 我確認 → 再全部做。
第一回合|AI 先規劃,不改程式
AI 先讀懂原始活動,只提出值得留下的 Learning Evidence、Learning Report、Teacher Dashboard、圖表與質性回答規劃。這時不應輸出新版 HTML,也不應修改 Universal GAS。
Teacher Checkpoint|老師確認後再做
規劃合理就只要回覆:「可以,照這個做。」 如果有不想收的資料或缺少的重要證據,先在這一步調整。
第二回合|AI 直接產生已串好 GAS 的完整 HTML
確認後,AI 才依同一份 CARE Prompt 產生完整新版 HTML,並直接使用你已提供的 GAS Web App URL。
R — Record|只測一筆,不要一次全班上
R 的目標,是把 A 階段已確認的 Learning Evidence 真正接進資料流。後端已經準備好,這裡不再回頭部署;只驗證資料有沒有真的走通。
- 開啟完成版 HTML,確認原本活動、Learning Report、右上角 Teacher 入口都正常。
- 以學生身分只送 1 筆測試資料。
- 確認 Google Sheet 出現資料,而且欄位符合剛才確認的 Learning Evidence。
- 打開 Teacher Dashboard,確認 KPI、圖表與開放式回答都能讀回同一筆資料。
| Safety Checkpoint | 通過標準 |
|---|---|
| 1|HTML | 可以正常開啟與操作。 |
| 2|Google Sheet | 收得到 1 筆測試資料。 |
| 3|Teacher Dashboard | 讀得到同一筆資料。 |
學生完成 → Learning Report → Download PNG → Classroom/LMS → 課後再用 AI/NotebookLM 整理。
GAS 是即時資料回收的進階路徑,不是使用教學網頁的入場券。
E — Evaluate & Respond|看到資料後,下一步怎麼教?
打開 Dashboard,問自己:「看到這些資料後,我下一步會怎麼教?」
| 層次 | 用途 |
|---|---|
| 課堂當下 | 直接看 Teacher Dashboard,處理「現在我要怎麼教?」 |
| 課後分析 | 把 Sheet 資料交給 AI,處理「這批資料還告訴我什麼?」 |
Learning Evidence Analyzer Prompt
不只摘要數字,而是找出已掌握、需要處理、可能迷思、可少教什麼,以及下一步教學建議。
Learning Evidence Analyzer課堂學習資料分析助手
Learning Evidence Analyzer|課堂學習資料分析助手
你是一位協助教師進行形成性評量(formative assessment)的教學分析助手,請分析這份學生學習資料。
## 分析原則
1. 不要只摘要數據,要找出「對下一步教學有意義的模式」。
2. 不要捏造資料中不存在的資訊,若資料不足,請直接說資料不足,不要猜測。
3. 請清楚區分:
- 資料直接顯示的事實(Evidence)
- 根據資料做出的可能推論(Possible interpretation)
4. 不要只找學生不會的地方,也要指出:
- 已經掌握、可能不需要再花時間重教的內容
- 學生共同的優勢
5. 若有開放式回答或 Reflection,請整理:
- 常見想法
- 有代表性的不同觀點
- 可能的迷思或困惑
- 值得帶回全班討論的主題
6. 若資料不足以做某項判斷,請直接說「目前資料不足」,不要猜測。
## 請用以下格式回答
### 1. Quick Snapshot|快速總覽
用 3–5 點告訴我這一班目前最值得注意的狀況。
### 2. What They Already Know|已掌握
列出學生整體表現良好、可能不需要重新詳細教學的內容。
### 3. What Needs Attention|需要處理
依重要程度列出 1–3 個最值得處理的學習問題,並提供資料證據。
### 4. Possible Misconceptions|可能的迷思
若某些錯誤呈現共同模式,說明可能的原因。
請標示這是「推論」,不是已證實事實。
### 5. Student Voices|學生想法
若資料有開放式回答,整理主要觀點、差異與值得全班討論的內容。
### 6. Who May Need Support|可能需要額外支持
若資料足夠,指出哪些學生或哪些類型的學生可能需要:
- 再教一次
- 額外鷹架
- 個別確認
- 延伸挑戰
不要進行人格或能力標籤。
### 7. What NOT to Reteach|可以少教什麼
明確指出哪些內容學生已大致掌握,可以快速帶過或不必重新完整講解。
### 8. Next Teaching Moves|下一步教學建議
請給我最多 3 個具體、可立即執行的教學行動。
每一項說明:
- 為什麼值得做
- 適合全班/小組/個別
- 建議花多少時間
### 9. Teacher To-do List|教師待辦
最後列出一份簡短待辦清單,依優先順序分成:
- 🔴 下一堂課前一定處理
- 🟡 有時間再處理
- 🟢 暫時不用處理
### 10. One-sentence Insight|一句話洞察
最後請用一句話回答:
「如果我是這個班的老師,看到這份資料後,下一步最值得做的是什麼?」
---
以下是我的學生學習資料:
【請把 Google Sheet 資料、CSV、表格或學生回答貼在這裡】
Classroom Data Visualization Assistant Prompt
讓 AI 判斷什麼值得畫、用什麼圖表,以及每張圖能回答什麼教學問題。
Classroom Data Visualization Assistant形成性評量資料視覺化
你是一位協助教師分析形成性評量資料的資料視覺化助手。我會提供學生學習資料。請先分析資料結構,再判斷哪些圖表真正有助於教師理解學生學習狀況。
請遵守以下原則:
1. 不要為了畫圖而畫圖。
2. 每張圖都必須能回答一個明確的教學問題。
3. 不要捏造缺少的資料。
4. 計算比例或平均值前先確認分母與缺漏值。
5. 清楚區分原始資料與 AI 推論。
6. 優先使用容易讓老師理解的圖表:
- Bar chart
- Grouped bar chart
- Distribution chart
- Scatter plot
7. 除非資料真的適合 part-to-whole,否則避免使用 pie chart。
8. 若開放式文字無法合理分類,不要強迫視覺化。
請先告訴我:
### A. What is worth visualizing?
列出最多 3 個值得視覺化的問題,並說明原因。
### B. Recommended charts
每一張圖請提供:
- 圖表名稱
- 要回答的教學問題
- 圖表類型
- X 軸
- Y 軸
- 分組方式
- 需要使用哪些資料欄位
### C. Create the charts
依照上述建議製作圖表。
### D. Teaching Insight
每張圖最後用一句話回答:「老師看到這張圖後,最值得採取什麼行動?」
若資料不足以產生某張圖,請直接說明,不要猜測。
Optional|Google Sheets Canvas
如果你的 Google Sheets 已經出現 Canvas 功能,也可以直接在 Sheet 裡把資料做成可互動的視覺介面。沒有這項功能也完全不影響 CARE。
Google Sheets Canvas Quick PromptOptional
請根據這份學生學習資料,建立一個教師容易閱讀的互動式 dashboard。優先呈現:1. 全班完成狀況;2. 重要題目或區塊表現;3. 常見錯誤或迷思;4. 學生自評或 Reflection。不要為了好看加入沒有教學意義的圖表。目標是讓老師快速看出下一步最值得處理什麼。
Production|Use it for real
Production 的目標不是再寫一次程式,而是讓另一個人真的使用,而且老師真的收到 Learning Evidence。
Step 1|Publish
R 的三個 Safety Checkpoints 都通過後,再把完成版 HTML 放到 Google Sites。
- 開啟 Google Sites,進入要放學習單的頁面。
- 使用「嵌入程式碼」貼上 AI 產出的完整 HTML。
- 預覽正常後插入並發布。
Google Sites 是免費、穩定、低門檻的發布方式;未來也可以學習 Netlify、GitHub Pages 等其他方式。
Step 2|One real response
把網站交給一位夥伴老師實際作答,再確認:學生端 → Sheet → Dashboard 整條資料流在正式發布環境中也成功。
Step 3|Production Check
完成標準不是「我有一份程式碼」;而是另一個人真的可以使用這個網站,而且老師真的看得到 Learning Evidence。
Wrap-up|What survives when tools change?
回到最初的問題
When is technology worth the trouble?
當它能讓原本看不見的學習變得看得見,而且那些資訊真的會改變我的下一步教學時。
What’s Next?|From Proof to Agent
| 階段 | 流程 | 白話說明 |
|---|---|---|
| Today|今天 | Technical Prep 技術準備 → Existing HTML 現有網頁 → CARE Prompt → Teacher Approval 老師確認 → Ready-to-use HTML 完成版網頁 → Test 測試 → Evaluate 判讀 | 今天我們把流程拆開來做,先學會每一層在做什麼,也保留老師最後確認 Learning Evidence 的角色。 |
| Next|之後 | CARE Prompt → Gem/Skill/AI Agent | 熟悉流程後,可以把同一份 CARE Prompt 封裝成 Gem 或 Skill,或交給 AI Agent 協助完成更多修改、串接、測試與部署工作。 |
CARE 決定「應該做什麼」;Prompt、Skill、Gem、Agent 只是不同的執行方式。
工具會改變,但工作流程應該留下來。
The tools will change. The workflow should survive.
Reference Links|課後延伸
英語歌曲互動網頁版學習單:Count on Me
這是一份為臺灣高中職 A1~A2 英語課堂設計的旗艦互動學習單!具備 10 題行內三選一聽力挖空、單字語音朗讀 (TTS)、雙語鷹架句型引導 (Sentence Starters) 與成果認證小卡。
💡 課後進階挑戰:請嘗試將今天學到的 CARE 3.0 工作流 套用到這份學習單上,為它接上萬用 Google Sheets 後台,打造屬於你的第二個學習歷程收集神器!