Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -621,7 +621,10 @@ def save_log(question, answer):
|
|
| 621 |
|
| 622 |
# Поиск ответа
|
| 623 |
def get_answer(question):
|
| 624 |
-
#
|
|
|
|
|
|
|
|
|
|
| 625 |
if "метролог" in question.lower():
|
| 626 |
conn = get_db_connection(SQLITE_DB_PATH)
|
| 627 |
cursor = conn.cursor()
|
|
@@ -635,70 +638,65 @@ def get_answer(question):
|
|
| 635 |
conn.close()
|
| 636 |
|
| 637 |
if result:
|
| 638 |
-
|
| 639 |
-
|
| 640 |
-
|
|
|
|
|
|
|
|
|
|
| 641 |
|
| 642 |
# 2. Поиск в Excel
|
| 643 |
qa_df = load_data()
|
| 644 |
-
|
| 645 |
-
|
| 646 |
|
| 647 |
for _, row in qa_df.iterrows():
|
| 648 |
table_question = str(row['Вопрос']).lower()
|
| 649 |
if fuzz.partial_ratio(question.lower(), table_question) > 85:
|
| 650 |
response = re.sub(r"^[a-zA-Zа-яА-Я]$\s*", "", str(row['Правильный ответ']))
|
| 651 |
source = str(row['Источник ответа']) if pd.notna(row['Источник ответа']) else "?"
|
| 652 |
-
|
| 653 |
-
|
| 654 |
|
| 655 |
-
if
|
| 656 |
-
|
| 657 |
-
|
| 658 |
-
|
| 659 |
-
|
| 660 |
-
|
| 661 |
-
|
| 662 |
-
return answer
|
| 663 |
|
| 664 |
-
# 3. Гибридный поиск
|
| 665 |
hybrid_results = hybrid_search_results(question)
|
| 666 |
-
|
| 667 |
if hybrid_results:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 668 |
try:
|
| 669 |
-
|
| 670 |
-
gpt_answer = generate_gpt_response(question, hybrid_results)
|
| 671 |
|
| 672 |
# Формируем полный ответ
|
| 673 |
-
answer = f"🤖
|
| 674 |
-
answer += "🔍 Использованные
|
| 675 |
|
| 676 |
-
for i, res in enumerate(
|
| 677 |
-
answer += f"###
|
| 678 |
-
answer += f"{res['
|
| 679 |
-
answer += f"\n📚 Источник: {res['source']}\n\n"
|
| 680 |
|
| 681 |
save_log(question, answer)
|
| 682 |
return answer
|
|
|
|
| 683 |
except Exception as e:
|
| 684 |
-
logger.error(f"Ошибка при
|
| 685 |
-
|
| 686 |
-
# 4. Обычный поиск
|
| 687 |
-
results = search_in_knowledge_base(question)
|
| 688 |
-
|
| 689 |
-
if not results.empty:
|
| 690 |
-
answer = "Найдены следующие релевантные фрагменты:\n\n"
|
| 691 |
-
for idx, row in results.iterrows():
|
| 692 |
-
source_parts = [
|
| 693 |
-
str(row['doc_type_short']) if pd.notna(row['doc_type_short']) else None,
|
| 694 |
-
str(row['doc_number']) if pd.notna(row['doc_number']) else None,
|
| 695 |
-
str(row['file_name']) if pd.notna(row['file_name']) else None
|
| 696 |
-
]
|
| 697 |
-
source = " ".join(filter(None, source_parts)) or "Источник не указан"
|
| 698 |
|
| 699 |
-
|
| 700 |
-
|
| 701 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 702 |
|
| 703 |
save_log(question, answer)
|
| 704 |
return answer
|
|
|
|
| 621 |
|
| 622 |
# Поиск ответа
|
| 623 |
def get_answer(question):
|
| 624 |
+
# Получаем все релевантные результаты
|
| 625 |
+
results = []
|
| 626 |
+
|
| 627 |
+
# 1. Проверка в базе данных
|
| 628 |
if "метролог" in question.lower():
|
| 629 |
conn = get_db_connection(SQLITE_DB_PATH)
|
| 630 |
cursor = conn.cursor()
|
|
|
|
| 638 |
conn.close()
|
| 639 |
|
| 640 |
if result:
|
| 641 |
+
results.append({
|
| 642 |
+
"text": result['chunk_text'],
|
| 643 |
+
"source": f"{result['doc_type_short'] or '?'} {result['doc_number'] or ''} {result['file_name'] or ''}".strip(),
|
| 644 |
+
"score": 1.0,
|
| 645 |
+
"type": "exact"
|
| 646 |
+
})
|
| 647 |
|
| 648 |
# 2. Поиск в Excel
|
| 649 |
qa_df = load_data()
|
| 650 |
+
excel_responses = []
|
| 651 |
+
excel_sources = []
|
| 652 |
|
| 653 |
for _, row in qa_df.iterrows():
|
| 654 |
table_question = str(row['Вопрос']).lower()
|
| 655 |
if fuzz.partial_ratio(question.lower(), table_question) > 85:
|
| 656 |
response = re.sub(r"^[a-zA-Zа-яА-Я]$\s*", "", str(row['Правильный ответ']))
|
| 657 |
source = str(row['Источник ответа']) if pd.notna(row['Источник ответа']) else "?"
|
| 658 |
+
excel_responses.append(response)
|
| 659 |
+
excel_sources.append(source)
|
| 660 |
|
| 661 |
+
if excel_responses:
|
| 662 |
+
results.append({
|
| 663 |
+
"text": ", ".join(set(excel_responses)),
|
| 664 |
+
"source": ", ".join([s for s in set(excel_sources) if s != '?']),
|
| 665 |
+
"score": 1.0,
|
| 666 |
+
"type": "excel"
|
| 667 |
+
})
|
|
|
|
| 668 |
|
| 669 |
+
# 3. Гибридный поиск
|
| 670 |
hybrid_results = hybrid_search_results(question)
|
|
|
|
| 671 |
if hybrid_results:
|
| 672 |
+
results.extend(hybrid_results)
|
| 673 |
+
|
| 674 |
+
# Если есть результаты, генерируем ответ с помощью GPT
|
| 675 |
+
if results:
|
| 676 |
try:
|
| 677 |
+
gpt_answer = generate_gpt_response(question, results)
|
|
|
|
| 678 |
|
| 679 |
# Формируем полный ответ
|
| 680 |
+
answer = f"🤖 Ответ:\n\n{gpt_answer}\n\n"
|
| 681 |
+
answer += "🔍 Использованные источники:\n\n"
|
| 682 |
|
| 683 |
+
for i, res in enumerate(results, 1):
|
| 684 |
+
answer += f"### Источник {i}\n"
|
| 685 |
+
answer += f"{res['source']}\n\n"
|
|
|
|
| 686 |
|
| 687 |
save_log(question, answer)
|
| 688 |
return answer
|
| 689 |
+
|
| 690 |
except Exception as e:
|
| 691 |
+
logger.error(f"Ошибка при генерации ответа GPT: {str(e)}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 692 |
|
| 693 |
+
# 4. Если не удалось сгенерировать ответ через GPT, возвращаем обычный поиск
|
| 694 |
+
if results:
|
| 695 |
+
answer = "Найдены следующие релевантные фрагменты:\n\n"
|
| 696 |
+
for idx, res in enumerate(results, 1):
|
| 697 |
+
answer += f"### Фрагмент {idx}\n"
|
| 698 |
+
answer += f"{res['text']}\n"
|
| 699 |
+
answer += f"\n📚 Источник: {res['source']}\n\n"
|
| 700 |
|
| 701 |
save_log(question, answer)
|
| 702 |
return answer
|