
大多數開發者使用 AI 編碼代理的方式是這樣:打開聊天視窗,輸入「幫設定頁面加一個深色模式切換鈕」之類的句子。代理會產出一些東西。大致能用。但邊邊角角還很粗糙。接下來二十分鐘,開發者就在來回往返中把東西補起來。
然後他們就認定這個模型不怎麼樣。
模型沒問題。問題出在提示詞。
提示詞裡的每一個模糊之處,都是模型在沒有你的情況下所做的決定。深色模式的偏好要不要跨工作階段保留?要不要尊重作業系統層級的設定?偏好要存在哪裡,localStorage、資料庫裡的使用者個人檔案,還是 cookie?用的是哪個元件庫,主題在裡面是怎麼運作的?
你沒說。所以模型用猜的。有時猜對。更多時候不是。於是你得到一段在一個環境正常、換個環境就壞掉的程式碼,或是一個忽略使用者既有偏好的元件。
這是資訊的問題。
認真打造 AI 輔助開發流程的團隊,摸索出來的結論是這樣:對於把一件事做好需要什麼,模型比大多數開發者更清楚該怎麼問。
模型處理過數量龐大、規格清楚明確的工程任務。所以它知道一份完整的功能請求長什麼樣,也知道一份模糊的錯誤回報通常缺了什麼。訣竅是,在你要求它做任何事之前,先讓它告訴你缺了什麼。
流程是這樣:
最後一步可有可無,但值得做。你可以對代理說:「根據我的回答,把我的原始請求改寫成一份完整的任務規格。」你拿回來的,是模型自己都認為夠完整、足以執行好的提示詞。再把這份提示詞當成真正的任務交出去。
有些人開始把這叫做任務執行的反向提示詞工程。你不是從零寫出一份完美提示詞,而是讓模型浮現出一份完美提示詞該包含什麼,再從那裡往下走。
假設你想在設定頁面加一個深色模式切換鈕。兩種做法是怎麼展開的。
天真的做法:
「幫設定頁面加一個深色模式切換鈕。」
代理產出一個寫死的切換鈕元件,把偏好存在元件狀態裡(重整就消失),不接任何既有的主題系統,而且用的是行內樣式,而不是你原本在用的 CSS 變數或主題 token。
接下來一小時你都在修。
反向提示詞的做法:
你從同一句話開始,然後問:「開始之前,要把這個做對,你需要知道什麼?我該釐清什麼?」
代理會回你大概像這樣的東西:
- 偏好該存在哪裡(localStorage、資料庫、cookie)?
- 有既有的主題系統嗎(next-themes、CSS 變數、Tailwind 的 dark: 變體)?
- 這個切換鈕要不要預設尊重使用者的作業系統深色模式設定?
- 它在設定頁面要放哪裡?有沒有既有的「外觀」區塊?
- 如果使用者已登入,偏好要不要跨工作階段同步?
你回答這些問題。你告訴它,這個 app 用的是 next-themes,偏好會透過既有的 PATCH /users/me 端點存進使用者的個人檔案,而且設定頁面已經有一個「外觀」區塊,裡面的其他切換鈕都遵循特定的元件模式。
現在代理有了它需要的東西。它產出的實作會接上正確的主題提供者、用既有的 API、配合既有的 UI 模式,也會處理作業系統偏好的備援。你什麼都不用修。
錯誤回報是模糊提示詞殺傷力最大的地方。因為一個脈絡不足的模型,不只產出平庸的程式碼,還會產出自信滿滿、但其實是錯的程式碼。
想像有人回報:「登入按鈕有時沒反應。」
天真的做法: 你把這句話貼進代理。它開始掃描驗證程式碼,看到一個可疑的 async/await 模式,覺得大概就是這裡,改寫了那個函式,然後開一個 PR。錯誤還在。它改的那個函式根本無關。
反向提示詞的做法:
你把錯誤回報交給代理,然後問:「要把這個診斷好,你需要知道什麼?資深工程師在碰任何程式碼之前,會先問哪些問題?」
它會這樣回應:
-「沒反應」是什麼意思?按鈕不回應點擊、點擊了但什麼都沒發生,還是跳出錯誤?
- 這能穩定重現,還是斷斷續續?有沒有什麼規律(特定瀏覽器、網路狀況、使用者狀態)?
- 發生時有沒有主控台錯誤,或失敗的網路請求?
- 是哪個元件處理按鈕點擊,哪個服務處理驗證?
- 這是原本就壞,還是最近才回歸?如果是回歸,改變了什麼?
你回頭找那位回報錯誤的人,拿到答案:這是斷斷續續的,只有使用者待在頁面超過十分鐘之後才會發生,沒有主控台錯誤,但網路請求完全沒發出去。這下是完全不同的錯誤了。原因很可能是 token 過期,或是事件處理器裡一個過時的閉包。
你把這些資訊交給代理,它這次就會去對的地方。它找到一個 useCallback,相依項目過時,從初次渲染就抓著一個驗證 token。修正就是一個鎖定目標的小改動,沒有其他傷及無辜。
多數 AI 輔助寫程式會像一場談判,讓你在好幾輪裡來回打磨輸出,原因就是最初的提示詞把太多決定留給了模型。每一輪的修改,都是你在更正模型因為你沒指定而做出的猜測。
反向提示詞把這些輪次的大部分,收攏成開頭的一場對話。模型的問題會精確告訴你,它本來會自己做出哪些決定。你來替它做這些決定。因為資訊完整,輸出第一次就對了。
還有一個附帶的好處。模型問的那些問題,本身就是一份檢查清單。如果你對類似的任務——像是加新的設定、修驗證的錯誤、整合新的 API——持續使用同一套技巧,那些問題會慢慢變得眼熟。久了之後,不用人問,你自然會把那些細節寫進提示詞裡,你基本的提示詞品質就提高了。
這套技巧對有工具和檔案存取能力的代理效果最好,像是 Cursor 或代理模式下的 GitHub Copilot。一個能讀你程式碼庫的代理,問的問題會比兩眼一抹黑、憑空工作的代理具體得多。
兩輪式的流程(你需要什麼 -> 給你 -> 現在做任務)確實多了一步。對又小又明確的任務來說,這有點小題大做。但只要是會碰多個檔案、要跟既有系統整合、或牽涉不明顯的設計決策的工作,它穩定比直接動手做實作出更好的結果。
第三步產出的那份規格值得留著。它是一份可以重複使用的範本。下次有人要加一個會存進使用者個人檔案的設定,你手上已經有一份規格清楚的提示詞了。
大多數開發者對編碼代理下提示詞的方式,是以犧牲品質為代價來追求速度。一句話快速丟進去、一個平庸的輸出丟回來,然後花十分鐘清理,一天重複幾十次。
反向提示詞的做法把這個取捨倒過來。你在一開始多花一點時間,確保模型有它需要的東西。回報是,輸出更接近你真正想要的,你花在修正上的時間也更少。
對一項任務來說最好的提示詞,是模型告訴你它需要的那一份。
© Melvin Laplanche - All rights reserved.