如何在Telegram信使中創(chuàng)建ChatGPT聊天機(jī)器人
譯文譯者 | 李睿
審校 | 重樓
如今,提供ChatGPT訪問的鏡像網(wǎng)站開始出現(xiàn),然而使用這些網(wǎng)站是不安全的,因?yàn)?/span>它可以收集和分析所有的通信。尤其是那些完全免費(fèi)訪問ChatGPT的網(wǎng)站。這些網(wǎng)站之所以出現(xiàn),因?yàn)橐恍﹪易柚沽嗽L問ChatGPT,而OpenAI公司也阻止了一些國家和地區(qū)訪問。此外,對于一些用戶來說,20美元的ChatGPT訂閱費(fèi)用比較高昂。
而現(xiàn)在可以在Telegram信使中基于ChatGPT創(chuàng)建自己的聊天機(jī)器人。這很容易做到,在某些任務(wù)中,使用它可能比OpenAI公司的ChatGPT還要方便。
在這里將采用Python編寫這種聊天機(jī)器人程序,并通過OpenAI API發(fā)送請求。
有些用戶在注冊ChatGPT時(shí),OpenAI公司會提供5~18美元的體驗(yàn)費(fèi)用。但是,即使是5美元,也足以讓用戶獲得大約65萬個(gè)ChatGPT v3.5令牌,這對于用戶聊天來說是足夠了。
相比之下,瑪格麗特·米切爾的著作《亂世佳人》大約有42萬字,列夫·托爾斯泰的著作《戰(zhàn)爭與和平》有59萬字。
另外,API的運(yùn)行速度比OpenAI公司的免費(fèi)ChatGPT要快,而且不像OpenAI公司需要付費(fèi)訂閱(每月20美元)。使用OpenAI API,用戶只需要為他使用的內(nèi)容付費(fèi),如果沒有很多請求,用戶使用API可以節(jié)省成本。
雖然ChatGPT-4 API現(xiàn)在還沒有向所有人開放,但是GPT-3.5版本也很好地解決了許多任務(wù)。
那么現(xiàn)在開始創(chuàng)建聊天機(jī)器人。
首先,需要?jiǎng)?chuàng)建一個(gè)Telegram BOT,為此需要請求Telegram BOT,采用BotFather創(chuàng)建一個(gè)聊天機(jī)器人。在Telegram的搜索欄中輸入@botfather,打開它,然后點(diǎn)擊“啟動(dòng)”。
要?jiǎng)?chuàng)建一個(gè)新的bot,先寫入/newbot,然后將被要求輸入bot的名稱,并提出一個(gè)唯一的名稱,需要注意的是,它應(yīng)該以單詞“bot”結(jié)尾。
在這里將創(chuàng)建的bot命名為sinenko_gpt4_bot,因?yàn)楹苡腥さ拿侄家呀?jīng)被人所用。
接下來,需要指定用戶名,它將代表用戶的bot。它也應(yīng)該以bot這個(gè)詞結(jié)尾。
在這里起同樣的名字——sinenko_gpt4_bot。在此之后,BotFather將提供一個(gè)令牌,可使用它來訪問Telegram API。
要從OpenAI公司獲得ChatGPT的API密鑰,需要遵循鏈接并注冊。
在注冊之后,需要?jiǎng)?chuàng)建一個(gè)新的API密鑰并保存它。
現(xiàn)在采用項(xiàng)目創(chuàng)建一個(gè)目錄,將其命名為TelegramBot。在這個(gè)目錄中,創(chuàng)建了一個(gè)Python腳本。將它命名為bot.py。在這里將需要Python庫:telebot、requests和JSON。但首先,在項(xiàng)目目錄中創(chuàng)建一個(gè)新的Python環(huán)境(這不是強(qiáng)制性的步驟,但最好為每個(gè)項(xiàng)目創(chuàng)建一個(gè)單獨(dú)的環(huán)境)。
打開終端,轉(zhuǎn)到項(xiàng)目目錄,然后執(zhí)行以下命令:
Shell
python -m venv tbot_env
其中tbot是環(huán)境的任意一個(gè)名稱。在成功創(chuàng)建新環(huán)境之后,項(xiàng)目目錄中將出現(xiàn)一個(gè)帶有環(huán)境名稱的文件夾。在這個(gè)例子中,它是bot_env?,F(xiàn)在需要通過運(yùn)行激活腳本來激活它:
Shell
.\tbot_env\bin\activate
根據(jù)系統(tǒng)和Python版本,激活腳本也可能在以下路徑中找到:
Shell
.\tbot_env\Scripts\activate
在成功激活后,命令行中將出現(xiàn)一個(gè)帶有環(huán)境名稱的綠色銘文,在這個(gè)例子中是tbot_env。
需要注意的是,有時(shí)在Windows 8及以上版本,當(dāng)激活環(huán)境時(shí),會給出一個(gè)錯(cuò)誤,禁止執(zhí)行可執(zhí)行文件。而要解決這個(gè)問題,需要執(zhí)行以下命令:
PowerShell
Set-ExecutionPolicy RemoteSigned
之后,將要求確認(rèn),需要輸入[Y]。
現(xiàn)在更新pip并安裝工作所需的庫:
Shell
python -m pip install --upgrade pip
pip install telebot, mysql-connector-python
現(xiàn)在編寫一個(gè)簡單的Telegram bot:
Python
import telebot
from telebot import types
bot = import telebot
from telebot import types
bot = telebot.TeleBot('TELEGRAM_API_KEY')
@bot.message_handler(commands=['start']) # This decorator says that the next function should be called when the bot receives a message with the /start command.
def start(message): # This is the definition of the start function. This function will be called when the bot receives a message with the /start command.
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
btn1 = types.KeyboardButton("Start")
markup.add(btn1)
bot.send_message(message.from_user.id, "Hi, I'm the Telegram bot ChatGPT!", reply_markup=markup)
bot.polling(none_stop=True, interval=1) # for the bot to start "listening" or "polling" the Telegram
之后,用下面的命令運(yùn)行腳本:
Shell
python .\bot.py
現(xiàn)在打開Telegram,并使用FatherBot給的鏈接與bot進(jìn)行聊天。在這個(gè)例子中,它是:t.me/sinenko_gpt4_bot
然后單擊“開始”按鈕或輸入/Start命令。之后,應(yīng)該會收到一條問候信息:“嗨,我是Telegram bot ChatGPT!”這意味著聊天機(jī)器人正在工作并成功處理用戶消息。這段代碼通過輪詢函數(shù)工作,這意味著腳本本身將每秒訪問一次Telegram服務(wù)器并檢查是否有新消息。當(dāng)腳本在本地計(jì)算機(jī)上運(yùn)行或服務(wù)器在互聯(lián)網(wǎng)上沒有空白IP地址和域時(shí),是非常方便的。
現(xiàn)在為用戶輸入的任何文本添加處理。為此,在start函數(shù)之后,添加以下代碼,它將對用戶輸入的任何消息響應(yīng)“OK”:
Python
@bot.message_handler(content_types=['text'])
def get_text_messages(message):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
bot.send_message(message.from_user.id, 'OK', reply_markup=markup)
現(xiàn)在測試這個(gè)聊天機(jī)器人并編寫一些文本。
現(xiàn)在已經(jīng)學(xué)習(xí)了如何接受來自用戶的傳入消息并給出響應(yīng)。
現(xiàn)在需要將接收到的消息重定向到ChatGPT,并將其答案返回給用戶。
要向API發(fā)出請求,需要以JSON格式向URL發(fā)送請求。
請求看起來應(yīng)該是這樣的:
Python
data = {
'model': 'gpt-3.5-turbo', # Selected GPT model
'messages': [
{'role': 'system','content': 'You are my assistant.'}, # We specify the role of the bot
{"role": "user", "content": 'some user message'}, # User request
{"role": "assistant", "content": 'Answer of ChatGPT'} # Answer of the Chat-GPT
],
'max_tokens': 1000, # Maximum number of tokens in the response
'n': 1, # Number of text variants
'temperature': 0.1 # Temperature (creative component)
}
要向GPT聊天發(fā)送用戶請求,需要在消息數(shù)組中傳遞{"role": "user," "content": 'some user message'}。
但為了讓ChatGPT理解它在對話中的作用,也可以傳遞{'role': 'system','content': 'You are my assistant.'}。
如果想讓ChatGPT記住整個(gè)對話,那么所有過去的對話需要在每個(gè)請求中傳遞:
{"role": "user," "content": 'first user message'},
{"role": "assistant," "content": 'first answer of ChatGPT'},
{"role": "user," "content": 'second user message'},
{"role": "assistant," "content": 'second answer of ChatGPT'},
{"role": "user," "content": 'some user message'}
但需要注意,令牌也用于發(fā)送所有前面的對話。
現(xiàn)在將用戶消息轉(zhuǎn)發(fā)到GPT聊天添加到我bot代碼中:
Python
import requests
import json
api_key_openai = 'OPENAI_API_KEY'
url = 'https://api.openai.com/v1/chat/completions'
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer '+api_key_openai
}
data = {
'model': 'gpt-3.5-turbo', # Selected GPT model
'messages': [
{'role': 'system','content': 'You are my assistant.'} # We specify the role of the bot
],
'max_tokens': 1000, # Maximum number of tokens in the response
'n': 1, # Number of text variants
'temperature': 0.1 # Temperature (creative component)
}
Python
@bot.message_handler(content_types=['text'])
def get_text_messages(message):
markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
data['messages'].append({"role": "user", "content": message.text}) # Add a new user request to our dialog array, form a request to the server on behalf of the user, with the text received in telegram
response = requests.post(url, headers=headers, data=json.dumps(data)) # Send a request to the server in json format
result = response.json() # get the answer in json format and convert to an array
print(result)
bot.send_message(message.from_user.id, result['choices'][0]['message']['content'], reply_markup=markup) # Take the text from the array from ChatGPT and send it to Telegram
data['messages'].append({"role": "assistant", "content": result['choices'][0]['message']['content']}) # Ad
現(xiàn)在運(yùn)行腳本并嘗試編寫一些消息:
在創(chuàng)建了一個(gè)功能齊全的聊天機(jī)器人之后,現(xiàn)在可以使用了。
API將發(fā)送整個(gè)對話;隨著時(shí)間的推移,對話可能會變得很大,花費(fèi)令牌將毫無意義,因此在發(fā)送消息之后,可以從消息數(shù)組中刪除第一條消息。例如,留下最后40條信息。這就足夠了。如果要清除舊消息,需要在發(fā)送消息后添加以下代碼:
Python
# Delete the first element of the array if the array is longer than 40 elements, but leave the first element of the array, which is the initial text of the bot
while len(data['messages']) > 40:
data['messages'].pop(1)
如果消息超過40條,刪除最早的消息,但第一條消息除外(因?yàn)榈谝粭l消息存儲了bot角色)。
也可以把機(jī)器人的角色變成任何人,可以讓它根據(jù)給出的句子寫詩,編寫恐怖故事或解決數(shù)學(xué)問題。為此,更改系統(tǒng)消息的內(nèi)容字段就足夠了。用下面的方法來改變它:
Python
data = {
'model': 'gpt-3.5-turbo', # Selected GPT model
'messages': [
{'role': 'system','content': 'You are my Chinese translator, translate all messages I write in Chinese and write the transcription in square brackets using English letters.'}, # We specify the role of the bot
],
'max_tokens': 1000, # Maximum number of tokens in the response
'n': 1, # Number of text variants
'temperature': 0.1 # Temperature (creative component)
}
以下啟動(dòng)并檢查操作:
順便說一下,對于'messages'變量中的翻譯角色,可以刪除除了系統(tǒng)消息之外的所有消息。這將顯著節(jié)省令牌,而5美元足夠翻譯30多萬個(gè)單詞。
本文展示了一個(gè)最簡單的創(chuàng)建ChatGPT示例,并且這個(gè)聊天機(jī)器人可以無限地改進(jìn)。還可以為每個(gè)單獨(dú)的Telegram用戶創(chuàng)建聊天分區(qū),將其保存到數(shù)據(jù)庫中,并添加廣告和訂閱。在API請求失敗的情況下也缺少錯(cuò)誤處理程序。
原文標(biāo)題:Own ChatGPT Bot in Telegram,作者:Ilya Sinenko