iT邦幫忙

2026 iThome 鐵人賽

DAY 25
0
Build on Google AI

今天學什麼?30 天用 Google AI 打造智慧學習卡系列 第 25 篇

Day 25|AI 寫完,人來決定:加入 Learning Card 編輯功能

  • 分享至 

  • xImage
  •  

昨天 Day 24,我暫時停下開發新功能,實際檢查 Gemini 產生的 15 張 Learning Cards。

結果發現,Structured Output 雖然可以確保每張卡都有固定格式:

emoji
title
content
question
answer

卻不能保證內容一定適合直接拿來當教材。

實際 Review 後,我看到了幾種問題:

Focus
→ 一張卡可能放進太多概念

Factual Accuracy
→ 知識內容可能不夠精確

Oversimplification
→ 為了容易理解而簡化過頭

所以昨天最後得到一個很重要的結論:

AI Output 是 Draft,而不是 Ground Truth。

但這也帶出下一個問題。

如果 Gemini 產生 5 張 Learning Cards,其中 4 張都沒問題,只有 1 張需要調整,我真的需要把整組重新產生嗎?

今天決定把 Human Review 再往前推一步:讓使用者可以直接編輯 AI 產生的 Learning Card。


今天想完成什麼?

目前 App 的主要資料流程已經是:

Form Data
↓
Prompt Template
↓
Gemini API
↓
Structured Output
↓
LearningCard[]
↓
React State
↓
UI

Day 23 又加入 Regenerate,所以不喜歡整組內容時,可以使用原本的條件重新產生。

但今天要處理的是另一種情況:

5 張 Learning Cards
↓
Human Review
↓
其中 1 張需要修改
↓
只修改這一張

因此今天的目標很單純:

AI Generated Draft
↓
Human Review
↓
Edit Single Card
↓
Save
↓
Update LearningCard[]
↓
React State
↓
UI

而且這次要做的是 Human Edit。

不是再請 AI 幫我修改。


怎麼請 Gemini 修改?

這次繼續使用 Gemini 3.8 Flash 協助修改 App。

我把 Scope 限制得很明確,只要求加入:

  • Learning Card 的「編輯」按鈕
  • Edit Mode
  • 編輯 emoji / title / content / question / answer
  • 「取消」與「儲存修改」
  • 儲存時只更新目前這一張 Learning Card
  • 保留原本所有 Generate、Regenerate、Loading、Error 等功能

同時也明確要求不要加入:

AI Rewrite
新增 / 刪除 Card
Firebase
LocalStorage
歷史版本
Undo / Redo
Approve / Reject
自動儲存

另外,前面 Day 16~21 已經逐漸確立一件事:

Gemini Generated Fields
├─ emoji
├─ title
├─ content
├─ question
└─ answer

App Managed Field
└─ id

所以這次也要求 id 不提供編輯。

Human Edit 可以修改教材內容,但不應該破壞 App 自己管理資料所需要的識別資訊。

Day25 new prompt add edit feature


Gemini 修改了什麼?

這次 Gemini 3.8 Flash 執行:

Ran for 188s

Edited 1 file
src/LearningCardApp.tsx

Built

Day25 Gemini Edited LearningCardApp

只修改了一個檔案,沒有去動:

Prompt Template
Structured Output Schema
LearningCard type
Gemini API

修改完成後,原本單純顯示 Learning Card 的畫面多了一個「編輯」按鈕。

流程變成:

Display Mode
↓
點擊「編輯」
↓
Edit Mode
↓
取消 / 儲存修改

進入 Edit Mode 後,可以看到:

Emoji
Title
Content
Question
Answer

五個欄位。

而 id 沒有出現在編輯介面。

這也符合目前 App 的資料分工。

Day25 new edit feature

Day25 Edit learning card ui


為什麼這次不需要 Gemini API?

這也是今天實作後,我覺得很有意思的地方。

如果使用者只是覺得:

「這個標題太長,我想改短一點。」

其實完全沒有必要走:

Human
↓
Prompt
↓
Gemini API
↓
Structured Output
↓
重新產生

直接:

Human
↓
Edit
↓
React State

反而更簡單。

生成式 AI 可以負責快速建立第一版 Draft,但最後的內容控制權還是在使用者手上。

所以今天雖然是在做 AI App,卻完全沒有增加新的 AI API 功能。


Test A|真的可以修改 AI 產生的 Card 嗎?

接著開始實際測試。

這次設定:

學習對象:7~8 歲兒童
學習主題:太陽系
卡片數量:5

Day25 產生學習卡7-8歲太陽系5張

Gemini 成功產生:

1. 🌌 認識太陽系
2. ☀️ 亮亮的太陽
3. 🪐 八大行星
4. 🌍 我們住的地球
5. 🌕 地球的好朋友月亮

Day25 TestA 7-8y solar 5cards before

這次選擇第 4 / 5 張:

🌍 我們住的地球

進行 Human Edit。

原本內容是:

Title:
我們住的地球

Content:
地球是我們居住的地方,它是八大行星中的一顆。
地球上有很多水和空氣,所以有生命喔!

Question:
我們住在哪顆行星上?

Answer:
地球。

點擊「編輯」後,畫面成功進入 Edit Mode。

Day25 TestA edit earth card before

可以修改:

Emoji
Title
Content
Question
Answer

同時提供:

取消
儲存修改

而 id 並沒有出現在畫面中。


把「我們住的地球」改成「地球」

這次先做一個最簡單的修改。

把:

我們住的地球

改成:

地球

其他 Content、Question、Answer 都保持不變。

接著按下:

儲存修改

畫面立即離開 Edit Mode。

Day25 Test edited title earth

原本:

🌍 我們住的地球

成功變成:

🌍 地球

其他內容則維持原本資料。

因此 Test A:

PASS ✅

Day25 TestA edited earth after

整個流程成功走完:

LearningCard
↓
Edit Mode
↓
Human Edit
↓
Save
↓
React State 更新
↓
Display Mode
↓
顯示修改後資料

這也代表使用者不需要為了一個小修改,把另外四張正常的 Learning Cards 一起重新產生。


Test B|修改一張,其他 Card 會不會一起被改掉?

接下來測試另一個重要情境。

今天不是要 Replace 整組 Learning Cards,而是:

只修改目前這一張。

儲存第 4 張後,我再切換其他 Learning Cards 檢查。

結果其他卡片都保持原本內容,只有剛才編輯的 Card 被更新。

因此 Test B:

PASS ✅

目前可以理解成:

LearningCard[]
      ↓
找到目前 Card
      ↓
更新這一張
      ↓
其他 Cards 保持不變
      ↓
Updated LearningCard[]

這正是我今天需要的行為。


Test C|改到一半不想改了呢?

有 Save,當然也要測 Cancel。

這次進入 Edit Mode 後先修改內容,但不按「儲存修改」,而是直接按:

取消

結果也符合預期:

Edit Mode
↓
修改 Draft
↓
Cancel
↓
離開 Edit Mode
↓
原本 LearningCard 保持不變

尚未儲存的修改不會寫回原本的 Cards State。

因此 Test C:

PASS ✅

這也代表 Edit Mode 中正在修改的 Draft,和真正顯示中的 Learning Card 資料可以分開處理。

只有按下 Save,修改才正式生效。


三個測試結果

今天實際測試結果:

Test 驗證內容 結果
Test A Edit → Save → UI 顯示修改內容 ✅ PASS
Test B 修改單張 Card,其他 Cards 不受影響 ✅ PASS
Test C Cancel 後不寫入修改內容 ✅ PASS

到這裡,基本的 Human Edit Workflow 就完成了。


Human-in-the-loop 終於不只是「檢查」

Day 24 我一直在談 Human Review。

但如果 App 只能讓使用者看到:

「嗯,這張 AI 好像寫得不太對。」

然後什麼都不能做,那 Human-in-the-loop 其實還不完整。

現在流程終於變成:

AI Generated Draft
        ↓
Human Review
        ↓
Human Edit
        ↓
Final Learning Card

使用者不只是負責檢查 AI。

還可以真正介入 AI 的輸出,修改內容,再決定最後留下什麼。

對目前這個 Learning Card App 來說,我覺得這比再多加一個 AI Feature 更重要。


不是所有 AI App 功能都需要 AI

做到這裡,我也開始重新思考一件事。

既然這是一個使用 Gemini 的 App,很容易直覺地認為:

每個功能是不是都應該再交給 Gemini?

例如:

「幫我改寫這張」
「幫我修正這張」
「幫我重新產生這張」

當然都可以做。

但如果使用者只是想把:

我們住的地球

改成:

地球

普通的 React Edit Form 反而是更直接的解法。

所以目前 App 的角色逐漸變得清楚:

Gemini
↓
快速產生教材 Draft

Human
↓
Review

React Edit
↓
人工修改

React State
↓
保存目前 App 中的結果

AI 不一定需要負責整個 Workflow。


編輯完成後,我又發現另一個問題

原本做到這裡,我以為今天差不多可以收工了。

結果在測試不同主題時,又發現目前 App 還有一個資料狀態問題。

這次我使用 Gemini 產生:

7~8 歲兒童
太陽系
5 張

產生完成後:

Gemini
↓
太陽系 LearningCard[]
↓
React State
↓
UI 正常顯示

Human Edit 也可以正常修改。

但是,如果這時候去點上方原本 App 就存在的 ThemeSelector,例如切換到:

森林探險

原本剛產生的「太陽系」Learning Cards 就不見了。


為什麼太陽系會消失?

回頭看目前 App 的設計,其實原因很清楚。

現在同時存在兩種 Learning Card 資料來源。

一種是 App 原本就有的預設主題:

ThemeSelector
├─ 海洋動物
├─ 森林探險
├─ 交通工具
└─ ...

這些主題都有事先準備好的 Cards。

另一種則是現在透過 Gemini 動態產生的資料:

產生學習卡表單
↓
太陽系
↓
Gemini API
↓
LearningCard[]
↓
React State

問題就在這裡。

當 Gemini 產生「太陽系」後,目前的 cards State 會變成太陽系資料。

但點擊 ThemeSelector 的「森林探險」後,原本的主題切換邏輯又會載入森林探險的預設資料。

結果變成:

太陽系 LearningCard[]
↓
點擊「森林探險」
↓
載入森林探險預設 Cards
↓
setCards(...)
↓
太陽系資料被取代

而目前又沒有 Firebase、LocalStorage 或其他 Persistence。

所以這組 Gemini 動態產生的太陽系資料一旦被覆蓋,就沒有地方可以再切回去了。


Gemini 能產生不同主題,不代表 App 已經支援不同主題

這個問題其實讓我重新看了一次目前的 App。

從 Gemini 的角度:

海洋動物 ✅
交通工具 ✅
太陽系   ✅
人體器官 ✅

Prompt 本身早就可以產生不同主題。

但從 App 的角度來看,目前其實還是:

預設 Theme Data
+
目前這一次 Gemini Generated Cards

並沒有真正把「動態產生的主題」納入同一套 Theme 管理。

也就是:

Gemini 已經支援不同主題,不代表我的 App 已經真正支援不同主題。

這個問題今天先記下來,不急著順手修改。

不然好不容易控制住 Day 25 的 Scope,又會一路改到 Theme Architecture 去 XD。


今天完成了什麼?

Day 25 沒有修改 Prompt Template,也沒有修改 Structured Output Schema。

今天主要完成:

Display Mode
↓
Edit Mode
↓
emoji / title / content / question / answer
↓
Save / Cancel
↓
React State

三個實際測試也都通過:

Edit + Save                 ✅
只修改目前 Card            ✅
Cancel 不寫入修改          ✅

所以目前 App 已經逐漸具備:

Generate       ✅
Regenerate     ✅
Human Review   ✅
Human Edit     ✅

Learning Card 不再只是:

Gemini 產生什麼,我就顯示什麼。

而開始變成:

AI 幫忙產生,人負責最後決定。


今天最大的收穫

今天最大的收穫其實有兩個。

第一個是 Human-in-the-loop。

現在整個 Learning Card Workflow 已經變成:

Learning Requirements
↓
Gemini
↓
Structured Output
↓
LearningCard[]
↓
Human Review
↓
Human Edit
↓
Final Learning Card

人不只是站在最後檢查 AI,而是真的可以修改 AI 的結果。

第二個則是今天意外發現的 Theme 問題。

前幾天我一直在確認:

Gemini 能不能產生不同的 Learning Card?

現在答案已經很明確:可以。

但下一個問題變成:

我的 App 能不能同時管理這些不同主題的 Learning Cards?

目前答案還不算真正做到。


明天預告

目前 ThemeSelector 管理的是原本寫好的預設主題,而 Gemini 動態產生的 Cards 只存在目前的 React State。

所以:

Gemini 產生「太陽系」
↓
切換「森林探險」
↓
預設資料取代 cards
↓
「太陽系」消失

明天就從這個實際遇到的問題開始。

先不碰 Firebase,也先不做永久儲存,而是想辦法讓同一次 App Session 裡:

太陽系
↓
森林探險
↓
再切回太陽系

資料還能存在。

也順便真正整理目前的 Theme 與 Learning Card 資料關係。

Day 26|不只海洋動物:把 Learning Card 擴充成不同學習主題


上一篇
Day 24|AI 產生的教材可以直接用嗎?開始檢查 Learning Card 內容
下一篇
Day 26|不只海洋動物:把 Learning Card 擴充成不同學習主題
系列文
今天學什麼?30 天用 Google AI 打造智慧學習卡 共 28 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言