kimrang commited on
Commit
d3bbfc6
·
verified ·
1 Parent(s): 2b445cb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -60
app.py CHANGED
@@ -11,60 +11,80 @@ from langchain.embeddings import HuggingFaceEmbeddings
11
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
12
 
13
  # 전역 변수들
14
- vectorstore = None
15
  embeddings = None
16
 
17
- import os
18
-
19
- def load_vectorstore():
20
- """벡터스토어를 로드하는 함수"""
21
- global vectorstore, embeddings
22
 
23
- if vectorstore is None:
24
- try:
25
- embeddings = HuggingFaceEmbeddings(
26
- model_name="sentence-transformers/all-MiniLM-L6-v2"
27
- )
28
-
29
- # 절대 경로로 확인
30
- vectorstore_path = os.path.join(os.getcwd(), "vectorstore")
31
- print(f"벡터스토어 경로: {vectorstore_path}")
32
-
33
- # 필수 파일들 확인
34
- required_files = ["index.faiss", "index.pkl"]
35
- missing_files = []
36
-
37
- if os.path.exists(vectorstore_path):
38
- existing_files = os.listdir(vectorstore_path)
39
- print(f"존재하는 파일들: {existing_files}")
40
 
41
- for file in required_files:
42
- if file not in existing_files:
43
- missing_files.append(file)
44
 
45
- if missing_files:
46
- print(f"❌ 누락된 파일들: {missing_files}")
47
- return None
48
- else:
49
- print("❌ vectorstore 폴더가 존재하지 않습니다")
50
- return None
51
-
52
- vectorstore = FAISS.load_local(
53
- vectorstore_path,
54
- embeddings,
55
- allow_dangerous_deserialization=True
56
- )
57
- print("✅ 벡터스토어 로드 완료")
58
-
59
- except Exception as e:
60
- print(f"❌ 벡터스토어 로드 실패: {e}")
61
- import traceback
62
- traceback.print_exc()
63
- vectorstore = None
64
 
65
- return vectorstore
 
 
 
 
 
66
 
67
- # 질문 리스트
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  suggested_questions = [
69
  '교원 신규 임용은 어떻게 하나요?',
70
  '교원 연구년 기간은 어떻게 되나요?',
@@ -88,24 +108,19 @@ suggested_questions = [
88
  '안전사고예방계획은 어디에 제출해야 하나요?'
89
  ]
90
 
91
- # 프롬프트 템플릿
92
  prompt_template = """당신은 한남대학교 규정집 도우미입니다.
93
  반드시 한국어로만 답변해주세요. 영어나 다른 언어는 절대 사용하지 마세요.
94
-
95
  주어진 문서 내용을 바탕으로 질문에 대해 정확하고 친절하게 한국어로 답변해주세요.
96
-
97
  참고 문서:
98
  {context}
99
-
100
  질문: {question}
101
-
102
  답변 지침:
103
  - 이용자를 반기는 인사로 시작하세요
104
  - 반드시 한국어로만 답변하세요
105
  - 정중하고 친근한 말투를 사용하세요
106
  - 구체적이고 도움이 되는 정보를 제공하세요
107
  - 문서에서 답을 찾을 수 없으면 "죄송하지만 해당 정보를 규정집에서 찾을 수 없습니다"라고 답변하세요
108
-
109
  한국어 답변:"""
110
 
111
  prompt = PromptTemplate(
@@ -113,7 +128,7 @@ prompt = PromptTemplate(
113
  input_variables=["context", "question"]
114
  )
115
 
116
- def respond_with_groq(question, selected_q, model):
117
  """질문에 대한 답변을 생성하는 함수"""
118
 
119
  # 선택된 질문이 있으면 그것을 사용
@@ -126,11 +141,18 @@ def respond_with_groq(question, selected_q, model):
126
  if not GROQ_API_KEY:
127
  return "❌ API 키가 설정되지 않았습니다. 관리자에게 문의하세요."
128
 
 
 
 
 
129
  try:
130
- # 벡터스토어 로드
131
- current_vectorstore = load_vectorstore()
132
- if not current_vectorstore:
133
- return "❌ 벡터스토어를 로드할 수 없습니다."
 
 
 
134
 
135
  # LLM 설정
136
  llm = ChatGroq(
@@ -154,6 +176,9 @@ def respond_with_groq(question, selected_q, model):
154
  return result['result']
155
 
156
  except Exception as e:
 
 
 
157
  return f"❌ 오류가 발생했습니다: {str(e)}"
158
 
159
  def update_question(selected):
@@ -162,6 +187,9 @@ def update_question(selected):
162
  return selected
163
  return ""
164
 
 
 
 
165
  # Gradio 인터페이스 생성
166
  with gr.Blocks(title="한남대학교 Q&A") as interface:
167
  gr.HTML("""
@@ -173,6 +201,28 @@ with gr.Blocks(title="한남대학교 Q&A") as interface:
173
 
174
  with gr.Row():
175
  with gr.Column(scale=1):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  question_dropdown = gr.Dropdown(
177
  choices=["직접 입력"] + suggested_questions,
178
  label="💡 자주 묻는 질문",
@@ -204,7 +254,7 @@ with gr.Blocks(title="한남대학교 Q&A") as interface:
204
  # 이벤트 연결
205
  submit_btn.click(
206
  fn=respond_with_groq,
207
- inputs=[question_input, question_dropdown, model_choice],
208
  outputs=output
209
  )
210
 
@@ -216,4 +266,4 @@ with gr.Blocks(title="한남대학교 Q&A") as interface:
216
 
217
  # 앱 실행
218
  if __name__ == "__main__":
219
- interface.launch()
 
11
  GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
12
 
13
  # 전역 변수들
14
+ vectorstores = {}
15
  embeddings = None
16
 
17
+ def find_vectorstore_folders():
18
+ """현재 디렉토리에서 벡터스토어 폴더들을 찾는 함수"""
19
+ current_dir = os.getcwd()
20
+ print(f"현재 디렉토리: {current_dir}")
 
21
 
22
+ # 모든 파일과 폴더 확인
23
+ all_items = os.listdir(current_dir)
24
+ print(f"현재 디렉토리 내 모든 항목들: {all_items}")
25
+
26
+ # 예상되는 벡터스토어 폴더들
27
+ expected_folders = ['vectorstore1', 'vectorstore2', 'vectorstore3']
28
+ vectorstore_folders = []
29
+
30
+ for folder_name in expected_folders:
31
+ folder_path = os.path.join(current_dir, folder_name)
32
+ if os.path.exists(folder_path) and os.path.isdir(folder_path):
33
+ try:
34
+ folder_contents = os.listdir(folder_path)
35
+ print(f"📁 {folder_name} 폴더 내용: {folder_contents}")
 
 
 
36
 
37
+ # 필수 파일들 확인
38
+ required_files = ['index.faiss', 'index.pkl']
39
+ has_all_files = all(file in folder_contents for file in required_files)
40
 
41
+ if has_all_files:
42
+ vectorstore_folders.append(folder_name)
43
+ print(f"✅ {folder_name} - 모든 필수 파일 존재")
44
+ else:
45
+ missing_files = [f for f in required_files if f not in folder_contents]
46
+ print(f"❌ {folder_name} - 누락된 파일: {missing_files}")
47
+
48
+ except Exception as e:
49
+ print(f"❌ {folder_name} 폴더 확인 중 오류: {e}")
50
+ else:
51
+ print(f"❌ {folder_name} 폴더가 존재하지 않음")
 
 
 
 
 
 
 
 
52
 
53
+ if not vectorstore_folders:
54
+ print("❌ 사용 가능한 벡터스토어 폴더를 찾을 수 없습니다")
55
+ else:
56
+ print(f"✅ 총 {len(vectorstore_folders)}개의 벡터스토어 폴더를 찾았습니다: {vectorstore_folders}")
57
+
58
+ return vectorstore_folders
59
 
60
+ def load_all_vectorstores():
61
+ """모든 벡터스토어를 로드하는 함수"""
62
+ global vectorstores, embeddings
63
+
64
+ if not embeddings:
65
+ embeddings = HuggingFaceEmbeddings(
66
+ model_name="sentence-transformers/all-MiniLM-L6-v2"
67
+ )
68
+
69
+ # 벡터스토어 폴더들 찾기
70
+ folders = find_vectorstore_folders()
71
+
72
+ for folder_name in folders:
73
+ if folder_name not in vectorstores:
74
+ try:
75
+ vectorstore = FAISS.load_local(
76
+ f"./{folder_name}",
77
+ embeddings,
78
+ allow_dangerous_deserialization=True
79
+ )
80
+ vectorstores[folder_name] = vectorstore
81
+ print(f"✅ {folder_name} 로드 완료")
82
+ except Exception as e:
83
+ print(f"❌ {folder_name} 로드 실패: {e}")
84
+
85
+ return list(vectorstores.keys())
86
+
87
+ # 질문 리스트 (기존과 동일)
88
  suggested_questions = [
89
  '교원 신규 임용은 어떻게 하나요?',
90
  '교원 연구년 기간은 어떻게 되나요?',
 
108
  '안전사고예방계획은 어디에 제출해야 하나요?'
109
  ]
110
 
111
+ # 프롬프트 템플릿 (기존과 동일)
112
  prompt_template = """당신은 한남대학교 규정집 도우미입니다.
113
  반드시 한국어로만 답변해주세요. 영어나 다른 언어는 절대 사용하지 마세요.
 
114
  주어진 문서 내용을 바탕으로 질문에 대해 정확하고 친절하게 한국어로 답변해주세요.
 
115
  참고 문서:
116
  {context}
 
117
  질문: {question}
 
118
  답변 지침:
119
  - 이용자를 반기는 인사로 시작하세요
120
  - 반드시 한국어로만 답변하세요
121
  - 정중하고 친근한 말투를 사용하세요
122
  - 구체적이고 도움이 되는 정보를 제공하세요
123
  - 문서에서 답을 찾을 수 없으면 "죄송하지만 해당 정보를 규정집에서 찾을 수 없습니다"라고 답변하세요
 
124
  한국어 답변:"""
125
 
126
  prompt = PromptTemplate(
 
128
  input_variables=["context", "question"]
129
  )
130
 
131
+ def respond_with_groq(question, selected_q, model, selected_vectorstore):
132
  """질문에 대한 답변을 생성하는 함수"""
133
 
134
  # 선택된 질문이 있으면 그것을 사용
 
141
  if not GROQ_API_KEY:
142
  return "❌ API 키가 설정되지 않았습니다. 관리자에게 문의하세요."
143
 
144
+ # 벡터스토어가 로드되지 않은 경우
145
+ if not vectorstores:
146
+ return "❌ 사용 가능한 벡터스토어가 없습니다. 관리자에게 문의하세요."
147
+
148
  try:
149
+ # 선택된 벡터스토어 확인
150
+ if selected_vectorstore not in vectorstores:
151
+ available_stores = list(vectorstores.keys())
152
+ return f"❌ 선택된 벡터스토어({selected_vectorstore})를 찾을 수 없습니다. 사용 가능한 스토어: {available_stores}"
153
+
154
+ current_vectorstore = vectorstores[selected_vectorstore]
155
+ print(f"✅ 사용 중인 벡터스토어: {selected_vectorstore}")
156
 
157
  # LLM 설정
158
  llm = ChatGroq(
 
176
  return result['result']
177
 
178
  except Exception as e:
179
+ import traceback
180
+ error_details = traceback.format_exc()
181
+ print(f"❌ 상세 오류 정보:\n{error_details}")
182
  return f"❌ 오류가 발생했습니다: {str(e)}"
183
 
184
  def update_question(selected):
 
187
  return selected
188
  return ""
189
 
190
+ # 앱 시작시 벡터스토어들 로드
191
+ available_vectorstores = load_all_vectorstores()
192
+
193
  # Gradio 인터페이스 생성
194
  with gr.Blocks(title="한남대학교 Q&A") as interface:
195
  gr.HTML("""
 
201
 
202
  with gr.Row():
203
  with gr.Column(scale=1):
204
+ # 벡터스토어 선택 드롭다운 추가
205
+ if available_vectorstores:
206
+ # 사용자 친화적인 이름으로 매핑
207
+ vectorstore_display_names = {
208
+ 'vectorstore1': '📚 데이터베이스 1',
209
+ 'vectorstore2': '📚 데이터베이스 2',
210
+ 'vectorstore3': '📚 데이터베이스 3'
211
+ }
212
+ display_choices = [vectorstore_display_names.get(vs, vs) for vs in available_vectorstores]
213
+
214
+ vectorstore_dropdown = gr.Dropdown(
215
+ choices=list(zip(display_choices, available_vectorstores)),
216
+ label="📚 데이터베이스 선택",
217
+ value=available_vectorstores[0] if available_vectorstores else None
218
+ )
219
+ else:
220
+ vectorstore_dropdown = gr.Dropdown(
221
+ choices=[("벡터스토어 없음", "none")],
222
+ label="📚 데이터베이스 선택",
223
+ value="none"
224
+ )
225
+
226
  question_dropdown = gr.Dropdown(
227
  choices=["직접 입력"] + suggested_questions,
228
  label="💡 자주 묻는 질문",
 
254
  # 이벤트 연결
255
  submit_btn.click(
256
  fn=respond_with_groq,
257
+ inputs=[question_input, question_dropdown, model_choice, vectorstore_dropdown],
258
  outputs=output
259
  )
260
 
 
266
 
267
  # 앱 실행
268
  if __name__ == "__main__":
269
+ interface.launch()