kimrang commited on
Commit
99d0976
·
verified ·
1 Parent(s): 06751f5

Upload 5 files

Browse files
Files changed (6) hide show
  1. .gitattributes +1 -0
  2. README.md +17 -6
  3. app.py +185 -59
  4. requirements.txt +8 -1
  5. vectorstore/index.faiss +3 -0
  6. vectorstore/index.pkl +3 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ vectorstore/index.faiss filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,14 +1,25 @@
1
  ---
2
- title: Hannam University Qa
3
- emoji: 💬
4
- colorFrom: yellow
5
  colorTo: purple
6
  sdk: gradio
7
- sdk_version: 5.0.1
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
11
- short_description: hnu aq chat-bot
12
  ---
13
 
14
- An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: 한남대학교 Q&A
3
+ emoji: 🏫
4
+ colorFrom: blue
5
  colorTo: purple
6
  sdk: gradio
7
+ sdk_version: 4.0.2
8
  app_file: app.py
9
  pinned: false
10
  license: apache-2.0
 
11
  ---
12
 
13
+ # 한남대학교 규정집 Q&A
14
+
15
+ 한남대학교 규정집에 대한 질문-답변 시스템입니다.
16
+
17
+ ## 사용 방법
18
+ 1. 드롭다운에서 자주 묻는 질문을 선택하거나
19
+ 2. 직접 질문을 입력하세요
20
+ 3. AI 모델을 선택하고 "답변 받기" 버튼을 클릭하세요
21
+
22
+ ## 기능
23
+ - 한남대학교 규정집 기반 질문 답변
24
+ - 자주 묻는 질문 드롭다운
25
+ - 다양한 AI 모델 선택 가능
app.py CHANGED
@@ -1,64 +1,190 @@
 
 
1
  import gradio as gr
2
- from huggingface_hub import InferenceClient
3
-
4
- """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
8
-
9
-
10
- def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
- ):
18
- messages = [{"role": "system", "content": system_message}]
19
-
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
25
-
26
- messages.append({"role": "user", "content": message})
27
-
28
- response = ""
29
-
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- demo = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
- ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  )
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
 
63
  if __name__ == "__main__":
64
- demo.launch()
 
1
+
2
+ import os
3
  import gradio as gr
4
+ from langchain_groq import ChatGroq
5
+ from langchain.chains import RetrievalQA
6
+ from langchain.prompts import PromptTemplate
7
+ from langchain.vectorstores import FAISS
8
+ from langchain.embeddings import HuggingFaceEmbeddings
9
+
10
+ # Groq API 키 (Hugging Face Secrets에서 가져옴)
11
+ GROQ_API_KEY = os.environ.get("GROQ_API_KEY")
12
+
13
+ # 전역 변수들
14
+ vectorstore = None
15
+ embeddings = None
16
+
17
+ def load_vectorstore():
18
+ """벡터스토어를 로드하는 함수"""
19
+ global vectorstore, embeddings
20
+
21
+ if vectorstore is None:
22
+ try:
23
+ embeddings = HuggingFaceEmbeddings(
24
+ model_name="sentence-transformers/all-MiniLM-L6-v2"
25
+ )
26
+ vectorstore = FAISS.load_local(
27
+ "vectorstore",
28
+ embeddings,
29
+ allow_dangerous_deserialization=True
30
+ )
31
+ print("✅ 벡터스토어 로드 완료")
32
+ except Exception as e:
33
+ print(f"❌ 벡터스토어 로드 실패: {e}")
34
+ vectorstore = None
35
+
36
+ return vectorstore
37
+
38
+ # 질문 리스트
39
+ suggested_questions = [
40
+ '교원 신규 임용은 어떻게 하나요?',
41
+ '교원 연구년 기간은 어떻게 되나요?',
42
+ '조교 신규 임용 기준은 무엇인가요?',
43
+ '교직원의 평일 근무시간은 어떻게 되나요?',
44
+ '직원 신규 임용 원칙은 무엇인가요?',
45
+ '직원 임용시 가산점이 있나요?',
46
+ '교원 업적의 심사 내용은 무엇인가요?',
47
+ '외국인 교원의 임기는 어떻게 되나요?',
48
+ '외국인 교원의 면직 기준은 무엇인가요?',
49
+ '기간제 계약직의 임기는 얼마정도인가요?',
50
+ '등록금 납부 방법은 무엇인가요?',
51
+ '교직 이수는 언제 신청이 가능한가요?',
52
+ '해외교류유학 지원자격은 어떻게 되나요?',
53
+ '만족도 조사 실행 대상은 누구인가요?',
54
+ '마이크로디그리의 유형은 무엇이 있나요?',
55
+ '장학금 관리 기관은 어디인가요?',
56
+ '학생 단체는 어떻게 등록하나요?',
57
+ '학생 설치물 중 금지된 설치물이 있나요?',
58
+ '비교과 교육과정의 종류는 무엇이 있나요?',
59
+ '안전사고예방계획은 어디에 제출해야 하나요?'
60
+ ]
61
+
62
+ # 프롬프트 템플릿
63
+ prompt_template = """당신은 한남대학교 규정집 도우미입니다.
64
+ 반드시 한국어로만 답변해주세요. 영어나 다른 언어는 절대 사용하지 마세요.
65
+
66
+ 주어진 문서 내용을 바탕으로 질문에 대해 정확하고 친절하게 한국어로 답변해주세요.
67
+
68
+ 참고 문서:
69
+ {context}
70
+
71
+ 질문: {question}
72
+
73
+ 답변 지침:
74
+ - 이용자를 반기는 인사로 시작하세요
75
+ - 반드시 한국어로만 답변하세요
76
+ - 정중하고 친근한 말투를 사용하세요
77
+ - 구체적이고 도움이 되는 정보를 제공하세요
78
+ - 문서에서 답을 찾을 수 없으면 "죄송하지만 해당 정보를 규정집에서 찾을 수 없습니다"라고 답변하세요
79
+
80
+ 한국어 답변:"""
81
+
82
+ prompt = PromptTemplate(
83
+ template=prompt_template,
84
+ input_variables=["context", "question"]
85
  )
86
 
87
+ def respond_with_groq(question, selected_q, model):
88
+ """질문에 대한 답변을 생성하는 함수"""
89
+
90
+ # 선택된 질문이 있으면 그것을 사용
91
+ if selected_q != "직접 입력":
92
+ question = selected_q
93
+
94
+ if not question.strip():
95
+ return "질문을 입력해주세요."
96
+
97
+ if not GROQ_API_KEY:
98
+ return "❌ API 키가 설정되지 않았습니다. 관리자에게 문의하세요."
99
+
100
+ try:
101
+ # 벡터스토어 로드
102
+ current_vectorstore = load_vectorstore()
103
+ if not current_vectorstore:
104
+ return "❌ 벡터스토어를 로드할 수 없습니다."
105
+
106
+ # LLM 설정
107
+ llm = ChatGroq(
108
+ groq_api_key=GROQ_API_KEY,
109
+ model_name=model,
110
+ temperature=0.1,
111
+ max_tokens=1000
112
+ )
113
+
114
+ # QA 체인 생성
115
+ qa_chain = RetrievalQA.from_chain_type(
116
+ llm=llm,
117
+ chain_type="stuff",
118
+ retriever=current_vectorstore.as_retriever(search_kwargs={"k": 3}),
119
+ chain_type_kwargs={"prompt": prompt},
120
+ return_source_documents=True
121
+ )
122
+
123
+ # 답변 생성
124
+ result = qa_chain({"query": question})
125
+ return result['result']
126
+
127
+ except Exception as e:
128
+ return f"❌ 오류가 발생했습니다: {str(e)}"
129
+
130
+ def update_question(selected):
131
+ """드롭다운 선택 시 질문을 업데이트하는 함수"""
132
+ if selected != "직접 입력":
133
+ return selected
134
+ return ""
135
+
136
+ # Gradio 인터페이스 생성
137
+ with gr.Blocks(title="한남대학교 Q&A") as interface:
138
+ gr.HTML("""
139
+ <div style="text-align: center; padding: 20px; background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 10px; margin-bottom: 20px;">
140
+ <h1>🏫 한남대학교 규정집 Q&A</h1>
141
+ <p>한남대학교 규정집에 대한 질문에 AI가 답변해드립니다.</p>
142
+ </div>
143
+ """)
144
+
145
+ with gr.Row():
146
+ with gr.Column(scale=1):
147
+ question_dropdown = gr.Dropdown(
148
+ choices=["직접 입력"] + suggested_questions,
149
+ label="💡 자주 묻는 질문",
150
+ value="직접 입력"
151
+ )
152
+
153
+ question_input = gr.Textbox(
154
+ label="❓ 질문을 입력하세요",
155
+ placeholder="예: 졸업 요건은 무엇인가요?",
156
+ lines=3
157
+ )
158
+
159
+ submit_btn = gr.Button("답변 받기", variant="primary", size="lg")
160
+
161
+ model_choice = gr.Radio(
162
+ choices=["llama3-70b-8192", "llama3-8b-8192"],
163
+ label="🤖 AI 모델 선택",
164
+ value="llama3-70b-8192"
165
+ )
166
+
167
+ with gr.Column(scale=2):
168
+ output = gr.Textbox(
169
+ label="💬 답변",
170
+ lines=15,
171
+ max_lines=20,
172
+ show_copy_button=True
173
+ )
174
+
175
+ # 이벤트 연결
176
+ submit_btn.click(
177
+ fn=respond_with_groq,
178
+ inputs=[question_input, question_dropdown, model_choice],
179
+ outputs=output
180
+ )
181
+
182
+ question_dropdown.change(
183
+ fn=update_question,
184
+ inputs=question_dropdown,
185
+ outputs=question_input
186
+ )
187
 
188
+ # 앱 실행
189
  if __name__ == "__main__":
190
+ interface.launch()
requirements.txt CHANGED
@@ -1 +1,8 @@
1
- huggingface_hub==0.25.2
 
 
 
 
 
 
 
 
1
+ gradio==4.0.2
2
+ langchain==0.1.0
3
+ langchain-groq==0.1.0
4
+ faiss-cpu==1.7.4
5
+ sentence-transformers==2.2.2
6
+ python-dotenv==1.0.0
7
+ pypdf==3.17.0
8
+ tiktoken==0.5.1
vectorstore/index.faiss ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8d595d3dab8036920c1428ccb10fa7ceca4ac06872905aee99b7fa0de7a459b5
3
+ size 854061
vectorstore/index.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:827cc3ca44a0a416f90c9ba15e40fff7bf94e639287d17b317aaf8c96d046ebf
3
+ size 460200