iT邦幫忙

2026 iThome 鐵人賽

DAY 30
0
ChatGPT & Codex

這隻 LINE Bot 不是我寫的:30 天讓 Codex 從零幫我做到上線系列 第 30

Day 30 - 從空 Repo 到咖啡護照: 30 篇文章,走完 LINE Cafe Bot 的鐵人賽

  • 分享至 

  • xImage
  •  

今天發出這篇文章時,我的 iThome 鐵人賽也終於來到了尾聲。

剛開始這個系列時,我看著一個幾乎空白的 Repo,想做的事情其實很單純:

用 Codex 從零開始,做一隻真的可以在 LINE 裡使用的咖啡廳 Bot。

那時候的我還不知道,這句話後面會接著 29 篇文章。

我也不知道,一開始只想讓 LINE Bot 正確收到訊息的自己,最後會做出一隻真的能找店、收藏、約時間、進入群組投票,還能留下咖啡足跡的 Bot。

現在回頭看,這 30 天表面上是在做一隻 LINE Cafe Bot,但真正慢慢改變的,好像是我看待「完成」這件事的方式,以及自己都不敢相信的毅力。

所以最後一篇,我不打算再介紹新的 API。

我想把這一天留給一路走來的心情,也留給那些沒有一次做對、卻反而讓我學得最多的時刻。

這 30 天,其實是從一場 Codex 演講開始的

最早的起點不是鐵人賽,而是一場 Codex Community Meetup 的演講。

接到演講時,我只是想著:如果真的要站上台分享 Codex,我應該準備些什麼?

我當然可以整理它有哪些功能、放幾段操作畫面,再做一個簡短 Demo。但越想越覺得,如果自己沒有真的拿它完成過一段夠長的開發,只靠文件和幾次示範,好像很難說清楚它在真實工作裡究竟能幫上什麼忙,又會在哪些地方需要人做決定。

與其只為演講準備一個看起來順利的範例,我更想從空白開始,看看自己能不能真的和 Codex 一起把一個想法做成可使用、可部署,也會在手機上實際遇到問題的產品。

想著想著,我決定把實作變成每天的紀錄,再替自己找一個不能輕易停下來的理由。結果原本只是想替一場演講準備內容,不小心就把自己推進了鐵人賽。

後來那場演講還在準備,LINE Cafe Bot 卻一天比一天長大。我真正能帶上台分享的,也不再只是某一個成功的功能,而是需求怎麼改變、問題怎麼出現,以及我和 Codex 怎麼一起把它修好的整段過程。這些經驗,是只準備一個順利的 Demo 不會得到的。

第一天時,我其實看不到第 30 篇會長什麼樣子

首次參加鐵人賽最讓人有壓力的地方,不只是要寫 30 篇,而是每天都必須再往前走一點。

第一天可以寫從零建立 Bot,第二天可以接 webhook,但寫到後面,還能做什麼?會不會有一天突然沒有題目?功能如果做不出來,文章又要寫什麼?

剛開始時,我沒有一張完整的 30 天藍圖。

我只有一個大方向,然後每天問自己:

如果今天真的打開這隻 Bot,下一個最想做的動作是什麼?

有時答案是傳送位置,有時是換一批咖啡廳;有時不是增加功能,而是「為什麼等這麼久都沒有反應?」

後來我才發現,沒有一開始就把 30 篇全部想好,並不代表準備不足。很多真正值得寫的題目,都是前一天的功能做完後,親手使用才出現的。

這個系列不是照著一張完整藍圖施工,比較像每天往前走,再從當天遇到的事情裡找到下一站。

生活沒有因為參賽,就特別空出 30 天給我

決定開始這件事時,剛好也是我的生日月。

生日月原本應該有聚餐、朋友和一些想好好放鬆的行程,但參加鐵人賽之後,每一天不管原本安排了什麼,心裡都會多放著一件事:

今天的文章還沒有完成。

有些假日已經和朋友約好出去玩,我還是會把電腦一起帶著。明明是假日,卻特別調了鬧鐘,早一點起床寫文章,想在出門以前先替當天的進度留一點時間。

甚至有一次,前一天和朋友喝酒喝到凌晨三點。回到家時其實已經很累了,腦袋也只想趕快睡覺,但深怕隔天睡過頭來不及發文。我最後還是打開電腦,把剩下的內容整理完,確認文章真的發出後才去睡。

而那場把我推進鐵人賽的 Codex 演講,也正在這 30 天裡同步準備;同一時間,還有一場 Scrum 內訓課程等著我整理。

一邊要整理 Codex 演講的內容,一邊要想怎麼把 Scrum 內訓課程講得清楚;回到自己的進度,還有當天的功能、測試和文章等著完成。那段時間,我經常得在講師、開發者和參賽者幾種身分之間來回切換。(噢還有一個上班族的身份)

那 30 天並不是每天都有完整的晚上,可以舒服地坐在桌前慢慢寫。有時候是在出門前趕一段,有時候把電腦帶在身邊,有時候則是行程全部結束後,才把原本應該拿來休息的時間補回文章裡。

當下其實不會每天都覺得自己很有毅力。

更多時候只是很累地想著:「都已經寫到這裡了,今天也不要停。」

現在回頭看,鐵人賽真正辛苦的地方,可能不是某一篇文章特別難,而是生活照常發生,我仍然要一次又一次替寫作留出位置。

這些事情不會出現在 GitHub 的 commit,也很難從最後完成的功能看出來。但對我來說,它們才是「連續 30 篇」這個數字真正的重量。

每天最難的,不一定是寫程式

這 30 天裡,我逐漸形成一個很固定的循環:

想到一個生活裡真的會遇到的問題
        ↓
和 Codex 討論怎麼做
        ↓
把功能接進原本的 Bot
        ↓
部署後拿手機實際操作
        ↓
發現原本沒想到的問題
        ↓
修正,再把過程寫成文章
        ↓
把當天的功能與文章整理進 AI Learning Lab

有時程式很快就完成了,文章卻卡很久。

我不想連續 30 天都用「今天要介紹某個 API」當開頭,也不希望文章只剩下一段段程式碼。

所以我必須一直回到生活裡,問自己為什麼要做它。

是因為我收藏了咖啡廳,後來還是忘記去;是因為站在櫃檯前看著菜單,後面有人排隊,自己卻還選不出飲料;也是因為朋友在群組裡都說「我都可以」,最後反而最難決定要去哪裡。

當我找到這些真正的情境,技術才不再只是技術名詞。

我也開始覺得,寫文章不是功能做完後的附加工作。它逼我停下來確認:我是真的理解今天做了什麼,還是只知道程式現在剛好能跑?

文章發布後,這一天其實還沒有完全結束。

我會再把當天完成的 Repo、功能和文章整理進 zona-ai-learning-lab,替這段學習旅程新增一站。

從「程式會動」到「使用者走得下去」

如果要說這 30 天最明顯的改變,大概就是我判斷完成的標準變了。

一開始,只要按下按鈕有回覆、資料有存進去,我就會覺得功能完成了。

但實際拿起手機後,我越來越常遇到這種情況:程式沒有壞,使用者卻不知道接下來要做什麼。

例如在群組裡傳送位置後,Bot 的確找到了咖啡廳,但畫面沒有告訴大家接下來要加入候選、再開始投票。

又例如不是發起人的成員按下「截止投票」,Bot 正確提醒他只有發起人可以截止。邏輯完全正確,但訊息送完就結束了,真正的發起人反而找不到可以接手的按鈕。

這些問題都讓我有一種很微妙的感覺:

我明明把規則寫對了,為什麼用起來還是不對?

後來我才理解,使用者不會看到 Firestore 裡的狀態,也不會知道 handler 已經正確判斷權限。他只會看到眼前這一句話,然後決定要不要繼續。

從那時候開始,我會在每一則回覆後多問一句:

看完這個畫面後,使用者的下一步還在嗎?

這句話對我的影響,比記住任何一個 API 都更久。

那些有點尷尬的發現,後來都變成了文章

這個系列裡,有幾次發現問題的瞬間,其實有點尷尬。

其中一次是準備做想去清單時,我才發現收藏功能以前就做過了。

原本可能會覺得:「那我這次是不是做重複了?」

但真正回去操作後,我輸入「收藏第二間」,才發現 Bot 不一定記得上方那輪推薦;就算收藏成功,也缺少一個能查看、去重、安排時間與移除店家的完整流程。

所以那次不是重做,而是優化。

我也因此學到,發現以前做過,不代表今天沒有東西可以寫。反而可以誠實地問:以前的版本為什麼還不夠?現在的我多看見了什麼?

另一次是在系列快結束時。

我替 Bot 做了咖啡護照,統計和卡片都順利出現,Gemini 咖啡回顧卻只說了半句。

我第一個反應是畫面截字,結果 Codex 一路往回追,最後才發現是輸出 token、thinking 和快取一起造成的問題。

最有意思的是,即使調整了 Gemini 設定,舊的半句已經被記住,重新打開還是會看到同樣內容。直到我們讓舊快取失效,問題才真的結束。

這很像整段鐵人賽給我的提醒:

不要急著修最像問題的地方,也不要因為畫面暫時正常,就以為所有影響都已經消失。

現在回頭看,如果每一天都一次成功,最後可能只會留下 30 篇功能介紹。正因為中間有懷疑、誤判和修正,這個系列才更像一段真實的開發過程。

我和 Codex 的關係,也在 30 天裡慢慢改變

一開始,我比較常對 Codex 說:

幫我做這個功能。

我在意的是它能不能找到檔案、寫出程式、通過測試,再幫我部署。

後來,我對它說的話開始變成:

我實際用起來覺得哪裡怪怪的。
這個人看完之後沒有下一步。
這個結果和我原本想像的不一樣。

我們的分工也慢慢清楚起來。

我負責描述生活中的情境、實際拿手機操作,以及決定我希望使用者感受到什麼;Codex 則負責讀懂現有程式,把模糊的不舒服拆成資料、狀態、權限、訊息和可能的原因。

有時候它會替我想到邊界,例如舊卡片一個月後還能不能按、群組平手時要怎麼辦,或分享出去的咖啡護照該不該包含使用者身分。

但最後的選擇不會只交給 AI。

平手要不要隨機選一間、只有誰可以截止、哪些資料適合分享,這些都不是程式自己能決定的。我必須回到使用情境,做出自己願意負責的選擇。

這 30 天讓我不再把 Codex 看成一個「輸入一句話就吐出完整產品」的按鈕。

它比較像一個很能追問題的協作者。我要把看到的現象說清楚,也要願意檢查它做出的假設。當我只說「壞掉了」,我們很難前進;當我能說出「誰按了什麼、畫面出現什麼、我原本期待什麼」,問題往往就開始變得可以處理。

每天做完的功能,最後拼成了一張地圖

30 天裡,我建立了不少獨立 Repo。

它們各自保存一個階段的功能:有些是搜尋與偏好,有些是收藏、提醒、菜單推薦,也有後來的群組投票和咖啡護照。

如果只看最後一個 Repo,很容易以為這隻 Bot 是一次完成的。但打開 AI Learning Lab 的時間軸,就會看到它其實是一站一站長出來的:今天多一個功能,明天修掉實測才發現的問題,後天又因為前一個結果想到新的方向。

我喜歡這種記錄方式,因為它保存的不只是最後正確的答案。

有些站記錄第一次把功能做出來,有些站記錄我原本怎麼想,又為什麼在使用後改變決定。它讓分散的程式碼、文章和當時的疑問有了前後關係,也讓「學會了什麼」不再只存在記憶裡。

寫到第 30 篇時,我才真正感覺到:每天多整理的那一小步,最後替整段旅程留下了可以回看的形狀。

咖啡護照為什麼適合放在旅程尾聲

做到最後,我其實還可以繼續替 Bot 增加新功能。

但我不想讓鐵人賽的結尾只是「再多做一個按鈕」。

所以我選擇做咖啡護照,把前面累積的收藏、評分、標籤和造訪紀錄重新整理,讓使用者可以回頭看看自己這個月、今年,或一路以來去了哪些地方。

它沒有要求使用者再學一套新流程,而是讓以前做過的每一件事,突然有了一個可以回看的地方。

現在想想,這也很像我正在寫的第 30 篇。

咖啡護照替 Bot 整理一路留下的足跡;完賽文則替我整理這 30 天留下的選擇、卡關和改變。

它們都不是再往前增加一件事,而是在真正結束以前,回頭確認自己已經走了多遠。

第 30 篇,我終於可以好好回頭看

參加鐵人賽以前,我只知道目標是完成 30 篇文章,卻不知道第 30 篇的我會站在哪裡。

每天身在其中時,注意力總是在明天:下一個功能是什麼?今天的問題修完了嗎?文章還差哪一段?

直到現在回頭看,我才發現,原來自己已經從一個空 Repo,走到一隻真的部署在 LINE 裡、可以被實際使用的 Cafe Bot;也留下了 29 篇文章,記錄每一段功能、修正,以及當時還不知道答案的自己。

如果要替這 30 天留下一句話,我想會是:

完成不是一開始就把所有事情想好,而是在生活照常前進時,仍然願意每天替一件在意的事留下一點位置。

謝謝這 30 天沒有因為「還不夠完整」就停下來的自己,也謝謝一路和我拆問題、讀程式、修流程的 Codex。

這個生日月除了聚會和出去玩的回憶,也留下了假日早起的鬧鐘、包包裡的電腦,以及凌晨三點回家後仍然亮起來的螢幕。那些當下只覺得疲累的片段,現在都成了完賽的一部分。

這是 LINE Cafe Bot 系列的最後一篇。

咖啡護照替 Bot 收進了最後一段足跡;而這第 30 篇文章,也替我收好了這趟鐵人賽留下的回憶。

恭喜自己!成功完賽了!

https://ithelp.ithome.com.tw/upload/images/20260910/20183556sgllSbqLML.jpg

LINE Cafe Bot 完整程式碼

AI 學習與專案紀錄:
https://github.com/zonawang/zona-ai-learning-lab


上一篇
Day 29 - LINE Cafe Bot 旅程尾聲,我把一路累積的足跡做成一本咖啡護照
系列文
這隻 LINE Bot 不是我寫的:30 天讓 Codex 從零幫我做到上線30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言