Skip to content

Commit f81b927

Browse files
committed
feat: Add detect_language_regex function to detect text language using regex
1 parent 6fb7370 commit f81b927

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed

llm_utils/graph.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
import json
3+
import re
34

45
from typing_extensions import TypedDict, Annotated
56
from langgraph.graph import END, StateGraph
@@ -16,6 +17,7 @@
1617
from llm_utils.tools import get_info_from_db
1718

1819
# 노드 식별자 정의
20+
DETECT_LANGUAGE = "detect_language"
1921
QUERY_REFINER = "query_refiner"
2022
GET_TABLE_INFO = "get_table_info"
2123
TOOL = "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 노드
37114
def query_refiner_node(state: QueryMakerState):
38115
res = query_refiner_chain.invoke(

0 commit comments

Comments
 (0)