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