soyleyicicem commited on
Commit
035ad05
·
verified ·
1 Parent(s): b4004d8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +281 -114
app.py CHANGED
@@ -1,5 +1,4 @@
1
  import uuid
2
- from wrappers import *
3
  from embedding_loader import *
4
  from initialize_db import QdrantClientInitializer
5
  from pdf_loader import PDFLoader
@@ -8,152 +7,320 @@ import gradio as gr
8
  from langchain_core.messages import HumanMessage, AIMessage
9
  from langchain.memory import ConversationBufferMemory
10
  from langchain_core.chat_history import InMemoryChatMessageHistory
 
 
 
 
 
11
 
12
  embeddings = import_embedding()
13
  AZURE_OPENAI_KEY = os.getenv('azure_api')
14
  os.environ['AZURE_OPENAI_KEY'] = AZURE_OPENAI_KEY
15
  openai.api_version = "2024-02-15-preview" # change it with your own version
16
  openai.azure_endpoint = os.getenv('azure_endpoint')
17
- model = "gpt35turbo" # deployment name on Azure OPENAI Studio
18
- myLLM = AzureChatOpenAI(azure_endpoint = openai.azure_endpoint,
 
19
  api_key=AZURE_OPENAI_KEY,
20
- api_version=openai.api_version,
21
- temperature=0,
22
- streaming=True,
23
- model = model,)
24
 
25
  obj_qdrant = QdrantClientInitializer()
26
  client = obj_qdrant.initialize_db()
27
  obj_loader = PDFLoader()
28
 
29
- # def print_result(question, result):
30
- # output_text = f"""### Question:
31
- # {question}
32
- # ### Answer:
33
- # {result}
34
- # """
35
- # return(output_text)
36
-
37
- # def format_chat_prompt(chat_history):
38
- # prompt = []
39
-
40
- # for turn in chat_history:
41
- # user_message, ai_message = turn
42
- # prompt.append(HumanMessage(user_message))
43
- # prompt.append(AIMessage(ai_message))
44
-
45
- # chat_history = InMemoryChatMessageHistory(messages=prompt)
46
- # memory = ConversationBufferMemory(chat_memory=chat_history, memory_key="history", input_key="question")
47
- # return memory
48
-
49
- # def chat(question, manual, history):
50
- # history = history or []
51
- # memory = format_chat_prompt(history)
52
- # manual_list = {"Toyota_Corolla_2024_TR": -8580416610875007536,
53
- # "Renault_Clio_2024_TR":-5514489544983735006,
54
- # "Fiat_Egea_2024_TR":-2026113796962100812}
55
-
56
- # collection_list = {"Toyota_Corolla_2024_TR": "TOYOTA_MANUAL_COLLECTION_EMBED3",
57
- # "Renault_Clio_2024_TR": "RENAULT_MANUAL_COLLECTION_EMBED3",
58
- # "Fiat_Egea_2024_TR": "FIAT_MANUAL_COLLECTION_EMBED3"}
59
-
60
- # collection_name = collection_list[f"{manual}"]
61
 
62
- # db = obj_loader.load_from_database(embeddings=embeddings, collection_name=collection_name)
 
63
 
64
- # CAR_ID = manual_list[f"{manual}"]
65
- # wrapper = Wrappers(collection_name, client, embeddings, myLLM, db, CAR_ID, memory)
 
 
 
66
 
67
- # inputs = {"question": question, "iter_halucination": 0}
68
- # app = wrapper.lagchain_graph()
69
-
70
- # for output in app.stream(inputs):
71
- # for key, value in output.items():
72
- # pprint(f"Finished running: {key}:")
73
- # # display(Markdown(print_result(question, value["generation"]['text'])))
74
- # response = value["generation"]['text']
75
- # history.append((question, response))
76
-
77
- # point_id = uuid.uuid4().hex
78
- # DatabaseOperations.save_user_history_demo(client, "USER_COLLECTION_EMBED3", question, response, embeddings, point_id, manual)
79
-
80
- # return '', history
81
-
82
- # def vote(data: gr.LikeData):
83
- # if data.liked:
84
- # print("You upvoted this response: ")
85
- # return "OK"
86
- # else:
87
- # print("You downvoted this response: " )
88
- # return "NOK"
89
-
90
-
91
-
92
- # manual_list = ["Toyota_Corolla_2024_TR", "Renault_Clio_2024_TR", "Fiat_Egea_2024_TR"]
93
-
94
- # with gr.Blocks() as demo:
95
-
96
- # chatbot = gr.Chatbot(height=600)
97
- # manual = gr.Dropdown(label="Kullanım Kılavuzları", value="Toyota_Corolla_2024_TR", choices=manual_list)
98
- # textbox = gr.Textbox()
99
- # clear = gr.ClearButton(components=[textbox, chatbot], value='Clear console')
100
- # textbox.submit(chat, [textbox, manual, chatbot], [textbox, chatbot])
101
- # chatbot.like(vote, None, None) # Adding this line causes the like/dislike icons to appear in your chatbot
102
 
103
- # # gr.close_all()
104
- # demo.launch(share=True)
105
 
106
- def print_result(question, result):
107
- output_text = f"""### Question:
108
- {question}
109
- ### Answer:
110
- {result}
111
- """
112
- return(output_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
 
115
- def format_chat_prompt(chat_history):
116
- prompt = []
117
 
118
- print(chat_history)
119
- for turn in chat_history:
120
- user_message, ai_message = turn
121
- prompt.append(HumanMessage(user_message))
122
- prompt.append(AIMessage(ai_message))
 
 
 
 
 
 
 
 
 
 
 
123
 
124
- chat_history = InMemoryChatMessageHistory(messages=prompt)
125
- memory = ConversationBufferMemory(chat_memory=chat_history, memory_key="history", input_key="question")
126
- return memory
127
-
128
  liked_state = gr.State(None)
129
  last_interaction = gr.State(None)
130
 
131
  def chat(question, manual, history, liked):
132
  history = history or []
133
- memory = format_chat_prompt(history)
134
- manual_list = {"Toyota_Corolla_2024_TR": -8580416610875007536,
135
- "Renault_Clio_2024_TR":-5514489544983735006,
136
- "Fiat_Egea_2024_TR":-2026113796962100812}
137
 
138
- collection_list = {"Toyota_Corolla_2024_TR": "TOYOTA_MANUAL_COLLECTION_EMBED3",
139
- "Renault_Clio_2024_TR": "RENAULT_MANUAL_COLLECTION_EMBED3",
140
- "Fiat_Egea_2024_TR": "FIAT_MANUAL_COLLECTION_EMBED3"}
141
 
142
  collection_name = collection_list[manual]
143
 
144
  db = obj_loader.load_from_database(embeddings=embeddings, collection_name=collection_name)
145
 
146
  CAR_ID = manual_list[manual]
147
- wrapper = Wrappers(collection_name, client, embeddings, myLLM, db, CAR_ID, memory)
148
 
149
- inputs = {"question": question, "iter_halucination": 0}
150
- app = wrapper.lagchain_graph()
151
-
152
- for output in app.stream(inputs):
153
- for key, value in output.items():
154
- pprint(f"Finished running: {key}:")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
- response = value["generation"]['text']
157
  history.append((question, response))
158
 
159
  # Store the last interaction without saving to the database yet
@@ -170,7 +337,7 @@ def save_last_interaction(feedback):
170
  if last_interaction.value:
171
  DatabaseOperations.save_user_history_demo(
172
  client,
173
- "USER_COLLECTION_EMBED3",
174
  last_interaction.value["question"],
175
  last_interaction.value["response"],
176
  embeddings,
@@ -180,7 +347,7 @@ def save_last_interaction(feedback):
180
  )
181
  last_interaction.value = None
182
 
183
- manual_list = ["Toyota_Corolla_2024_TR", "Renault_Clio_2024_TR", "Fiat_Egea_2024_TR"]
184
 
185
  with gr.Blocks() as demo:
186
  chatbot = gr.Chatbot(height=600)
 
1
  import uuid
 
2
  from embedding_loader import *
3
  from initialize_db import QdrantClientInitializer
4
  from pdf_loader import PDFLoader
 
7
  from langchain_core.messages import HumanMessage, AIMessage
8
  from langchain.memory import ConversationBufferMemory
9
  from langchain_core.chat_history import InMemoryChatMessageHistory
10
+ from qdrant_client import QdrantClient, models
11
+ from db_operations import DatabaseOperations
12
+ from openai import AzureOpenAI
13
+ import json
14
+ from qdrant_client.http import models as rest
15
 
16
  embeddings = import_embedding()
17
  AZURE_OPENAI_KEY = os.getenv('azure_api')
18
  os.environ['AZURE_OPENAI_KEY'] = AZURE_OPENAI_KEY
19
  openai.api_version = "2024-02-15-preview" # change it with your own version
20
  openai.azure_endpoint = os.getenv('azure_endpoint')
21
+
22
+ model = "gpt4o" # deployment name on Azure OPENAI Studio
23
+ client = AzureOpenAI(azure_endpoint = openai.azure_endpoint,
24
  api_key=AZURE_OPENAI_KEY,
25
+ api_version=openai.api_version)
 
 
 
26
 
27
  obj_qdrant = QdrantClientInitializer()
28
  client = obj_qdrant.initialize_db()
29
  obj_loader = PDFLoader()
30
 
31
+ # -----
32
+ def retriever_db(db, CAR_ID):
33
+
34
+ retriever = db.as_retriever(search_kwargs={'k': 4}, filter=rest.Filter(
35
+ must=[
36
+ models.FieldCondition(key="car_id", match=models.MatchValue(value=CAR_ID))
37
+ ]
38
+ ))
39
+
40
+ return retriever
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ ## new version
43
+ def chat_gpt(prompt=None, history=[], model=model, client=client, tools=[None]):
44
 
45
+ if prompt is None:
46
+ messages = history
47
+ else:
48
+ history.append({"role": "user", "content": f"{prompt}"})
49
+ messages = history
50
 
51
+ completion = client.chat.completions.create(
52
+ model=model,
53
+ messages=messages,
54
+ tools=tools
55
+ )
56
+ return completion
57
+
58
+ retrieval_functions = [
59
+ {
60
+ "type": "function",
61
+ "function":{
62
+ "name": "get_section_content",
63
+ "description": """Use this function to get the contents of a particular section of a user manual.""",
64
+ "parameters": {
65
+ "type": "object",
66
+ "properties": {
67
+ "section_title": {
68
+ "type": "string",
69
+ "description": "Title of the section in the user manual",
70
+ },
71
+ "sub_section_title": {
72
+ "type": "string",
73
+ "description": "Title of the subsection in the user manual",
74
+ },
75
+ "sub_sub_section_title": {
76
+ "type": "string",
77
+ "description": "Title of the subsubsection in the user manual",
78
+ }
79
+ },
80
+ "required": ["section_title", "sub_section_title", "sub_sub_section_title"],
81
+ }
82
+ }
83
+ }
84
+ ]
 
85
 
86
+ table_of_contents_path = "tableofcontent.txt"
 
87
 
88
+ def get_section_content(section_title, sub_section_title, sub_sub_section_title, content_path=table_of_contents_path):
89
+
90
+ with open(content_path, "r") as file:
91
+ doc_section_content = json.loads(file.read())
92
+
93
+ response = None
94
+ for sections in doc_section_content["TableOfContents"]:
95
+ if sections['title'] == section_title:
96
+ # print("Section:", sections)
97
+
98
+ for sub_sections in sections['subsections']:
99
+ if sub_sections['title'] == sub_section_title:
100
+ # print("SubSection:", sub_sections)
101
+
102
+ for sub_sub_sections in sub_sections['subsections']:
103
+ if sub_sub_sections['title'] == sub_sub_section_title:
104
+ # print("SubSubSection:", sub_sub_sections)
105
+
106
+ try:
107
+ # print("SubSubSection_Details:", str(sub_sub_sections['details']))
108
+ response = sub_sub_sections['details']
109
+ # print("SubSubSection_Details:", str(sub_sub_sections['content']))
110
+ # response = sub_sub_sections['content']
111
+ except:
112
+ pass
113
+
114
+ else:
115
+ # response = sub_sections['content']
116
+ pass
117
+
118
+ else:
119
+ # response = sections['content']
120
+ pass
121
+
122
+
123
+ else:
124
+ pass
125
+
126
+ return response
127
+
128
+ def get_lead_result(question):
129
+ hizmet_listesi = {"Bakım": """Check-Up, Periyodik Bakım, Aks Değişimi, Amortisör Değişimi, Amortisör Takozu Değişimi, Baskı Balata Değişimi, Benzin Filtresi Değişimi,
130
+ Debriyaj Balatası Değişimi, Direksiyon Kutusu Değişimi, Dizel Araç Bakımı, Egzoz Muayenesi, Fren Kaliperi Değişimi, El Freni Teli Değişimi,
131
+ Fren Balatası Değişimi, Fren Disk Değişimi, Hava Filtresi Değişimi, Helezon Yay Değişimi, Kampana Fren Balatası Değişimi,
132
+ Kızdırma Bujisi Değişimi, Rot Başı Değişimi, Rot Kolu Değişimi, Rotil Değişimi, Silecek Değişimi, Süspansiyon, Triger Kayışı Değişimi,
133
+ Triger Zinciri Değişimi, V Kayışı Değişimi, Yağ Filtresi Değişimi, Yakıt Filtresi Değişimi, Havayastığı Değişimi""",
134
+ "Yağ ve Sıvılar": """Şanzıman Yağı Değişimi, Dizel Araçlarda Yağ Değişimi, Yağ Değişimi, Fren Hidrolik Değişimi, Antifriz Değişimi,""",
135
+ "Akü": """Akü Şarj Etme, Akü Değişimi""",
136
+ "Klima": """Oto Klima Kompresörü Tamiri, Oto Klima Tamiri, Araç Klima Temizliği, Araç Klima Bakteri Temizliği, Klima Gazı Dolumu, Klima Dezenfeksiyonu, Polen Filtresi Değişimi""",
137
+ "Elektrik": """Servis Uyarı Lambası Sıfırlama,Buji Kablosu Değişimi, Arıza Tespit, Göstergelerin Kontrolü, Far Ayarı ve Ampul Değişimi, Buji Değişimi, Sigorta Değişimi""",
138
+ "Lastik/ Jant": """Lastik Jant Satış, Lastik Değişimi, Balans Ayarı, Rot Ayarı, Rotasyon, Lastik Tamiri, Hava Kontrolü, Nitrojen Dolumu, Supap Değişimi, Lastik Saklama (Lastik Oteli), Jant Sökme Takma,""",
139
+ "Diğer": """Cam Tamiri""",
140
+ "Hibrit Araçlar": "Hibrit Araç Aküsü"}
141
+
142
+ lead_functions = [
143
+ {
144
+ "type": "function",
145
+ "function": {
146
+ "name": "grade_service_relevance",
147
+ "description": "Grade the relevance of services to a user question",
148
+ "parameters": {
149
+ "type": "object",
150
+ "properties": {
151
+ "binary_score": {
152
+ "type": "string",
153
+ "description": "Services are relevant to the question, 'yes' or 'no'",
154
+ "enum": ["yes", "no"]
155
+ }
156
+ },
157
+ "required": ["binary_score"]
158
+ }
159
+ }
160
+ }
161
+ ]
162
+
163
+ # System message
164
+
165
+ system_message = """Soruyu cevaplarken:
166
+ 1- Önce soruyu düşün.
167
+ 2- Kullanıcının sorduğu soru, hizmet listesinde sunulan hizmetlerle alakalı mı?
168
+ Alakalı ise "yes", değilse "no" olarak cevap ver."""
169
+
170
+ def service_grader_relevance(hizmet_listesi: str, question: str) -> dict:
171
+ completion = client.chat.completions.create(
172
+ model=model,
173
+ messages=[
174
+ {"role": "system", "content": system_message},
175
+ {"role": "user", "content": f"Provided services: \n\n {hizmet_listesi} \n\n User question: {question}"}
176
+ ],
177
+ tools=lead_functions,
178
+ tool_choice={"type": "function", "function": {"name": "grade_service_relevance"}}
179
+ )
180
+
181
+ tool_call = completion.choices[0].message.tool_calls[0]
182
+ return json.loads(tool_call.function.arguments)
183
 
184
 
185
+ result = service_grader_relevance(hizmet_listesi, question)
186
+ return result['binary_score']
187
 
188
+ def chat_gpt_nofn(prompt=None, history=[], model=model, client=client):
189
+
190
+ if prompt is None:
191
+ messages = history
192
+ else:
193
+ history.append({"role": "user", "content": f"{prompt}"})
194
+ messages = history
195
+
196
+ completion = client.chat.completions.create(
197
+ model=model,
198
+ messages=messages,
199
+ )
200
+ return completion
201
+
202
+ with open("tableofcontent.txt", "r") as file:
203
+ content = json.loads(file.read())
204
 
 
 
 
 
205
  liked_state = gr.State(None)
206
  last_interaction = gr.State(None)
207
 
208
  def chat(question, manual, history, liked):
209
  history = history or []
210
+ conv = history.copy()
211
+ manual_list = {"Toyota_Corolla_2024_TR": -8580416610875007536}
 
 
212
 
213
+ collection_list = {"Toyota_Corolla_2024_TR": "TOYOTA_MANUAL_COLLECTION_EMBED3"}
 
 
214
 
215
  collection_name = collection_list[manual]
216
 
217
  db = obj_loader.load_from_database(embeddings=embeddings, collection_name=collection_name)
218
 
219
  CAR_ID = manual_list[manual]
 
220
 
221
+ retriever = retriever_db(db, CAR_ID)
222
+
223
+ first_hop = f"""Soruyu cevaplarken:
224
+ 1- Önce soruyu düşün.
225
+ 2- Kullanıcının sorduğu sorunun konu başlıkları neler olabilir?
226
+ 3- Bu konu başlıkları kullanım kılavuzu içindekiler tablosu başlıkları ile alakalı mı?
227
+ 4- Alakalı olabilecek tüm başlıkları türet.
228
+ Buna göre, aşağıda vereceğim kullanım kılavuzu içindekiler tablosu (başlıklar) bilgisini kullanarak bu içeriğe erişmek için uygun fonksiyonları üret.
229
+
230
+ Eğer herhangi bir içeriğe ulaşamazsan, bunu belir ve sorunun cevabı hakkında yorum yapma.
231
+ Kullanım Kılavuzu İçindekiler Tablosu:
232
+ {content}
233
+
234
+ """
235
+ conv = [{"role": "system", "content": f"{first_hop}"}]
236
+ conv.append({"role": "system", "content": f"{first_hop}"})
237
+ first_hop_response = chat_gpt(prompt=f"Soru: {question}", history=conv, tools=retrieval_functions)
238
+ conv.append(first_hop_response.choices[-1].message)
239
+
240
+ path = "Toyota_Corolla_2024_TR_Structured"
241
+ i = 0
242
+ json_files = [file for file in os.listdir(path) if file.endswith('.json')]
243
+ function_contents = []
244
+ while(i < 2):
245
+ tool_calls = first_hop_response.choices[-1].message.tool_calls
246
+ if tool_calls:
247
+ for tool_call in tool_calls:
248
+ whole_content = []
249
+ function_name = tool_call.function.name
250
+ args = json.loads(tool_call.function.arguments)
251
+ print(f"Will call {function_name} with arguments {args}")
252
+
253
+ if function_name == 'get_section_content':
254
+ for json_file in json_files:
255
+ try:
256
+ file_path = os.path.join(path, json_file)
257
+ addition = get_section_content(str(args['section_title']), str(args['sub_section_title']), str(args['sub_sub_section_title']), content_path=file_path)
258
+
259
+ if addition == None:
260
+ pass
261
+ else:
262
+ whole_content.append(addition)
263
+ function_contents.append(addition)
264
+ except:
265
+ pass
266
+ conv.append({
267
+ "tool_call_id": tool_call.id,
268
+ "role": "tool",
269
+ "name": function_name,
270
+ "content": str(whole_content)
271
+ })
272
+ first_hop_response = chat_gpt(prompt=None, history=conv, tools=retrieval_functions)
273
+ else:
274
+ conv.append(first_hop_response.choices[-1].message)
275
+ break
276
+ i += 1
277
+ documents = retriever.invoke(question)
278
+
279
+ if get_lead_result(question).lower() == 'yes':
280
+ lead = """ Cevabın sonunda, "Nasıl devam edeceğinizden emin değilseniz." ifadesiyle başlayarak, kullanıcılara hızlı ve uygun fiyatlı çözümler için OtoPratik mağazalarını ziyaret etmelerini teklif etmelisin."""
281
+ print('Lead: yes')
282
+ else:
283
+ lead = ''
284
+ print('Lead: no')
285
+
286
+ prompt = f"""
287
+ Sen, yalnızca araba sorunları ve araç bilgilerine odaklanan, ARVI adında uzman bir asistansın.
288
+ Amacın, araba sorunları, bakım, onarımlar, teknik özellikler ve diğer araçla ilgili konularla ilgili sorulara doğru, yardımcı ve net cevaplar vermektir.
289
+
290
+ Ayrıca, temel nezaket etkileşimlerine uygun ve kibar bir şekilde yanıt vermek için tasarlandın. İşte yönergeler:
291
+
292
+ 1. Araba Sorunları ve Araç Bilgileri:
293
+
294
+ - Araba sorunları, teşhis, onarımlar, bakım ve araç teknik özellikleri ile ilgili soruları her zaman yanıtla.
295
+ - Kullanıcılara araba sorunlarını çözmelerine veya araçları hakkında daha fazla bilgi edinmelerine yardımcı olabilecek detaylı ve pratik tavsiyeler ver.
296
+
297
+ 2. Referanslar:
298
+
299
+ - Bir soruyu yanıtlarken, eğer aşağıdaki ya da sorunun içindeki içerikten faydalandıysan, cevabın sonunda içeriğin sayfa numarasını referans olarak ekle.
300
+ - Aynı referansı tekrar etme.
301
+
302
+ Her zaman "Yetkili Servis, Bakım" gibi ifadeler yerine yalnızca "OtoBakım Servisi" yazmalısın.
303
+
304
+ Lead: {lead} \n
305
+
306
+ Dokümanlarda ve sorunun içinde verilen tüm bilgilere dayanarak, aşağıdaki soruyu kısaca yanıtla: \n
307
+ Soru: {question} \n
308
+
309
+ Dokümanlar: {documents}
310
+ Kullanıcıya doğrudan cevap ver. \n
311
+ Yeni fonksiyon çağırma. \n
312
+ Soru çok genel ise, spesifik bilgi iste. \n
313
+ Eğer sorunun cevabına ulaşamadıysan, bu soruya cevap veremeyeceğini belirt.
314
+ Kesinlikle cevaplar üzerine yorum yapma ve bilgi dağarcığını kullanma
315
+ Referans verme örneği:
316
+ Ref-1: "Sayfa numarası"
317
+ Ref-2: "Sayfa numarası"
318
+ ...
319
+ """
320
+ final_response = chat_gpt_nofn(prompt=prompt, history=conv)
321
+ response = final_response.choices[-1].message.content
322
+ conv.append(final_response.choices[-1].message)
323
 
 
324
  history.append((question, response))
325
 
326
  # Store the last interaction without saving to the database yet
 
337
  if last_interaction.value:
338
  DatabaseOperations.save_user_history_demo(
339
  client,
340
+ "USER_COLLECTION_EMBED3_v2",
341
  last_interaction.value["question"],
342
  last_interaction.value["response"],
343
  embeddings,
 
347
  )
348
  last_interaction.value = None
349
 
350
+ manual_list = ["Toyota_Corolla_2024_TR"]
351
 
352
  with gr.Blocks() as demo:
353
  chatbot = gr.Chatbot(height=600)