授權(quán)聲明: 本文基于九天Hector的原創(chuàng)課程資料創(chuàng)作,已獲得其正式授權(quán)。
原課程出處:九天Hector的B站主頁,感謝九天Hector為學習者帶來的寶貴知識。
請尊重原創(chuàng),轉(zhuǎn)載或引用時,請標明來源。
全文共7000余字,預計閱讀時間約15~30分鐘 | 滿滿干貨(附代碼),建議收藏!
本文目標:理解OpenAI提供的Completions模型類,熟悉其調(diào)用方法和調(diào)參技巧,通過實現(xiàn)一個多輪對話的聊天機器人,提供一種基于Completions模型開發(fā)上層應用的思路。
代碼下載點這里
一、 Completions基本概念
對于先進的深度學習模型,它們通常通過大量的文本數(shù)據(jù)進行訓練,掌握語法關(guān)系和多種表達風格。在這個基于廣泛語義空間的訓練過程中,這些模型不僅學習了基本的文本模式,還會經(jīng)過微調(diào),更好地適應特定的人類意圖。當模型作出預測時,其本質(zhì)是根據(jù)給定的輸入(或稱為提示)來產(chǎn)生對應的文本輸出。通常,這樣的模型的訓練會分為兩個主要階段:
- 階段一:預訓練
在這個階段,模型使用大量未標記的文本進行訓練,如在線收集的書籍和文章。這一步主要是進行語言模型訓練,使模型能預測給定上下文中的下一個單詞,從而掌握詞匯、語法和基本知識。
- 階段二:微調(diào)
預訓練完成后,模型會在特定任務的數(shù)據(jù)上進行進一步的訓練。例如,對于一個問答任務,可以提供成對的問題和答案來調(diào)整模型,從而在該任務上達到更好的效果。
OpenAI公司的GPT系列模型在NLP領(lǐng)域中是領(lǐng)先的。它為開發(fā)者提供了API接口,允許開發(fā)者向模型發(fā)送文本提示,并獲得模型的響應,意味著開發(fā)者可以無需自行訓練和部署大型模型,而是直接利用OpenAI的服務。
所謂的“Completions”模型實際上是指OpenAI基于其GPT系列模型提供的自動文本補全能力。這種模型不僅可以自動生成和補全文本,還可以回答問題、撰寫文章等。此過程,即根據(jù)提示生成相應文本的機制,被稱為“Completion”。因此,能夠執(zhí)行此功能的模型被稱為“Completion模型”。例如,經(jīng)過RLHF微調(diào)后基于text-davinci-002模型的text-davinci-003,就是這樣的一個Completion模型。
總的來說:Completions 是 OpenAI 提供的 API,以用來生成文本,Completions API 主要用于補全問題,用戶輸入一段提示文字,模型按照文字的提示給出對應的輸出。
二、 Completions模型類
截至目前,OpenAI官網(wǎng)發(fā)布的Completions模型類如下:
OpenAI發(fā)布的帶有"text"標識的A、B、C、D四大類模型都屬于Completions模型系列,即GPT-3系列模型。GPT-3.5和GPT-4則被定義為Chat Completions模型。
從功能角度來看,Completions模型具有更基礎且全面的功能,而且它是唯一一個OpenAI提供微調(diào)接口的模型。相反,Chat Completions模型則是一種更專業(yè)、更先進的模型。每種模型都有其獨特的應用場景。本文先主要講解Completions模型的參數(shù)及用法。
三、 Completion.create API
3.1 參數(shù)詳解
在OpenAI提供的在線大模型中,所有的Completions模型都需要通過Completion.create進行調(diào)用,并在實際調(diào)用的過程中通過超參數(shù)設置對應的調(diào)用模型及模型相關(guān)參數(shù)。
看下OpenAI官網(wǎng)給出的參數(shù)列表:
各參數(shù)解釋如下:
3.2 調(diào)用測試
- Step 1:引入依賴包和加載OPENAI_API_KEY
import os
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
- Step 2:調(diào)用測試
所有的Completions模型都需要通過Completion.create()函數(shù)進行調(diào)用,在實際調(diào)用的過程中通過超參數(shù)設置對應的調(diào)用模型及模型相關(guān)參數(shù),測試代碼如下:
response = openai.Completion.create(
model="text-davinci-003",
prompt="This is a test message"
)
輸出結(jié)果如下:
如果程序不報錯,基本就證明了已經(jīng)正常調(diào)用了,返回結(jié)果response包含了text_completion id(completion任務編碼)、模型回復結(jié)果及本輪調(diào)用的資源使用情況,從模型的回復上來看,Completions作為補全模型,會根據(jù)輸入繼續(xù)生成后面的內(nèi)容,也就是從This is a test message – > This is a test message to test how emails work. Depending on the
最簡單的調(diào)用是僅設置model和prompt參數(shù),也就只有這兩個參數(shù)是必填的,其中model表示調(diào)用的模型,而prompt則表示提示詞。
- Step 3:數(shù)據(jù)操作
當?shù)玫交貜秃螅涂梢允褂肞ython做一些基礎的操作,首先response是一個OpenAIObject類型對象
- 提取response中具體返回的文本
- 提取text對象
需要強調(diào)的是:生成式大模型的輸出結(jié)果往往是不確定且難以復現(xiàn)的。雖然理論上,當temperature
設為0時,模型會在每個步驟中始終選擇概率最高的下一個token,使得輸出變得更加確定和一致。但實際上,由于模型內(nèi)部計算的精度限制、舍入誤差等因素,仍然不能保證輸出結(jié)果的完全一致性。
除了temperature外,目前OpenAI并沒有提供任何額外的可以用于控制結(jié)果隨機性的參數(shù)。top_p盡管可以影響輸出結(jié)果,但并不能完全控制模型隨機性。此外,目前OpenAI的在線大模型也并沒有類似機器學習領(lǐng)域的隨機數(shù)種子的參數(shù)設置。因此,就目前的情況而言,控制大語言輸出結(jié)果使其能夠復現(xiàn),幾乎是不可能做到的。
3.3 調(diào)參實踐
大語言模型是非常復雜的黑箱模型,導致很多時候參數(shù)設置導致的結(jié)果并不能完全按照理論情況來進行推演,因此需要通過大量的實踐,來積累不同參數(shù)的使用經(jīng)驗,即掌握不同參數(shù)在實際Completion過程中對輸出結(jié)果的影響。
先來試一下 嘗試調(diào)整Completion.create的核心參數(shù)來觀察模型輸出結(jié)果變化情況
3.3.1 參數(shù)n
response = openai.Completion.create(
model="text-davinci-003",
prompt="請問什么是機器學習",
max_tokens=1000,
n=3
)
- 參數(shù)n:表示一個提示返回幾個Completion
當輸入n=3時,就有3個completion返回,如下:
可以這樣查看單獨的某一個:
response["choices"][0]["text"].strip('?\n\n')
輸出如下:
當n不等于1的時候,取結(jié)果就采用索引的方式,當輸入n=3的時候,response[“choices”][0]就是取第一個Completion的內(nèi)容,response[“choices”][1]就是取第二個Completion的內(nèi)容…
將上述過程封裝成一個函數(shù),代碼如下:
import openai
import json
def get_completion_response(model, prompt, n=1):
"""
使用OpenAI的API查詢并獲取響應。
參數(shù):
- model (str): 要查詢的模型名稱,例如 "text-davinci-003"。
- prompt (str): 用于查詢的提示或問題。
- n (int): 返回響應的數(shù)量,默認為1。
返回:
- str: 一個包含所有響應的JSON字符串。
示例:
result = get_completion_response("text-davinci-003", "請問什么是機器學習", 3)
print(result)
"""
# 使用OpenAI的API獲得響應
response = openai.Completion.create(
model=model,
prompt=prompt,
max_tokens=1000,
n=n
)
# 存儲處理后的響應文本
response_texts = []
# 根據(jù)n的大小,依次處理每一個響應的內(nèi)容
for i in range(n):
text = response["choices"][i]["text"].strip('?\n\n')
print(f"Response {i + 1}: {text}") # 打印內(nèi)容
response_texts.append(text)
# 把返回內(nèi)容封裝在一個Json中
response_json = json.dumps({"responses": response_texts}, ensure_ascii=False)
return response_json
測試一下函數(shù):
# 調(diào)用函數(shù)示例
model = "text-davinci-003"
prompt = "請問什么是機器學習"
n = 3
# result = get_completion_response(model=model, prompt=prompt, n=n)
# print(result)
get_completion_response(model=model, prompt=prompt, n=n)
看下輸出結(jié)果:
3.3.2 參數(shù)temperature
- temperature是非常核心且重要的參數(shù),它用于控制模型輸出結(jié)果隨機性的參數(shù)。其取值范圍在0-2之間,默認值為1,數(shù)值越大模型隨機性越大。
先嘗試設置temperature=1.5,調(diào)用代碼如下:
response = openai.Completion.create(
model="text-davinci-003",
prompt="請問什么是機器學習",
max_tokens=1000,
n=3,
temperature=1.5
)
看下模型的返回結(jié)果:
其實能明顯的這個 回答已經(jīng)很隨機了,甚至都不能連成正常的一句話。
再嘗試設置一個更小的temperature取值,并觀察輸出結(jié)果:
response = openai.Completion.create(
model="text-davinci-003",
prompt="請問什么是機器學習",
max_tokens=1000,
n=3,
temperature=0.8
)
看下結(jié)果:
從結(jié)果上就能看出,當temperature參數(shù)數(shù)值下降時,回復會更加嚴謹。這很能說明temperature對文本輸出結(jié)果的隨機性影響非常大,所以這個參數(shù)是一定要重視的。
兩條temperature參數(shù)的設置技巧可供參考,但具體如何設置,還需要根據(jù)實際情況來判斷
- temperature的數(shù)值對模型結(jié)果影響極大,往往小幅的數(shù)值調(diào)整就會導致非常大的影響,因此建議的調(diào)整范圍在**[0.8,1.2]**之間;
- 伴隨著temperature取值逐漸增加,返回的文本也將從嚴謹表述逐漸變?yōu)椤昂詠y語”,但temperature在某些取值時,返回的結(jié)果會呈現(xiàn)出具備一定“啟發(fā)性”的特性,所以有時候讓模型回復更發(fā)散的內(nèi)容,能給我們一定的啟發(fā)。
當添加上temperature參數(shù)時,函數(shù)更新如下:
import openai
import json
def get_completion_response(model, prompt, n=1, temperature=0.8):
"""
使用OpenAI的API查詢并獲取響應。
參數(shù):
- model (str): 要查詢的模型名稱,例如 "text-davinci-003"。
- prompt (str): 用于查詢的提示或問題。
- n (int): 返回響應的數(shù)量,默認為1。
- temperature (float): 用于控制輸出隨機性的參數(shù),值范圍為[0, 1]。較低的值會使輸出更確定,而較高的值會使其更隨機。
返回:
- str: 一個包含所有響應的JSON字符串。
示例:
result = get_completion_response("text-davinci-003", "請問什么是機器學習", 3, 0.8)
print(result)
"""
# 使用OpenAI的API獲得響應
response = openai.Completion.create(
model=model,
prompt=prompt,
max_tokens=1000,
n=n,
temperature=temperature
)
# 存儲處理后的響應文本
response_texts = []
# 根據(jù)n的大小,依次處理每一個響應的內(nèi)容
for i in range(n):
text = response["choices"][i]["text"].strip('?\n\n')
print(f"Response {i+1}: {text}") # 打印內(nèi)容
response_texts.append(text)
# 把返回內(nèi)容封裝在一個Json中
response_json = json.dumps({"responses": response_texts}, ensure_ascii=False)
return response_json
測試一下:
# 調(diào)用函數(shù)示例
model = "text-davinci-003"
prompt = "請問什么是機器學習"
n = 3
temperature = 0.8
# result = get_completion_response(model=model, prompt=prompt, n=n)
# print(result)
get_completion_response(model=model, prompt=prompt, n=n, temperature=temperature)
看下模型輸出:
3.3.3 參數(shù)presence_penalty
- 參數(shù)presence_penalty制返回語句的精煉程度
簡單點理解:temperature越大,就越胡說八道,presence_penalty越小,就越啰嗦,presence_penalty參數(shù)在[-2,2]中取值,數(shù)值越大,返回結(jié)果越精煉,數(shù)值越小,返回結(jié)果越啰嗦。
仍然還是以“請問什么是機器學習”作為提示,觀察presence_penalty取值不同時的輸出結(jié)果,當取較大的值的時候,
response = openai.Completion.create(
model="text-davinci-003",
prompt="請問什么是機器學習",
max_tokens=1000,
n=3,
presence_penalty=2
)
看下模型的返回結(jié)果:
此時的輸出結(jié)果是非常精煉的。而如果設置presence_penalty為-2:
response = openai.Completion.create(
model="text-davinci-003",
prompt="請問什么是機器學習",
max_tokens=1000,
n=3,
presence_penalty=-2
)
看下模型的返回結(jié)果:
確實是磨嘰了一下,文本較短還看的不是那么明顯,當輸出長了以后,是非常直觀的。
經(jīng)長期測試及看了其他開發(fā)者的經(jīng)驗后,我個人建議在實際調(diào)用大模型進行Completion時,presence_penalty參數(shù)和temperature參數(shù)搭配進行使用,往往能達到非常好的效果。一般來說,如果希望模型更加具有創(chuàng)造力,則會增加temperature取值,并且適當降低presence_penalty取值,比如可以這樣做:
response = openai.Completion.create(
model="text-davinci-003",
prompt="請問什么是機器學習",
max_tokens=1000,
n=3,
presence_penalty=-0.8,
temperature=1.2
)
結(jié)果如下:
反之,如果希望結(jié)果更加精準,嘗試適當降低temperature,同時增加presence_penalty取值:
response = openai.Completion.create(
model="text-davinci-003",
prompt="請問什么是機器學習",
max_tokens=1000,
n=3,
presence_penalty=2,
temperature=0.8
)
結(jié)果如下:
**這也就是經(jīng)常會看到一些大語言模型具備三種不同的模式,分別為精確模式、平衡模式和創(chuàng)造力模式,其功能的實現(xiàn)都是通過大模型的參數(shù)調(diào)整來完成的,而支持這些不同模式功能實現(xiàn)的最基礎的兩個參數(shù)就是presence_penalty參數(shù)和temperature參數(shù)。**所以你現(xiàn)在知道,New bing的三種模式是怎么來的了嗎?
再更新一下函數(shù),加入presence_penalty參數(shù),代碼如下:
import openai
import json
def get_completion_response(model, prompt, n=1, temperature=0.8, presence_penalty=2.0):
"""
使用OpenAI的API查詢并獲取響應。
參數(shù):
- model (str): 要查詢的模型名稱,例如 "text-davinci-003"。
- prompt (str): 用于查詢的提示或問題。
- n (int): 返回響應的數(shù)量,默認為1。
- temperature (float): 用于控制輸出隨機性的參數(shù),值范圍為[0, 1]。較低的值會使輸出更確定,而較高的值會使其更隨機。
- presence_penalty (float): 用于增加或減少新內(nèi)容出現(xiàn)在輸出中的懲罰。
返回:
- str: 一個包含所有響應的JSON字符串。
示例:
result = get_completion_response("text-davinci-003", "請問什么是機器學習", 3, 0.8, 2)
print(result)
"""
# 使用OpenAI的API獲得響應
response = openai.Completion.create(
model=model,
prompt=prompt,
max_tokens=1000,
n=n,
temperature=temperature,
presence_penalty=presence_penalty
)
# 存儲處理后的響應文本
response_texts = []
# 根據(jù)n的大小,依次處理每一個響應的內(nèi)容
for i in range(n):
text = response["choices"][i]["text"].strip('?\n\n')
print(f"Response {i+1}: {text}") # 打印內(nèi)容
response_texts.append(text)
# 把返回內(nèi)容封裝在一個Json中
response_json = json.dumps({"responses": response_texts}, ensure_ascii=False)
return response_json
測試一下函數(shù)功能:
# 調(diào)用函數(shù)示例
model = "text-davinci-003"
prompt = "請問什么是機器學習"
n = 3
temperature = 0.8
presence_penalty = 2.0
# result = get_completion_response(model=model, prompt=prompt, n=n)
# print(result)
get_completion_response(model=model, prompt=prompt, n=n, temperature=temperature, presence_penalty=presence_penalty)
看下模型輸出:
3.3 4 參數(shù)best_of
- 參數(shù)best_of:讓模型預測多組結(jié)果,并擇優(yōu)進行輸出。
比如:如果設置best_of=5,則代表總共創(chuàng)建5個備選文本,再從中選取概率最大(得分最高)的一組進行輸出:
response = openai.Completion.create(
model="text-davinci-003",
prompt="請問什么是機器學習",
max_tokens=1000,
presence_penalty=-1,
temperature=1.2,
best_of=5
)
模型的輸出結(jié)果如下:
這個參數(shù)顯而易見的效果是隨著best_of值增加,最終的輸出結(jié)果質(zhì)量也會隨之提升,畢竟是多個答案選擇最優(yōu)的嘛,但是同時會消耗大量Token配額以及每分鐘調(diào)用次數(shù)配額,看情況用吧。
有一個參數(shù)搭配是:同時使用best_of和n,如best_of=2、n=2時,就會發(fā)出四次請求,最終返回兩個結(jié)果。
best_of是自動篩選最優(yōu)結(jié)果,參數(shù)n可以支持手動篩選最佳結(jié)果
所以進一步更新封裝的函數(shù):
import openai
import json
def get_completion_response(model, prompt, n=1, temperature=0.8, presence_penalty=2.0, best_of=1):
"""
使用OpenAI的API查詢并獲取響應。
參數(shù):
- model (str): 要查詢的模型名稱,例如 "text-davinci-003"。
- prompt (str): 用于查詢的提示或問題。
- n (int): 返回響應的數(shù)量,默認為1。
- temperature (float): 用于控制輸出隨機性的參數(shù),值范圍為[0, 1]。較低的值會使輸出更確定,而較高的值會使其更隨機。
- presence_penalty (float): 用于增加或減少新內(nèi)容出現(xiàn)在輸出中的懲罰。
- best_of (int): 用于指定多少次嘗試中選擇最佳輸出。
返回:
- str: 一個包含所有響應的JSON字符串。
示例:
result = get_completion_response("text-davinci-003", "請問什么是機器學習", 3, 0.8, 2, 5)
print(result)
"""
# 使用OpenAI的API獲得響應
response = openai.Completion.create(
model=model,
prompt=prompt,
max_tokens=1000,
n=n,
temperature=temperature,
presence_penalty=presence_penalty,
best_of=best_of
)
# 存儲處理后的響應文本
response_texts = []
# 根據(jù)n的大小,依次處理每一個響應的內(nèi)容
for i in range(n):
text = response["choices"][i]["text"].strip('?\n\n')
print(f"Response {i+1}: {text}") # 打印內(nèi)容
response_texts.append(text)
# 把返回內(nèi)容封裝在一個Json中
response_json = json.dumps({"responses": response_texts}, ensure_ascii=False)
return response_json
最終測試一下:
# 調(diào)用函數(shù)示例
model = "text-davinci-003"
prompt = "請問什么是機器學習"
n = 3
temperature = 0.8
presence_penalty = 2.0
best_of = 3
# result = get_completion_response(model=model, prompt=prompt, n=n)
# print(result)
get_completion_response(model=model, prompt=prompt, n=n, temperature=temperature, presence_penalty=presence_penalty, best_of=best_of)
看下模型的輸出:
ok,沒問題,大家可以自行嘗試更多的參數(shù),豐富這個函數(shù),便于以后使用。
四、使用Completion模型實現(xiàn)多輪對話機器人
經(jīng)過上述內(nèi)容對Completion模型API的深入了解和掌握,其實已經(jīng)具備使用Completion.create()
函數(shù)開發(fā)高級應用的能力。本文展示一下如何開發(fā)一個多輪對話的聊天機器人示例,并通過調(diào)整不同的參數(shù)來適應多種使用場景。這僅為一種可能的應用思路,供大家參考和啟發(fā)。
首先,一個聊天機器人的業(yè)務流程應該是這樣的:
為實現(xiàn)這個流程,可以一步一步的來進行項目拆解。
- Step 1:構(gòu)建聊天功能函數(shù)
要構(gòu)建聊天機器人,核心是要具備向openai.Completion.create()
發(fā)送請求并獲取答案的基本功能。在實現(xiàn)核心功能后,加入了一些優(yōu)化,如下
- 參數(shù)化:
當前,model
, temperature
, 和 presence_penalty
是外部變量。為了使函數(shù)更具有通用性和自足性,建議將它們設置為函數(shù)的參數(shù)。
- 錯誤處理:
為了更好地了解發(fā)生了什么錯誤,可以考慮返回更具體的錯誤信息。例如:return f"Error: {str(exc)}"
。
- 結(jié)果處理:
直接返回answer
可能包含了額外的空格、換行符等。要根據(jù)情況確保返回的文本格式整潔。
- 添加日志:
在函數(shù)內(nèi)部,添加一些日志來記錄關(guān)鍵步驟或捕獲的錯誤,這樣在開發(fā)和調(diào)試過程中會更方便。所以最終的對話函數(shù)如下:
def chat(prompt, model="text-davinci-003", temperature=1.0, presence_penalty=0.0):
"""
Send a chat prompt to the OpenAI API and get the answer.
:param prompt: The chat prompt.
:param model: The model to be used.
:param temperature: Sampling temperature.
:param presence_penalty: Presence penalty value.
:return: The AI's response or error message.
"""
try:
response = openai.Completion.create(
model=model,
prompt=prompt,
max_tokens=1000,
temperature=temperature,
presence_penalty=presence_penalty,
stop=[" Human:", " AI:"]
)
answer = response["choices"][0]["text"].strip()
return answer
except Exception as exc:
error_message = f"Error: {str(exc)}"
print(error_message) # This is a simple logging, consider using a logging library in real applications.
return error_message
- Step 2:設置三種對話模式
上面文章也提到過,類似于New bing的對話模型其原理就是通過預設不同的temperature參數(shù)和presence_penalty參數(shù)組合來實現(xiàn)的,可以這樣來實現(xiàn):
# 三種模式對應的參數(shù),依次為平衡模式、精確模式、創(chuàng)造力模式
if mode == 'balance':
temperature = 1
presence_penalty = 0
elif mode == 'precision':
temperature = 0.8
presence_penalty = 2
elif mode == 'creativity':
temperature = 1.2
presence_penalty = -1
else:
raise ValueError("Invalid mode. Choose from 'balance', 'precision', or 'creativity'.")
簡單理解:temperature越大,就越胡說八道,presence_penalty越小,就越啰嗦
- Step 3:構(gòu)建多輪對話邏輯
要實現(xiàn)多輪對話,其核心就是要讓本輪對話的大模型具備上下文記憶能力,思路就是將本輪human提出的question和前幾輪human提出的question+對應的AI question拼接到一起,共同輸入到大模型中,代碼實現(xiàn)的過程如下:
# 存儲對話記錄
chat_history = []
# 執(zhí)行多輪對話
while True:
# 啟動對話框
user_input = input("Human: ")
# 輸入"退出"結(jié)束對話
if user_input == "退出":
break
# 將之前的對話和當前的用戶輸入組合為新的提示
chat_prompt = "\n".join(chat_history + ["Human: " + user_input])
# 使用chat函數(shù)獲取回答
ai_response = chat(chat_prompt, temperature, presence_penalty)
# 如果回答是錯誤消息,則嘗試再次調(diào)用chat函數(shù)
while ai_response.startswith("Error:"):
print("請求失敗,正在重試...")
ai_response = chat(chat_prompt, temperature, presence_penalty)
# 輸出機器人的回答
print(f"AI: {ai_response}")
# 更新聊天記錄
chat_history.extend(["Human: " + user_input, "AI: " + ai_response])
# 保留最多10輪對話
if len(chat_history) > 20: # 因為每輪對話有2條記錄:一條Human,一條AI
chat_history = chat_history[2:]
可以在指定位置添加打印語句來查看每一輪的Prompt輸出情況,如下:
# ... [前面的代碼不變]
# 將之前的對話和當前的用戶輸入組合為新的提示
chat_prompt = "\n".join(chat_history + ["Human: " + user_input])
# 打印chat_prompt以查看每輪的模型輸入
print("\n當前的chat_prompt:\n", chat_prompt, "\n")
# ... [前面的代碼不變]
# 更新聊天記錄
chat_history.extend(["Human: " + user_input, "AI: " + ai_response])
# 打印chat_history以查看當前的對話歷史
print("\n當前的chat_history:\n", chat_history, "\n")
測試一下:
通過這種方式,使得模型存在上下文記憶能力,但需要注意的是:每輪對話有2條記錄:一條Human,一條AI,所以當你想保留10條最近的會話信息的話,chat_history的長度限制要寫成 >20.
- Step 4:完整函數(shù)
def multi_round_chat(model='text-davinci-003', mode='balance'):
"""
基于Completion.create函數(shù)的多輪對話機器人
:param model: The model to be used.
:param mode: The chat mode, which can be 'balance', 'precision', or 'creativity'.
"""
def chat(prompt, temperature=1.0, presence_penalty=0.0):
"""
對話函數(shù)
Send a chat prompt to the OpenAI API and get the answer.
:param prompt: The chat prompt.
:param temperature: Sampling temperature.
:param presence_penalty: Presence penalty value.
:return: The AI's response or error message.
"""
try:
response = openai.Completion.create(
model=model,
prompt=prompt,
max_tokens=1000,
temperature=temperature,
presence_penalty=presence_penalty,
stop=[" Human:", " AI:"]
)
answer = response["choices"][0]["text"].strip()
return answer
except Exception as exc:
error_message = f"Error: {str(exc)}"
print(error_message) # This is simple logging. In real applications, consider using a logging library.
return error_message
# 設置三種對話模式的參數(shù)
if mode == 'balance':
temperature = 1
presence_penalty = 0
elif mode == 'precision':
temperature = 0.8
presence_penalty = 2
elif mode == 'creativity':
temperature = 1.2
presence_penalty = -1
else:
raise ValueError("Invalid mode. Choose from 'balance', 'precision', or 'creativity'.")
# 啟動對話框
print("請輸入你的問題 (輸入'退出'結(jié)束對話):")
# 存儲對話記錄
chat_history = []
# 執(zhí)行多輪對話
while True:
# 啟動對話框
user_input = input("Human: ")
# 輸入"退出"結(jié)束對話
if user_input == "退出":
break
# 將之前的對話和當前的用戶輸入組合為新的提示
chat_prompt = "\n".join(chat_history + ["Human: " + user_input])
# 打印chat_prompt以查看每輪的模型輸入
print("\n當前的chat_prompt:\n", chat_prompt, "\n")
# 使用chat函數(shù)獲取回答
ai_response = chat(chat_prompt, temperature, presence_penalty)
# 如果回答是錯誤消息,則嘗試再次調(diào)用chat函數(shù)
while ai_response.startswith("Error:"):
print("請求失敗,正在重試...")
ai_response = chat(chat_prompt, temperature, presence_penalty)
# 輸出機器人的回答
print(f"AI: {ai_response}")
# 更新聊天記錄
chat_history.extend(["Human: " + user_input, "AI: " + ai_response])
# 打印chat_history以查看當前的對話歷史
print("\n當前的chat_history:\n", chat_history, "\n")
# 保留最多10輪對話
if len(chat_history) > 20: # 因為每輪對話有2條記錄:一條Human,一條AI
chat_history = chat_history[2:]
print("下次再見!")
最后測試一下:
兩個細節(jié):
- input 1是:“你好,你知道什么是機器學習嗎”,在末尾會出現(xiàn)一個問號(?),這是因為目前使用的是text-davinci-003,它是補全模型啊!
- input 2 直接輸入了“具體點應該如何學習呢?”,因為加了問號(?),是一個完整的輸入,所以并沒有補全,這就驗證了細節(jié)1中的問題,同時,并沒有提到機器學習相關(guān)的內(nèi)容,但是模型的回復是“如何學習機器學習”相關(guān)的內(nèi)容,這也驗證了模型具備上下文記憶的能力。
五、總結(jié)
本文詳細闡述了OpenAI的Completions與Chat Completions模型的基本概念與模型類。接著,對Completion.create API進行了深度解析,包括參數(shù)詳解、代碼測試以及參數(shù)調(diào)參實踐,特別是對n、temperature、presence_penalty、best_of等參數(shù)的詳細講解。最后,以Completion.create函數(shù)為基礎,實現(xiàn)了一個多輪對話機器人,展現(xiàn)了AI對話系統(tǒng)的靈活性。掌握這些知識,對優(yōu)化AI對話系統(tǒng)具有重要的指導意義。文章來源:http://www.zghlxwxcb.cn/news/detail-589783.html
最后,感謝您閱讀這篇文章!如果您覺得有所收獲,別忘了點贊、收藏并關(guān)注我,這是我持續(xù)創(chuàng)作的動力。您有任何問題或建議,都可以在評論區(qū)留言,我會盡力回答并接受您的反饋。如果您希望了解某個特定主題,也歡迎告訴我,我會樂于創(chuàng)作與之相關(guān)的文章。謝謝您的支持,期待與您共同成長!文章來源地址http://www.zghlxwxcb.cn/news/detail-589783.html
到了這里,關(guān)于大模型開發(fā)(六):OpenAI Completions模型詳解并實現(xiàn)多輪對話機器人的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!