File size: 3,828 Bytes
4fda0fb
 
 
 
2b2154a
4fda0fb
 
2b2154a
4fda0fb
2b2154a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4fda0fb
 
 
 
 
 
 
2b2154a
 
4fda0fb
2b2154a
4fda0fb
 
 
2b2154a
4fda0fb
 
 
 
 
 
 
 
 
 
 
 
 
2b2154a
 
 
4fda0fb
 
 
 
 
 
 
 
 
 
 
2b2154a
 
4fda0fb
 
2b2154a
4fda0fb
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import gradio as gr
import glob
from docx import Document

def get_all_text_from_docx():
    docx_list = glob.glob("*.docx")
    if not docx_list:
        return ["Файл .docx с методичкой не найден!"]
    doc = Document(docx_list[0])
    blocks = []

    # Извлекаем все нестандартные абзацы (пропускаем короткие технические, например '4')
    for p in doc.paragraphs:
        txt = p.text.strip()
        if txt and not (len(txt) <= 3 and txt.isdigit()):
            blocks.append(txt)

    # Вытаскиваем ТЕКСТ из ТАБЛИЦ.
    for table in doc.tables:
        for row in table.rows:
            # склеиваем все ячейки строки таблицы через " | "
            row_text = " | ".join(cell.text.strip() for cell in row.cells if cell.text.strip())
            if row_text:  # отсекаем совсем пустые строки
                blocks.append(row_text)

    # дополнительно: удаляем дубли (могут встречаться в Word после копирования)
    seen = set()
    uniq_blocks = []
    for b in blocks:
        if b not in seen:
            uniq_blocks.append(b)
            seen.add(b)
    return uniq_blocks

paragraphs = get_all_text_from_docx()

# Проверьте, сколько блоков реально читается!
print("Блоков для поиска:", len(paragraphs))

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

vectorizer = TfidfVectorizer().fit(paragraphs)
paragraph_matrix = vectorizer.transform(paragraphs)

def search_faq(question):
    if not question.strip():
        return "Пожалуйста, введите вопрос."
    if len(paragraphs) < 2:
        return "Ошибка: база знаний пуста или слишком мала. Проверьте содержимое .docx или перезагрузите файл с материалами."
    user_vec = vectorizer.transform([question])
    sims = cosine_similarity(user_vec, paragraph_matrix)[0]
    idx = sims.argmax()
    score = sims[idx]
    if score < 0.12:
        return "Не найдено подходящего ответа. Попробуйте иначе сформулировать вопрос или обратитесь к преподавателю."
    return paragraphs[idx]

EXAMPLES = [
    "Какие требования к объему магистерской диссертации?",
    "Как оформить список литературы?",
    "Какие сроки сдачи и защиты ВКР?",
    "Что должно быть во введении?",
    "Какой процент оригинальности требуется?"
]

with gr.Blocks() as demo:
    gr.Markdown(
        """
        # Чат-бот по ВКР на базе вашей методички

        Задайте вопрос — бот ищет точный ответ в вашем документе, в том числе в таблицах!
        """
    )
    question = gr.Textbox(label="Ваш вопрос", lines=2)
    ask_btn = gr.Button("Получить ответ")
    answer = gr.Textbox(label="Ответ", lines=8, interactive=False)
    ask_btn.click(search_faq, question, answer)
    question.submit(search_faq, question, answer)
    gr.Markdown("#### Примеры вопросов:")
    gr.Examples(EXAMPLES, inputs=question)
    gr.Markdown("""
    ---

    ### Контакты (заполните сами)
    Преподаватель: ___________________
    Email: ___________________________
    Кафедра: _________________________
    """)

demo.launch()