昨天測 grill-me,今天測它的進階版 grill-with-docs——同樣來自 Matt Pocock 的技能包,疊了一層新主張:不只問清楚,還要邊問邊把討論出來的共識寫成文件,讓這些決定不會隨對話結束就消失。

拆開看,grill-with-docs 等於同時叫出昨天測過的 grilling,加上一個新技能 domain-modeling。後者的規則訂得很具體:
CONTEXT.md 衝突,要立刻講。CONTEXT.md,不要累積到最後:一個詞一旦定案,立刻寫進去。規則特別強調 CONTEXT.md 只放詞彙,不放實作細節。CONTEXT.md 的格式也寫死在一份 CONTEXT-FORMAT.md 裡,原文列了幾條規則:「要有主見」——同一個概念有好幾種叫法時,選一個最好的,其他列進 _Avoid_;「定義要精簡」——最多一兩句話,定義「它是什麼」,不要寫「它會做什麼」;「只收這個專案特有的詞」——一般的程式概念(逾時、錯誤類型)就算常用也不收錄。規則也預先處理了專案變大的情況:單一情境的專案只要一份根目錄的 CONTEXT.md;如果拆成多個情境(例如訂單、帳務、出貨各自獨立),就改放一份 CONTEXT-MAP.md 當索引,列出每個情境各自的 CONTEXT.md 在哪、彼此之間怎麼溝通。今天測的專案小到只需要一份根目錄檔案,這個多情境的分支沒機會測到。
今天想測三件事:詞彙表會不會真的生出來、ADR 的節制規則做不做得到、還有它自己判斷「這個決定夠不夠格寫 ADR」準不準。
昨天的測試是單輪的 headless 呼叫,grill-me 問完第一輪就結束,因為沒有人回答。但 domain-modeling 的「詞彙定案才寫進 CONTEXT.md」這個動作,前提是真的有人回答問題——單輪測不到。所以今天改用 --session-id 搭配 --resume,模擬一次完整的來回:同一個「加收藏功能」需求丟進去,拿到第一輪問題後,我扮演使用者逐題回答,讓對話繼續跑完,直到它真的動手實作為止。
問題一出來就看到 domain-modeling 在起作用。原文照抄 Q1:
❓ Q1 - 「收藏」的定義:「收藏文章」是指使用者把文章標記起來,之後能在一個地方找回來(類似書籤或 favorite)嗎?它跟「按讚」「稍後閱讀」「訂閱作者」是不同的概念,還是你想把其中幾個合併?
➡️ 只做單純的「收藏/取消收藏」二元狀態,不含按讚、稍後閱讀、已讀狀態。詞彙統一用「收藏(Bookmark)」。
這題不是在問功能設計,是在逼我把「收藏」這個詞跟「按讚」「稍後閱讀」這些容易混在一起的概念分清楚——正好對應規則裡「模糊詞要逼出精確說法」那條。同一輪另外四題,Q2 問要不要分類(決定了「收藏夾」這個概念第一版不存在)、Q3 問文章下架後收藏紀錄怎麼處理、Q4 問收藏是不是私人資料、Q5 把介面範圍攤開成五個選項讓我一次選。問題問完後,它明講了接下來要等探查專案現況的子代理回報,才能問「登入機制」「資料存哪」這類依賴事實的問題——這一步確實兌現了:子代理回報後,它發現專案根本沒有使用者概念,回頭把 Q4 標成「答案取決於下面的 Q6」,而不是放著不管。
回答第一輪之後還有個小細節:我刻意沒有針對 Q5(介面範圍)給出明確答案,它沒有卡住等我,也沒有悄悄假設,而是講清楚:「你沒有明確回答 Q5,但 Q7 已經排除詳情頁。我暫時把 Q5 當成只做『列表頁的收藏按鈕』加『我的收藏』頁……如果不對,請告訴我。」——把「我在猜」這件事攤開講,而不是當成已經問過。
我照著它的建議逐題回答之後,它真的建立了 CONTEXT.md,格式跟 domain-modeling 文件裡定義的一模一樣:
# 文章收藏
讓讀者把喜歡的文章標記起來,之後能在同一個地方找回來。
## Language
**收藏**:
使用者對某篇文章做的二元標記,只有「已收藏」與「未收藏」兩種狀態(英文 Bookmark)。
_Avoid_: 按讚、稍後閱讀、訂閱、書籤、favorite
每個詞條下面都有一行 _Avoid_,列出容易混淆、不該拿來替代的說法——這是我沒有要求的細節,是技能文件裡規定的格式。對話又跑完一輪實作後,我把整個暫存目錄翻過一次,CONTEXT.md 真的存在,三個詞條(文章、收藏、我的收藏)都在,沒有任何實作細節混進去。
對話進行到後面,它做了一個會影響架構的決定:收藏資料用寫死的 demo 使用者 ID、存在伺服器記憶體裡,不做真的登入或資料庫。這種「先用假資料撐過原型階段」的決定,照理說很容易被過度熱心的文件機制寫成一份 ADR。但它在完成實作後的回報裡主動講了這句:
沒用 ADR:記憶體儲存和寫死使用者都是原型階段的暫時決定,容易回頭改,不符合 ADR 的「難以回復」條件。
這代表它真的在用三個條件去檢查,不是看到「架構決定」四個字就反射性寫一份文件。我把整個目錄翻過,docs/adr/ 確實沒有被建立。這個「我考慮過要不要寫,決定不寫,並且講出理由」的動作,比單純「沒有寫」更能證明節制不是巧合。
我拿 ADR-FORMAT.md 裡列的「什麼樣的決定夠格」清單自己對了一遍,想確認這個判斷站不站得住,不是只聽它自己講。清單裡的「技術選型會卡死」特別點名「登入服務」這個類別——乍看會讓人以為「跳過登入」正好對上。但原文的判準是「選了一個會卡住未來的方案」,今天的決定是反過來的:明講現在不做登入,之後要加才切換,而且切換點只有 lib/db.ts 裡的 CURRENT_USER_ID 一行,不是選了某個登入服務綁死。清單裡真正對得上的反而是另一條——「刻意偏離常規做法,一般讀者會以為做了相反的事」——而這條的門檻是「容易被誤解成疏忽」,不是「使用了非常規技術」。今天的程式碼裡,lib/db.ts 自己就寫了一行註解交代這個決定(// No auth yet: every request acts as this fixed demo user.),讀程式碼的人不需要另外去翻 ADR 才看得懂,這點也支持「不寫 ADR」是合理判斷,不是偷懶。
最後我自己把實作出來的 lib/db.ts 單獨跑了一次,不靠它回報的建置結果,用 npx tsx 直接執行一段腳本:收藏兩篇文章、重複收藏同一篇、對一個不存在的 slug 收藏、取消其中一篇,逐步印出清單。結果是:
bookmarked order: [ 'react-server-components', 'intro-to-islands' ]
after remove: [ 'react-server-components' ]
isBookmarked check (removed): false
最近收藏的排在前面、重複收藏沒有產生重複項、不存在的 slug 被安靜忽略、取消收藏後清單跟 isBookmarked 都正確反映——四個情境都跟它在回報裡聲稱的行為一致,不是我用肉眼讀程式碼推測出來的,是真的執行過。
這系列測到現在,常見的失望來源是「規則存在,但沒被照做」。今天剛好相反:規則不只被照做,連規則裡「什麼時候該克制」那部分也被照做了。這點值得跟前兩天放在一起比——prompt-improver 的問題是「判斷要不要做」這一步沒接住;grill-me 把判斷題拿掉,改成使用者主動觸發,問題被解決了。今天 domain-modeling 更進一步:連「寫不寫文件」這個判斷題,都靠寫死的三條件去代替模糊的「自己看著辦」,而不是乾脆兩個極端——要嘛每個決定都寫一份、要嘛乾脆都不寫。把判斷題換成可以核對的條件清單,看起來是這幾個機制共同的成功關鍵。
這個模式其實重複出現了三次,值得單獨拉出來講:grilling 把「問不問」換成「frontier 空了沒」;domain-modeling 把「寫不寫 ADR」換成「三個條件是否同時成立」;就連 CONTEXT.md 本身的格式,也是用「有沒有 _Avoid_ 這個欄位」取代「這個定義寫得好不好」這種主觀判斷。三個規則有同一個共通點:原本容易讓模型憑感覺拿捏的地方,全部被改寫成「對照清單、逐條核對」。這跟這系列從 Day 1 就在驗證的一件事互相呼應——弱模型(甚至強模型)在「憑感覺判斷」這件事上並不可靠,但在「照著一份寫清楚的清單逐條核對」這件事上通常可以做得不錯。今天測到的不是「這個模型比較聰明」,是「這份規則把判斷題拆解得夠具體」。

CONTEXT.md 這類輕量詞彙表值得抄這個格式——每個詞條附一行「不要跟什麼搞混」,比單純寫定義更實用,之後接手的人才知道為什麼某個詞不能亂用。--resume 模擬多輪對話才測到真正的行為,這個方法可以留給以後測類似的機制。CONTEXT-FORMAT.md)對一次格式,比單看內容合不合理更快抓到落差。 今天的 CONTEXT.md 連「每個詞條附一行 _Avoid_」這種細節都對上,這種格式層級的精確,是光讀文字內容不容易注意到的。
grill-me 跟 grill-with-docs 兩天測下來,是這系列目前難得的「連續兩天都測出正面結果」的組合,而且兩天測的是同一個引擎(grilling)疊加不同的外掛技能,疊加之後沒有互相干擾,新加的 domain-modeling 也沒有搶戲——文件該寫的時候寫,不該寫的時候老實講原因。
兩天合起來看,也剛好示範了這系列一直想做的事:不是測一次就下結論,是把同一個引擎放進不同情境,看它在加了新的外掛技能之後,原本測過的部分會不會跟著跑位。今天的答案是沒有——昨天測過的問題品質,今天疊加 domain-modeling 之後沒有變差,新增的文件機制也沒有搶走原本的對話節奏。這點本身就值得記一筆,因為疊加功能最常見的失敗方式,就是新功能悄悄把舊功能原本做得好的地方擠壞。
Matt Pocock 的技能包還有其他幾個沒碰過的方向(像處理驗證回饋的技能),之後找機會再回來測。明天想換一個完全不同的候選。