以正確的方式向 AI 程式碼代理下提示詞

以正確的方式向 AI 程式碼代理下提示詞

以下是大多數開發者使用 AI 程式碼代理 (AI coding agent) 的方式:他們打開聊天視窗,輸入類似「在設定頁面新增一個深色模式切換開關」的內容。代理生成了一些東西。它似乎能用,但邊緣有些粗糙。開發者接下來的二十分鐘都在反覆修補。

然後他們得出結論:這個模型不怎麼樣。

模型沒問題。問題出在提示詞 (prompt) 身上。

模糊提示詞的殘酷現實

提示詞中的每一個模糊不清之處,都是模型在你缺席時替你做出的決定。深色模式偏好應該在工作階段之間保留嗎?它應該尊重作業系統層級的設定嗎?這個偏好儲存在何處——localStorage、資料庫中的使用者設定檔,還是 cookie?專案中使用了哪個元件庫,它的主題系統是如何運作的?

你沒說。所以模型只能猜測。有時候它猜對了。但通常它會猜錯,於是你得到的程式碼在某個環境中可用,在另一個環境中卻會崩潰;或是生成了一個無視使用者現有偏好的元件;亦或是一個完全不起作用的切換開關,因為它壓根沒有連接到正確的上下文中。

這不是模型品質的問題。這是資訊缺失的問題。

技巧:讓代理自己建構提示詞

真正有效的方法,也是那些建構嚴謹 AI 輔助開發工作流的團隊所發現的技巧是:對於如何出色地完成一項任務,模型比大多數開發者更清楚它需要什麼資訊,也更懂如何提問。

它處理過海量規格明確的工程任務。它知道一個完整的功能需求長什麼樣。它也知道一份模糊的錯誤報告通常遺漏了什麼資訊。這個訣竅就在於:在要求它執行任何操作之前,先讓它告訴你缺了什麼。

流程大致如下:

  1. 粗略地描述你的目標 —— 只要足以讓代理理解問題空間即可。
  2. 詢問它需要什麼才能妥善完成 —— 「若要出色地完成此任務,你需要什麼資訊?我應該釐清哪些模糊之處?有哪些我沒有說明的細節需要具體指出?」
  3. 填補空白 —— 回答它的問題,提供它所要求的上下文。
  4. 現在把任務交給它 —— 要麼將它的問題融入你的提示詞中,要麼讓它把你的原始請求重寫成一份完整的規範,然後你再批准並執行。

最後一個步驟是選擇性的,但非常強大。你可以問代理:「基於我的回答,請將我最初的請求重寫為一份完整的任務規範。」你得到的答覆,將是模型自己認為足夠完整、可以完美執行的一段提示詞。然後,你再將這段提示詞作為實際任務提交。

有人開始將這種方法稱為面向任務執行的「逆向提示詞工程 (reverse prompt engineering)」——你不再是從零開始寫出完美的提示詞,而是利用模型來幫你揭示完美的提示詞應該包含什麼。

案例 1:建構功能

假設你想要在設定頁面新增一個深色模式切換開關。我們看看這兩種方法的實際效果。

天真的方法:

「在設定頁面新增一個深色模式切換開關。」

代理生成了一個帶有寫死邏輯的切換元件,將偏好狀態保存在元件內部(一重新整理就會遺失),沒有將其連接到任何現有的主題系統,而且使用的是行內樣式 (inline styles),而不是你已經在用的 CSS 變數或主題 token。

接下來的一個小時你都在修復它。

逆向提示詞方法:

你以同樣的一句話開頭,然後問:「在你開始之前,若要妥善實作這個功能,你需要知道些什麼?我該釐清哪些細節?」

代理的答覆大概會是:

你回答了這些問題。你告訴它應用程式使用了 next-themes,偏好設定透過現有的 PATCH /users/me 端點儲存在使用者設定檔中,而且設定頁面已經有一個「外觀」區塊,裡面有其他遵循特定元件模式的開關。

現在代理掌握了必要的資訊。它交出的實作正確連接了主題提供者,使用了現有的 API,匹配了當前的 UI 模式,並處理了作業系統的退路邏輯 (fallback)。你完全不需要修補任何東西。

產出品質的落差是顯而易見的。

案例 2:修復 Bug

錯誤報告是模糊提示詞造成最大破壞的地方。因為沒有足夠上下文的模型不僅會產生平庸的程式碼,更會自信地寫出錯誤的程式碼。

想像有人提交了一個 bug:「登入按鈕有時候點不了。」

天真的方法:

你把這句話貼給代理。它開始掃描身分驗證程式碼,發現了一個可疑的 async/await 模式,斷定那就是問題所在,重寫了函式並開啟了一個 PR。結果 Bug 依舊存在,它改動的是一個毫不相干的函式。

逆向提示詞方法:

你把錯誤報告交給代理,並問它:「你需要知道什麼才能進行有效的診斷?一個資深工程師在修改程式碼之前會問哪些問題?」

它回答:

你找到提 Bug 的人拿到了答案:是間歇性的,只有在使用者在頁面停留超過 10 分鐘時才會發生,主控台沒有報錯,但網路請求壓根沒發出去。這完全是另外一個 Bug 了——很可能是 Token 過期問題,或是事件處理函式中出現了過時的閉包 (stale closure),根本不是什麼 async/await 問題。

你把這些資訊給代理,這次它找對了地方。它定位到了一個 useCallback,裡面的過時依賴項捕捉了初始渲染時的認證 Token。一次精準的修復,沒有引發任何附帶損害。

為什麼這麼做很有效

大多數 AI 輔助程式設計之所以感覺像是在「談判」——你來我往好幾個回合不斷打磨結果——是因為初始提示詞將太多決策權留給了模型。每一輪的修改,都是在糾正模型因為你的未曾說明而做出的隨機猜測。

逆向提示詞將這幾輪較量壓縮為一次前期對話。模型的提問精準地告訴你,它本應自行做決定的地方在哪裡。而你代替它做出了決策。因為擁有了完整的資訊,它第一次就能產出正確的結果。

還有一個額外的好處:模型問的問題就是一份檢查清單。如果你經常把相同的技巧用於類似的任務——新增設定、修復驗證 Bug、整合新 API——這些問題就會變得眼熟。久而久之,你就學會了在不用被問的情況下主動把細節放進提示詞裡,你的基準提示詞品質也就隨之提升了。

一些實用的注意事項

這一技巧在配合具有工具呼叫和檔案存取權限的代理(如 Cursor、Agent 模式下的 GitHub Copilot、Claude 或類似工具)時效果最佳。能閱讀程式碼庫的代理會比「盲眼」工作的代理提出具體得多的問題。

這套「來回」(你需要什麼 → 給,這是你要的 → 現在去執行)的流程確實多了一步。對於微小、定義極度明確的任務來說也許是殺雞用牛刀。但只要任務涉及到修改多個檔案、與現有系統整合,或包含不明顯的架構設計時,它所產生的結果一直都優於直接讓模型寫程式碼。

並且,第三步所生成的提示詞規範是值得保存下來的。這是一個可高度重複使用的模板。下一次再有人需要「在使用者個人資料中新增可保存的偏好設定」時,你手裡已經有一份完美的任務提示詞了。

更深刻的意義

大多數開發者給代理寫提示詞的方式是「速度至上,犧牲品質」。隨意丟一句短短的指令,收到一個馬馬虎虎的結果,然後花十分鐘收尾擦屁股——每天重複這麼幾十次。

逆向提示詞法顛覆了這種取捨。你多花一點點前期時間,確保模型擁有必要的彈藥。作為回報,它的輸出更為接近你的真實意圖,你也省下了更多「修補」的時間。

某個任務最完美的提示詞,絕不是你花 30 秒敲出來的那句話。而是模型親口告訴你,它所需要的那段話。

© Melvin Laplanche - All rights reserved.