langchain-telegram-gpt-chatbot
/
chatbot.py
216 строк · 6.8 Кб
1import os2import openai3import requests4import telebot5import pickle6from langchain.vectorstores import FAISS as BaseFAISS7
8from dotenv import load_dotenv9from gtts import gTTS10from pydub import AudioSegment11from celery import Celery12import speech_recognition as sr13
14from langchain.embeddings import OpenAIEmbeddings15
16load_dotenv()17
18SYSTEM_PROMPT = os.getenv('SYSTEM_PROMPT')19
20app = Celery('chatbot', broker=os.getenv('CELERY_BROKER_URL'))21
22TELEGRAM_BOT_TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')23
24bot = telebot.TeleBot(TELEGRAM_BOT_TOKEN)25
26OPENAI_API_KEY = os.getenv('OPEN_AI_KEY')27MODEL_NAME = os.getenv('MODEL_NAME')28
29embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY)30
31# Store the last 10 conversations for each user
32conversations = {}33
34
35class FAISS(BaseFAISS):36@staticmethod37def load(file_path):38with open(file_path, "rb") as f:39return pickle.load(f)40
41
42# Load the FAISS index
43faiss_obj_path = "models/" + MODEL_NAME + ".pickle"44faiss_index = FAISS.load(faiss_obj_path)45
46
47# @app.task
48def generate_response_chat(message_list):49if faiss_index:50# Add extra text to the content of the last message51last_message = message_list[-1]52
53# Get the most similar documents to the last message54try:55docs = faiss_index.similarity_search(query=last_message["content"], k=2)56
57updated_content = last_message["content"] + "\n\n"58for doc in docs:59updated_content += doc.page_content + "\n\n"60except Exception as e:61print(f"Error while fetching : {e}")62updated_content = last_message["content"]63
64print(updated_content)65
66# Create a new HumanMessage object with the updated content67# updated_message = HumanMessage(content=updated_content)68updated_message = {"role": "user", "content": updated_content}69
70# Replace the last message in message_list with the updated message71message_list[-1] = updated_message72
73openai.api_key = OPENAI_API_KEY74# Send request to GPT-3 (replace with actual GPT-3 API call)75gpt3_response = openai.ChatCompletion.create(76model="gpt-4",77temperature=0,78messages=[79{"role": "system",80"content": SYSTEM_PROMPT},81] + message_list82)83
84assistant_response = gpt3_response["choices"][0]["message"]["content"].strip()85
86return assistant_response87
88
89def conversation_tracking(text_message, user_id):90"""91Make remember all the conversation
92:param old_model: Open AI model
93:param user_id: telegram user id
94:param text_message: text message
95:return: str
96"""
97# Get the last 10 conversations and responses for this user98user_conversations = conversations.get(user_id, {'conversations': [], 'responses': []})99user_messages = user_conversations['conversations'][-9:] + [text_message]100user_responses = user_conversations['responses'][-9:]101
102# Store the updated conversations and responses for this user103conversations[user_id] = {'conversations': user_messages, 'responses': user_responses}104
105# Construct the full conversation history in the user:assistant, " format106conversation_history = []107
108for i in range(min(len(user_messages), len(user_responses))):109conversation_history.append({110"role": "user", "content": user_messages[i]111})112conversation_history.append({113"role": "assistant", "content": user_responses[i]114})115
116# Add last prompt117conversation_history.append({118"role": "user", "content": text_message119})120# Generate response121response = generate_response_chat(conversation_history)122# task = generate_response_chat.apply_async(args=[conversation_history])123# response = task.get()124
125# Add the response to the user's responses126user_responses.append(response)127
128# Store the updated conversations and responses for this user129conversations[user_id] = {'conversations': user_messages, 'responses': user_responses}130
131return response132
133
134@bot.message_handler(commands=["start", "help"])135def start(message):136if message.text.startswith("/help"):137bot.reply_to(message, "/clear - Clears old "138"conversations\nsend text to get replay\nsend voice to do voice"139"conversation")140else:141bot.reply_to(message, "Just start chatting to the AI or enter /help for other commands")142
143
144# Define a function to handle voice messages
145@bot.message_handler(content_types=["voice"])146def handle_voice(message):147user_id = message.chat.id148# Download the voice message file from Telegram servers149file_info = bot.get_file(message.voice.file_id)150file = requests.get("https://api.telegram.org/file/bot{0}/{1}".format(151TELEGRAM_BOT_TOKEN, file_info.file_path))152
153# Save the file to disk154with open("voice_message.ogg", "wb") as f:155f.write(file.content)156
157# Use pydub to read in the audio file and convert it to WAV format158sound = AudioSegment.from_file("voice_message.ogg", format="ogg")159sound.export("voice_message.wav", format="wav")160
161# Use SpeechRecognition to transcribe the voice message162r = sr.Recognizer()163with sr.AudioFile("voice_message.wav") as source:164audio_data = r.record(source)165text = r.recognize_google(audio_data)166
167# Generate response168replay_text = conversation_tracking(text, user_id)169
170# Send the question text back to the user171# Send the transcribed text back to the user172new_replay_text = "Human: " + text + "\n\n" + "sonic: " + replay_text173
174bot.reply_to(message, new_replay_text)175
176# Use Google Text-to-Speech to convert the text to speech177tts = gTTS(replay_text)178tts.save("voice_message.mp3")179
180# Use pydub to convert the MP3 file to the OGG format181sound = AudioSegment.from_mp3("voice_message.mp3")182sound.export("voice_message_replay.ogg", format="mp3")183
184# Send the transcribed text back to the user as a voice185voice = open("voice_message_replay.ogg", "rb")186bot.send_voice(message.chat.id, voice)187voice.close()188
189# Delete the temporary files190os.remove("voice_message.ogg")191os.remove("voice_message.wav")192os.remove("voice_message.mp3")193os.remove("voice_message_replay.ogg")194
195
196@bot.message_handler(func=lambda message: True)197def echo_message(message):198user_id = message.chat.id199
200# Handle /clear command201if message.text == '/clear':202conversations[user_id] = {'conversations': [], 'responses': []}203bot.reply_to(message, "Conversations and responses cleared!")204return205
206response = conversation_tracking(message.text, user_id)207
208# Reply to message209bot.reply_to(message, response)210
211
212if __name__ == "__main__":213print("Starting bot...")214print("Bot Started")215print("Press Ctrl + C to stop bot")216bot.polling()217