一文告訴你如何用 Python 操作 ChatGPT
楔子
ChatGPT 相信大家都用過,你覺得它給你的工作帶來了多少幫助呢?目前我們使用 ChatGPT 的方式是通過瀏覽器訪問 chat.openai.com,然后輸入問題,就像下面這樣。
圖片
除了網頁之外,ChatGPT 還提供了 API 接口,讓我們可以在程序中訪問 GPT 模型。需要注意的是,如果使用網頁,那么 GPT 3.5 是免費的,GPT 4 則是一個月收費 20 美元。
但如果要通過 API 來訪問 GPT 模型,那么不管什么版本都是收費的,至于費用多少則取決于 token 的數(shù)量。GPT 會對文本進行分詞,切分后的結果就是一個個的 token,而 token 的數(shù)量決定了費用。
那么 Python 如何訪問 GPT 模型呢?首先需要安裝一個包,直接 pip install openai 即可。
然后登錄 platform.openai.com/api-keys,創(chuàng)建一個 API-KEY,如果要通過接口訪問,它是不可或缺的。
下面就可以通過 Python 來訪問了,我們舉例說明。
生成文本
我們可以給 GPT 一段話,讓它以文本的形式生成回復內容。
from openai import OpenAI
import httpx
# 我的 API_KEY,以及代理
from config import API_KEY, PROXIES
# openai 底層是通過 httpx 發(fā)送請求
# 但因為眾所周知的原因,我們不能直接訪問,需要設置代理
httpx_client = httpx.Client(proxies=PROXIES)
# 然后指定 api_key 參數(shù)和 httpx_client 參數(shù)
# 如果你不指定 httpx_client,那么內部會自動創(chuàng)建,但此時就無法設置代理了
# 當然要是你當前機器的網絡能直接訪問,也可以不用指定 http_client 參數(shù)
client = OpenAI(
api_key=API_KEY,
http_client=httpx_client
)
chat = client.chat.completions.create(
messages=[
{
"role": "user",
"content": "1 + 1 等于幾",
},
],
model="gpt-3.5-turbo",
)
# chat.choices[0] 返回的是 pydantic 里面的 BaseModel
# 我們可以調用 dict 方法轉成字典
print(chat.choices[0].dict())
"""
{
'finish_reason': 'stop',
'index': 0,
'logprobs': None,
'message': {'content': '1 + 1 等于2。',
'role': 'assistant',
'function_call': None,
'tool_calls': None}
}
"""
然后解釋一下 client.chat.completions.create 里面的參數(shù)。
messages
ChatGPT 是有記憶功能的,它在回答的時候會結合上下文。那么問題來了,如果是通過接口的話,怎么把這個上下文傳遞過去呢?
# 注意 messages 里面的字典的 "role" 這個 key
# 如果 "role" 為 "user",那么 "content" 表示用戶問的問題
# 如果 "role" 為 "assistant",那么 "content" 表示 GPT 的回答
chat = client.chat.completions.create(
messages=[
{
"role": "user", # 開發(fā)者輸入內容
"content": "記住:高老師總能分享出好東西",
},
{
"role": "assistant", # GPT 回答
"content": "好的,我知道了",
},
{
"role": "user", # 開發(fā)者輸入內容
"content": "請問誰總能分享出好東西,告訴我那個人的名字",
},
],
model="gpt-3.5-turbo",
)
print(chat.choices[0].dict())
"""
{
'finish_reason': 'stop',
'index': 0,
'logprobs': None,
'message': {'content': '高老師',
'role': 'assistant',
'function_call': None,
'tool_calls': None}
}
"""
所以 messages 是一個列表,它里面可以接收多個消息,如果希望 GPT 擁有記憶功能,那么每一次都要將完整的對話傳遞過去,顯然這會比較耗費 token。
舉個例子,我們通過接口來模擬網頁版 GPT。
messages = [] # 負責保存消息
while True:
content = input("請輸入內容:")
messages.append({"role": "user", "content": content})
# 發(fā)送請求
chat = client.chat.completions.create(
messages=messages, model="gpt-3.5-turbo"
)
# 除了通過 chat.choices[0].dict() 轉成字典之外
# 也可以直接通過 chat.choices[0].message.content 獲取回復內容
gpt_reply = chat.choices[0].message.content
print(f"GPT 回答如下:{gpt_reply}")
# 將 GPT 的回復添加進去,開啟下一輪對話
messages.append({"role": "assistant", "content": gpt_reply})
執(zhí)行程序,效果如下:
圖片
由于每次都要將歷史對話一起帶過去,所以這個過程比較耗費 token。
model
然后是 model 參數(shù),它表示 GPT 所使用的模型,支持如下種類。
"gpt-4-0125-preview",
"gpt-4-turbo-preview",
"gpt-4-1106-preview",
"gpt-4-vision-preview",
"gpt-4",
"gpt-4-0314",
"gpt-4-0613",
"gpt-4-32k",
"gpt-4-32k-0314",
"gpt-4-32k-0613",
"gpt-3.5-turbo",
"gpt-3.5-turbo-16k",
"gpt-3.5-turbo-0301",
"gpt-3.5-turbo-0613",
"gpt-3.5-turbo-1106",
"gpt-3.5-turbo-0125",
"gpt-3.5-turbo-16k-0613",
一般選擇 gpt-3.5-turbo 或 gpt-4-turbo-preview 即可。
stream
默認情況下,GPT 會將內容全部生成完畢,然后一次性返回。顯然這在耗時比較長的時候,對用戶不是很友好。如果希望像網頁那樣,能夠將內容以流的形式返回,那么可以將該參數(shù)設置為 True。
chat = client.chat.completions.create(
messages=[
{"role": "user",
"content": "請重復一句話:高老師總能分享出好東西"}
],
model="gpt-3.5-turbo",
stream=True # 流式返回
)
for chunk in chat:
print(chunk.choices[0].delta.dict())
"""
{'content': '', 'function_call': None, 'role': 'assistant', 'tool_calls': None}
{'content': '高', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': '老', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': '師', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': '總', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': '能', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': '分享', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': '出', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': '好', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': '東', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': '西', 'function_call': None, 'role': None, 'tool_calls': None}
{'content': None, 'function_call': None, 'role': None, 'tool_calls': None}
"""
如果 GPT 生成內容時耗時比較長,那么這種實時響應的方式會更友好。
n
GPT 回復內容的時候,可以讓它同一時刻回復多個版本,然后我們選擇一個滿意的。具體返回多少個,取決于 n 的大小,默認為 1。
chat = client.chat.completions.create(
messages=[
{"role": "user",
"content": "世界上最高的雪山叫什么"}
],
model="gpt-3.5-turbo",
n=3, # 同時生成三個回復
)
print(chat.choices[0].message.content)
"""
珠穆朗瑪峰(Mount Everest)
"""
print(chat.choices[1].message.content)
"""
世界上最高的雪山是珠穆朗瑪峰。珠穆朗瑪峰是位于喜馬拉雅山脈的一座高峰,
也是世界上海拔最高的山峰,海拔達到了8848米。
由于其極高的海拔和陡峭的山脊,珠穆朗瑪峰成為許多登山者夢寐以求的挑戰(zhàn)之一。
每年都有數(shù)百名登山者前往珠穆朗瑪峰嘗試攀登,但由于極端的氣候和高海拔帶來的極大危險,
很多人最終未能成功登頂。
"""
print(chat.choices[2].message.content)
"""
世界上最高的雪山是被稱為珠穆朗瑪峰,位于喜馬拉雅山脈,
是地球上海拔最高的山峰,也是登山愛好者們夢寐以求征服的目標。
"""
這里為了閱讀方便,我手動對回復的內容進行了換行。以上就是參數(shù) n 的作用,不過說實話,為了不浪費 token,我們一般都會使用默認值 1。
生成圖像
再來看看如何生成圖像。
images = client.images.generate(
# 提示詞
prompt="幫我生成一張蕾姆的照片,她穿著婚紗站在教堂里",
# 模型,可選 "dall-e-2" 或 "dall-e-3"
model="dall-e-3",
# 同時生成多少張照片,默認為 1
n=1,
# 圖像質量,可選 "standard" 或 "hd"
# "hd" 更精細,但只支持 dall-e-3
quality="standard",
# 圖片的響應格式,可選 "url" 或 "b64_json"
response_format="url",
# 圖像大小,如果模型是 dall-e-2,可選 "256x256", "512x512", "1024x1024"
# 如果模型是 dall-e-3,可選 "1024x1024", "1792x1024", "1024x1792"
size="1024x1024",
# 圖像風格,可選 "vivid" 或 "natural","vivid" 更加超現(xiàn)實
style="vivid",
)
print(images.data[0].url)
"""
返回的圖片鏈接
"""
print(images.data[0].b64_json)
"""
因為 response_format 是 url,所以 b64_json 為空
"""
print(images.data[0].dict())
"""
{
"b64_json": None,
"revised_prompt": "修正之后的提示詞",
"url": "https://...."
}
"""
效果如下:
圖片
感覺不太像啊,頭發(fā)不應該是藍色的嗎?
小結
以上就是 Python 調用 ChatGPT 的相關內容,當然還有很多其它功能,比如生成圖像之后,如果覺得不滿意,可以在原有圖像的基礎上繼續(xù)編輯。有興趣可以自己了解一下。