這一系列文章其實就是 Andrew Ng 大大與 OpenAI 合作的一門免費課程【Building Systems with the ChatGPT API】的筆記。很建議大家直接看原本的課程影片,內容蠻淺顯易懂的。
我們第二篇學習筆記將會針對思考鏈推論來做介紹。
所謂思考鏈(Chain of Thought),簡單來說就是將問題拆解成一個一個更小的步驟來引導 LLM 解出我們需要的資訊,更明確的說明,我們直接以範例來跟大家解釋。
訊息處理提示
我們會以實做一個 3C 賣場的客服助理來做示範,以下的提示訊息會以思考鏈來引導語言模型如何推論產品的比較問題:
delimiter = "####"
system_message = f"""
按照以下步驟回答客戶的問題。 客戶的查詢將以四個井字號作為分隔符號,\
也就是 {delimiter}。
步驟1:{delimiter} 首先判斷用戶是否在問關於特定產品或多種產品的問題。 \
不考慮產品類別。
步驟2:{delimiter} 如果用戶在問關於特定產品的問題, \
辨認該產品是否在以下列表中。
所有產品:
1. 產品:TechPro Ultrabook
類別:電腦與筆記型電腦
品牌:TechPro
型號:TP-UB100
保固:1年
評價:4.5
特性:13.3吋顯示器,8GB 記憶體,256GB SSD,Intel Core i5處理器
描述:一款適合日常使用的輕便筆記型電腦。
價格:$799.99
2. 產品:BlueWave 電競筆電
類別:電腦與筆記型電腦
品牌:BlueWave
型號:BW-GL200
保固:2年
評價:4.7
特性:15.6吋顯示器,16GB RAM,512GB SSD硬碟,NVIDIA GeForce RTX 3060顯示卡
描述:一款性能強勁的電競筆記型電腦,讓您沉浸其中。
價格:$1199.99
... 中間省略 ...
步驟3:{delimiter} 如果訊息中包含上述列表中的產品, \
列出使用者訊息中可能的假設,例如筆記本X比筆記本Y大,或者筆記本Z有2年保固。
步驟4:{delimiter} 如果用戶有任何假設, \
根據您的產品資訊判斷該假設是否正確。
步驟5:{delimiter} 首先,如果適用,請禮貌地糾正客戶的錯誤假設。 \
只提及或參考上述五種產品資訊,因為這些是商店售賣的唯一五種產品。 \
以友善的語氣回答客戶。
使用以下格式:
步驟1:{delimiter} <步驟1的理由>
步驟2:{delimiter} <步驟2的理由>
步驟3:{delimiter} <步驟3的理由>
步驟4:{delimiter} <步驟4的理由>
回覆給使用者:{delimiter} <回覆給客戶的內容>
確保每一步都包含 {delimiter} 來進行分隔。
"""
我們從上面的提示範例可以看到幾個重點:
- 我們直接列出引導 LLM 的步驟,並且註明每個步驟的處理重點,最後也讓要求LLM 依照步驟一步一步解題。
- 分隔符號的使用。
不論是使用者的訊息,或者 LLM 每個步驟的輸出,我們都使用分隔號來做區隔。
我們提供給 LLM 的使用者訊息使用分隔號是為了讓 LLM 更清楚使用者訊息的界限,而要求 LLM 輸出時使用分隔號則是方便我們稍後可以簡單切割出來我們要的回應訊息,這個部分在稍後會跟大家介紹。
- 最後,我們也可以觀察到每個步驟後方的角括弧,這實質上提供了一個讓語言模型進行填充的空間。
使用者訊息測試一
透過以上的提示,語言模型會如何處理客戶端產品比較問題呢? 我們直接來看測試範例:
user_message = f"""
你們的 BlueWave Chromebook 比 TechPro 桌機貴多少?
"""
messages = [
{'role':'system',
'content': system_message},
{'role':'user',
'content': f"{delimiter}{user_message}{delimiter}"},
]
response = get_completion_from_messages(messages)
print(response)
--- 以下是 LLM 的回覆 ---
步驟1:#### 用戶在問關於特定產品的問題,不考慮產品類別。
步驟2:#### 該產品 BlueWave Chromebook 在產品列表中,價格為 $249.99。
TechPro 桌機也在產品列表中,價格為 $999.99。
步驟3:#### 用戶沒有提供任何假設。
步驟4:#### 無需判斷假設是否正確。
回覆給使用者:#### BlueWave Chromebook 的價格是 $249.99,
而 TechPro 桌機的價格是 $999.99。
因此,BlueWave Chromebook 比 TechPro 桌機便宜了 $750。
另外我們再來看一個反例,如果客戶詢問的產品沒有在我們的產品清單內,它會怎麼反應呢?
使用者訊息測試二
user_message = f"""
你們有賣電視嗎?
"""
messages = [
{'role':'system',
'content': system_message},
{'role':'user',
'content': f"{delimiter}{user_message}{delimiter}"},
]
response = get_completion_from_messages(messages)
print(response)
--- 以下是 LLM 的回覆 ---
步驟1:#### 客戶詢問關於特定產品或多種產品的問題。不考慮產品類別。
步驟2:#### 由於客戶沒有詢問特定產品,因此我們無法回答關於產品的問題。
請問您需要關於哪種類型的產品的資訊? 例如,電腦、手機、家電等等。
回覆給客戶:#### 請問您需要關於哪種類型的產品的資訊?
例如,電腦、手機、家電等等。
看到這裏大家應該更有感覺,什麼是思考鏈以及思考鏈的威力了吧!?
最後,讓我們探討如何從思考鏈的思考程序中,提取出最後要回傳給使用者的訊息。
回覆訊息的提取
我們前面已經提及,在列出步驟時使用的分隔號,其主要目的就是便於我們提取回覆訊息。下面就是一個簡單版本的提取函式以及提取出來的內容:
try:
# 使用分隔符號來切割訊息,並且取出真的要回覆的內容
final_response = response.split(delimiter)[-1].strip()
except Exception as e:
# 發現無法處理的訊息時的回覆訊息
final_response = """很抱歉,我無法處理你這個問題,
請您試著詢問其他問題。"""
print(final_response)
--- 提取後的回覆訊息 ---
BlueWave Chromebook 的價格是 $249.99,而 TechPro 桌機的價格是 $999.99。
因此,BlueWave Chromebook 比 TechPro 桌機便宜了 $750。
以上思考鏈在實際應用時的其中一個示範。