vanhai123 commited on
Commit
0a5ee4c
·
verified ·
1 Parent(s): 738af1a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +200 -199
app.py CHANGED
@@ -1,199 +1,200 @@
1
- import gradio as gr
2
- import os
3
- from datetime import datetime
4
- from retriever import retriever, reload_retriever
5
- from generator import answer_query
6
- from langchain_community.document_loaders import PyPDFLoader, TextLoader, CSVLoader, UnstructuredWordDocumentLoader
7
- from langchain.text_splitter import RecursiveCharacterTextSplitter
8
- from langchain_community.embeddings import HuggingFaceEmbeddings
9
- from langchain_community.vectorstores import FAISS
10
-
11
- # Hàm xử lý upload tài liệu và làm mới FAISS
12
- def process_document(file):
13
- file_path = file.name
14
-
15
- # Chọn loader theo đuôi file
16
- if file_path.endswith(".pdf"):
17
- loader = PyPDFLoader(file_path)
18
- elif file_path.endswith(".csv"):
19
- loader = CSVLoader(file_path)
20
- elif file_path.endswith(".txt"):
21
- loader = TextLoader(file_path)
22
- elif file_path.endswith(".docx") or file_path.endswith(".doc"):
23
- loader = UnstructuredWordDocumentLoader(file_path)
24
- else:
25
- return "Định dạng file không hỗ trợ!"
26
-
27
- # Load tài liệu
28
- documents = loader.load()
29
-
30
- # Cắt chunk văn bản
31
- splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
32
- docs = splitter.split_documents(documents)
33
-
34
- if not docs:
35
- return "Không trích xuất được nội dung từ file tải lên."
36
-
37
- # Tạo FAISS mới
38
- embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
39
- db = FAISS.from_documents(docs, embeddings)
40
-
41
- db.save_local("vectorstore")
42
- reload_retriever()
43
-
44
- timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
45
- return f"Đã xử lý và thêm {len(docs)} đoạn tài liệu vào VectorStore lúc {timestamp}"
46
-
47
- # Hàm xử lý tìm kiếm
48
- def query_function(question, model_choice, temperature, include_sources):
49
- answer, sources = answer_query(question, model=model_choice, temperature=temperature)
50
-
51
- if include_sources and sources:
52
- sources_text = "\n\n**Nguồn tài liệu:**\n"
53
- for i, doc in enumerate(sources):
54
- sources_text += f"{i+1}. {doc.page_content}\n"
55
- if hasattr(doc, 'metadata') and doc.metadata:
56
- sources_text += f" - Nguồn: {doc.metadata.get('source', 'Unknown')}\n"
57
- sources_text += f" - Trang: {doc.metadata.get('page', 'N/A')}\n"
58
- result = answer + sources_text
59
- else:
60
- result = answer
61
- result = result.encode('utf-8', errors='ignore').decode('utf-8')
62
- return result
63
-
64
- def clear_inputs():
65
- return "", []
66
-
67
- # Giao diện Gradio
68
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
69
- with gr.Row():
70
- with gr.Column(scale=3):
71
- gr.Markdown(
72
- """
73
- # 🔎 RAGFlow Enterprise Search
74
- ### Công cụ tìm kiếm thông minh dựa trên RAG (Retrieval-Augmented Generation)
75
-
76
- Hệ thống giúp truy xuất và trả lời câu hỏi từ tài liệu nội bộ doanh nghiệp.
77
- """
78
- )
79
-
80
- with gr.Tabs():
81
- # Tab tìm kiếm
82
- with gr.TabItem("Tìm kiếm 🔍"):
83
- with gr.Row():
84
- with gr.Column(scale=3):
85
- question = gr.Textbox(
86
- label="Nhập câu hỏi của bạn:",
87
- placeholder="Ví dụ: Quy trình xin nghỉ phép nội bộ là gì?",
88
- lines=2
89
- )
90
- with gr.Column(scale=1):
91
- model_choice = gr.Dropdown(
92
- label="Mô hình AI",
93
- choices=["Gemini Pro", "GPT-3.5", "GPT-4", "Claude"],
94
- value="Gemini Pro"
95
- )
96
- temperature = gr.Slider(
97
- label="Temperature",
98
- minimum=0.0,
99
- maximum=1.0,
100
- value=0.2,
101
- step=0.1
102
- )
103
- include_sources = gr.Checkbox(
104
- label="Hiển thị nguồn tài liệu",
105
- value=True
106
- )
107
-
108
- search_button = gr.Button("🔍 Tìm kiếm", variant="primary")
109
- clear_button = gr.Button("🗑️ Xóa")
110
- output = gr.Textbox(
111
- label="Kết quả tìm kiếm:",
112
- lines=15,
113
- interactive=False
114
- )
115
-
116
- search_button.click(
117
- query_function,
118
- inputs=[question, model_choice, temperature, include_sources],
119
- outputs=output
120
- )
121
- question.submit(
122
- query_function,
123
- inputs=[question, model_choice, temperature, include_sources],
124
- outputs=output
125
- )
126
- clear_button.click(clear_inputs, outputs=[question, output])
127
-
128
- # Tab quản lý tài liệu
129
- with gr.TabItem("📚 Quản lý tài liệu"):
130
- with gr.Row():
131
- with gr.Column():
132
- upload_file = gr.File(
133
- label="Tải lên tài liệu mới (PDF, Word, CSV, TXT)",
134
- file_types=[".pdf", ".docx", ".doc", ".csv", ".txt"]
135
- )
136
- upload_button = gr.Button("📤 Tải lên và xử lý", variant="primary")
137
-
138
- with gr.Column():
139
- upload_status = gr.Textbox(
140
- label="📄 Trạng thái:",
141
- lines=3,
142
- interactive=False
143
- )
144
-
145
- gr.Markdown("### 📊 Danh sách tài liệu đã xử lý")
146
- upload_button.click(
147
- process_document,
148
- inputs=upload_file,
149
- outputs=upload_status
150
- )
151
-
152
- # Tab cài đặt (optional)
153
- with gr.TabItem("⚙️ Cài đặt hệ thống"):
154
- gr.Markdown("### ⚙️ Cấu hình Vector Store & Embedding")
155
- with gr.Row():
156
- with gr.Column():
157
- vector_store = gr.Dropdown(
158
- label="Vector Store",
159
- choices=["FAISS", "Pinecone", "Milvus"],
160
- value="FAISS"
161
- )
162
- embedding_model = gr.Dropdown(
163
- label="Embedding Model",
164
- choices=["Sentence-Transformers", "OpenAI Embeddings", "Cohere Embeddings"],
165
- value="Sentence-Transformers"
166
- )
167
- with gr.Column():
168
- chunk_size = gr.Slider(
169
- label="Chunk size (độ dài văn bản mỗi đoạn)",
170
- minimum=100,
171
- maximum=1000,
172
- value=500,
173
- step=50
174
- )
175
- chunk_overlap = gr.Slider(
176
- label="Chunk overlap (chồng lấp giữa các đoạn)",
177
- minimum=0,
178
- maximum=200,
179
- value=50,
180
- step=10
181
- )
182
-
183
- save_settings = gr.Button("💾 Lưu cài đặt", variant="primary")
184
- settings_status = gr.Textbox(
185
- label="🗂️ Trạng thái:",
186
- interactive=False
187
- )
188
-
189
- def save_system_settings(vector_store, embedding_model, chunk_size, chunk_overlap):
190
- return f"✅ Đã lưu: VectorStore={vector_store}, Embedding={embedding_model}, ChunkSize={chunk_size}, Overlap={chunk_size}"
191
-
192
- save_settings.click(
193
- save_system_settings,
194
- inputs=[vector_store, embedding_model, chunk_size, chunk_overlap],
195
- outputs=settings_status
196
- )
197
-
198
-
199
- demo.launch()
 
 
1
+ import gradio as gr
2
+ import os
3
+ from datetime import datetime
4
+ from retriever import retriever, reload_retriever
5
+ from generator import answer_query
6
+ from langchain_community.document_loaders import PyPDFLoader, TextLoader, CSVLoader, UnstructuredWordDocumentLoader
7
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
8
+ from langchain_community.embeddings import HuggingFaceEmbeddings
9
+ from langchain_community.vectorstores import FAISS
10
+
11
+ # Hàm xử lý upload tài liệu và làm mới FAISS
12
+ def process_document(file):
13
+ file_path = file.name
14
+
15
+ # Chọn loader theo đuôi file
16
+ if file_path.endswith(".pdf"):
17
+ loader = PyPDFLoader(file_path)
18
+ elif file_path.endswith(".csv"):
19
+ loader = CSVLoader(file_path)
20
+ elif file_path.endswith(".txt"):
21
+ loader = TextLoader(file_path)
22
+ elif file_path.endswith(".docx") or file_path.endswith(".doc"):
23
+ loader = UnstructuredWordDocumentLoader(file_path)
24
+ else:
25
+ return "Định dạng file không hỗ trợ!"
26
+
27
+ # Load tài liệu
28
+ documents = loader.load()
29
+
30
+ # Cắt chunk văn bản
31
+ splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
32
+ docs = splitter.split_documents(documents)
33
+
34
+ if not docs:
35
+ return "Không trích xuất được nội dung từ file tải lên."
36
+
37
+ # Tạo FAISS mới
38
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
39
+ db = FAISS.from_documents(docs, embeddings)
40
+
41
+ db.save_local("vectorstore")
42
+ reload_retriever()
43
+
44
+ timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
45
+ return f"Đã xử lý và thêm {len(docs)} đoạn tài liệu vào VectorStore lúc {timestamp}"
46
+
47
+ # Hàm xử lý tìm kiếm
48
+ def query_function(question, model_choice, temperature, include_sources):
49
+ answer, sources = answer_query(question, model=model_choice, temperature=temperature)
50
+
51
+ if include_sources and sources:
52
+ sources_text = "\n\n**Nguồn tài liệu:**\n"
53
+ for i, doc in enumerate(sources):
54
+ sources_text += f"{i+1}. {doc.page_content}\n"
55
+ if hasattr(doc, 'metadata') and doc.metadata:
56
+ sources_text += f" - Nguồn: {doc.metadata.get('source', 'Unknown')}\n"
57
+ sources_text += f" - Trang: {doc.metadata.get('page', 'N/A')}\n"
58
+ result = answer + sources_text
59
+ else:
60
+ result = answer
61
+ result = result.encode('utf-8', errors='ignore').decode('utf-8')
62
+ return result
63
+
64
+ def clear_inputs():
65
+ return "", []
66
+
67
+ # Giao diện Gradio
68
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
69
+ with gr.Row():
70
+ with gr.Column(scale=3):
71
+ gr.Markdown(
72
+ """
73
+ # 🔎 RAGFlow Enterprise Search
74
+ ### Công cụ tìm kiếm thông minh dựa trên RAG (Retrieval-Augmented Generation)
75
+
76
+ Hệ thống giúp truy xuất và trả lời câu hỏi từ tài liệu nội bộ doanh nghiệp.
77
+ """
78
+ )
79
+
80
+ with gr.Tabs():
81
+ # Tab tìm kiếm
82
+ with gr.TabItem("Tìm kiếm 🔍"):
83
+ with gr.Row():
84
+ with gr.Column(scale=3):
85
+ question = gr.Textbox(
86
+ label="Nhập câu hỏi của bạn:",
87
+ placeholder="Ví dụ: Quy trình xin nghỉ phép nội bộ là gì?",
88
+ lines=2
89
+ )
90
+ with gr.Column(scale=1):
91
+ model_choice = gr.Dropdown(
92
+ label="Mô hình AI",
93
+ choices=["Gemini Pro", "GPT-3.5", "GPT-4", "Claude"],
94
+ value="Gemini Pro"
95
+ )
96
+ temperature = gr.Slider(
97
+ label="Temperature",
98
+ minimum=0.0,
99
+ maximum=1.0,
100
+ value=0.2,
101
+ step=0.1
102
+ )
103
+ include_sources = gr.Checkbox(
104
+ label="Hiển thị nguồn tài liệu",
105
+ value=True
106
+ )
107
+
108
+ search_button = gr.Button("🔍 Tìm kiếm", variant="primary")
109
+ clear_button = gr.Button("🗑️ Xóa")
110
+ output = gr.Textbox(
111
+ label="Kết quả tìm kiếm:",
112
+ lines=15,
113
+ interactive=False
114
+ )
115
+
116
+ search_button.click(
117
+ query_function,
118
+ inputs=[question, model_choice, temperature, include_sources],
119
+ outputs=output
120
+ )
121
+ question.submit(
122
+ query_function,
123
+ inputs=[question, model_choice, temperature, include_sources],
124
+ outputs=output
125
+ )
126
+ clear_button.click(clear_inputs, outputs=[question, output])
127
+
128
+ # Tab quản lý tài liệu
129
+ with gr.TabItem("📚 Quản lý tài liệu"):
130
+ with gr.Row():
131
+ with gr.Column():
132
+ upload_file = gr.File(
133
+ label="Tải lên tài liệu mới (PDF, Word, CSV, TXT)",
134
+ file_types=[".pdf", ".docx", ".doc", ".csv", ".txt"]
135
+ )
136
+ upload_button = gr.Button("📤 Tải lên và xử lý", variant="primary")
137
+
138
+ with gr.Column():
139
+ upload_status = gr.Textbox(
140
+ label="📄 Trạng thái:",
141
+ lines=3,
142
+ interactive=False
143
+ )
144
+
145
+ gr.Markdown("### 📊 Danh sách tài liệu đã xử lý")
146
+ upload_button.click(
147
+ process_document,
148
+ inputs=upload_file,
149
+ outputs=upload_status
150
+ )
151
+
152
+ # Tab cài đặt (optional)
153
+ with gr.TabItem("⚙️ Cài đặt hệ thống"):
154
+ gr.Markdown("### ⚙️ Cấu hình Vector Store & Embedding")
155
+ with gr.Row():
156
+ with gr.Column():
157
+ vector_store = gr.Dropdown(
158
+ label="Vector Store",
159
+ choices=["FAISS", "Pinecone", "Milvus"],
160
+ value="FAISS"
161
+ )
162
+ embedding_model = gr.Dropdown(
163
+ label="Embedding Model",
164
+ choices=["Sentence-Transformers", "OpenAI Embeddings", "Cohere Embeddings"],
165
+ value="Sentence-Transformers"
166
+ )
167
+ with gr.Column():
168
+ chunk_size = gr.Slider(
169
+ label="Chunk size (độ dài văn bản mỗi đoạn)",
170
+ minimum=100,
171
+ maximum=1000,
172
+ value=500,
173
+ step=50
174
+ )
175
+ chunk_overlap = gr.Slider(
176
+ label="Chunk overlap (chồng lấp giữa các đoạn)",
177
+ minimum=0,
178
+ maximum=200,
179
+ value=50,
180
+ step=10
181
+ )
182
+
183
+ save_settings = gr.Button("💾 Lưu cài đặt", variant="primary")
184
+ settings_status = gr.Textbox(
185
+ label="🗂️ Trạng thái:",
186
+ interactive=False
187
+ )
188
+
189
+ def save_system_settings(vector_store, embedding_model, chunk_size, chunk_overlap):
190
+ return f"✅ Đã lưu: VectorStore={vector_store}, Embedding={embedding_model}, ChunkSize={chunk_size}, Overlap={chunk_size}"
191
+
192
+ save_settings.click(
193
+ save_system_settings,
194
+ inputs=[vector_store, embedding_model, chunk_size, chunk_overlap],
195
+ outputs=settings_status
196
+ )
197
+
198
+
199
+ demo.launch(share=True)
200
+