Mastering OpenAI Python APIs 第三節 Prompt Engineering 筆記

The Elements of a Good Prompt 指令的構成要素

  • \color{orangered}{Prompt\ Design:}
    • \color{dodgerblue}{Main\ Instructions\ 主要指令} – 指示 LLM 如何輸出結果的主要指令
      • a task you want the model to perform
      • Includes output instructions
        • what type of output do you want? What format?
          • CSV comma format, JSON format, HTML format, etc.
    • \color{dodgerblue}{Data} – 輸入的背景資料及要給 LLM 解決的核心任務
      • any input data (if necessary)
    • \color{dodgerblue}{Output\ (By LLM)} – LLM 針對 User 輸入的 Prompt 所回覆的回應(Response)
      • The return response from LLM completion API


(圖片擷取自 www.deeplearning.ai 吳恩達博士的 ChatGpt Prompt Engineering for Developers 的課程範例程式碼片段。)

The Principle of Prompt Writing 撰寫指令的基本原則

  1. \color{red}{Write\ clear\ and\ specific\ instructions\ 明確且具體你的指令撰寫}

    • Clear != Short or Simple 簡短並非等義於明確
      • To simple summary the following input texts → 不明確,何謂 simple?
      • To summary the following input texts in 2~3 sentences → 明確,用兩三個句子總結輸入的文字
      • more:
        • 使用如 “”" 或 ### 這類的分隔符號輔助,便於讓 LLM 更好分辨我們的指令的分段
        • 角色扮演: 指定 LLM 使用怎樣的角色來輸出結果,例如: You are a sellsman (扮演業務員),You are a python language expert (扮演 python 程式專家)等等
        • 指定對象: 指定輸出的結果所要針對的對象,例如: for the sells department (給業務單位),for the elder people (針對老人)
        • 指定輸出樣貌: 包含樣式,例如: To a list (輸出成清單), To HTML texts (輸出成 HTML文本),To JSON object (輸出成 json 物件)等等
        • 提供讓 LLM 參照的範例,使其依據範例的樣貌來回應結果,例如: 英國: 倫敦; 中國: 北京; 日本:
  2. \color{red}{Provide\ the\ model\ time\ to\ 'think'\ 讓 LLM 有時間思考}

    • 將任務化繁為簡,由大化小 → 將任務切分為更小單位的一系列清單任務
    prompt = f"""
    Identify the following items from the review text: 
    - Sentiment (positive or negative)
    - Is the reviewer expressing anger? (true or false)
    - Item purchased by reviewer
    - Company that made the item
      
    The review is delimited with triple backticks. \
    Format your response as a JSON object with \
    "Sentiment", "Anger", "Item" and "Brand" as the keys.
    If the information isn't present, use "unknown" \
    as the value.
    Make your response as short as possible.
    Format the Anger value as a boolean.
      
    Review text: '''{lamp_review}'''
    """
    response = get_completion(prompt)
    print(response)
    

    ○ 指定完成任務所需的步驟

    text_1 = f"""
    Making a cup of tea is easy! First, you need to get some \ 
    water boiling. While that's happening, \ 
    grab a cup and put a tea bag in it. Once the water is \ 
    hot enough, just pour it over the tea bag. \ 
    Let it sit for a bit so the tea can steep. After a \ 
    few minutes, take out the tea bag. If you \ 
    like, you can add some sugar or milk to taste. \ 
    And that's it! You've got yourself a delicious \ 
    cup of tea to enjoy.
    """
    prompt = f"""
    You will be provided with text delimited by triple quotes. 
    If it contains a sequence of instructions, \ 
    re-write those instructions in the following format:
    
    Step 1 - ...
    Step 2 - …
    …
    Step N - …
    
    If the text does not contain a sequence of instructions, \ 
    then simply write \"No steps provided.\"
    
    \"\"\"{text_1}\"\"\"
    """
    response = get_completion(prompt)
    print("Completion for Text 1:")
    print(response)
    
    • 指示模型在急於完成任務之前也找出自己的解決方案

      • 錯誤版:
      prompt = f"""
      Determine if the student's solution is correct or not.
      
      Question:
      I'm building a solar power installation and I need \
       help working out the financials. 
      - Land costs $100 / square foot
      - I can buy solar panels for $250 / square foot
      - I negotiated a contract for maintenance that will cost \ 
      me a flat $100k per year, and an additional $10 / square \
      foot
      What is the total cost for the first year of operations 
      as a function of the number of square feet.
      
      Student's Solution:
      Let x be the size of the installation in square feet.
      Costs:
      1. Land cost: 100x
      2. Solar panel cost: 250x
      3. Maintenance cost: 100,000 + 100x
      Total cost: 100x + 250x + 100,000 + 100x = 450x + 100,000
      """
      response = get_completion(prompt)
      print(response)
      
      • 修正版:
      prompt = f"""
      Your task is to determine if the student's solution \
      is correct or not.
      To solve the problem do the following:
      - First, work out your own solution to the problem. 
      - Then compare your solution to the student's solution \ 
      and evaluate if the student's solution is correct or not. 
      Don't decide if the student's solution is correct until 
      you have done the problem yourself.
      
      Use the following format:
      Question:
      ###
      question here
      ###
      Student's solution:
      ###
      student's solution here
      ###
      Actual solution:
      ###
      steps to work out the solution and your solution here
      ###
      Is the student's solution the same as actual solution \
      just calculated:
      ###
      yes or no
      ###
      Student grade:
      ###
      correct or incorrect
      ###
      
      Question:
      ###
      I'm building a solar power installation and I need help \
      working out the financials. 
      - Land costs $100 / square foot
      - I can buy solar panels for $250 / square foot
      - I negotiated a contract for maintenance that will cost \
      me a flat $100k per year, and an additional $10 / square \
      foot
      What is the total cost for the first year of operations \
      as a function of the number of square feet.
      ###
      Student's solution:
      ###
      Let x be the size of the installation in square feet.
      Costs:
      1. Land cost: 100x
      2. Solar panel cost: 250x
      3. Maintenance cost: 100,000 + 100x
      Total cost: 100x + 250x + 100,000 + 100x = 450x + 100,000
      ###
      Actual solution:
      """
      response = get_completion(prompt)
      print(response)
      
  3. \color{red}{"Let's\ Think\ Step\ By\ Step" Prompting }

    • 對於一些邏輯較為複雜,甚至存在歸納陷阱的核心問題,可以加入 “Let’s Think Step By Step” 這樣的魔法語句,來避免 ChatGpt 歸納總結出錯的結果,而這個魔法的指令,其實是來自一篇論文:


    (以上截圖 出自 Udemy Colt Steele Mastering OpenAI Python APIs: Unleash ChatGpt and GPT4 課程內容)

Model Limitations

  • \color{red}{LLM\ 模型限制:}
    • Hallucinations 模型幻覺 – LLM 模型為了提供回應,即便心裡沒譜的答案,也會蓋得天花亂墜
      • 以前的話,需要迴避可能造成 AI 沒譜的詢問,但現在可以官方版的 OpenAI 已經有可聯網查詢的 Plugin 了,因此要注意的是,即便讓 LLM 幫你產生結果,你也要有能對結果判斷真偽的基本能力
      • 加入限制 LLM 亂回答的指令,比方說,If you could 100% confidance, just say ‘I have no answer’ 或是 ‘before provide the answer, provide me the reference link of this answer dependance at first. And then response it base on this reference’ (要求模型在回答前先提供真實的引用來源,並針對此引用來源來進行回答)

Prompt Types & Skills

  • 針對不同類型的應用,我們會需要不同形式的指令來使得 LLM 更好的幫我們完成任務,以下是綜合這節課程與吳恩達老師 ChatGPT Prompt Engineering for Developers 課程中提到的一些類型及技巧:
    1. \color{red}{Iterative\ 迭代:}

      • 迭代優化你的 Prompt Instrunctions,與其信守網路上別人收集歸納的XX的30個完美提示語,不如訂定一個好的標的,逐次迭代來優化提示工程~
        Image 2
        (圖片擷取自 www.deeplearning.ai 吳恩達博士的 ChatGpt Prompt Engineering for Developers 的課程範例程式碼片段。)
    2. \color{red}{Summarizing\ (文字)摘要:}

      • 簡言之,就是讓 LLM 對你列舉的一段新聞或文章的內容,做總結歸納,這是最單純的一種,你需要做的只是把指令需求與核心問題分開,還記得前面提到的概念,核心問題(輸入的任務文字)擺後面,需求指令擺前面,需求指令部分注意要明確清晰~
      • 此外,這類的核心問題,通常都很長,你需要做的是要將所有文字內容切算成一段段來餵入,後面老師的課程中會有個別的練習專案,來練習把一本書這樣的內容餵入,並讓 LLM 幫我們簡單總結這本書的內容。

        ( 以上截圖出自 Udemy Colt Steele Mastering OpenAI Python APIs: Unleash ChatGpt and GPT4 課程內容)
    3. \color{red}{Inferring\ 推論:}

      • 推論是指模型使用文字作為輸入,並執行某種分析的任務,包含:

        • 簡言之,這類的問題,通常是我們要從一些評論或是某些統計資訊文章,找出裡面符合我們要搜尋的資料特徵,將其找出來,歸納整理在一起,又或是你有一些數據,你希望 LLM 幫你歸納資料走勢 → 情感分析(Sentiment Analysis)
      • 使用 LLM 執行推論分析任務的優勢:

        • 對比在傳統的機器學習工作流程中,我們需要做非常大量的工作流程:
          • 蒐集資料並標注
          • 訓練模型並調整
          • 把模型部署在雲端環境中
        • 可能會很有效,但非常費工,而且每個任務都需要單獨的一個模型
      • 然而對於LLM來說,只需要編寫適合的提示,只要一個 API,就能立即開始生成結果。這在開發應用上有非常巨大的速度優勢

        • 例如下面老師的這則範例,有一家餐廳,裡面有很多訪客的點評訊息,我們想從這些點評訊息找出客人評價最多的餐點,首先我們先嘗試,能否從單則客人點評訊息,找出訊息文字中有列舉的餐點名稱(單則可以的話,多則也就沒問題)


        ( 以上截圖出自 Udemy Colt Steele Mastering OpenAI Python APIs: Unleash ChatGpt and GPT4 課程內容)

        • 剛剛有提到,情感分析(Sentiment Analysis)也是推論類型的重要應用~

          • 所謂情感分析,就是透過一段文字或數據,讓我們依據其走勢,來推算這個主題是正面(Positive)、中性(Neuture)或是負面(Negative)的情緒,比方說,一間餐廳訪客的點評分布,或是新創公司於透資論壇的討論熱度等等。像 Reddit 就是美國很這名的一個集合新聞、娛樂及各類主題的 BBS 站台,這個站台甚至提供 API,你可以透過 API 取得你想要主題的訪客討論或點評內容訊息,然後可從中來獲取一些相關主題的情感走勢的資訊。
          • 像這樣情感分析的需求,我們不再使用直接式的歸納,取而代之是請 LLM 幫我們做分類(Classify),直接來看看下面這則範例:


          ( 以上截圖出自 Udemy Colt Steele Mastering OpenAI Python APIs: Unleash ChatGpt and GPT4 課程內容)

          • 有時在情感分析上,有些核心問題較為複雜,如果在沒有任何參照範例的提示下,往往 LLM 無法正確回應到我們要的點,此時就須要倚賴提供參照範例的技巧,通常如果直接詢問核心問題而沒有任何參照範例提示,我們稱為 Zero-Shot,如果提供一個範例者,稱為 One-Shot,而提供一個以上範例者,則稱為 Few-Shot~

            ( 以上截圖出自 Udemy Colt Steele Mastering OpenAI Python APIs: Unleash ChatGpt and GPT4 課程內容)
  1. \color{red}{Transforming\ 轉換:}

    • 什麼是轉換?
      • 可以是將一段文字由一種語言翻譯成另一種語言
      • 也可以是協助拼寫或是文法修正(替換文字)
      • 亦可以是修改語氣:例如正式、非正式或是替換時態、狀態或是模擬替換成某些人的口語特徵
      • 又或是修改格式:例如: 將 javascript code 轉成 python code; 將 csv comma format 換成 json format 等等的替換行為
    • LLM 的本質是 NLP,本身就非常擅長執行上述這些的文字轉換行為
  2. \color{red}{Expanding\ (文字)擴寫:}

    • 擴寫是給定一段短的文字片段作為起頭,讓 LLM 幫我們生成更長的文本
    • 應用範疇:
      • 作為腦力激蕩的夥伴
      • 批次生成大量郵件(若有人濫用 → 垃圾郵件)
        • 在使用 LLM 的時候,請記得以負責任的方式使用,以幫助人們
    • 透過調整模型的 temperature 溫度參數可調整模型輸出的隨機性程度,如要提高多樣性(提高創意性) → 提高溫度;若要降低多樣性(提高同質性) → 降低溫度
    1. \color{red}{ChatBot\ 聊天機器人:}
      • ChatGPT 本質其實就是一個聊天機器人,當作為文字生成器使用時,我們是用(單人)呼叫模式在使用,但這一小節 OpenAI 工程師 Isa 要展示的則是(角色)對話模式 → 透過網路文字聊天介面所呈現的聊天機器人。


        (上圖取自 www.deeplearning.ai 吳恩達博士的 ChatGpt Prompt Engineering for Developers 的課程範例程式碼片段。)

      • 應用範疇: 我們可以很簡單的用 LLM 來建立你自己的聊天機器人,例如: 扮演AI客服或扮演餐廳AI接單員

      • 如以使用 LLM Model 為 gpt-3.5-turbo 為例,當使用此 Model 時,我們可以設定以下三種不同的角色內容:

        • system:用來指定 ChatBot 的個性角色設定或框訂其行為規範(全域的背景設定)
        • user:使用者發出的訊息,或是預期使用者回覆 ChatBot 的範例訊息
        • assistant:ChatBot 回覆的訊息,或是預期它回覆 user 的範例訊息
      • 在使用API進行多輪對話的時候:

        • 每一次對話,其實都是獨立的對話,因此在對話當下,ChatGpt 並不會記得前一次的對話內容,因此也無法對前面歷史紀錄的對話內容作反應。
        • 如要 ChatBot 記住先前的對話,須將先前的歷史對話於新一輪對話發起時,同時把這些歷史對話重送一次給 LLM 模型(即所謂的上下文 Context),作為讓 ChatGpt 回答參照的上下文範例。
        • 隨著加入的上下文越來越多,Prompt 也會變得越來越長,連同 ChatGpt 扮演的 ChatBot 角色的回答,其實全部對話的總文字長度是有 Token 限制,所有訊息的 token 總和不能超過 Max_Tokens or Using LLM Tokens Limitation。

Prompt Engineering Mindmap (From Facebook - AI DATA TOOLS)


Prompt Engineering 小工具

~ 本章節筆記整理到此,祝大家與 ChatGpt 一同快樂的學習 ~

1個讚