Development Journal

實光開發紀錄

一個高中畢業十週年的線上活動平台,從設計脈絡、參與數據,到那些踩過的技術坑。

因應高中畢業十週年,想辦一個線上的紀念活動,和一些朋友與 AI 討論後,決定藉著離職待業期間練習使用 AI 開發,全程使用 Claude Code,只有後期有一個我覺得它解不好的效能問題丟給 Codex 去解看看。

TL;DR

點段落名稱可跳到內文對應位置

十年問卷用「過去/現在/未來」各十題的框架取代開放式命題,降低分享門檻;任選五題即通過第一道關卡。71 人中 38 人動筆,19 人寫到 10–19 題,3 人答滿 30 題。待改進:沒有文字格式與超連結功能,長答案不好讀;「寄信給十年後的自己」因 email 授權與服務存續問題退回手動存 PDF。
每日遊戲・三真一假每天輪換主角製造回訪動機;不強制寫價值觀,只禁止玩文字遊戲;答完立刻揭曉分佈,但刻意不公開誰選了哪一項,避免不敢作答。共 35 題、458 人次作答,平均作答率 43.2%。待改進:題目沒附主角個人頁連結;沒讓主角預先寫「假在哪、真相是什麼」;後期幾乎沒人回頭修改題目,顯示應該一開始就引導寫出最佳題目。
未來夢想寫下未來十年的一個夢想,其他人可以附議,把連結延伸到活動結束之後。35 人完成;最多人附議的夢想是財富自由。
Onboard 三道門檻問卷 → 三真一假 → 夢想全部完成才解鎖全站,確保進來的人都願意先分享,而不只是單向窺探。71 人註冊、35 人走完全程(49.3%);最大流失在問卷關(−21 人);73.2%(52 人)用 Google 登入。待改進:門檻確實增加了摩擦力,應在填答前就標示「遊戲期開始前不會公開給其他人看」讓大家放心填。
積分與表情互動把單向填答、靜態閱讀改成可對每則回答按表情,互動即得分,積分再拿去驅動養成與排行。積分明細在 dashboard 全透明呈現,看得到誰按你表情、誰附議你的夢想,由使用者自行決定要不要聯繫。
植物養成AI 依問卷答案分析人格,5 種植物 × 3 種材質共 15 型、各 5 個成長階段;最高階段刻意定為「凋萎」而非「盛開」。共 75 張圖,25 人解鎖,多數人的結果是「玻璃蕨」。已修改:上線隔天把解鎖條件從「問卷期答滿十題」放寬為遊戲期也能靠互動積分觸發。待改進:沒顯示 AI 的判斷依據,也沒讓使用者回饋準不準;達標自動分析的 cron 嫌麻煩沒做。
排行榜與連續登入總分榜外另設四個子榜(最了解同學/最積極參與/最多夢想同伴/連續王者);連續登入七天起,當日答題分數 ×1.5。各榜第一名可獲紀念盆栽;共做 30 個,線下活動只有 3 人報名,最後開放自由領取。
同學看板與 Dashboard提供以「題目」為軸的另一種剖面,橫向讀同一題所有人的回答;卡片進度條顯示已讀過幾位同學。刻意不做站內留言與私訊。不重造輪子,把聯繫導回既有社群平台,活動系統下線後也不會失聯。待改進:當時可以另外開一個註冊者都能加入的 Discord server 讓大家聊天。
活動成效活動結束後在個人 IG 限動做非正式投票,問大家藉這次活動重新聯絡上多少位老同學。17 人回覆,其中 8 人(47%)聯絡上三位以上,也就是真的超出主辦人本身。侷限:樣本自我選擇(會看限動又願意回答的人參與度偏高),且沒放「0 位」選項,因為每個人至少都會和主辦人聯絡上。故不計回覆率、不加總成總聯絡次數。
AI 開發方式全程 Claude Code,權限全部設為需人工審核,藉此了解 AI 每一步在做什麼;大部分用 sonnet,少數盤點交給 opus。抓到幾次 AI 規劃了沒必要的檢查;所選服務全部停在免費方案內即可負擔。待改進:沒做正式的使用者回饋調查(事後只在 IG 做了非正式投票),應該在最後一天答題後跳問卷或活動結束後寄出。
技術踩坑schema 把排程拆到另一張表、AI 忽略第三方 API 預設上限、基本 upsert 沒做、對 egress 沒有背景知識。首次登入耗時從 10–13 秒縮短到 5–6 秒。已修改:排程題目未同步使用者修改、排行榜卡在前 1000 筆、提醒信每分鐘限兩封、夢想欄位每次修改都新增一筆、egress 流量爆量。

設計脈絡

  1. 註冊 / 登入

  2. 個人資料

  3. 門檻一

    十年問卷

  4. 門檻二

    三真一假

  5. 門檻三

    未來夢想

  6. 進入系統

三道門檻全部完成才會解鎖全站。以下依序說明每一個環節的設計考量與實際數據。

十年問卷

一開始我就很確定我想要的是大家分享自己的故事、經驗與長大後形塑的價值觀,所以重點是如何讓人願意分享,也讓人有意願去認真閱讀彼此的故事。如果只是丟一個大主題讓大家自由發揮,那肯定寫不出什麼好的答案,倒不是因為不願認真寫,而是因為沒有框架依據讓使用者去跟隨,很容易會失焦或寫不出這些年來的各自生命累積的深度。

所以最後決定以「現在、過去和未來」三大區段各十題的問卷形式讓大家填答,至於裡面要問什麼問題,除了一開始我和 River 發想出基本的 20 題之外,也和 AI 進行多輪拷打,把一些不具體或其實問題核心重複的題目改寫,最終有了讓人一看就覺得「這個需要沉澱身心來寫」的三十題(裡面也還是有少數輕鬆的題目啦)。使用者只需要從中任選五題回答,就完成第一個參加門檻。

填答欄形式上,我有考慮要加上讓使用者可以自己編輯文字格式,但想說也不用寫成類似部落格的樣子,只是填填問卷,對使用者需要做格式決策的壓力應該比較小。後來想想沒做這個功能有點小可惜,因為有些人的答案比較長,還是會需要至少加粗體或改字級標段落的功能。另外,實際上線後發現有使用者貼上連結,但因為沒有做超連結點擊的功能,只能讓大家自己複製貼上網址,這個使用者體驗有點小可惜。

關於問卷,因為除了是讓大家分享故事之外,在答題的同時,其實也是為自己的人生沉澱留下紀錄,所以本來有規劃要在有彙整個人問卷答題的個人檔案頁面,新增一個排程寄信給十年後的自己的功能。但因為技術上面臨 email 授權考量,加上我也不確定我現在選用的郵寄服務十年後是否還會存在,最後是請大家手動把頁面存成 pdf,再用自己的郵件帳號排程寄給十年後的自己。

問卷答題數分布:兩座山峰,剛好卡在兩條門檻上

虛線是兩道門檻的位置。分布明顯雙峰,10–19 題那一叢正是被 10 題門檻吸過去的。

答滿 5 題就能玩遊戲,答滿 10 題才能解鎖植物分析。7 人停在剛好 5 題、19 人落在 10–19 題,兩個門檻各自留下一叢人。

問卷填寫畫面
圖一:問卷填寫畫面

每日遊戲

一開始我也確定要讓活動不只是個一、兩小時就結束的事件性活動,而是希望大家可以在這段期間多加互動,有更多的聯繫,所以如果只有靜態閱讀問卷回答,感覺有點無聊,而且也沒有每日回訪的動機。因此決定拿出最經典的破冰遊戲「三真一假」來作為每日遊戲的環節。

而針對三真一假的設計,一開始是有想過是否要堅持讓每個真實選項都要寫出或反應某種人生價值觀,雖然有難度但一樣可以透過框架去引導寫出,但後來想想也有點強人所難,因為使用者可能不想揭露這麼多自己的內在思想。因此最後決定只要不是操弄文字遊戲即可(比如二十歲做的事硬改成二十一歲),內容完全可以自由發揮,寫完四個選項即完成第二個參加門檻。最後證明這也蠻好的,大家的創意和想法很多元,有不少有趣的事跡分享,完全超出我原本的預想。

而題目的安排則是根據人數去排程,在活動的 13 天期間內,每天有二到四位同學的三真一假可以玩。而排程的依據則是透過我的管理者後台去看大家寫的內容,先把感覺比較有趣的人的題目排在前幾天作為引導,讓其他使用者看到後可以去修改自己的題目。每個人在自己的題目作為主角日之前都可以自由去修改,確定排程後,該同學的三真一假頁面會顯示他的主角日日期,系統也會在該同學的主角日三天前寄出最後修改機會提醒信。修改權是網路文化中的基本人權,至於要不要用到這個功能,就讓使用者自己選擇。不過實際看數據,到後期還有意願去修改自己題目的人偏少,所以這種遊戲設計的機制,最好還是一開始就要讓使用者創造出最佳題目,畢竟回頭去修改也是種時間和認知成本。

每日題目的設計,核心是讓活動期間大家都要回訪,引導每天的舞台燈光照在不同的人身上因此這裡事後回想有個可以再改善的地方,就是加上那題主角的個人頁面連結,讓大家在答題前可以去個人頁面看看那個主角的相關資訊。並且每日題目只有當天可以查看,所以如果當天沒有去作答,隔天之後就再也看不到這道題目。這個遊戲也是測驗大家對老同學過去十年的事蹟或性格是否瞭解,所以答題後答案會立刻揭曉,也可以即時看到當下的答題數據,例如各選項有多少人選擇以及答對率是多少,也可以對選項按表情符號互動。數據部分刻意設計成看不到每個選項的選擇者有誰,是因為擔心如果無法匿名答題,大家會不敢選,但如果可以的話,真想做個 A/B testing 看看如果顯示各選項答題者是誰,是否會增加 engagement。另一個可以優化的地方,我覺得是讓主角一開始寫題目的一假時,同時寫假的部分是假在哪,真正的答案應該是什麼,並在使用者答題後自動揭曉。(但這部分我是用個人的 ig 限動每日評論主角們的選項用行銷方式去補足)

每日共同題作答狀況

上:實際作答人次(灰色底槽是當天應作答人次)。下:作答率,虛線是全期加權平均 43.2%。

  • 作答人次
  • 應作答人次
  • 作答率 %
三真一假頁面
圖二:三真一假頁面(因遊戲已結束故呈現答題數據)

未來夢想

最後一個參加門檻則是填寫你未來十年的一個夢想,讓其他有志一同的人可以附議,例如有人想在竹科開餐廳,如果有人也有這個夢想,那就可以私下討論、一起實踐。即便不是在活動期間,如果是多年後有一個契機,令你想起曾經有朋友也有類似的夢想,那也是一個彼此重新連線的機會。雖然最後發現很多人的夢想都是財富自由,這個夢想也是最多人附議的🤣

整體 Onboard 統計

所以整體 onboard 流程是:註冊/登入* ➡️ 完成個人基本資料輸入 ➡️ 第一門檻:回答至少五題問卷題目 ➡️ 第二門檻:完成三真一假 ➡️ 第三門檻:填寫夢想,這樣就可以進系統看到所有頁面。在完成全部流程前,只能看到主頁和修改自己的基本資料,點擊其餘連結,系統都會強制你回到你尚未完成的關卡去完成參與門檻。這個設計的考量是因為我希望進來的人都是願意分享自己故事的人,而不是只有進來單方面窺探別人的資訊而不願袒露自我。但後來想想這個設計應該有增加 onboard 的摩擦力,因為大家不知道自己填的資訊會怎樣被呈現,就要先填,可能會有點害怕(雖然如果是我的話,我會先隨便填到足以滿足門檻的資訊進來看一下,之後再回去改)。事後回想這部分應該可以再用一個小標語說明,遊戲期開始前填寫的內容不會讓其他人看到,讓大家比較放心填寫,而不只是填完後到各頁面去查看,才看到本頁資訊在遊戲期開始前不會讓其他人看到。

Onboard 漏斗:71 人開帳號,35 人走到最後

金色是留下來的人,灰色是流失的部分,接在同一條軌道上。

  • 通過此階段
  • 流失

最大斷點在問卷完成:只有 63.2% 的人跨過去,一次少掉 21 人。

每日註冊與完成 Onboard

註冊在開放首日一次衝到 23 人,之後靠幾個時間節點推動。

  • 當日註冊
  • 當日完成 onboard

5/31 問卷期截止當天完成數衝到 8 人(全期單日最高),是明顯的截止日效應;隔日遊戲開始後回落。

積分制度

但如果只有以上設計的話,互動部分只有三真一假遊戲,感覺太少了,所以將原本單方填問卷和其他人靜態閱讀的部分,新增可以對每個答覆按表情符號互動的功能,而如何增加大家互動的動機呢?我設計了積分制度,只要有互動就能累積得分。那累積得分後可以幹嘛呢?這裡我就想到養成遊戲。那要養成什麼呢?我想能反映「時間過去,大家都有成長」的意象,還是用植物比較可以符合意象,也可以隨著積分有階段性的成長狀態。

至於植物的養成,如果每個人都是一模一樣的植物,只隨積分有階段差異的話又太無聊,也少了一種十週年團聚的集體感。所以我決定要讓大家的植物都不一樣,最後可以累積成屬於我們 31 屆的專屬花園景觀。那要怎麼讓大家的植物不一樣呢?就是根據每個人的問卷回答用 AI 做性格分析,以判斷那個人屬於什麼種類的植物。

植物種類的選擇,我和 Norman 決定要找出五種不同的植物搭配三種不同的材質,因此總共會有十五種。而決定的準則則是希望那種植物的成長階段要有較明顯的型態變化,最後確定五個種類為「蕨類、松科、罌粟科、禾草科和多肉植物」,然後每種都拆解成五個成長階段為「種子、幼苗、開花、結果和凋萎」。這裡有一個我很有感觸的決策邏輯,一開始我和 AI 討論,它給我的五階段是「種子、發芽、成長、花苞和盛開」,但 Norman 卻認為最後應該是「凋萎」,因為他覺得植物枯零的樣子也很美。我想這個提議是我怎樣和 AI 討論都討論不出的,因為所有人都太習慣最高等級就是盛開這種預設邏輯,在這裡大大讚賞 Norman 的點子!最後我們採用最高等級是凋萎的分段,除了有獨特的人類品味與美感外,其實也有很好的寓意:「在這段活動期間,我們累積養分入土回饋到自己身上,為生命畫下一個階段性的休止,下一個十年再見」。

然後因為我們的植物圖片是用 AI 輔助生成,因此有做一些小實驗,測試看看哪些材質表現出來的效果比較好,最後確定採用「玻璃、金屬與珊瑚礁」三種材質。結果最後大多數人測驗出來都是「玻璃蕨(你對細微的光和氣氛都感應得到,別人還沒察覺的時候你已經知道了。你不急著說出來,有時候只是靜靜地接收。跟你相處久的人會發現,你其實把很多東西都看在眼裡。)」這裡感覺還可以加強的設計是顯示 AI 的分析邏輯,讓使用者簡單按下讚或倒讚,回饋他是否認同這個分析。

而因為導入了積分制,可以設計的地方又多了不少。例如在遊戲開始前,我為了鼓勵使用者多填答問卷,除了滿足基本門檻得到基本積分外,每多填一題都會得到額外的積分,並且要在問卷期到達至少十題的門檻才能解鎖自己的植物種類分析。然而這裡有點失策,因為要填的題目太多,且植物種類性格分析也只是個額外的趣味,並不影響實際參加門檻,所以到遊戲開始後,很多人都沒有解鎖自己的植物。但因為我覺得既然 Norman 都設計了那麽多好看的植物圖鑑圖片(五種植物 X 五個階段 X 三個種類 = 75 張圖片),一定要盡量都曝光才有價值啊!所以活動上線隔天我就修改解鎖機制,讓遊戲開始後依然可以隨著互動積分到達解鎖門檻讓使用者觸發分析**,最後總共有 25 人解鎖。

植物解鎖累計:放寬條件後斜率才立起來

階梯面積是累計解鎖人數,下方柱子是當日新解鎖,深藍那段是後來分析過多次的人。

  • 累計解鎖
  • 當日新解鎖(僅分析一次)
  • 當日新解鎖(後來分析過多次)

6/02 放寬解鎖條件前,17 天只累積 10 人;之後 12 天再加 15 人,斜率明顯轉陡,最後共 25 人解鎖、其中 11 人分析過多次。

植物圖鑑畫面
圖三:圖鑑畫面

另一個跟積分有關的設計是連續登入的加成得分,只要連續登入七天,從第七天起,當天的答題分數就會乘以 1.5,鼓勵大家每天都回訪參與。

那既然有積分,就會有排行榜啦。除了總分榜之外,我另外設計了四個子榜:最了解同學(答對最多題三真一假)、最積極參與(互動總得分最高)、最多夢想同伴(最多人附議)和連續王者(最長連續回訪答題天數),每個榜的最高分就可以拿到本次活動的紀念盆栽***

排行榜畫面
圖四:排行榜

而這些積分的明細都會在每個使用者的 dashboard 顯示出來,哪些分數是來自填答問卷、哪些是來自表情符號互動等等,這裡可以看到很詳細的資訊,包含誰給你表情符號以及誰附議你的夢想,使用者就可以自由決定是否要去和對方聯繫。

而 dashboard 上面留了一個很大的區塊給「同學看板」,卡片上會有進度條顯示你點入多少個同學的個人頁面去閱讀他的問卷回答和夢想了。而點入同學看板後,除了可以看到有誰註冊與大家現在的所在地之外,這個頁面呈現資訊的邏輯則是另一個剖面,在這個頁面上可以方便大家直接看到每個問卷題目來自不同人的回答和大家各自的夢想。

同學看板畫面
圖五:同學看板

至於為什麼不在系統上做留言或私訊的功能,第一考量是工程複雜度有點高,懶得維護這麼多資料表,第二考量是大家應該都有彼此的社交媒體好友可以傳訊,就不要一直重新發明輪子,第三是如果彼此沒有社交媒體好友的人,可以趁這次去加好友,建立更長期的聯繫機會(不會隨本活動系統下線就失聯)。不過倒是覺得當時可以建立一個註冊者可以加入的 discord server,大家可以在裡面聊天。

整體的感受與學習

我覺得我在過程中真的從 AI 身上學到很多一個軟體 PM 該考慮的事情,尤其是很多未知的估計值,例如有多少人會真的加入系統、高峰期的各項數值、積分門檻應該怎麼設定才有可能在活動期間讓大家達到最高等級等等,這些問題背後都牽涉到設計與技術決策。很幸好最後我選用的服務都剛好在免費方案就能符合使用需求與流量負擔,例如 AI 問卷性格分析的 api calling 次數可能是多少?有辦法只用 Gemini 的 free tier api 完成嗎?

在這整個專案中,我的權限設定全部都是需要通過審核,沒有讓 Claude code 自主決策和行動,這是因為我想從 AI 上學習,了解他每一步要幹麻。結果也真的有幾次被我抓到它規劃了沒必要的檢查。因此,雖然 AI 很好用,但對於人類品味與決策考量的重要性,我也有更深刻的感受了。

另外因為我只有最基本方案的訂閱,所以我一直很怕 token 不夠用,全程大部分都只用 sonnet 開發,只有兩三次開 opus 來用。發現 sonnet 的盤點總是不夠全面,而 opus 就會主動把所有牽涉到的相關檔案和設計一次性排開,給我比較完整的資訊去判斷(但如果強迫 sonnet 在特定範圍去多做幾次盤點,它也是做得到啦)。

另外覺得這次比較缺乏的是收集使用者回饋,應該可以在最後一天每日遊戲答題完後,跳出問卷調查讓使用者填寫,或者在活動結束後寄問卷調查給使用者,也可以順便調查大家因為此次活動和多少老同學重新聯繫上。但當時已經做到有點覺得自己無力再做一次重聚活動,所以想說也沒下一次了就不必調查🤣(不過現在寫下這些開發紀錄,又覺得好想要有下一次機會把沒做好的地方做好來!)

但是為了寫這篇開發文章,讓數據和故事更豐富,我還是有在自己的 ig 限動做了一個非正式的投票,問大家藉這次活動重新聯絡上多少位老同學,總共有 17 人回覆。這裡要先把這份數據的侷限講清楚:會看我限動又願意回答的人,參與度本來就偏高,所以樣本是偏正向的;另外我當時沒有放「0 位」這個選項,因為每個人至少都會和我本人聯絡上,所以「1–2 位」那一組裡,很可能有人唯一聯絡上的就是我。也因此真正比較有意義的數字是:17 位回覆者中有 8 位(47%)聯絡上三位以上的老同學,也就是真的超出了我這個主辦人本身。

藉活動重新聯絡上的老同學人數:17 位回覆者中有 8 位聯絡上三位以上

活動結束後在個人 IG 限動做的非正式投票,非系統數據。

  • 3 位以上(超出主辦人本身)
  • 1–2 位

兩個侷限要先說:① 會看我限動又願意回答的人,參與度本來就偏高,樣本是偏正向的;② 沒有放「0 位」選項,因為每個人至少都會和我本人聯絡上,所以 1–2 位那組可能有人唯一聯絡上的就是我。也因此刻意不計回覆率(分母不明),也不把人數加總成總聯絡次數(同一段關係會被雙方各算一次)。

技術踩坑

本專案上線後最大的 bug 是排程後的三真一假題目沒有隨著使用者的修改而更新,這個問題是我自己進後台看資料表去比對才查到的。這點可以說是 sonnet 的失誤(它沒有自動去更新關聯的資料表),也可以說是我的決策考量不夠好,因為一開始在定義所需的資料表和 schema 時,我沒有仔細去思考將排程資料分到另一個資料表的缺點,現在想想放在同個資料表加欄位就好了。

還有兩個我自己發現的坑是 sonnet 引用其他服務的 api 時,很容易忽略參數的預設值限制,例如只會顯示前 1000 筆資料,就讓排行榜資料到第四天後無法更新最新現況。以及主角題排程日提醒信每分鐘只能寄出兩封,所以超過兩題的天數,一開始沒找到 root cause 還要我手動去觸發第三封以上,後來才修成自動 sleep 個幾秒就好。

另外還有收到一個使用者回報的 bug 是夢想欄位並沒有 upsert 更新,導致每次修改都變成一筆新的紀錄。這個我就覺得有點被 AI 雷到,因為我覺得這是很基本的設計應該不用明確下 prompt。

最後就是活動進行倒數第三天的時候,收到服務商寄來的 egress 流量爆炸問題。這個部分是因為我先前完全沒有相關的背景知識,根本不曉得要去考慮到這個問題,後來也是請 AI 快速修改,把流量降下來,就依然平安的用免費方案即可。

還有回到開篇說請 Codex 解的問題是頁面載入速度提升,本來一開始初次登入因為 middleware 寫了重複的邏輯和迴圈,所以可能需要花 10 到 13 秒,後來改掉後縮短到 5 到 6 秒(但這部分還是可以再優化啦)。

關於支援團隊

這次找了三位同學 Norman、River 和 Munus 一起籌辦這個活動,但我們每個人都在不同時區,溝通上有點不及時,加上這完全是無酬的額外任務,所以有些決策就沒辦法很迅速討論出來,未來在時程上的規劃我就學到要再多留一點餘裕。我本身也一直跟團隊強調請大家顧好本職和自己的生活,有餘裕再投入就好,因為當時大家都有各自的工作,只有我是很閑的待業人士。不過最後我們很幸運地在決定活動名稱時剛好大家都在線,就快速地投票出這次活動的名字「實光」(另一個選擇是我想出來很中二的「實植成長」🤣)。

另外則是因為題目的排程完全是靠有管理者權限的人手動安排,我是有想過萬一在這段期間我出了什麼意外要怎麼辦,所以有徵求活動期間都有空的同學一起來當管理員。但後來想想,管理員主要的職責也只是排程,那這完全其實可以用 AI 和程式解決,根據三真一假填寫的趣味性依序自動鎖定題目日期,並自動用剩餘天數平均處理每日需要安排多少位同學的題目,然後保留人類管理員調整排程的權利。

這次專案還有一個小遺憾是來不及根據 Norman 的設計去調整字型,本來他想要用的是圓體,但我因為時間不足,還有加上技術上有點麻煩,就沒有實作這部分,直接使用預設的字體。我對不起我的設計師🥲

最後,很感謝三位同學的幫忙,不論是投入大量時間做設計或是給予技術和設計上的意見,都非常感謝你們!也很感謝所有幫我宣傳和轉發的同學們!

最後最後,也感謝校友會贊助製作紀念盆栽****的經費,大家快加入校友會吧!今年 8/29(六)有校友盃比賽和會員大會,歡迎大家一起回學校看看,我也會在現場分享本次活動的籌辦心得~