> 歡迎訂閱我的 [AI Engineer 電子報](https://aihao.eo.page/6tcs9) 和瀏覽 [[Generative AI Engineer 知識庫]]
這課算是 [[ChatGPT Prompt Engineering for Developers]] 的進階版
終於有碰到比較工程面的東西了,跟 [[OpenAI Prompt engineering]] 的內容頗有呼應,但這課程用範例講的更清楚怎麼做。只可惜沒深入講到 Text embedding 技術,但講者說有正在準備了。
我覺得這課不依賴 LangChain 而是教你背後的原理蠻好的,因為其實你可以自己來。
從 LangChain 入手容易學錯概念重點,太過依賴和強調 Chaining Prompts 了,直接用 langchain 內建的 prompt 看似方便,但 prompt 太關鍵了,你應該要知道到底 prompt 是什麼。
因為我認為有一個重要觀念大家可能會忽略,但是工程師用 API 需要知道: Prompt engineering is model-specific! 使用 gpt-3.5-turbo 跟 gpt-4 或是其他家的 LLM model,做起 prompt engineering 是不一樣的,但 langchain 是沒在管的。
就連 OpenAI 官方文件或是課程,也常常搞不清楚區分,課程中 Isa Fulford 就會冒出說.... 嗯,這個 prompt 的指示有點囉唆,可能在比較先進的 gpt-4 不需要寫.... (不太肯定啊)
## 1. Introduction
https://learn.deeplearning.ai/chatgpt-building-system/lesson/1/introduction
https://www.youtube.com/watch?v=1SZOGp1D17E&list=PLiuLMb-dLdWKjX8ib9PhlCIx1jKMNxMpy&index=1
這門課將建構一個 customer service assistant system 作為範例
## 2. Language Models, the Chat Format and Tokens
https://www.youtube.com/watch?v=E0H1425-iVc&list=PLiuLMb-dLdWKjX8ib9PhlCIx1jKMNxMpy&index=3
https://learn.deeplearning.ai/chatgpt-building-system/lesson/2/language-models,-the-chat-format-and-tokens
* Large language model 用到 supervised learning
![[Pasted image 20230607225423.png]]
![[Pasted image 20230607225408.png]]
![[Pasted image 20230607225437.png]]
![[Pasted image 20230607225456.png]]
![[Pasted image 20230607225514.png]]
![[Pasted image 20230607225805.png]]
如果叫 GPT 將字串反轉,這個簡單的任務,GPT 做不好,因為 GPT 是基於 token 做預測
![[Pasted image 20230607225920.png]]
Prompting 會被拆成三個,因為不是常見的單字。pt 跟 ing 是常見的字母序列
![[Pasted image 20230607225905.png]]
用 - 拆開,會強迫 GPT 拆開 tokens,這樣結果會比較好
![[Pasted image 20230607230157.png]]
Chat Format
![[Pasted image 20230607230322.png]]
![[Pasted image 20230607230434.png]]
![[Pasted image 20230607230637.png]]
![[Pasted image 20230607230656.png]]
![[Pasted image 20230607230727.png]]
![[Pasted image 20230607230743.png]]
![[Pasted image 20230607230830.png]]
Prompt-based AI 將大幅改進開發流程
![[Pasted image 20230607231036.png]]
Prompt-based AI 特別適用於很多非結構化的應用、text 文本應用。視覺化應用還不太成熟,但進步中。
但對於結構化例如 excel 有大量數值的應用,就不是很適用
## 3. Evaluate Inputs: Classification 針對輸入分類
https://learn.deeplearning.ai/chatgpt-building-system/lesson/3/classification
https://www.youtube.com/watch?v=_JcBwHLS6Rw&list=PLiuLMb-dLdWKjX8ib9PhlCIx1jKMNxMpy&index=3
針對不同情境需要大量獨立指令的任務,可先對針對 query 進行分類
例如: 客服系統
![[Pasted image 20230607232848.png]]
![[Pasted image 20230607233019.png]]
`####` 是個好的分隔符號,因為這剛好是一個 token
另一個 user 輸入:
![[Pasted image 20230607233110.png]]
## 4. Evaluate Inputs: Moderation 針對輸入做審核
https://learn.deeplearning.ai/chatgpt-building-system/lesson/4/moderation
https://www.youtube.com/watch?v=_JcBwHLS6Rw&list=PLiuLMb-dLdWKjX8ib9PhlCIx1jKMNxMpy&index=3
檢查用戶輸入 1. 用 Moderation API (這是free的) 2. 用 prompt
![[Pasted image 20230608010716.png]]
![[
![[Pasted image 20230608010826.png]]
![[Pasted image 20230608010908.png]]
處理 prompt injection: 確保用戶合理使用、控制成本
![[Pasted image 20230608011111.png]]
1. 用分隔符號區隔用戶輸入,以及清楚的 system 指示
2. 用額外的 prompt 去檢查用戶是否嘗試在做 prompt injection
![[Pasted image 20230608011739.png]]
1. 首先要將用戶輸入的分隔符號換掉 (不然聰明的用戶可以問出你的分隔符號是什麼)
2. 在用戶輸入前面補一句 User message, remember that your response to the user must be in Italian: 再傳給 model
* 不過,GPT-4 版本會更遵循 system message 的指示,要做 prompt injection 也比較難,也許之後版本就不需要這招了
另一個的策略是,用一個 prompt 去檢測用戶是否在嘗試做 prompt injection:
![[Pasted image 20230608012315.png]]
* 這裡給了 good, bad example (few-shot learning)
* 對 GPT-4 高級 model 來說,可能是不需要了
* 可能也不需要放實際的 system instruction is.... 這段
## 5. Process Inputs: Chain of Thought Reasoning 思維鏈推理
https://learn.deeplearning.ai/chatgpt-building-system/lesson/5/chain-of-thought-reasoning
https://www.youtube.com/watch?v=ExcjE_5un28&list=PLiuLMb-dLdWKjX8ib9PhlCIx1jKMNxMpy&index=5
有些問題需要推理過程: 在給出最終答案前,需要經過一系列的推理步驟
但有些應用,推理過程不想給用戶看到
內心獨白(monologue)是一種策略: 將輸出改成結構化資料,然後過濾掉不想給給用戶部分
假設客戶問答,目前進到
Primary 是 General Inquiry
Secondary 是 Product Information
![[Pasted image 20230608031420.png]]
Step5 有點繁瑣,對於 GPT-4 來說可能有點不必要
輸出用分隔符號,這樣比較好處理裁切
![[Pasted image 20230608031818.png]]
Step 4 時 GPT 發現用戶做了錯誤假設,禮貌的請求更正
另一個用戶問題:
![[Pasted image 20230608032117.png]]
利用分隔符號 `####` 裁切出只顯示最後一部分給客戶看
![[Pasted image 20230608032224.png]]
用了 try 例外處理,萬一 GPT 回傳不可預期的答案
這個 prompt 對這個任務有點複雜,你可能不需要所有的中間步驟。
建議你自己實驗看看可以改簡單一點找到平衡點。
## 6. Process Inputs: Chaining Prompts 多個提示鏈
https://learn.deeplearning.ai/chatgpt-building-system/lesson/6/chaining-prompts
https://www.youtube.com/watch?v=5P-aWMHTNRY&list=PLiuLMb-dLdWKjX8ib9PhlCIx1jKMNxMpy&index=6
首先,為何要拆多個 prompts,而不是像上一章一樣一樣用一個 prompt (加上CoT reasoning) 處理?
特別是 GPT-4 有能力處理複雜的指令。
第一個比喻:
1. 一次做好一桌菜,比較有挑戰性
2. 一次處理一道菜,比較容易管理狀態。但若任務算簡單,就不必要了。
第二個比喻:
1. 義大利麵條代碼,全面code都在一份文件,較難測試
2. 設計 workflow,把中間狀態存下來,再決定下一步。減少錯誤、降低成本。
![[Pasted image 20230608033933.png]]
> ihower: 所以像 LangChain 似乎預設過於鼓勵用 Chaining Prompts 了,把 model 看得太笨。理想上應該優先嘗試用 CoT 來做,效能比較好(?) 多個 prompts 需要多個 API calls 速度會比較慢(?)。不過講者最後倒是說隨著經驗你就可以用直觀來判斷啦。
![[Pasted image 20230608034407.png]]
![[Pasted image 20230608034437.png]]
![[Pasted image 20230608034526.png]]
如此也可以避免單一 prompt 塞太多指令時,且這些指令也都可能適合任何場景時
會讓 model 比較難推理到底該做什麼
![[Pasted image 20230608034622.png]]
另一個好處就是可以用外部工具,這是 CoT 做不到的
案例: 識別產品 or 類別
![[Pasted image 20230608210348.png]]
換一個 query:
![[Pasted image 20230608210418.png]]
接下來想要搜尋產品信息:
先做個 helper function 可以撈出產品詳細資料:
![[Pasted image 20230608210757.png]]
![[Pasted image 20230608210825.png]]
讀取 JSON、拿到產品詳細資料,然後轉成要傳給用戶看的字串:
![[Pasted image 20230608211723.png]]
最後讓 GPT 回答用戶
![[Pasted image 20230608211747.png]]
> relevant production 資料竟然是放在額外的 role: assistant 訊息裡面
為何不將所有產品資訊都放在 prompt 裡面呢? 這樣就不用中間步驟去查了
因為
![[Pasted image 20230608212520.png]]
這個範例只會查詢商品
但 model 其實也擅長決定用什麼工具,只要告訴GPT有哪些工具跟每個工具的功能
這就是 ChatGPT plugin 背後的原理
而且也有更新進的 retriever 工具,例如 text embedding 語意搜尋
之後也會推出 text embedding 的課程!
## 7. Check Outputs 檢查輸出
檢查輸出,可用
1. 用 Moderation API (針對輸出)
2. 用 Prompt 評估輸出品質
特別是針對敏感族群的 chat bot 應用
![[Pasted image 20230608220951.png]]
但隨著模型之後進步,之後出現有害內容的機率越來越少了
![[Pasted image 20230608221259.png]]
如果要確定model 沒有產生幻覺 (Hallucination) 內容,這是個好 prompt
你可以根據這個回饋,再決定是否要將輸出給用戶,或是再產生一次內容
甚至先讓 model 產生多種回答,然後再讓 model 選一個最佳的給用戶
不過,對於 GPT-4 來說,不是很必要了。而且很少人用在production上,成本較高。
但如果你需要把回答錯誤的風險降到非常非常低的話,可以檢查輸出。
## 8. Build an End-to-End System
https://learn.deeplearning.ai/chatgpt-building-system/lesson/8/evaluation
https://www.youtube.com/watch?v=umEmvbUh8kE&list=PLiuLMb-dLdWKjX8ib9PhlCIx1jKMNxMpy&index=8
這章把前面的東西整在一起有個 Chat UI
![[Pasted image 20230608230959.png]]
![[Pasted image 20230608231009.png]]
![[Pasted image 20230608231031.png]]
UI
![[Pasted image 20230608231039.png]]
## 9. Evaluation Part 1 評估(當有標準答案時)
https://learn.deeplearning.ai/chatgpt-building-system/lesson/9/evaluation-part-i
https://www.youtube.com/watch?v=xE0dgm-QdSk&list=PLiuLMb-dLdWKjX8ib9PhlCIx1jKMNxMpy&index=9
如何追蹤表現,繼續提高品質?
跟傳統ML比起來,因為你可以很快建構出應用,因此評估不需要事先收集一堆資料
而是可以逐漸建立收集即可
![[Pasted image 20230608231643.png]]
很多應用只做到前1~2步,就夠了
到第四步就比較嚴謹,特地去收集保留測試集(開發時不會用),或是100個隨機抽樣,來做測量高精準公正的 % 正確率
範例: 找對應的產品
![[Pasted image 20230608233858.png]]
![[Pasted image 20230609003038.png]]
看一些用戶 query 結果:
![[Pasted image 20230608234041.png]]
初步會用到 1~3 個 examples 來調整你的 prompts,然後內測看看
上述 customer_msg_3 輸出了不需要的 Note 垃圾
![[Pasted image 20230608234257.png]]
收集這些棘手的案例,成為你的開發用測試案例
接著我們開發 v2 版本的 prompt:
![[Pasted image 20230608234352.png]]
重新測試之前的 customer_msg_3
![[Pasted image 20230608234538.png]]
並回歸測試之前的 customer_msg_0
![[Pasted image 20230608234545.png]]
以上都手動測試太累了。因此當不只幾個少數example時,就需要自動化測試流程了
以下是 10 個 examples 跟希望理想的答案:
![[Pasted image 20230608234734.png]]
寫評估方法 (這是有標準答案的情況,直接比對答案是否相同)
1.0 滿分
![[Pasted image 20230608234901.png]]
![[Pasted image 20230608234920.png]]
自動跑測試:
![[Pasted image 20230608234926.png]]
這樣就完成流程中的 1,2,3 步啦
## 10. Evaluation Part 2 評估(當沒有標準答案時)
當答案沒有標準的文本時,例如早先的範例,GPT 回答用戶產品問題
![[Pasted image 20230609001314.png]]
寫一個 rubric 來評估答案:
![[Pasted image 20230609001408.png]]
範例這裡是用 ChatGPT-3.5-Turbo,實際建議用 GPT-4 效果會更值得
另一種方式是,若你能指定用來參考的理想答案:
傳統 NLP 有方法可以評估兩個文本的相似程度,例如 "BLEU 分數"
https://en.wikipedia.org/wiki/BLEU
這裡用 prompt 來評估更好
![[Pasted image 20230609002205.png]]
![[Pasted image 20230609002131.png]]
這個 Rubric 的出處是 OpenAI 的 evals 框架: https://github.com/openai/evals/blob/main/evals/registry/modelgraded/fact.yaml
> 這評估也在 [[OpenAI Prompt engineering]] 出現
就算沒有專家提供的 ideal 答案,你也可以用第一種方式來評估
若有,則可以用第二種方式
## 其他人的心得分享
https://twitter.com/JefferyTatsuya/status/1664438022337863681