從 Rational Process 到 Prompt 設計
如何將人類智慧傳輸給 AI
最近我在開發軟體時,需要調用一個函式庫。我透過 LLM 來輔助,但是無論我怎麼調整 prompt,LLM 都失敗了。最後我靠自己慢慢思考把答案湊出來。這段經歷讓我重新思考 prompt 的設計方式,並歸納出一個有效的方法:結構化思考 prompt。
要開發的軟體是 Editor Plugin。很不幸地,我對我用的程式語言、還有應用的平台 (Editor) 都不夠熟。正面地來講,這讓我有機會可以同理那些,多年不太親手寫程式的 staff-level programmer 的感受。
我需要調用函式庫來做一個編碼 (encoding),而那個函式庫並沒有直接支援我要應用的那個案例。然而,我傾向相信說不定還是可以調用那個函式庫來處理,只是需要用一些比較特別的方式來呼叫函式庫。
不巧的事情是,文件裡並沒有範例清楚地示範,我想要的那種呼叫方式是怎麼做。
我請 LLM 示範一個函式庫的調用,並且告訴它:「想要的 output,想要調用的函式庫,還有我的特殊要求。」
LLM 第一次就失敗了。於是,我想,很有可能我給的 context 不夠,所以第二個實驗,我把函式庫的 README 完整地附加在 prompt 之後,也是失敗。第三個實驗,我把整個函式庫包含 README,還有所有的 source code 都變成 plaint text,也是附加在我的 prompt 之後,也還是失敗。
最後,我自己慢慢想了很久,把答案做出來。正確的作法確實很繞彎:我為特殊要求的部分,自己寫了一些些程式碼,並且利用函式庫既有的鬆耦合機制,將自己寫的程式碼部分,註冊給函式庫。這樣子調用就成功了。
在完成這個挑戰之後,我重新設計了我的 prompt,把它改成:
${AAA} 是我想要的 output,請你調用 ${BBB} 函式庫來達成它,必須滿足 ${CCC} 這個條件。
你在解這個問題時,請依照以下的順序進行思考:
欲使用之功能,是否可能是 ${BBB} 函式庫的設計者最初沒有覆蓋到的情境?
函式庫的設計者是否已經對這種情況,應用了鬆耦合機制,讓使用者日後可以做出修改?
開發 ${BBB}函式庫的程式語言 ${DDD},它的鬆耦合機制為何?
綜合考慮 1, 2, 3 之後,該如何調用 ${BBB} 函式庫?
當我使用這個新的 prompt 去請 LLM 示範函式庫的調用時,LLM 的產出,品質大幅提高。有的 LLM 成功了;就算是失敗的,也只差一步之遙了。
Rational Process 與 prompt 設計的啟發
幾年前,我讀了一本名為 The Rational Manager 的書。作者提出一套管理框架,包含情境評估(Situational Appraisal)、決策(Decision Making)、問題解決(Problem Solving)與規劃(Planning)——統稱為 理性流程(Rational Process)。理性流程是一連串由問題驅動的步驟,在此過程中會蒐集、整理並分析資訊與判斷,以達成恰當的結論。
當我回顧自己成功的提示詞設計時,我發現它與這個方法有顯著的相似之處。正如理性流程引導管理者做出健全的決策,結構化思考的提示詞也能一步步引導大型語言模型(LLM)朝向正確的解答。
什麼是結構化思考 prompt?
結構化思考 prompt 的核心,是將我們人類解決複雜問題的思維模式,系統化地轉譯成 LLM 能夠執行的步驟。這意味著你不再只是單純丟出問題,而是引導它一步步思考,讓它遵循清晰、有邏輯的推理路徑。(LLM 其實不會思考,但是,一步步前進的話,他有更高的機率生成對的答案。)
naive prompt 就像是「直接要求給出答案」,而結構化思考 prompt 則是「指導思考的過程」。
回想我的例子,過去的 naive prompt 只是簡單一句:「幫我用這個函式庫達成這個目標。」這就像是直接要求一個新人:「把這個專案做好」,新人會因為缺乏背景知識與思考方向而感到困惑。
而我的結構化思考 prompt 則是:「請你像個資深工程師一樣,先想想這個函式庫的設計目的,再思考它是否預留了擴充的可能性,最後才綜合這些資訊來給出解決方案。」
這四個思考步驟,其實就是我在解決問題時的思維軌跡。我將這個思維軌跡寫成了 prompt,成功地將我的「人類經驗」傳輸給了 LLM。
結構化思考 prompt 與 Context Engineering 的差異
一開始,我將整個函式庫的 README、甚至是所有原始碼都附加在 prompt 後面,這種做法其實就是 Context Engineering 的一種。我的想法很直覺:既然 LLM 缺乏資訊,那我就把所有資訊都給它。
然而,這種做法是失敗的。原因很簡單:
資訊過載: 雖然 LLM 的 context window 很大,但是,如果沒有明確的指引,它在處理龐大而零散的上下文時,其準確度會顯著地下降。
缺乏思考路徑: LLM 在處理如此龐大的上下文時,它並不知道應該從何處開始、應該如何組織這些資訊來得出結論。它像是在一個無邊無際的圖書館裡迷路了,雖然手邊有很多書,但不知道該看哪一本、如何把書中的知識串聯起來。
結構化思考 prompt 的成功,恰恰彌補了 Context Engineering 的不足。它並非只是一股腦地提供資料,而是提供了資料的「使用說明書」。它告訴 LLM:「嘿,你不需要把所有東西都看過一遍。我已經幫你歸納好思考的步驟了,請你按照 1、2、3、4 的順序,一步步地篩選、分析和推理這些資訊。」
這種做法就像是給圖書館裡的學生一張清晰的導覽地圖,並告訴他:「先去 A 區找概念書,再去 B 區找相關範例,最後綜合起來就可以找到答案。」這不僅大幅降低了資訊處理的複雜度,也讓 LLM 能夠更有目的性地利用它所擁有的上下文資訊。
應用的挑戰
我有試著在其它的軟體開發應用案例上,思考我是不是也能推導出類似的結構化思考 prompt。但是,並不是每次都很順利。比方說,當我要 porting 一個函式庫時,我會做的事情是,我要先用人腦,一一檢查函式庫的依賴關系之後,才會叫 LLM 幫我 port,同時我也會告訴 LLM,哪些依賴的函式庫要更換為哪些。
像上述如此複雜的情況,一方面是要寫出完整的結構化思考 prompt 並不容易,我前後考慮的步驟超過十步了吧?此外,步驟愈多,失敗率也愈高。這也提示我們,要設計一個有效的結構化 prompt,前提是我們自己必須先對問題有透徹的理解和清晰的解決思路。
總結
當面對複雜問題時,單純提供大量資料給 LLM 並非萬靈丹,「指導思考」比「提供資料」更為關鍵。結構化思考 prompt 的核心,在於將人類解決問題的思維模式,系統化地傳授給 LLM。這不僅提升了輸出的品質,也讓我們能更有效地利用 LLM 的強大能力。


