Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -325,6 +325,10 @@ def google_search(term, num_results=3, lang="en", timeout=5, safe="active", ssl_
|
|
325 |
|
326 |
return all_results
|
327 |
|
|
|
|
|
|
|
|
|
328 |
def ask_question(question, temperature, top_p, repetition_penalty, web_search, chatbot):
|
329 |
if not question:
|
330 |
return "Please enter a question."
|
@@ -341,21 +345,20 @@ def ask_question(question, temperature, top_p, repetition_penalty, web_search, c
|
|
341 |
else:
|
342 |
database = None
|
343 |
|
344 |
-
max_attempts =
|
345 |
context_reduction_factor = 0.7
|
346 |
-
|
347 |
|
348 |
if web_search:
|
349 |
contextualized_question, topics, entity_tracker, instructions = chatbot.process_question(question)
|
350 |
serializable_entity_tracker = {k: list(v) for k, v in entity_tracker.items()}
|
351 |
|
352 |
-
|
353 |
-
search_results = google_search(contextualized_question, num_results=3) # Reduced number of results
|
354 |
all_answers = []
|
355 |
|
356 |
for attempt in range(max_attempts):
|
357 |
try:
|
358 |
-
web_docs = [Document(page_content=result["text"]
|
359 |
|
360 |
if database is None:
|
361 |
database = FAISS.from_documents(web_docs, embed)
|
@@ -365,7 +368,6 @@ def ask_question(question, temperature, top_p, repetition_penalty, web_search, c
|
|
365 |
database.save_local("faiss_database")
|
366 |
|
367 |
context_str = "\n".join([f"Source: {doc.metadata['source']}\nContent: {doc.page_content}" for doc in web_docs])
|
368 |
-
context_str = context_str[:max_context_chars]
|
369 |
|
370 |
instruction_prompt = f"User Instructions: {instructions}\n" if instructions else ""
|
371 |
|
@@ -382,23 +384,51 @@ def ask_question(question, temperature, top_p, repetition_penalty, web_search, c
|
|
382 |
"""
|
383 |
|
384 |
prompt_val = ChatPromptTemplate.from_template(prompt_template)
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
392 |
|
393 |
full_response = generate_chunked_response(model, formatted_prompt)
|
394 |
answer = extract_answer(full_response, instructions)
|
395 |
all_answers.append(answer)
|
396 |
break
|
397 |
|
|
|
|
|
|
|
|
|
|
|
398 |
except Exception as e:
|
399 |
print(f"Error in ask_question (attempt {attempt + 1}): {e}")
|
400 |
if attempt == max_attempts - 1:
|
401 |
-
all_answers.append(f"I apologize, but
|
402 |
|
403 |
answer = "\n\n".join(all_answers)
|
404 |
sources = set(doc.metadata['source'] for doc in web_docs)
|
@@ -420,12 +450,6 @@ def ask_question(question, temperature, top_p, repetition_penalty, web_search, c
|
|
420 |
relevant_docs = retriever.get_relevant_documents(question)
|
421 |
context_str = "\n".join([doc.page_content for doc in relevant_docs])
|
422 |
|
423 |
-
if attempt > 0:
|
424 |
-
words = context_str.split()
|
425 |
-
context_str = " ".join(words[:int(len(words) * context_reduction_factor)])
|
426 |
-
|
427 |
-
context_str = context_str[:max_context_chars]
|
428 |
-
|
429 |
prompt_template = """
|
430 |
Answer the question based on the following context from the PDF document:
|
431 |
Context:
|
@@ -434,18 +458,35 @@ def ask_question(question, temperature, top_p, repetition_penalty, web_search, c
|
|
434 |
Provide a summarized and direct answer to the question.
|
435 |
"""
|
436 |
|
437 |
-
|
438 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
439 |
|
440 |
full_response = generate_chunked_response(model, formatted_prompt)
|
441 |
answer = extract_answer(full_response)
|
442 |
|
443 |
return answer
|
444 |
|
|
|
|
|
|
|
|
|
|
|
445 |
except Exception as e:
|
446 |
print(f"Error in ask_question (attempt {attempt + 1}): {e}")
|
447 |
if attempt == max_attempts - 1:
|
448 |
-
return f"I apologize, but
|
449 |
|
450 |
return "An unexpected error occurred. Please try again later."
|
451 |
|
|
|
325 |
|
326 |
return all_results
|
327 |
|
328 |
+
def estimate_tokens(text):
|
329 |
+
# Rough estimate: 1 token ~= 4 characters
|
330 |
+
return len(text) // 4
|
331 |
+
|
332 |
def ask_question(question, temperature, top_p, repetition_penalty, web_search, chatbot):
|
333 |
if not question:
|
334 |
return "Please enter a question."
|
|
|
345 |
else:
|
346 |
database = None
|
347 |
|
348 |
+
max_attempts = 5
|
349 |
context_reduction_factor = 0.7
|
350 |
+
max_estimated_tokens = 30000 # Leave some room for the model's response
|
351 |
|
352 |
if web_search:
|
353 |
contextualized_question, topics, entity_tracker, instructions = chatbot.process_question(question)
|
354 |
serializable_entity_tracker = {k: list(v) for k, v in entity_tracker.items()}
|
355 |
|
356 |
+
search_results = google_search(contextualized_question, num_results=3)
|
|
|
357 |
all_answers = []
|
358 |
|
359 |
for attempt in range(max_attempts):
|
360 |
try:
|
361 |
+
web_docs = [Document(page_content=result["text"], metadata={"source": result["link"]}) for result in search_results if result["text"]]
|
362 |
|
363 |
if database is None:
|
364 |
database = FAISS.from_documents(web_docs, embed)
|
|
|
368 |
database.save_local("faiss_database")
|
369 |
|
370 |
context_str = "\n".join([f"Source: {doc.metadata['source']}\nContent: {doc.page_content}" for doc in web_docs])
|
|
|
371 |
|
372 |
instruction_prompt = f"User Instructions: {instructions}\n" if instructions else ""
|
373 |
|
|
|
384 |
"""
|
385 |
|
386 |
prompt_val = ChatPromptTemplate.from_template(prompt_template)
|
387 |
+
|
388 |
+
# Start with full context and progressively reduce if necessary
|
389 |
+
current_context = context_str
|
390 |
+
current_conv_context = chatbot.get_context()
|
391 |
+
current_topics = topics
|
392 |
+
current_entities = serializable_entity_tracker
|
393 |
+
|
394 |
+
while True:
|
395 |
+
formatted_prompt = prompt_val.format(
|
396 |
+
context=current_context,
|
397 |
+
conv_context=current_conv_context,
|
398 |
+
question=question,
|
399 |
+
topics=", ".join(current_topics),
|
400 |
+
entities=json.dumps(current_entities)
|
401 |
+
)
|
402 |
+
|
403 |
+
# Estimate token count
|
404 |
+
estimated_tokens = estimate_tokens(formatted_prompt)
|
405 |
+
|
406 |
+
if estimated_tokens <= max_estimated_tokens:
|
407 |
+
break
|
408 |
+
|
409 |
+
# Reduce context if estimated token count is too high
|
410 |
+
current_context = current_context[:int(len(current_context) * context_reduction_factor)]
|
411 |
+
current_conv_context = current_conv_context[:int(len(current_conv_context) * context_reduction_factor)]
|
412 |
+
current_topics = current_topics[:max(1, int(len(current_topics) * context_reduction_factor))]
|
413 |
+
current_entities = {k: v[:max(1, int(len(v) * context_reduction_factor))] for k, v in current_entities.items()}
|
414 |
+
|
415 |
+
if len(current_context) + len(current_conv_context) + len(str(current_topics)) + len(str(current_entities)) < 100:
|
416 |
+
raise ValueError("Context reduced too much. Unable to process the query.")
|
417 |
|
418 |
full_response = generate_chunked_response(model, formatted_prompt)
|
419 |
answer = extract_answer(full_response, instructions)
|
420 |
all_answers.append(answer)
|
421 |
break
|
422 |
|
423 |
+
except ValueError as ve:
|
424 |
+
print(f"Error in ask_question (attempt {attempt + 1}): {ve}")
|
425 |
+
if attempt == max_attempts - 1:
|
426 |
+
all_answers.append(f"I apologize, but I'm having trouble processing the query due to its length or complexity. Could you please try asking a more specific or shorter question?")
|
427 |
+
|
428 |
except Exception as e:
|
429 |
print(f"Error in ask_question (attempt {attempt + 1}): {e}")
|
430 |
if attempt == max_attempts - 1:
|
431 |
+
all_answers.append(f"I apologize, but an unexpected error occurred. Please try again with a different question or check your internet connection.")
|
432 |
|
433 |
answer = "\n\n".join(all_answers)
|
434 |
sources = set(doc.metadata['source'] for doc in web_docs)
|
|
|
450 |
relevant_docs = retriever.get_relevant_documents(question)
|
451 |
context_str = "\n".join([doc.page_content for doc in relevant_docs])
|
452 |
|
|
|
|
|
|
|
|
|
|
|
|
|
453 |
prompt_template = """
|
454 |
Answer the question based on the following context from the PDF document:
|
455 |
Context:
|
|
|
458 |
Provide a summarized and direct answer to the question.
|
459 |
"""
|
460 |
|
461 |
+
while True:
|
462 |
+
prompt_val = ChatPromptTemplate.from_template(prompt_template)
|
463 |
+
formatted_prompt = prompt_val.format(context=context_str, question=question)
|
464 |
+
|
465 |
+
estimated_tokens = estimate_tokens(formatted_prompt)
|
466 |
+
|
467 |
+
if estimated_tokens <= max_estimated_tokens:
|
468 |
+
break
|
469 |
+
|
470 |
+
# Reduce context if estimated token count is too high
|
471 |
+
context_str = context_str[:int(len(context_str) * context_reduction_factor)]
|
472 |
+
|
473 |
+
if len(context_str) < 100:
|
474 |
+
raise ValueError("Context reduced too much. Unable to process the query.")
|
475 |
|
476 |
full_response = generate_chunked_response(model, formatted_prompt)
|
477 |
answer = extract_answer(full_response)
|
478 |
|
479 |
return answer
|
480 |
|
481 |
+
except ValueError as ve:
|
482 |
+
print(f"Error in ask_question (attempt {attempt + 1}): {ve}")
|
483 |
+
if attempt == max_attempts - 1:
|
484 |
+
return f"I apologize, but I'm having trouble processing your question due to the complexity of the document. Could you please try asking a more specific or shorter question?"
|
485 |
+
|
486 |
except Exception as e:
|
487 |
print(f"Error in ask_question (attempt {attempt + 1}): {e}")
|
488 |
if attempt == max_attempts - 1:
|
489 |
+
return f"I apologize, but an unexpected error occurred. Please try again with a different question."
|
490 |
|
491 |
return "An unexpected error occurred. Please try again later."
|
492 |
|