Refactoring English: Month 18

Michael Lynch

Refactoring English:第 18 個月

原文由 Michael Lynch 發布,訂閱此部落格

一句話總結

書寫完了!呃,算是啦。

第一次來嗎?

嗨,我是 Michael。我是一名軟體開發者,也是幾間小型獨立科技公司的創辦人。我目前正在寫一本書,書名是Refactoring English: Effective Writing for Software Developers

每個月我都會像這樣發一篇回顧,分享寫書的進度以及整體工作近況。

本月亮點

  • 我已經完成了全書 22 章的撰寫。
  • 我本來以為 AI 能讓原型開發更快,現在卻不太確定了。

目標達成度

每個月月初,我都會先訂下想完成的目標。以下是這個月的達成情況:

Refactoring English 達到「內容完稿」

  • 結果:已完成所有章節。
  • 評分:A

過去六週以來,每週都覺得「再一週就好了」,所以現在終於把所有章節都寫完,真的鬆了一口氣。

打造一個讓 Refactoring English 讀者能在閱讀時直接回饋的工具

  • 結果:工具只完成了約 40%。
  • 評分:C

這原本看起來應該是個兩、三天就能做完的專案,但實際做下去才發現比想像中困難得多,尤其是因為大阻塞的關係。

Refactoring English 數據表現

指標2026 年 4 月2026 年 5 月變化
不重複訪客2,5781,752-826 (-32%)
預購收入$587.73$407.61-$180.12 (-31%)

哎呀,我一直沒好好做行銷,數據也因此很難看。

我急著想把最後幾章趕完,所以把心力全放在寫書上,完全沒投入行銷。

漏洞賞金成果

我還是有在做資安漏洞賞金,不過投入的時間變少了。原本計畫的 70/30 時間分配沒做到,大概比較接近 60/40 吧。

主要合作的廠商這次又付了我 $7k(累計已達 $17k)的獎金,不過他們處理回報的速度變慢了,所以我也大多暫停在他們的程式碼中找新漏洞。

我也向其他幾個專案提交了漏洞,想看看有沒有處理比較快的,但結果都沒有:

  • KeePassXC —— 我在 5 月 18 日透過 Zero Day Initiative 提交了一個 RCE,但至今沒有收到任何回覆。
    • 對 KeePassXC 的使用者來說,這不是那種零點擊攻擊,也不會讓你只是逛個惡意網站就導致資料庫被入侵,所以不用太擔心。
  • Cloudflare —— 我在 5 月 22 日透過 HackerOne 提交了一個 DoS/邏輯繞過漏洞。沒有回應。
  • Proton —— 我提交了一個低嚴重性的問題。他們要求提供影片形式的 PoC,所以我在 5 月 29 日錄了一段,他們說會再通知我。

書什麼時候才算「完成」?

雖然已經把所有章節都寫完了,讓人鬆了一口氣,但我還不認為這本書算是正式「完成」。

這本書是過去一年半以來,一次專注寫一章慢慢累積出來的。我還從來沒有從頭到尾把自己的書完整讀過一遍,確認前後是否一致。我想至少要完整讀過幾遍之後,才能算是真正完成了。

為什麼我沒有持續修訂這本書?

我原本計畫要根據讀者的回饋持續修改書的內容。這樣等我寫到最後一章時,書應該就差不多完成了,因為前面的章節都已經根據讀者意見修過好幾輪。

但實際上,我整合讀者回饋的程度遠比預期的少很多。

我發現要在「修訂舊章節」和「寫新章節」之間分配注意力很困難。如果花一週時間去修舊的章節,就會覺得沒有在往前推進;但只要新增一章,公開的進度條就會多填一點,讓人很有成就感。

來自書籍官網的進度條

另一個沒有持續修訂的原因,是我跟讀者互動的頻率遠低於原先的計畫。某種程度上,是因為我一直覺得寫書進度落後,心裡總想著:「先把這章趕出來,然後再來好好經營讀者關係。」

但即使我真的去聯繫讀者,也很少對書的內容產生實質影響。最常見的回覆就是「我很喜歡這本書」或是「我還沒開始看」。

就算偶爾收到比較詳細的回饋,我也不一定知道該怎麼整合。有些情況下我認同對方的意見,做決定就很簡單;但更多時候,讀者會建議加入一些我覺得沒必要的內容。這不是說讀者錯了,只是我會想看到多位讀者有一致的回饋,才會願意推翻自己的直覺,而我收到的回饋數量根本不足以看出什麼規律。

我的讀者回饋工具

現在所有章節都完成了,我覺得比較有餘裕去聯繫讀者了。

我很喜歡Help this Book這個概念——一個讓讀者可以直接在電子書裡留下回饋的網頁應用程式,但我不想把所有回饋都託管給第三方,還得每個月付費。

我看到 Julia Evans為自己的產品打造了專屬的讀者回饋工具,覺得這個點子很棒,所以我也正在做一個類似的東西。

我正在開發一個網頁應用程式,讓讀者更容易針對我的書提供回饋。

AI 專案與大阻塞

整體來說,我發現寫程式時 AI 確實讓我更有效率。像解決 git 合併衝突、除錯不熟悉的程式碼,或是做些簡單的小工具這類任務,AI 的幫助非常明顯。

我以前覺得 AI 在幫我啟動專案方面很厲害,但現在不太確定了。我一直卡在一個我稱之為「大阻塞」的狀況裡。

直接叫 AI 生出原型

六個月前,我會給 AI agent 一個高層次的需求概述,請它實作一個基本的 v1 原型。我知道它產出的程式碼會很亂,但反正只是原型,我可以不斷給它回饋,直到它符合我的程式設計品味。

結果發現,要整理一個糟糕的原型比我想像中困難得多。一旦原型爛到一定程度,我就很難釐清這段程式碼到底想做什麼。

AI 似乎有一種奇怪的偏誤,會去合理化已經存在的程式碼。如果我跟 AI 說某個元件很讓人困惑,因為它對同一份資料迭代了三次,它就會堅持說我們就是得迭代三次,原因是 X、Y、Z。但它從來不會去質疑 X、Y、Z 是不是人為製造出來的限制。

這就是阻塞。我會被卡住,無法跨越 AI 堆出來那道由混亂程式碼砌成的高牆。

如果不修正核心邏輯,問題只會越來越嚴重。程式碼的異味像黴菌一樣滋生,並在整個程式碼庫中蔓延。我等於是在脆弱的地基上繼續蓋房子,而 AI 只是不斷複製那些已經存在的糟糕模式。

把原型拆小

好吧,簡單的解法:讓 AI agent 分成更小的單位來建立原型。把 AI 牽緊一點,別讓它跑太遠。與其讓 AI 一次生出整個原型,不如先讓它做一個歡迎頁面。等審核、合併之後,再加一個簡單的功能,依此類推。

這招在遇到像驗證機制這種複雜的功能之前都還管用。AI 會生出一個 2-5k LOC、讓人看得一頭霧水的 pull request,然後那又變成一堵高牆。我想不到還能怎麼把這個功能拆得更細,結果就卡在這個巨大的 PR 上——又是另一個大阻塞。

一個 4k LOC 的變更,不只審查時間是 400 LOC 變更的 20 倍,還需要更長的連續審查時間。如果我有 20 分鐘的空檔,可以處理 400 LOC 的變更;但如果是 4k LOC 的變更,光是建立上下文就要花 20 分鐘。要在不把大部分時間浪費在切換上下文的情況下,對 4k LOC 的變更做出實質進展,我需要 90 分鐘的完整空檔,這對週末專案來說尤其難得。

範例:為 Little Moments 實作驗證

舉個例子。對於Little Moments,我是用魔法登入連結的電子郵件來做驗證的。好幾個星期以來,我都想不出如何在不產生無用程式碼或功能壞掉的情況下,把這個功能拆開。登入流程怎麼可能只做一半?

在花了好幾週慢慢啃那個巨大的 PR 之後,我才意識到,其實我可以只實作一半的登入功能。我維護的另一個應用程式PicoShare有一套很簡單的驗證流程。這個應用程式假設只有單一授權使用者,所以驗證就只是通關密語,甚至連帳號/密碼組合都不用。與其一次從「沒有驗證」跳到「電子郵件驗證」,我可以先從「沒有驗證」進展到「通關密語驗證」。

所以,我先讓通關密語驗證動了起來,但要從通關密語再進展到魔法登入連結,仍然是一個巨大、需要花好幾週審查的 PR。在連續 hack 了好幾天後,我發現還可以拆得更細。

與其真的寄出帶有登入連結的電子郵件,我可以直接把使用者重新導向到我本來會寄給他的那個連結。這樣做仍然是一個 1.7k LOC 的 PR,但已經比真的去寄信好處理多了。而且這也讓真正寄信的那個部分縮減到只有 1k LOC。

AI 如何讓這變得更困難

讓我開始懷疑 AI 在這類工作上到底是不是利大於弊的原因是,我知道如果不是用 AI,我早就會發現這些拆解問題的機會。我絕對不會先做出一個 4k LOC 的 PR,然後才說:「嗯,這好像有點大。」當 PR 越變越大,處理起來就越痛苦,所以我自然會去找出把變更拆小的機會。

AI 打亂了這個自然的回饋循環。用 AI 的話,產生一個 4k LOC 的 PR 完全不會痛,因為它在我收個信的兩分鐘內就生出來了。而且我可以輕鬆地對這個巨大的 PR 提出修改意見,還會覺得自己有在推進,但這麼大的變更反而讓我很難辨識出哪些部分可以獨立抽出來、變成更小的變更。

現在我已經意識到,為複雜的功能產生巨大、難以管理的 PR 是多麼容易的事,我就可以改變使用 AI 的方式,在前期就投入更多心力,把功能拆成更小的變更。

總結

完成了什麼?

  • 發布了書的最後幾章。
  • 為書籍回饋應用程式做出了部分原型。
  • 為 Little Moments 部分實作了驗證功能。
  • 發布了 PicoShare 的兩個新版本。

學到的教訓

  • 使用 AI 會消除那個促使我以更小單位來開發軟體的自然回饋循環。
    • 我想解法是在複雜功能的生命週期早期就更努力地把東西拆小,並且更嚴格地審查 AI 的產出。

下個月的目標

  • 至少投入五小時來改善 Refactoring English 的網站。
  • Refactoring English 網站吸引 30k 名不重複訪客。
  • 完成我的讀者回饋工具。

本文章由 muse-spark-1.2-contributor 進行翻譯

留言