學習筆記 — 如何在Python中透過API對ChatGPT進行提示-(2)透過迭代,不斷修正品質?

Sean Yeh
Python Everywhere -from Beginner to Advanced
16 min readJul 4, 2023

--

Antwerpen, Belgium, photo by Sean Yeh

OpenAI於2022年底發表chatGPT後,在短短的五天內,就吸引了超過百萬的使用者註冊。這款聊天機器人,雖然在外觀上與我們以前所看過的聊天機器人很像,但是它回答問題的能力與品質,卻遠遠超出過去的聊天機器人。

以下是根據網站DeepLearning.AI上開啟的ChatGPT Prompt Engineering for Developers(給開發者的ChatGPT指令工程)課程學習,並綜合參考仿間的書籍所寫的筆記以及個人心得。該課程為Coursera創辦人吳恩達(Andrew Ng)與Isa Fulford所教授。目前為免費課程,長度為一小時,不需具備深度學習或自然語言的相關背景知識,強烈建議對ChatGPT有興趣的朋友可以進入網站進行學習。如果想從頭開始暸解這門課程,可以從下面這篇開始閱讀:

訓練模型需不斷嘗試

透過迭代,不斷修正品質

當我們訓練機器學習模型時,幾乎不可能在第一次就成功的。當我們使用大型語言模型建立應用程式時也是一樣的,很難在第一次就讓模型有很好的表現。使用ChatGPT提示也是一樣的。

實際上,必須透過迭代的方式,不斷的嘗試與修改來訓練模型。

以機器學習來說,在開發的過程中,通常會先有一個想法,然後開始動手實施。從編寫程式碼開始,接著取得需要的數據,提供數據進行模型的訓練,最後得到初步的結果。整個流程還沒有結束,我們接著會查看輸出的結果,對他開始進行錯誤分析並且做評價,判斷結果找出與原先想法的落差,然後修改進行的方式,再次進行測試,如此反覆實施,最終獲得有效的機器學習模型。修改的過程中甚至會改變您對於原本問題的處理方法或想法。

當您編寫ChatGPT提示,來開發使用LLM的應用程式時,這個過程與訓練機器學習模型的方式非常相似,首先我們有一個一個想法,有一個想要完成的任務。然後開始動手實施,從編寫一個清晰且明確的prompt提示,然後執行提示,看看會得到什麼結果。如果對於這個提示的結果不滿意,可以透過找出提示不夠清楚或提供演算法足夠的時間思考等方式,逐步的改進您起初的想法與提示等,並在迭代中不斷嘗試,直到找到適合您的提示。

換句話說,開發的流程大致上需要經過下面幾的步驟:1.構想、2.實作、3.測試以及4.錯誤分析。

如此不斷的循環形成一個迴圈,直到我們得到滿意的結果為止。現實上並不存在一個可以放諸四海皆準的完美提示。因為每個人,每一次的需求都不相同,輸入的資料也不一樣。只有在不斷地循環嘗試和修正中,才能迭代出符合開發者需求的結果。

範例實作

因此,讓我們一起透過一個程式碼,來暸解這個概念。

開始前:設定

開始操作前,必須先前往OpenAI的網站,註冊帳號、登入OpenAI,並申請API金鑰與設定API Keys。

完成以上步驟之後,還要在您的工作區(Python的虛擬環境下)安裝安裝openai套件。最後,還需要做下面兩件事:

  1. 將API Keys設定在環境變數中

如果不想要如此麻煩的話,也可以直接將API Keys寫在程式碼中。只不過這樣子做,恐怕已經預先將資安的風險埋在程式碼中。

import openai
import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file
openai.api_key = os.getenv('OPENAI_API_KEY')

2. 建立回傳結果之函式 get_completion

def get_completion(prompt, model="gpt-3.5-turbo"):
messages = [{"role": "user", "content": prompt}]
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=0, # this is the degree of randomness of the model's output
)
return response.choices[0].message["content"]

這部分的詳細說明可以參考下面這篇文章:

實際練習:資料部分

在吳恩達教授的課程中,有下面這個範例。該範例想要說明的是:提供LLM模型相關的產品資訊,並要求該模型依據產品資訊,輸出一個可以放在EC網站上的說明文字。

以下為產品相關資訊內容的節錄:

fact_sheet_chair = """
OVERVIEW
- Part of a beautiful family of mid-century inspired office...
- more....

CONSTRUCTION
- 5-wheel plastic coated aluminum base.
- more....

DIMENSIONS
- WIDTH 53 CM | 20.87”
- more....

OPTIONS
- Soft or hard-floor caster options.
- more....

MATERIALS
SHELL BASE GLIDER
- Cast Aluminum with modified nylon PA6/PA66 coating.
- more....
SEAT
- HD36 foam
- more....

COUNTRY OF ORIGIN
- Italy
- more....
"""

將內容翻譯為中文的話,其意思如下:

fact_sheet_chair = """
概述
- 屬於一系列美麗的中世紀風格辦公家具,包括文件櫃、辦公桌、書櫃、會議桌等等。
- 提供多種外殼顏色和底座飾面選擇。
- 可選擇塑料背面和前面襯墊(SWC-100),或10種布料和6種皮革選項的全襯墊(SWC-110)。
- 底座飾面選項有:不銹鋼、啞黑、光澤白或鉻。
- 椅子可選擇有或沒有扶手。
- 適用於家居或商業環境。
- 合格於合約使用。

結構
- 五輪塑膠鍍鋁底座。
- 氣壓式椅子調節,方便升降操作。

尺寸
- 寬度 53 公分 | 20.87 英寸
- 深度 51 公分 | 20.08 英寸
- 高度 80 公分 | 31.50 英寸
- 座位高度 44 公分 | 17.32 英寸
- 座位深度 41 公分 | 16.14 英寸

選項
- 軟地或硬地滾輪選擇。
- 兩種座位泡棉密度選擇:中等(1.8磅/立方英尺)或高密度(2.8磅/立方英尺)。
- 有扶手或8個位置可調節的PU扶手。

材料
外殼底座滑輪
- 鋁鑄造,經過改良的尼龍PA6/PA66塗層。
- 外殼厚度:10毫米。
座位
- HD36泡棉

原產地
- 意大利
"""

內容裡面包括了產品的概述、結構、尺寸、選項、材料、座位與原產地等。有了這些「素材」之後,就可以透過prompt提示提供LLM模型相關的產品資訊。

步驟1:首次嘗試

基於此,我們使用prompt提示,開始讓模型輸出一個可以放在EC網站上的說明文字。以下是prompt提示的中文翻譯(影片使用的prompt是英文,以下的示範都會使用繁體中文):

prompt = f"""
你的任務是協助一個行銷團隊根據技術規格書為
零售網站的產品創建描述。

根據由三個反引號括起來的技術規格書中提供的資訊,
撰寫一個產品描述。

技術規格:```{fact_sheet_chair}```"""

response = get_completion(prompt)
print(response)

執行看看:

結果是產生了。但是,讓我們等了不算久的時間。而且給出的結果對我們來說似乎太長了。

接下來,我們需要調整prompt提示的方式,來進行修正。期望下一輪產生的結果比較接近我們的需要。

步驟2:修改提示,加入限制

針對結果太長對提示句子進行下面的修改。我們可以在提示句子中加入一些限制性的命令。例如限制產生出來的字數或句子等等。

因此,我們在提示中加上『撰寫一段不超過50個字的產品描述』的命令。以下是prompt提示:

prompt = f"""
你的任務是協助一個行銷團隊根據技術規格書為
零售網站的產品創建描述。

根據由三個反引號括起來的技術規格書中提供的資訊,
撰寫一個產品描述。

撰寫一段不超過50個字的產品描述。

技術規格:```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

再執行看看:

這次產生的結果就不像上次那樣冗長了。不過,下面的敘述,似乎不太能打動我們想要溝通的對象:

回答:  

這款中世紀風格的辦公椅是一個美麗的選擇,適用於家居或商業環境。
它具有多種外殼顏色和底座飾面選擇,
可選擇塑料背面和前面襯墊或多種布料和皮革選項的全襯墊。
椅子具有氣壓式調節和五輪塑膠鍍鋁底座,提供方便的升降操作。
尺寸為寬53公分、深51公分、高80公分,座位高度44公分,座位深度41公分。
這款椅子還提供軟地或硬地滾輪選擇,以及不同座位泡棉密度和扶手選項。
它的材料來自意大利,具有高品質和耐用性。

因此,我們需要對prompt再進行下一輪的修正。

步驟3:繼續修改提示,指定目標對象

由於上一輪的結果並不能滿足我們對於目標客戶的需要。這次,我們要鎖定目標溝通對象,修改prompt提示。因此,我們會在提示中說明『該描述將針對家具零售商, 因此應具有技術性質,並著重於產品所使用的材料。』,透過這個方式讓結果可以針對我們的目標溝通對象。以下是prompt提示:

prompt = f"""
你的任務是協助一個行銷團隊根據技術規格書為
零售網站的產品創建描述。

根據由三個反引號括起來的技術規格書中提供的資訊,
撰寫一個產品描述。

撰寫一段不超過50個字的產品描述。

該描述將針對家具零售商,
因此應具有技術性質,並著重於產品所使用的材料。

技術規格:```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

下面是執行後產生的結果:

回答:  
這款中世紀風格的辦公椅是一系列美麗的家具,包括文件櫃、辦公桌、書櫃和會議桌等。
它提供多種外殼顏色和底座飾面選擇,
可選擇塑料背面和前面襯墊或多種布料和皮革選項的全襯墊。
這款椅子適用於家居或商業環境,並符合合約使用的要求。
它具有五輪塑膠鍍鋁底座和氣壓式椅子調節功能,方便升降操作。
尺寸為寬53公分、深51公分、高80公分,座位高度44公分,座位深度41公分。
此外,它還提供軟地或硬地滾輪選擇,兩種座位泡棉密度選擇和有或沒有扶手的選項。
這款辦公椅的外殼底座滑輪由鋁鑄造,經過改良的尼龍塗層,外殼厚度為10毫米。
座位使用高密度泡棉,原產地為意大利。

步驟3.5:繼續修改提示,增加條件

結果中少了產品的ID,因此再修改一次prompt提示並重新執行。中文提示修改如下:

prompt = f"""
你的任務是協助行銷團隊根據技術規格書為零售網站上的產品撰寫描述。

根據由三個反引號括起來的技術規格書提供的資訊,
撰寫一段不超過50個字的產品描述。

該描述將針對家具零售商,
因此應具有技術性質,並著重於產品所使用的材料。

在描述的末尾,包括技術規格中每個7個字元的產品ID。

技術規格:```{fact_sheet_chair}```
"""
response = get_completion(prompt)
print(response)

產生的結果如下:

步驟4:使用最佳實踐作為原則

當我們深入Python程式的海洋,特別是在與chatGPT互動時,上一篇提到的「最佳實踐」絕對是我們的良師益友。舉例來說,我們在撰寫首次提示(prompt)時,別忘了給予模型足夠的思考時間,然後進行測試看看結果如何。若果不盡人意,那麼就讓我們持續改進,讓提示更貼近我們的需求。事實上,許多優秀的提示都是透過這種反覆試驗和修正的過程而達到的,並非一蹴可幾。所以,別怕犯錯,反覆實踐才能磨練出真知。

步驟5:調整輸出格式

我們在使用chatGPT時,除了可以透過優化提示來提升結果的品質外,更可以進一步控制輸出的格式。例如,我們希望模型在產出一段描述後,能附上一個規格說明的表格。這樣的技巧完全依賴於先前提到的最佳實踐原則:給出明確的指示。

如何實踐這個原則呢?我們可以在提示中具體要求模型生成一個規格表格,並明確說明這個表格的內容。例如,表格需要有兩個欄位,第一個欄位是產品的長、寬、高等規格,第二個欄位則是相應的尺寸,並要求所有尺寸的單位為公分或吋。我們也可以指定表格的標題是「產品規格」。

然而,我們的請求並不只此而已。為了使輸出的格式更能夠廣泛的被使用,我們還會要求模型以HTML格式輸出結果。這樣,不僅能確保輸出的格式符合我們的需求,還能提高其在各種情境中的可用性。無論是在撰寫部落格文章還是在開發網頁應用,這樣的輸出格式都會大大提升我們的工作效率。

因此,在剛剛的prompt基礎上,我們可以在後面增加一些指示,希望它可以產出一個HTML格式的表格。以下是修改後的prompt:

prompt = f"""
你的任務是協助行銷團隊根據技術規格書為零售網站上的產品撰寫描述。

根據由三個反引號括起來的技術規格書提供的資訊,
撰寫一段不超過50個字的產品描述。

該描述將針對家具零售商,
因此應具有技術性質,並著重於產品所使用的材料。

在描述的末尾,包括技術規格中每個7個字元的產品ID。

在描述之後,包括一個表格來呈現產品的尺寸。該表格應該有兩列。
在第一列中,包含尺寸的名稱。在第二列中,僅以英吋表示尺寸。

給該表格一個名為「產品尺寸」的標題。

將所有內容格式化為可以在網站上使用的HTML。將描述放在一個<div>元素中。

技術規格:```{fact_sheet_chair}```
"""

response = get_completion(prompt)
print(response)

下面是執行prompt後產生的HTML結果:

回答:  <div>
<p>這款中世紀風格辦公家具系列包括文件櫃、辦公桌、書櫃和會議桌等。提供多種外殼顏色和底座飾面選擇。可選擇塑料背面和前面襯墊(SWC-100),或10種布料和6種皮革選項的全襯墊(SWC-110)。底座飾面選項有:不銹鋼、啞黑、光澤白或鉻。椅子可選擇有或沒有扶手。適用於家居或商業環境。合格於合約使用。</p>
<p>產品ID:SWC-100</p>
</div>

<table>
<caption>產品尺寸</caption>
<tr>
<th>尺寸名稱</th>
<th>尺寸(英寸)</th>
</tr>
<tr>
<td>寬度</td>
<td>20.87</td>
</tr>
<tr>
<td>深度</td>
<td>20.08</td>
</tr>
<tr>
<td>高度</td>
<td>31.50</td>
</tr>
<tr>
<td>座位高度</td>
<td>17.32</td>
</tr>
<tr>
<td>座位深度</td>
<td>16.14</td>
</tr>
</table>

<p>材料:外殼底座滑輪為鋁鑄造,經過改良的尼龍PA6/PA66塗層,外殼厚度為10毫米。座位使用HD36泡棉。</p>
<p>原產地:意大利</p>

以上的例子,就是一種迭代的過程。你會發現,我們並不是一開始就要求模型一步到位,而是先測試局部的概念或想法,然後再一次次的調整,最後將它們整合在一起。

結論

進入人工智慧的新時代,我們必須翻新我們的思維模式與觀念。在實際的商業環境中,身為主管的領導者並非直接修改屬下的作業,而是透過明確的指示引導他們完成任務。只有在領導者的指示恰如其分,屬下才有可能做出正確的事情,這個道理同樣適用於人工智慧GPT工具上。

人類在這場新的「人機合作關係」中扮演的角色,就如同企業中的領導者,而AI則像是勤勉的屬下。

我們對AI的期望,並非讓它走錯再花費大量的人力去修正,而是透過妥善的指示與培育,讓AI能主動產出正確且有價值的成果。

在這個由人工智慧和人類共創的世界,我們都擁有自己的角色與責任,而如何讓這樣的合作關係達到最大的效益,就需要我們用全新的思維去探索與學習,學會對GPT下精確的指令。學會如何透過良好的Prompting 技巧,與ChatGPT互動取得更高品質的回答。

--

--

Sean Yeh
Python Everywhere -from Beginner to Advanced

# Taipei, Internet Digital Advertising,透過寫作讓我們回想過去、理解現在並思考未來。並樂於分享,這才是最大贏家。