使用 ChatGPT API 建立系統 學習筆記 - 3

使用 ChatGPT API 建立系統 學習筆記 - 3

更新於 發佈於 閱讀時間約 22 分鐘

這一系列文章其實就是 Andrew Ng 大大與 OpenAI 合作的一門免費課程【Building Systems with the ChatGPT API】的筆記。很建議大家直接看原本的課程影片,內容蠻淺顯易懂的。


整合提示

在上一篇文章中,我們實際展示了「思考鏈」概念在實作過程中的運用。接著,我們將更進一步地示範如何將大型語言模型(LLM)與我們的其他程式碼進行深度整合。我們將以一個3C賣場的客服助理為例,展示如何在收到使用者訊息後提取出有助於我們進一步處理的提示(prompt),再將提取出的產品資訊與後端的產品資料庫結合,最後將整合後的完整資訊回傳給LLM,由LLM產生出最終的回應訊息。

使用者訊息的解析

接下來的範例中,我們將進一步分析客戶的詢問,並提供一份簡化的產品清單來限縮語言模型回答的範疇,最後會要求語言模型產生一份我們可以直接使用的Python物件列表。

delimiter = "####"
system_message = """
1. 你將會收到一些客戶服務查詢。客戶服務查詢將由 {delimiter} 字元作為分隔符。
2. 如果客戶訊息中的產品在下方允許產品清單中,你就輸出一個Python物件列表,
每個物件同時具有以下格式:
'category': <以下其中一項:電腦和筆記本,手機和配件,電視和家庭劇院系統,
遊戲機和配件,音響設備,相機和攝影機>

'products': <必須在以下列出的允許產品中找到的產品列表>
3. 客戶提到下方允許產品清單中的產品時,也同時在在物件屬性列出它對應的類別。
4. 如果客戶沒有特別提到什麼產品,你只要列出類別就好。
5. 如果客戶訊息中的產品不在下方允許產品清單中,你就輸出一個空列表。
6. 如果產品屬性是空的,也不要輸出類別屬性,直接輸出空列表。

允許的產品:

電腦和筆記型電腦類別:
TechPro Ultrabook
BlueWave 電競筆電
PowerLite 二合一電腦
TechPro 桌機
BlueWave Chromebook

... 中間省略 ...

相機和攝影機類別:
FotoSnap 單眼相機
ActionCam 4K 攝影機
FotoSnap 無反光鏡相機
ZoomMaster 攝影機
FotoSnap 拍立得相機

你只可以輸出Python物件列表,不能輸出其他任何資訊。
"""

使用者訊息的處理範例如下:

user_message_1 = f"""
請跟我介紹 SmartX ProPhone 和 FotoSnap 單眼相機, \
也順便告訴我你們是否有電視。
"""

# 中文版本的 prompt 如果沒有加上下方的 in-context learning 範例,
#GPT 的回應會莫名自己加上【回應: 】字樣。
# 課程中的英文版本則不會。
in_context_user1 = "你們有賣 ProGamer 方向盤 嗎?"
in_context_assistant1 = [
{'category': '遊戲機和配件', 'products': 'ProGamer 方向盤'}]

in_context_user2 = "我正在找某個音響。"
in_context_assistant2 = [{'category': '音響設備'}]

messages = [
{'role':'system',
'content': system_message},
{'role':'user',
'content': f"{delimiter}{in_context_user1}{delimiter}"},
{'role':'assistant',
'content': f"{in_context_assistant1}"},
{'role':'user',
'content': f"{delimiter}{in_context_user2}{delimiter}"},
{'role':'assistant',
'content': f"{in_context_assistant2}"},
{'role':'user',
'content': f"{delimiter}{user_message_1}{delimiter}"},
]
category_and_product_response_1 = get_completion_from_messages(messages)
print(category_and_product_response_1)

--- 以下是 LLm 的回覆 ---
[{'category': '手機和配件', 'products': ['SmartX ProPhone']},
{'category': '相機和攝影機', 'products': ['FotoSnap 單眼相機']},
{'category': '電視和家庭劇院系統', 'products': ['CineView 4K 液晶電視',
'CineView 8K 液晶電視', 'CineView OLED 電視', 'SoundMax 家庭劇院']}]
在以上提示作業英翻中的過程中,我們遇到了一些小插曲。在我們將提示中文化後發現,ChatGPT對於中文的理解和處理相對於英文存在明顯的落差,這使得ChatGPT對中文提示的理解不如預期。因此,我們最後不僅重新修改了提示,還在傳入LLM的訊息中加入了in-context learning,這才讓LLM能夠按照我們的期待來處理訊息。

對於這部分,當大家在設計中文提示時,可能需要特別留意。

詳細資訊的取得

接下來我們將使用Python的dictionary物件來模擬一個小型資料庫,並從中提取詳細的資訊。具體的程式碼如下:

# 產品資訊
products = {
"TechPro Ultrabook": {
"name": "TechPro Ultrabook",
"category": "電腦與筆記型電腦",
"brand": "TechPro",
"model_number": "TP-UB100",
"warranty": "一年",
"rating": 4.5,
"features": ["13.3 吋顯示器", "8GB 記憶體", "256GB SSD硬碟", \
"Intel Core i5 處理器"],
"description": "一款適合日常使用的輕薄 Ultrabook。",
"price": 799.99 },
... 中間省略 ...
"FotoSnap 拍立得相機": {
"name": "FotoSnap 拍立得相機",
"category": "相機和攝影機",
"brand": "FotoSnap",
"model_number": "FS-IC10",
"warranty": "一年",
"rating": 4.1,
"features": ["立即列印", "內建閃光燈", "自拍鏡", "可攜式電池"],
"description": "用這款有趣和便攜的拍立得相機創造即時回憶。",
"price": 69.99 }
}

以下則是一些資料提取的工具函式以及其使用範例:

def get_product_by_name(name):
return products.get(name, None)

def get_products_by_category(category):
return [product for product in products.values() \
if product["category"] == category]

print(get_product_by_name("TechPro Ultrabook"))
>>> {'name': 'TechPro Ultrabook', 'category': '電腦與筆記型電腦',
'brand': 'TechPro', 'model_number': 'TP-UB100', 'warranty': '一年',
'rating': 4.5, 'features': ['13.3 吋顯示器', '8GB 記憶體',
'256GB SSD硬碟', 'Intel Core i5 處理器'],
'description': '一款適合日常使用的輕薄 Ultrabook。',
'price': 799.99}

print(get_products_by_category("電腦與筆記型電腦"))
>>> [{'name': 'TechPro Ultrabook', 'category': '電腦與筆記型電腦',
'brand': 'TechPro', 'model_number': 'TP-UB100', 'warranty': '一年',
'rating': 4.5, 'features': ['13.3 吋顯示器', '8GB 記憶體',
'256GB SSD硬碟', 'Intel Core i5 處理器'],
'description': '一款適合日常使用的輕薄 Ultrabook。', 'price': 799.99},
... 中間省略 ...
{'name': 'BlueWave Chromebook', 'category': '電腦與筆記型電腦',
'brand': 'BlueWave', 'model_number': 'BW-CB100', 'warranty': '一年',
'rating': 4.1, 'features': ['11.6 吋顯示器', '4GB 記憶體',
'32GB eMMC 硬碟', 'Chrome 作業系統'],
'description': '一款便捷的Chromebook,適合在網路上瀏覽和處理基本工作。.',
'price': 249.99}]

接下來的工具函式則是用來將LLM回傳的訊息轉換成JSON物件:

import json

def read_string_to_list(input_string):
if input_string is None:
return None

try:
# 單引號改為雙引號,這樣才是合法的 JSON 字串格式
input_string = input_string.replace("'", "\"")
data = json.loads(input_string)
return data
except json.JSONDecodeError:
print("Error: Invalid JSON string")
return None

轉換成JSON物件的實際結果如下

category_and_product_list = read_string_to_list(category_and_product_response_1) 

print(category_and_product_list)
>> [{'category': '手機和配件', 'products': ['SmartX ProPhone']},
{'category': '相機和攝影機', 'products': ['FotoSnap 單眼相機']},
{'category': '電視和家庭劇院系統', 'products': [ 'CineView 4K 液晶電視',
'CineView 8K 液晶電視', 'CineView OLED 電視', 'SoundMax 家庭劇院',
'SoundMax 音箱'] }]

接下來,我們要展示的是將從訊息中提取的產品/產品類別資訊與外部資料結合的核心函式:

def generate_output_string(data_list):
output_string = ""

if data_list is None:
return output_string

for data in data_list:
try:
# 如果有 "products" 屬性,就代表是要查詢產品
if "products" in data:
products_list = data["products"]
for product_name in products_list:
# 透過產品名稱取得產品資訊
product = get_product_by_name(product_name)
if product:
# 將產品資訊轉換為 JSON 格式,並加入換行符號
output_string += json.dumps(product, indent=4, ensure_ascii=False) + "\n"
else:
print(f"Error: Product '{product_name}' not found")
# 如果有 "category" 屬性,就代表是要查詢類別
elif "category" in data:
category_name = data["category"]
# 透過類別名稱取得產品資訊
category_products = get_products_by_category(category_name)
for product in category_products:
# 將產品資訊轉換為 JSON 格式,並加入換行符號
output_string += json.dumps(product, indent=4, ensure_ascii=False) + "\n"
else:
print("Error: Invalid object format")
except Exception as e:
print(f"Error: {e}")
return output_string

以下是該函式的實際使用情況及結果:

product_information_for_user_message_1 = generate_output_string( \
category_and_product_list)
print(product_information_for_user_message_1)

>> {
"name": "SmartX ProPhone",
"category": "手機和配件",
"brand": "SmartX",
"model_number": "SX-PP10",
"warranty": "一年",
"rating": 4.6,
"features": [
"6.1 吋顯示器",
"128GB 儲存空間",
"12MP 雙鏡頭",
"5G 網路"
],
"description": "一款功能強大並具有先進照相功能的智慧手機",
"price": 899.99 }
{
"name": "FotoSnap 單眼相機",
"category": "相機和攝影機",
"brand": "FotoSnap",
"model_number": "FS-DSLR200",
"warranty": "一年",
"rating": 4.7,
"features": [
"24.2MP 感光元件",
... 中間省略 ...
"description": "使用這款時尚且音質出色的音響升級您的電視聲光效果。",
"price": 199.99
}

整合資訊並生成回應訊息

有了以上的各種工具函式,我們現在可以將使用者的訊息從提取訊息到獲取詳細資訊,最後產生回應訊息的完整流程串連起來,具體的使用方法如下:

ystem_message = f"""
您是一家大型3C賣場的客服助理。 \
請以親切且樂於助人的態度回答問題,\
並確保您的答案簡潔明瞭。\
也要記得向用戶提出相關的追問。
"""
user_message_1 = f"""
請告訴我關於SmartX Pro手機以及 \
FotoSnap單眼相機的資訊。 \
另外也請介紹一下你們的電視產品。
"""
messages = [
{'role':'system', 'content': system_message},
{'role':'user', 'content': user_message_1},
{'role':'assistant', 'content': f"""相關產品資訊:\n\
{product_information_for_user_message_1}"""},
]

final_response = get_completion_from_messages(messages)
print(final_response)

--- 以下是語言模型的回覆訊息 ---
>> 以上是我們店裡的 SmartX Pro 手機和 FotoSnap 單眼相機的資訊。
SmartX Pro 手機擁有6.1吋顯示器、128GB 儲存空間、12MP 雙鏡頭和5G 網路等功能。
FotoSnap 單眼相機則擁有24.2MP 感光元件、1080p 影片、
3 吋 LCD 和可更換鏡頭等功能。
此外,我們店裡還有多款電視產品可供選擇。
CineView 4K 液晶電視擁有55吋顯示器、4K 解析度、HDR 和智慧電視等功能。
CineView 8K 液晶電視則擁有65吋顯示器、8K 解析度、HDR 和智慧電視等功能。
CineView OLED 電視則擁有55吋顯示器、4K 解析度、HDR 和智慧電視等功能。
此外,我們還有 SoundMax 家庭劇院和 SoundMax 音箱等產品,
可以升級您的電視聲光效果。 如果您對這些產品有任何問題或需要更多資訊
,請隨時向我們詢問。

以上就是語言模型與外部系統整合的基本架構,如果你對完整的程式碼感興趣,可以參考這裡:HelloGPT/building-system-with-chatgpt-api-03-Chaining Prompts.ipynb at main · u8621011/HelloGPT (github.com)


avatar-img
Ted Chen的沙龍
18會員
19內容數
留言
avatar-img
留言分享你的想法!
Ted Chen的沙龍 的其他內容
本篇文章深入探討了如何評估模糊訊息在對話系統開發中的它的品質驗證方式,並且使用了類似Rubic評分準則的方法來評估回覆訊息。也介紹了專家回覆與實際回覆比較的評估方式。文章最終目的希望能讓讀者具備開發自己的對話機器人的知識。
此文針對對話系統的持續開發和改進過程進行詳細解說,尤其在提示訊息的設計與驗證方面。以大賣場的銷售助理為例,我們設計了提示訊息,進行多次測試與調整,確保回應結果符合預期。透過建立測試集和評估函式,我們實現了批次驗證,確保所有測試項目的有效性。
本篇文章探討如何整合大型語言模型與外部程式與資源來生成回應訊息。我們使用OpenAI的Moderation API來確認內容的合適性,並使用新的提示來評估是否真正解答了使用者的疑問。整體流程的匯整讓我們一覽全貌。我們將在下一篇文章中分享更多有關回應訊息評估的細節。
本篇文章深入探討了如何評估模糊訊息在對話系統開發中的它的品質驗證方式,並且使用了類似Rubic評分準則的方法來評估回覆訊息。也介紹了專家回覆與實際回覆比較的評估方式。文章最終目的希望能讓讀者具備開發自己的對話機器人的知識。
此文針對對話系統的持續開發和改進過程進行詳細解說,尤其在提示訊息的設計與驗證方面。以大賣場的銷售助理為例,我們設計了提示訊息,進行多次測試與調整,確保回應結果符合預期。透過建立測試集和評估函式,我們實現了批次驗證,確保所有測試項目的有效性。
本篇文章探討如何整合大型語言模型與外部程式與資源來生成回應訊息。我們使用OpenAI的Moderation API來確認內容的合適性,並使用新的提示來評估是否真正解答了使用者的疑問。整體流程的匯整讓我們一覽全貌。我們將在下一篇文章中分享更多有關回應訊息評估的細節。