SergeyO7 commited on
Commit
b381fdf
·
verified ·
1 Parent(s): a8d757c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -0
app.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from langchain_community.document_loaders import UnstructuredMarkdownLoader
3
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
4
+ from langchain_core.documents import Document
5
+ from langchain_huggingface import HuggingFaceEmbeddings
6
+ from langchain.vectorstores import FAISS
7
+ from langchain_community.llms import HuggingFaceHub
8
+ from langchain.prompts import ChatPromptTemplate
9
+ from dotenv import load_dotenv
10
+ import os
11
+
12
+ # Загрузка переменных окружения
13
+ load_dotenv()
14
+
15
+ DATA_PATH = ""
16
+ PROMPT_TEMPLATE = """
17
+ Ответь на вопрос, используя только следующий контекст:
18
+ {context}
19
+ ---
20
+ Ответь на вопрос на основе приведенного контекста: {question}
21
+ """
22
+
23
+ # Глобальная переменная для статуса
24
+ status_message = "Инициализация..."
25
+
26
+ def initialize_vectorstore():
27
+ global status_message
28
+ try:
29
+ status_message = "Загрузка и обработка документов..."
30
+ documents = load_documents()
31
+ chunks = split_text(documents)
32
+
33
+ status_message = "Создание векторной базы..."
34
+ vectorstore = save_to_faiss(chunks)
35
+
36
+ status_message = "База данных готова к использованию."
37
+ return vectorstore
38
+
39
+ except Exception as e:
40
+ status_message = f"Ошибка инициализации: {str(e)}"
41
+ raise
42
+
43
+ def generate_data_store():
44
+ documents = load_documents()
45
+ if documents:
46
+ chunks = split_text(documents)
47
+ return save_to_faiss(chunks)
48
+
49
+ def load_documents():
50
+ file_path = os.path.join(DATA_PATH, "pl250320252.md")
51
+ if not os.path.exists(file_path):
52
+ raise FileNotFoundError(f"Файл {file_path} не найден")
53
+ loader = UnstructuredMarkdownLoader(file_path)
54
+ return loader.load()
55
+
56
+ def split_text(documents: list[Document]):
57
+ text_splitter = RecursiveCharacterTextSplitter(
58
+ chunk_size=900,
59
+ chunk_overlap=300,
60
+ length_function=len,
61
+ add_start_index=True,
62
+ )
63
+ return text_splitter.split_documents(documents)
64
+
65
+ def save_to_faiss(chunks: list[Document]):
66
+ embeddings = HuggingFaceEmbeddings(
67
+ model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
68
+ model_kwargs={'device': 'cpu'},
69
+ encode_kwargs={'normalize_embeddings': True}
70
+ )
71
+ return FAISS.from_documents(chunks, embeddings)
72
+
73
+ def process_query(query_text: str, vectorstore):
74
+ if vectorstore is None:
75
+ return "База данных не инициализирована", []
76
+
77
+ try:
78
+ results = vectorstore.similarity_search_with_relevance_scores(query_text, k=3)
79
+ global status_message
80
+ status_message += f"\nНайдено {len(results)} результатов"
81
+
82
+ if not results:
83
+ return "Не найдено результатов.", []
84
+
85
+ context_text = "\n\n---\n\n".join([
86
+ f"Релевантность: {score:.2f}\n{doc.page_content}"
87
+ for doc, score in results
88
+ ])
89
+
90
+ prompt_template = ChatPromptTemplate.from_template(PROMPT_TEMPLATE)
91
+ prompt = prompt_template.format(context=context_text, question=query_text)
92
+
93
+ model = HuggingFaceHub(
94
+ repo_id="google/flan-t5-small",
95
+ model_kwargs={"temperature": 0.5, "max_length": 512}
96
+ )
97
+ response_text = model.predict(prompt)
98
+
99
+ sources = list(set([doc.metadata.get("source", "") for doc, _ in results]))
100
+ return response_text, sources
101
+
102
+ except Exception as e:
103
+ return f"Ошибка обработки запроса: {str(e)}", []
104
+
105
+ def chat_interface(query_text):
106
+ global status_message
107
+ try:
108
+ vectorstore = initialize_vectorstore()
109
+ response, sources = process_query(query_text, vectorstore)
110
+ full_response = f"{status_message}\n\nОтвет: {response}\n\nИсточники: {', '.join(sources) if sources else 'Нет источников'}"
111
+ return full_response
112
+ except Exception as e:
113
+ return f"Критическая ошибка: {str(e)}"
114
+
115
+ # Интерфейс Gradio
116
+ interface = gr.Interface(
117
+ fn=chat_interface,
118
+ inputs=gr.Textbox(lines=2, placeholder="Введите ваш вопрос здесь..."),
119
+ outputs="text",
120
+ title="Чат с документами",
121
+ description="Задайте вопрос, и я отвечу на основе загруженных документов."
122
+ )
123
+
124
+ if __name__ == "__main__":
125
+ interface.launch()