ManTea commited on
Commit
d8a8160
·
1 Parent(s): de833bd

First demo with no history memory db and curent time

Browse files
NLP_model/__pycache__/chatbot.cpython-311.pyc ADDED
Binary file (9.64 kB). View file
 
NLP_model/__pycache__/chatbot.cpython-312.pyc ADDED
Binary file (2.52 kB). View file
 
NLP_model/__pycache__/read_file.cpython-311.pyc ADDED
Binary file (8.49 kB). View file
 
NLP_model/__pycache__/read_file.cpython-312.pyc ADDED
Binary file (1.88 kB). View file
 
NLP_model/chatbot.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import google.generativeai as genai
3
+ from langchain_google_genai import ChatGoogleGenerativeAI
4
+ from langchain_community.embeddings import HuggingFaceEmbeddings
5
+ from langchain_community.vectorstores import FAISS
6
+ from langchain.chains import RetrievalQA, ConversationalRetrievalChain
7
+ from langchain_google_genai import ChatGoogleGenerativeAI
8
+ from langchain.prompts import PromptTemplate
9
+ from langchain_ollama import OllamaLLM
10
+ from pinecone import Pinecone, ServerlessSpec
11
+ from langchain_pinecone import PineconeVectorStore
12
+ from dotenv import load_dotenv
13
+ import threading
14
+ from datetime import datetime
15
+ from langchain.schema import HumanMessage, AIMessage
16
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
17
+ # Load environment variables
18
+ load_dotenv()
19
+
20
+ # Configure API keys from environment variables
21
+ google_api_key = os.getenv("GOOGLE_API_KEY")
22
+ pinecone_api_key = os.getenv("PINECONE_API_KEY")
23
+
24
+ if not google_api_key or not pinecone_api_key:
25
+ raise ValueError("Missing required API keys in environment variables")
26
+
27
+ os.environ["GOOGLE_API_KEY"] = google_api_key
28
+ os.environ["PINECONE_API_KEY"] = pinecone_api_key
29
+
30
+ genai.configure(api_key=google_api_key)
31
+
32
+ #lấy model chatbot
33
+ model = ChatGoogleGenerativeAI(model="gemini-1.5-flash-8b-latest",
34
+ temperature=0.8)
35
+ # model = OllamaLLM(model="llama2")
36
+ # print("Llama2 đã được tải thành công!")
37
+
38
+ #lấy model embedding
39
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
40
+
41
+
42
+ # Biến lưu history cho từng user (dạng chuỗi)
43
+ user_histories = {}
44
+ history_lock = threading.Lock()
45
+
46
+ # Create a prompt template with conversation history
47
+ prompt = PromptTemplate(
48
+ template = """Goal:
49
+ You are a professional tour guide assistant that assists users in finding information about places in Da Nang, Vietnam.
50
+ You can provide details on restaurants, cafes, hotels, attractions, and other local venues. You have to chat with users, who are Da Nang tourists.
51
+
52
+
53
+ Return Format:
54
+ - Respond in clear, natural, and concise English.
55
+ - If you do not have enough information to answer user's question, reply with "I don't know", and explain that you are not sure about the information.
56
+ - When sufficient information is available in the Context, provide a specific and informative answer.
57
+ - Let's support users like a real tour guide, not a bot. The information in context is your own knowledge.
58
+ - You just care about time that user mention when they ask about Solana event.
59
+
60
+ Warning:
61
+ - Your knowledge is provided in the Context. All of information in Context is about Da Nang, Vietnam.
62
+ - Do not fabricate or guess information.
63
+ - Answer with "I don't know" if you don't have enough information.
64
+
65
+ Context:
66
+ {context}
67
+
68
+ Conversation History:
69
+ {chat_history}
70
+
71
+ User question:
72
+ {question}
73
+
74
+ Your answer:
75
+ """,
76
+ input_variables = ["context", "question", "chat_history"],
77
+ )
78
+
79
+ def get_history(user_id):
80
+ """Get conversation history for a specific user"""
81
+ with history_lock:
82
+ return user_histories.get(user_id, "")
83
+
84
+ def update_history(user_id, new_entry):
85
+ """Update conversation history for a user.
86
+ new_entry should be a string containing the new conversation information, e.g.:
87
+ "User: {question}\nBot: {answer}\n"
88
+ """
89
+ with history_lock:
90
+ current_history = user_histories.get(user_id, "")
91
+ # Store only the last 30 interactions by keeping the 60 most recent lines
92
+ # (assuming 2 lines per interaction: 1 for user, 1 for bot)
93
+ history_lines = current_history.split('\n')
94
+ if len(history_lines) > 60:
95
+ history_lines = history_lines[-60:]
96
+ current_history = '\n'.join(history_lines)
97
+
98
+ updated_history = current_history + new_entry + "\n"
99
+ user_histories[user_id] = updated_history
100
+
101
+ def string_to_message_history(history_str):
102
+ """Convert string-based history to LangChain message history format"""
103
+ if not history_str.strip():
104
+ return []
105
+
106
+ messages = []
107
+ lines = history_str.strip().split('\n')
108
+ i = 0
109
+
110
+ while i < len(lines):
111
+ line = lines[i].strip()
112
+ if line.startswith("User:"):
113
+ user_message = line[5:].strip() # Get the user message without "User:"
114
+ messages.append(HumanMessage(content=user_message))
115
+
116
+ # Look for a Bot response (should be the next line)
117
+ if i + 1 < len(lines) and lines[i + 1].strip().startswith("Bot:"):
118
+ bot_response = lines[i + 1][4:].strip() # Get bot response without "Bot:"
119
+ messages.append(AIMessage(content=bot_response))
120
+ i += 2 # Skip the bot line too
121
+ else:
122
+ i += 1
123
+ else:
124
+ i += 1 # Skip any unexpected format lines
125
+
126
+ return messages
127
+
128
+ def get_chain():
129
+ """Get the retrieval chain with Pinecone vector store"""
130
+ try:
131
+ pc = Pinecone(
132
+ api_key=os.environ["PINECONE_API_KEY"]
133
+ )
134
+
135
+ # Get the vector store from the existing index
136
+ vectorstore = PineconeVectorStore.from_existing_index(
137
+ index_name="testbot768",
138
+ embedding=embeddings,
139
+ text_key="text"
140
+ )
141
+
142
+ retrieve = vectorstore.as_retriever(search_kwargs={"k": 3})
143
+
144
+ return retrieve
145
+ except Exception as e:
146
+ print(f"Error getting vector store: {e}")
147
+ return None
148
+
149
+ def chat(request, user_id="default_user"):
150
+ """Process a chat request from a specific user"""
151
+ try:
152
+ # Get retrieval chain
153
+ retriever = get_chain()
154
+ if not retriever:
155
+ return "Error: Could not initialize retriever"
156
+
157
+ # Get current conversation history as string
158
+ conversation_history_str = get_history(user_id)
159
+
160
+ # Convert string history to LangChain message format
161
+ message_history = string_to_message_history(conversation_history_str)
162
+
163
+ # Get current time
164
+ current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
165
+
166
+ # Add timestamp to question
167
+ question_with_time = f"{request}\n(Current time: {current_time})"
168
+ # print("User question:", question_with_time)
169
+
170
+ # Create a ConversationalRetrievalChain
171
+ # Get relevant documents from retriever
172
+ retrieved_docs = retriever.get_relevant_documents(question_with_time)
173
+ print("Retrieved documents page content:", [doc.page_content for doc in retrieved_docs])
174
+
175
+ conversation_chain = ConversationalRetrievalChain.from_llm(
176
+ llm=model,
177
+ retriever=retriever,
178
+ combine_docs_chain_kwargs={"prompt": prompt}
179
+ )
180
+
181
+ # Call the chain with question and converted message history
182
+ response = conversation_chain({"question": question_with_time, "chat_history": message_history})
183
+ answer = str(response['answer'])
184
+
185
+ # Update conversation history string
186
+ new_entry = f"User: {question_with_time}\nBot: {answer}"
187
+ update_history(user_id, new_entry)
188
+ print(get_history(user_id))
189
+
190
+ print(answer)
191
+ return answer
192
+ except Exception as e:
193
+ print(f"Error in chat: {e}")
194
+ return f"I encountered an error: {str(e)}"
195
+
196
+ def clear_memory(user_id="default_user"):
197
+ """Clear the conversation history for a specific user"""
198
+ with history_lock:
199
+ if user_id in user_histories:
200
+ del user_histories[user_id]
201
+ return f"Conversation history cleared for user {user_id}"
202
+ return f"No conversation history found for user {user_id}"