11import os
22import json
3+ import re
34
45from typing_extensions import TypedDict , Annotated
56from langgraph .graph import END , StateGraph
1617from llm_utils .tools import get_info_from_db
1718
1819# 노드 식별자 정의
20+ DETECT_LANGUAGE = "detect_language"
1921QUERY_REFINER = "query_refiner"
2022GET_TABLE_INFO = "get_table_info"
2123TOOL = "tool"
@@ -33,6 +35,81 @@ class QueryMakerState(TypedDict):
3335 generated_query : str
3436
3537
38+ # 노드 함수: 언어 감지
39+ def detect_language_regex (state : QueryMakerState ):
40+ """
41+ 정규표현식을 사용해 텍스트의 언어를 감지하는 함수.
42+
43+ Args:
44+ text (str): 감지할 텍스트
45+
46+ Returns:
47+ dict: 감지된 언어와 관련 정보
48+ """
49+ # 언어별 고유 문자 패턴 정의
50+ patterns = {
51+ "ko" : r"[\u3131-\u3163\uAC00-\uD7A3]" , # 한글 (Hangul)
52+ "ja" : r"[\u3040-\u309F\u30A0-\u30FF]" , # 일본어 (Hiragana, Katakana)
53+ "zh" : r"[\u4E00-\u9FFF]" , # 중국어 (Han characters)
54+ "ru" : r"[\u0400-\u04FF]" , # 러시아어 (Cyrillic)
55+ "fr" : r"[àâçéèêëîïôûùüÿ]" , # 프랑스어 고유 문자
56+ "es" : r"[áéíóúñ¿¡]" , # 스페인어 고유 문자
57+ "en" : r"[a-zA-Z]" , # 영어 (기본 Latin alphabet)
58+ }
59+ text = state ["messages" ][- 1 ].content
60+
61+ # 특수 문자와 공백 제거
62+ cleaned_text = re .sub (r"[!@#$%^&*(),.?\"':{}|<>]" , "" , text )
63+ cleaned_text = cleaned_text .strip ()
64+
65+ if not cleaned_text :
66+ return {"language" : None , "confidence" : 0.0 , "method" : "regex" }
67+
68+ # 각 언어별 문자 수 계산
69+ char_counts = {}
70+ total_chars = len (cleaned_text )
71+
72+ for lang , pattern in patterns .items ():
73+ matches = re .findall (pattern , cleaned_text )
74+ char_count = len (matches )
75+
76+ # 언어별 가중치 적용
77+ if lang in ["fr" , "es" ]:
78+ # 프랑스어나 스페인어 고유 문자가 있으면 해당 언어일 가능성이 매우 높음
79+ if char_count > 0 :
80+ char_count = total_chars
81+ elif lang == "en" :
82+ # 영어는 라틴 알파벳을 공유하는 언어들이 많으므로 가중치 감소
83+ char_count *= 0.8
84+
85+ if char_count > 0 :
86+ char_counts [lang ] = char_count
87+
88+ if not char_counts :
89+ return {"language" : None , "confidence" : 0.0 , "method" : "regex" }
90+
91+ # 가장 많은 문자 수를 가진 언어 선택
92+ detected_lang = max (char_counts , key = char_counts .get )
93+ confidence = char_counts [detected_lang ] / total_chars
94+
95+ # 신뢰도 조정
96+ if detected_lang in ["fr" , "es" ] and confidence > 0.1 :
97+ confidence = 0.95 # 고유 문자가 있으면 높은 신뢰도
98+ elif detected_lang == "en" :
99+ # 다른 언어의 문자가 없을 때만 영어 신뢰도 상승
100+ other_chars = sum (
101+ char_counts .get (lang , 0 ) for lang in char_counts if lang != "en"
102+ )
103+ if other_chars == 0 :
104+ confidence = 0.95
105+
106+ return {
107+ "language" : detected_lang ,
108+ "confidence" : round (confidence , 4 ),
109+ "method" : "regex" ,
110+ }
111+
112+
36113# 노드 함수: QUERY_REFINER 노드
37114def query_refiner_node (state : QueryMakerState ):
38115 res = query_refiner_chain .invoke (
0 commit comments