重構英文:第 14 個月
一句話總結
發現 AI 沙盒的威力
初次來訪?
嗨,我是 Michael(麥可)。我是一名軟體開發者,也是小型獨立科技事業的創辦人。我目前正在撰寫一本名為 Refactoring English: Effective Writing for Software Developers(《重構英文:寫給軟體開發者的有效寫作指南》) 的書。
每個月我都會發布一篇像這樣的回顧,分享我的新書進度與整體工作近況。
本月亮點
- 尋找書籍讀者的新策略已帶來正向成果。
- 讓 AI 代理在無限制模式下運行,帶來了突破性的體驗。
- 我一直在運用 AI 來修正過去在技術選型上令我後悔的決定。
目標達成度
每個月月初,我都會宣告當月想完成的目標。以下是我達成這些目標的情況:
出版 《重構英文》 三個章節
- 結果:發布了兩個新章節
- 成績:B-
我還是遇到和上個月相同的問題:對 AI 實驗過於投入,以致壓縮了寫作時間。
發布我的 2025 年度回顧(第八年)
- 結果:已發布
- 成績:A
完成了!我對成果相當滿意。至此,我已結束一連串因傳統或主題時效性而感到必須在特定期限前發布的文章。
《重構英文》數據指標
| 指標 | 2025 年 12 月 | 2026 年 1 月 | 變化 |
|---|---|---|---|
| 不重複訪客 | 2,266 | 38,511 | +36,245 (+1600%) |
| 預購收入 | $492.55 | $1,132.75 | +$640.20 (+130%) |
| 贊助收入 | $48.25 | $0.00 | -$48.25 (-100%) |
我在 1 月初發布了〈2025 年 Hacker News 最受歡迎的部落格〉,成效遠超出預期。這篇文章讓 1 月成為自去年 Kickstarter 募資以來,本書訪客數與營收最高的月份。
其他收入則有所下滑,因為我沒有接到任何編輯案,而 TinyPilot 的現任持有者也在 2025 年結束了對本書的贊助。我不打算再尋求更多企業贊助,因為企業似乎興趣不大,而且專注於讀者反而更單純。
藉由書寫其他作者而獲得成功
〈2025 年 Hacker News 最受歡迎的部落格〉是我過去約半年來探索的一項策略的延續。簡單來說就是:表揚其他軟體寫作者。
去年夏天在一場派對上,我認識了一位自行出版的羅曼史小說家。聽她談論自己的工作很有趣,因為儘管我們寫作的主題截然不同,卻面臨類似的難題。
我問她如何找到讀者,她說:「這就是關鍵問題!」
她告訴我,她透過開設電子報來評論其他羅曼史小說(主要來自獨立作者)獲得了很好的成效。這形成了一個正向循環:
- 讀者在閱讀她的電子報後發現並購買她的書。
- 其他獨立作者樂於見到自己的作品被評論,因此會將自己的讀者導向她的電子報,進而提升(1)的效果。
- 她的訂閱者則透過電子報發現其他有趣的小說。
我很喜歡這種讓各方誘因一致的策略,因此開始思考如何將其應用到我的書上。我開始撰寫關於我喜歡的其他部落客與書籍作者的文章,並發布在我的部落格上,效果相當不錯:
| 文章 | 不重複讀者 | Hacker News 分數 | Lobsters 分數 |
|---|---|---|---|
| 2025 年 Hacker News 最受歡迎的部落格 | 33.8k | 692 | - |
| 形塑我的那些軟體散文 | 25.6k | 308 | 85 |
| 《打造直譯器》導論為何如此出色? | 3.5k | - | 137 |
發現 AI 沙盒的威力
一年前,當我第一次開始使用 AI 代理時,我有了一次令人大開眼界的體驗。當時,我只是讓它在旁邊編輯檔案、看著它操作,就覺得把這麼大的控制權交給 LLM 已經相當嚇人。
在過去一年裡,我大多使用 Cline 這個 VS Code 上的 AI 代理擴充套件。它加速了我的許多工作流程,但我也因為不信任它在我的開發機上執行任意操作,而對它進行嚴格的人工監督。
幾週前,我的朋友 okay 向我展示了他使用 Codex(OpenAI 推出的終端機 AI 代理)的工作流程。okay 讓 Codex 在沒有直接監督的情況下編輯檔案並執行指令。這讓我意識到,自己花了多少時間在緊盯 AI 代理,以及處理 Cline 當機的問題上。
okay 說他有時會讓 Codex 無人看管地工作一小時以上,我簡直不敢相信。如果我交給 Cline 一個需要超過 10 分鐘的任務,它不是卡住介面、走錯方向,就是讓我的費用暴增。但 Codex 採用固定費用而非按 token 計費,這讓你不再需要擔心成本。
我仍然不信任任何 AI 代理在我的實體電腦上恣意運行,因此我在本機上為執行 AI 代理設置了一個自訂的沙盒。我進入其中一個專案的目錄並執行我的自訂指令:sb。它會啟動一個無根 Podman 容器,該容器無法存取我的區域網路,且只能看到目前的工作目錄。它已預先安裝並以我的帳號完成驗證的 Codex 與 Claude Code。
在沙盒中運行 AI 後,我便能放心地賦予它編輯檔案、安裝應用程式等完整權限。
哇,差異真是天壤之別!
看著 AI 代理在擁有完整權限的情況下運行,是我另一個突破性的時刻。以前,如果我說:「幫我做一張過去 8 年收入的長條圖」,大約有 30% 的機率,AI 代理會做出部分錯誤的實作。我得自己檢查結果,然後說:「不行,長條圖沒對齊,修正一下。」但當 AI 代理在自己的沙盒中擁有 root 權限時,它就能自行啟動測試伺服器、在瀏覽器中檢視頁面,並反覆迭代直到完成任務。
接著我聽說了 Ralph Loops。我至今還沒找到一個好的說明,所以不確定自己做的是否為「正統」的 Ralph Loops,但以下是我的做法。我會執行一個名為 ralph-loop 的 bash 腳本,內容是這段簡單的程式碼:
#!/usr/bin/env bash
rm ALL-DONE.txt || true
while true; do
cat AGENT-WORKFLOW.md | codex exec
if [[ -f "ALL-DONE.txt" ]]; then
echo "ALL-DONE.txt detected. Exiting."
exit 0
fi
done
而 AGENT-WORKFLOW.md 看起來像這樣:
1. Pick the top task in TODO.md and begin work on it
- If no actions remain, write a file called ALL-DONE.txt to the current
directory, and exit.
1. Complete the task and delete the entry from TODO.md.
- If the task is unachievable, explain why in the commit message.
1. Commit the changes with a detailed commit message explaining what you
changed, why you changed it, and what impact it had.
然後我只需建立一個 TODO.md 檔案,裡面列出任務清單。有些任務會讓代理人建立後續任務,因此清單會隨著代理人的進度而增減。
Ralph Loop 讓我能夠讓 AI 代理自主運行超過 10 小時而無需監督。早上回到電腦前,看到 AI 代理在我睡覺時完成了所有指派的工作,感覺真的很超現實。
AI 很擅長移植程式碼
透過過去幾個月的 AI 實驗,我注意到它在以下情況最能發揮作用:
- 你可以客觀地定義成功標準。
- 例如,「找出造成這次當機的原因」是客觀且可定義的,而「讓這個登陸頁面變得更好」則不然。
- AI 代理可以獨立驗證是否成功。
- 例如:「在瀏覽器中開啟頁面,並驗證按下按鈕時背景是否變為藍色。」
- 問題的性質是,具備初階軟體知識的人只要有搜尋引擎、肯實驗並有耐心,就能解決。
以下是符合這些條件的幾類軟體任務:
- 已有自動化測試的程式碼重構
- 在保留行為的前提下,將程式碼從一種語言/技術移植到另一種
- 從原始碼編譯專案並安裝所有必要相依套件
- 修正程式碼以使測試通過
最近,我一直用 AI 來移植程式碼。我有一些程式碼庫,當初在技術選型上做了讓我現在後悔的決定,但要全部重寫一直以來都太耗時。但有了 AI,替換技術堆疊中的元件變得既便宜又快速。
我已在幾個專案中成功移植了程式碼:
- 將 Zestful 網站從 Vue/Nuxt2 轉換為使用 Hugo 的純 HTML
- 我收到 GitHub 警示,指出我透過某個從未聽過的遞移性 Node.js 函式庫存在一個愚蠢的漏洞。我心想:「真希望以後再也不要看到這些警示。」於是我讓 AI 用 Hugo 和純 HTML/JS/CSS 重寫了網站。
- 將 PicoShare 的 CSS 框架從 Bulma 移植到 Bootstrap
- 當初建立 PicoShare 時,我想試試 Bulma 這個 CSS 框架。它還算堪用,但我更偏好 Bootstrap,所以我在其他地方一直都用 Bootstrap,每當要處理 PicoShare 時就得切換思維。
- 將 LogPaste 的端對端測試從 Cypress 轉換為 Playwright
- 我在發現 Playwright 之前就寫好了端對端測試,現在我已經太習慣 Playwright,很難再回到 Cypress。
- 將 fusion RSS 閱讀器從 Svelte 轉換為純 HTML + Go 模板
- 這目前只是個概念驗證,因為 fusion 並非我的專案,但我想 fork 它以使用我偏好的技術堆疊。AI 在將所有 Svelte 程式碼轉換為純 HTML 與 Go 模板方面做得很好,但如果要認真移植,我會希望建立更完善的測試基礎設施。
- 將 MeshCore 網頁應用程式從 Vue.js 轉換為 Flutter
- 這個其實效果不佳,因為缺少了「AI 能驗證結果」的步驟。我原以為 Flutter 會為其網頁應用程式輸出語意化的 HTML,但實際上它產生的是怪異的、以 Flutter 為中心的 HTML 方言。而且 MeshCore 應用程式高度依賴外部硬體裝置(LoRa 無線電),所以我必須頻繁介入。
業餘專案
StreamPreserve
我曾思考過,如果我正在用手機目擊並想錄下某個事件,但有人可能會搶走我的手機並刪除影片、甚至把手機整個毀掉,那該怎麼辦。
因此,我製作了 StreamPreserve,這是一款能迅速將關鍵影片搬移到遠端安全伺服器的網頁應用程式。

StreamPreserve 會擷取重要影片,並盡快將其搬移到遠端伺服器。
運作方式如下:
- 我打開 StreamPreserve 應用程式並開始錄影。
- 應用程式會將低解析度影片串流至後端伺服器,並依據可用頻寬調整串流品質。
- 應用程式會以離散的區塊將高解析度影片錄製到瀏覽器儲存空間中。
- 若有剩餘頻寬,應用程式會在持續串流的同時,將高解析度影片區塊上傳至伺服器。
- 錄製停止時,應用程式會將高解析度影片儲存為本地裝置上的下載檔。
- 當應用程式開啟且未在錄製時,它會將裝置上所有高解析度影片同步至伺服器。
因此,其構想是,如果我錄下了某個事件而有人砸爛了我的手機,我的 StreamPreserve 伺服器上仍會保有該影片的低解析度副本。而如果有人奪走我的手機以阻止我錄影,網頁應用程式仍會在背景上傳高解析度影片。
當我意識到有幾個缺陷時,我對這個點子的熱情就消退了:
- 它不適合用來錄製長達數小時的影片。
- 將其作為網頁應用程式來實作會增加複雜度並有遺失影片的風險。它應該是一個原生行動應用程式,但我不喜歡行動開發。
- 這不是一個適合交給 AI 的任務,因為它依賴於瀏覽器相機 API,而在 AI 沙盒中要偽造這個 API 很麻煩。
總結
完成了什麼?
- 發布了《身為自籌創辦人的第八年》
- 發布了 《重構英文》 的兩個新章節
- 修復了 PoDoFo PDF 閱讀器中的一個當機問題,該問題是我透過我的 PDF 模糊測試流程發現的
學到的教訓
- 表揚其他軟體寫作者有助於我找到新讀者。
- 當 AI 代理在擁有 root 權限、能夠安裝應用程式並搜尋網路的環境中運行時,其實用性會大幅提升。
- 當你能客觀地定義成功標準,且代理人有辦法透過反覆迭代來驗證成功並自我修正時,AI 就很擅長解決問題。
- AI 很擅長將程式碼從一種技術移植到另一種技術。
下個月的目標
- 發布 《重構英文》 的兩個章節。
- 為 《重構英文》 的讀者安排一場線上直播活動。
隨機一篇部落格