Spaces:
Sleeping
Sleeping
Update api.py
Browse files
api.py
CHANGED
@@ -202,6 +202,89 @@ def generate_text_typical(model, prompt, max_len=100, max_gen=98,
|
|
202 |
yield decoded
|
203 |
break
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
async def async_generator_wrapper(prompt: str):
|
206 |
gen = generate_text_typical(model, prompt)
|
207 |
for text_piece in gen:
|
|
|
202 |
yield decoded
|
203 |
break
|
204 |
|
205 |
+
def is_valid_response(response):
|
206 |
+
if len(response.strip()) < 2:
|
207 |
+
return False
|
208 |
+
if re.search(r'[ㄱ-ㅎㅏ-ㅣ]{3,}', response):
|
209 |
+
return False
|
210 |
+
if len(response.split()) < 2:
|
211 |
+
return False
|
212 |
+
if response.count(' ') < 2:
|
213 |
+
return False
|
214 |
+
if any(tok in response.lower() for tok in ['hello', 'this', 'ㅋㅋ']):
|
215 |
+
return False
|
216 |
+
return True
|
217 |
+
|
218 |
+
def extract_main_query(text):
|
219 |
+
sentences = re.split(r'[.?!]\s*', text)
|
220 |
+
sentences = [s.strip() for s in sentences if s.strip()]
|
221 |
+
if not sentences:
|
222 |
+
return text
|
223 |
+
last = sentences[-1]
|
224 |
+
last = re.sub(r'[^가-힣a-zA-Z0-9 ]', '', last)
|
225 |
+
particles = ['이', '가', '은', '는', '을', '를', '의', '에서', '에게', '한테', '보다']
|
226 |
+
for p in particles:
|
227 |
+
last = re.sub(rf'\b(\w+){p}\b', r'\1', last)
|
228 |
+
return last.strip()
|
229 |
+
|
230 |
+
def get_wikipedia_summary(query):
|
231 |
+
cleaned_query = extract_main_query(query)
|
232 |
+
url = f"https://ko.wikipedia.org/api/rest_v1/page/summary/{cleaned_query}"
|
233 |
+
res = requests.get(url)
|
234 |
+
if res.status_code == 200:
|
235 |
+
return res.json().get("extract", "요약 정보를 찾을 수 없습니다.")
|
236 |
+
else:
|
237 |
+
return "위키백과에서 정보를 가져올 수 없습니다."
|
238 |
+
|
239 |
+
def simple_intent_classifier(text):
|
240 |
+
text = text.lower()
|
241 |
+
greet_keywords = ["안녕", "반가워", "이름", "누구", "소개", "어디서 왔", "정체", "몇 살", "너 뭐야"]
|
242 |
+
info_keywords = ["설명", "정보", "무엇", "뭐야", "어디", "누구", "왜", "어떻게", "종류", "개념"]
|
243 |
+
math_keywords = ["더하기", "빼기", "곱하기", "나누기", "루트", "제곱", "+", "-", "*", "/", "=", "^", "√", "계산", "몇이야", "얼마야"]
|
244 |
+
|
245 |
+
if any(kw in text for kw in greet_keywords):
|
246 |
+
return "인사"
|
247 |
+
elif any(kw in text for kw in info_keywords):
|
248 |
+
return "정보질문"
|
249 |
+
elif any(kw in text for kw in math_keywords):
|
250 |
+
return "수학질문"
|
251 |
+
else:
|
252 |
+
return "일상대화"
|
253 |
+
|
254 |
+
def parse_math_question(text):
|
255 |
+
text = text.replace("곱하기", "*").replace("더하기", "+").replace("빼기", "-").replace("나누기", "/").replace("제곱", "*2")
|
256 |
+
text = re.sub(r'루트\s(\d+)', r'math.sqrt(\1)', text)
|
257 |
+
try:
|
258 |
+
result = eval(text)
|
259 |
+
return f"정답은 {result}입니다."
|
260 |
+
except:
|
261 |
+
return "계산할 수 없는 수식이에요. 다시 한번 확인해 주세요!"
|
262 |
+
|
263 |
+
# 전체 응답 함수
|
264 |
+
def respond(input_text):
|
265 |
+
intent = simple_intent_classifier(input_text)
|
266 |
+
|
267 |
+
if "이름" in input_text:
|
268 |
+
return "제 이름은 InteractGPT입니다."
|
269 |
+
|
270 |
+
if "누구" in input_text:
|
271 |
+
return "저는 InteractGPT이라고 해요."
|
272 |
+
|
273 |
+
if intent == "수학질문":
|
274 |
+
return parse_math_question(input_text)
|
275 |
+
|
276 |
+
if intent == "인사":
|
277 |
+
return "반가워요! 무엇을 도와드릴까요?"
|
278 |
+
|
279 |
+
if intent == "정보질문":
|
280 |
+
keyword = re.sub(r"(에 대해|에 대한|에 대해서)?\s*(설명해줘|알려줘|뭐야|개념|정의|정보)?", "", input_text).strip()
|
281 |
+
if not keyword:
|
282 |
+
return "어떤 주제에 대해 궁금한가요?"
|
283 |
+
summary = get_wikipedia_summary(keyword)
|
284 |
+
return f"{summary}\n다른 궁금한 점 있으신가요?"
|
285 |
+
|
286 |
+
return generate_text_typical(input_text)
|
287 |
+
|
288 |
async def async_generator_wrapper(prompt: str):
|
289 |
gen = generate_text_typical(model, prompt)
|
290 |
for text_piece in gen:
|