Skip to content

Commit a3331ba

Browse files
authored
Merge pull request #22 from hanjuhn/main
fix: intent router 수정
2 parents 81ab32c + e2b92a1 commit a3331ba

6 files changed

Lines changed: 59 additions & 28 deletions

File tree

core/shared/constants/__init__.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
# Shared constants package
22

33
from .constants import (
4-
TARIFF_SESSION_KEYWORDS,
5-
NUMBER_SELECTION_PATTERNS,
64
TARIFF_PREDICTION_KEYWORDS,
75
CUSTOMS_TRACKING_KEYWORDS,
6+
TARIFF_SESSION_KEYWORDS,
7+
NUMBER_SELECTION_PATTERNS,
8+
QUESTION_PATTERNS,
89
INTENT_CLASSIFICATION_PROMPT,
910
INTENT_TYPES,
10-
DEFAULT_INTENT
11+
DEFAULT_INTENT,
12+
SESSION_CHECK_MESSAGE_COUNT
1113
)
1214

1315
from .error_codes import *
1416

1517
__all__ = [
16-
'TARIFF_SESSION_KEYWORDS',
17-
'NUMBER_SELECTION_PATTERNS',
1818
'TARIFF_PREDICTION_KEYWORDS',
1919
'CUSTOMS_TRACKING_KEYWORDS',
20+
'TARIFF_SESSION_KEYWORDS',
21+
'NUMBER_SELECTION_PATTERNS',
22+
'QUESTION_PATTERNS',
2023
'INTENT_CLASSIFICATION_PROMPT',
2124
'INTENT_TYPES',
22-
'DEFAULT_INTENT'
25+
'DEFAULT_INTENT',
26+
'SESSION_CHECK_MESSAGE_COUNT'
2327
]

core/shared/constants/constants.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Shared constants for the entire application
22

3+
# 관세 예측 관련 키워드
4+
TARIFF_PREDICTION_KEYWORDS = [
5+
'코드', 'hs', '관세', '세금', '세율', '관세 계산', '관세 예측', '세금 얼마', '관세 얼마',
6+
'관세 계산해줘', '관세 예측해줘', '세금 예측', '예상 관세', '뭘 샀어', '뭐 샀어', '샀어', '구매',
7+
'저기에', '저기', '그곳에', '그곳', '여기에', '여기', '저기에는', '그곳에는', '여기에는',
8+
'적합하지', '맞지', '틀렸', '잘못', '다른 것', '다른 코드', '새로운', '새로', '다시', '재시도'
9+
]
10+
11+
# 배송 추적 관련 키워드
12+
CUSTOMS_TRACKING_KEYWORDS = [
13+
'운송장', '통관', '조회', '추적', '배송상태', '위치', '도착', '출고', '통관번호', '운송장번호'
14+
]
15+
16+
# 의도 분류 관련 상수들
17+
318
# 관세 예측 세션 관련 키워드
419
TARIFF_SESSION_KEYWORDS = [
520
'hs6 코드 후보', 'hs10 코드 후보', '번호를 선택', '관세 계산', '관세 예측',
@@ -16,18 +31,12 @@
1631
r'^\d{4}\.\d{2}$', # 8471.60 등 HS 코드
1732
]
1833

19-
# 관세 예측 관련 키워드
20-
TARIFF_PREDICTION_KEYWORDS = [
21-
'코드', 'hs', '관세', '세금', '세율', '관세 계산', '관세 예측', '세금 얼마', '관세 얼마',
22-
'관세 계산해줘', '관세 예측해줘', '세금 예측', '예상 관세', '뭘 샀어', '뭐 샀어', '샀어', '구매',
23-
'없다', '코드가 없다', '재예측', '다시', '틀렸다', '맞지 않다', '다른', '새로', '다시 예측', '다른 코드', '적합하지 않다', '코드가 없어',
24-
'저기에', '저기', '그곳에', '그곳', '여기에', '여기', '저기에는', '그곳에는', '여기에는',
25-
'적합하지', '맞지', '틀렸', '잘못', '다른 것', '다른 코드', '새로운', '새로', '다시', '재시도'
26-
]
27-
28-
# 배송 추적 관련 키워드
29-
CUSTOMS_TRACKING_KEYWORDS = [
30-
'운송장', '통관', '조회', '추적', '배송상태', '위치', '도착', '출고', '통관번호', '운송장번호'
34+
# 질문 형태 감지 패턴
35+
QUESTION_PATTERNS = [
36+
r'\?$', # 물음표로 끝나는 경우
37+
r'^어떻게', r'^무엇', r'^언제', r'^어디서', r'^왜', r'^누가',
38+
r'^무슨', r'^어떤', r'^얼마나', r'^어디', r'^언제', r'^왜',
39+
r'알려줘', r'알려주세요', r'궁금해', r'궁금합니다'
3140
]
3241

3342
# 의도 분류 프롬프트
@@ -61,4 +70,8 @@
6170
INTENT_TYPES = ["customs_tracking", "tariff_prediction", "qna"]
6271

6372
# 기본 의도 (오류 시 사용)
64-
DEFAULT_INTENT = "tariff_prediction"
73+
DEFAULT_INTENT = "tariff_prediction"
74+
75+
# 세션 연속성 확인을 위한 메시지 수
76+
SESSION_CHECK_MESSAGE_COUNT = 3
77+

core/shared/router/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Router package
2+
3+
from .intent_router import intent_router
4+
5+
__all__ = [
6+
'intent_router'
7+
]

core/shared/router/intent_router.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
from core.shared.constants import (
77
TARIFF_SESSION_KEYWORDS,
88
NUMBER_SELECTION_PATTERNS,
9+
QUESTION_PATTERNS,
910
INTENT_CLASSIFICATION_PROMPT,
1011
INTENT_TYPES,
11-
DEFAULT_INTENT
12+
DEFAULT_INTENT,
13+
SESSION_CHECK_MESSAGE_COUNT
1214
)
1315

1416
def intent_router(state: CustomsAgentState) -> CustomsAgentState:
@@ -24,6 +26,9 @@ def intent_router(state: CustomsAgentState) -> CustomsAgentState:
2426
is_number_selection = True
2527
break
2628

29+
# 질문 형태 감지
30+
is_question = any(re.search(pattern, current_query) for pattern in QUESTION_PATTERNS)
31+
2732
# 이전 대화에서 관세 예측 중인지 확인
2833
messages = state.get("messages", [])
2934
is_in_tariff_session = False
@@ -33,7 +38,7 @@ def intent_router(state: CustomsAgentState) -> CustomsAgentState:
3338
is_in_tariff_session = True
3439

3540
# 2. 최근 메시지들을 확인하여 관세 예측 세션 중인지 판단
36-
for msg in messages[-5:]: # 최근 5개 메시지 확인
41+
for msg in messages[-SESSION_CHECK_MESSAGE_COUNT:]: # 최근 메시지 확인
3742
if hasattr(msg, 'content') and isinstance(msg.content, str):
3843
content = msg.content.lower()
3944
# 관세 예측 관련 키워드가 있거나 HS 코드 선택 메시지가 있으면 관세 예측 세션으로 판단
@@ -45,22 +50,26 @@ def intent_router(state: CustomsAgentState) -> CustomsAgentState:
4550
if messages and len(messages) > 0:
4651
last_msg = messages[-1]
4752
if hasattr(last_msg, 'content') and isinstance(last_msg.content, str):
48-
if 'tariff_prediction' in last_msg.content:
53+
if 'tariff_prediction' in last_msg.content or '관세 예측 세션' in last_msg.content:
4954
is_in_tariff_session = True
5055

5156
# 관세 예측 세션 중이면 무조건 tariff_prediction으로 분류
5257
if is_in_tariff_session:
5358
state["intent"] = "tariff_prediction" # type: ignore
5459
state["messages"].append(AIMessage(content=f"의도 분류 완료: {state['intent']} (관세 예측 세션 연속성 유지)"))
55-
print(state)
60+
return state
61+
62+
# 질문 형태이면서 관세 예측 세션이 아닌 경우 QnA로 분류
63+
if is_question and not is_in_tariff_session:
64+
state["intent"] = "qna" # type: ignore
65+
state["messages"].append(AIMessage(content=f"의도 분류 완료: {state['intent']} (질문 형태 감지)"))
5666
return state
5767

5868
# 숫자 선택이지만 관세 예측 세션이 아닌 경우에도 tariff_prediction으로 분류
5969
# (HS 코드 직접 입력 등의 경우)
6070
if is_number_selection:
6171
state["intent"] = "tariff_prediction" # type: ignore
6272
state["messages"].append(AIMessage(content=f"의도 분류 완료: {state['intent']} (숫자 선택 감지)"))
63-
print(state)
6473
return state
6574

6675
# LLM 기반 의도 분류를 수행
@@ -75,10 +84,9 @@ def intent_router(state: CustomsAgentState) -> CustomsAgentState:
7584
if intent not in INTENT_TYPES:
7685
intent = DEFAULT_INTENT # 기본값을 tariff_prediction으로 변경
7786
except Exception as e:
78-
print(f"[DEBUG] LLM 분류 오류: {e}")
87+
# LLM 분류 실패 시 기본값 사용
7988
intent = DEFAULT_INTENT # 오류 시에도 tariff_prediction으로 분류
8089

8190
state["intent"] = intent # type: ignore
8291
state["messages"].append(AIMessage(content=f"의도 분류 완료: {intent} (LLM 분류)"))
83-
print(state)
8492
return state

core/tariff_prediction/constants/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@
168168
169169
💡 **상품 묘사의 정확도가 높을수록 정확한 관세 예측이 가능합니다!**
170170
171-
💡 **배송비는 따로 입력받고 있지 않습니다. 국제배송비(직배송)는 관세기준에 포함되지 않지만 현지 배송비는 관세기준에 포함되니 참고하시어 상품 가격과 같이 입력 부탁드립니다!**
171+
💡 **배송비는 따로 입력받고 있지 않습니다. 국제 배송비(직배송)는 관세기준에 포함되지 않지만 현지 배송비는 관세기준에 포함되니 참고하시어 상품 가격에 포함 후 입력 부탁드립니다!**
172172
173173
예시:
174174
\"아랫창은 고무로 되어있고 하얀색 운동화를 80000원에 독일에서 샀어요\"

core/tariff_prediction/tools/parse_tariff_result.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ def parse_tariff_result(tariff_result: str) -> Dict[str, Any]:
3535

3636
# 가격 포맷팅
3737
formatted_price = format_price(parsed['product_price'])
38-
formatted_shipping = format_price(parsed['shipping_cost'])
3938
formatted_tariff = format_price(parsed['tariff_amount'])
4039
formatted_vat = format_price(parsed['vat_amount'])
4140
formatted_total = format_price(parsed['total_tax'])

0 commit comments

Comments
 (0)