Skip to content

36 언어 감지 노드 추가 #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 83 additions & 1 deletion llm_utils/graph.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import json
import re

from typing_extensions import TypedDict, Annotated
from langgraph.graph import END, StateGraph
Expand All @@ -16,6 +17,7 @@
from llm_utils.tools import get_info_from_db

# 노드 식별자 정의
DETECT_LANGUAGE = "detect_language"
QUERY_REFINER = "query_refiner"
GET_TABLE_INFO = "get_table_info"
TOOL = "tool"
Expand All @@ -31,6 +33,84 @@ class QueryMakerState(TypedDict):
best_practice_query: str
refined_input: str
generated_query: str
language: str
confidence: float
method: str


# 노드 함수: 언어 감지
def detect_language_regex(state: QueryMakerState):
"""
정규표현식을 사용해 텍스트의 언어를 감지하는 함수.

Args:
text (str): 감지할 텍스트

Returns:
dict: 감지된 언어와 관련 정보
"""
# 언어별 고유 문자 패턴 정의
patterns = {
"ko": r"[\u3131-\u3163\uAC00-\uD7A3]", # 한글 (Hangul)
"ja": r"[\u3040-\u309F\u30A0-\u30FF]", # 일본어 (Hiragana, Katakana)
"zh": r"[\u4E00-\u9FFF]", # 중국어 (Han characters)
"ru": r"[\u0400-\u04FF]", # 러시아어 (Cyrillic)
"fr": r"[àâçéèêëîïôûùüÿ]", # 프랑스어 고유 문자
"es": r"[áéíóúñ¿¡]", # 스페인어 고유 문자
"en": r"[a-zA-Z]", # 영어 (기본 Latin alphabet)
}
text = state["messages"][-1].content

# 특수 문자와 공백 제거
cleaned_text = re.sub(r"[!@#$%^&*(),.?\"':{}|<>]", "", text)
cleaned_text = cleaned_text.strip()

if not cleaned_text:
return {"language": None, "confidence": 0.0, "method": "regex"}

# 각 언어별 문자 수 계산
char_counts = {}
total_chars = len(cleaned_text)

for lang, pattern in patterns.items():
matches = re.findall(pattern, cleaned_text)
char_count = len(matches)

# 언어별 가중치 적용
if lang in ["fr", "es"]:
# 프랑스어나 스페인어 고유 문자가 있으면 해당 언어일 가능성이 매우 높음
if char_count > 0:
char_count = total_chars
elif lang == "en":
# 영어는 라틴 알파벳을 공유하는 언어들이 많으므로 가중치 감소
char_count *= 0.8

if char_count > 0:
char_counts[lang] = char_count

if not char_counts:
return {"language": None, "confidence": 0.0, "method": "regex"}

# 가장 많은 문자 수를 가진 언어 선택
detected_lang = max(char_counts, key=char_counts.get)
confidence = char_counts[detected_lang] / total_chars

# 신뢰도 조정
if detected_lang in ["fr", "es"] and confidence > 0.1:
confidence = 0.95 # 고유 문자가 있으면 높은 신뢰도
elif detected_lang == "en":
# 다른 언어의 문자가 없을 때만 영어 신뢰도 상승
other_chars = sum(
char_counts.get(lang, 0) for lang in char_counts if lang != "en"
)
if other_chars == 0:
confidence = 0.95

return {
"language": detected_lang,
"confidence": round(confidence, 4),
"method": "regex",
}


# 노드 함수: QUERY_REFINER 노드
Expand Down Expand Up @@ -134,9 +214,10 @@ def query_maker_node_with_db_guide(state: QueryMakerState):

# StateGraph 생성 및 구성
builder = StateGraph(QueryMakerState)
builder.set_entry_point(QUERY_REFINER)
builder.set_entry_point(DETECT_LANGUAGE)

# 노드 추가
builder.add_node(DETECT_LANGUAGE, detect_language_regex)
builder.add_node(QUERY_REFINER, query_refiner_node)
builder.add_node(GET_TABLE_INFO, get_table_info_node)
# builder.add_node(QUERY_MAKER, query_maker_node) # query_maker_node_with_db_guide
Expand All @@ -145,6 +226,7 @@ def query_maker_node_with_db_guide(state: QueryMakerState):
) # query_maker_node_with_db_guide

# 기본 엣지 설정
builder.add_edge(DETECT_LANGUAGE, QUERY_REFINER)
builder.add_edge(QUERY_REFINER, GET_TABLE_INFO)
builder.add_edge(GET_TABLE_INFO, QUERY_MAKER)

Expand Down