-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] 점수화 로직 추가 #11
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
[Feat] 점수화 로직 추가 #11
Changes from all commits
4c14646
26985a2
0a4e72d
f86a0e2
1f161cf
a2ac0a0
ea9188e
caf71e0
216b7be
1d31df4
2792d52
1adef5d
922ff2e
ef7fe53
d71b9f3
eba29c1
c313c8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -204,4 +204,4 @@ cython_debug/ | |
| # Marimo | ||
| marimo/_static/ | ||
| marimo/_lsp/ | ||
| __marimo__/ | ||
| __marimo__/ | ||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,131 @@ | ||
| CAT01 기관 사칭형 | ||
| A:30:검찰청|경찰서|금융감독원|형사기동대 | ||
| B:10:사건 송치|수사 협조|조사 회신 | ||
| C:10:문서번호|공문 발송|사건번호 | ||
| D:10:주민등록번호|주소|성명 | ||
| E:10:명의 도용|압수|보안 강화|검찰소환 | ||
| F:10:bit.ly|han.gl|is.gd|vo.la|me2.do|http|https | ||
|
|
||
| CAT02 대출 사기형 | ||
| A:30:은행|농협|신한저축|금융복지정책 | ||
| B:15:대출진행|대환대출|생계자금|정부지원상품 | ||
| C:10:무직자 가능|신용등급 무관|무서류|저금리 | ||
| D:10:신분증|등본|통장사본|재직증명서 | ||
| E:10:신청서.zip|앱설치|.apk|hxxp | ||
| F:5:상담신청|접수완료|한도조회|대표번호 | ||
|
|
||
| CAT03 카드사 사칭형 | ||
| A:30:KB국민카드|현대카드|롯데카드|신한카드|카드 | ||
| B:15:카드 신청완료|카드 발급완료|개통완료 | ||
| C:15:본인 신청 아니면 신고|본인 아닐 경우 문의|본인 아님 신고 | ||
| D:10:개인정보 유출|승인 거절|이상 거래 감지 | ||
| E:5:상담접수|즉시 문의|콜센터|취소 요청 | ||
| F:5:Web발신|승인불가|개통내용 아닌 경우 | ||
|
|
||
| CAT04 돌잔치 초대장형 | ||
| A:35:돌잔치|첫돌|아들 돌잔치|축하해주세요|많이많이 축하 | ||
| B:20:모바일 초대장|초대장을 보내드렸습니다|참석하여 주시기 바랍니다 | ||
| C:5:축복해주세요|모두 축하 | ||
| D:20:oa.to|vo.to|pa.to|pro.ps|.apk|bit.ly|han.gl|is.gd|http|https | ||
|
|
||
| CAT05 모바일 청첩장형 | ||
| A:35:결혼식|재혼|웨딩홀|결혼합니다|사랑의 결실 | ||
| B:20:모바일청첩장|청첩장 도착|청접장|Wedding Invitation | ||
| C:5:축하해주세요|참석 부탁|인연으로 하나됩니다 | ||
| D:20:han.gl|bit.ly|c11.kr|na.to|.apk|is.gd|vo.la|me2.do|http|https | ||
|
|
||
| CAT06 부고문자형 | ||
| A:40:별세|소천|사망하셨습니다|부고|訃告 | ||
| B:10:아버님|어머님|부모님|부친|모친 | ||
| C:10:삼가 고인의 명복|안타깝게도|불행하게도 | ||
| D:10:장례식장|빈소|오시는 길 | ||
| E:10:buly.kr|vo.la|iplogger.com|xgo.kr|gg.gg|bit.ly|han.gl|is.gd|http|https | ||
|
|
||
| CAT07 범칙금/과태료 부과형 | ||
| A:30:도로교통법 위반|정지선 위반|어린이 보호구역 | ||
| B:15:과태료 부과|벌점 통지서|고지서 발송|가압류|장기연체대상자 | ||
| C:10:민원24|신고 접수|단속되어|민원내용 확인 | ||
| D:10:쓰레기 무단투기|음식물분리수거 위반|층간소음행위 | ||
| E:10:관세청|수입세금|관세징수과|통관번호|세금 미납 안내 | ||
| F:5:paso.mobilecar.pe.kr|goosmsi.com|homes|mobilecar|bit.ly|han.gl|is.gd|http|https | ||
|
|
||
| CAT08 건강보험공단 사칭형 | ||
| A:35:국민건강보험|건강보험공단|건강지키미 | ||
| B:10:건강검진 통지서|건강검사 통보문|종합건강검진 | ||
| C:15:환급금 신청마감|보험료 환급금|건강보험료 미납 | ||
| D:10:확인바랍니다|조회하기|신청요망 | ||
| E:10:dokdo.in|nhisis.xyz|cloud|nhis|nhi|bit.ly|han.gl|is.gd|http|https | ||
|
|
||
| CAT09 경찰 출석 요구형 | ||
| A:30:검찰청|경찰서|법원|국정원 | ||
| B:10:출석요구서|소환장|사건조회번호 | ||
| C:10:형사소송건|민사소송|재산몰수 통지서 | ||
| D:10:긴급출석요구|발부되었습니다|즉시 확인 | ||
| E:10:사건번호|고단 | ||
| F:10:sc-police.co.kr|xuto.tk|is.gd|bit.ly|han.gl|http|https | ||
|
|
||
| CAT10 국세청 사칭형 | ||
| A:35:국세청|홈택스|국민연금공단|납세자연맹 | ||
| B:10:종합소득세|연말정산|세금 미납|세금 환급금 | ||
| C:15:환급 대상자|환급금 수령|금액 확인|환급 내역 조회 | ||
| D:10:신청하세요|수령 확인|조회 및 납부|통지서 확인 | ||
| E:10:han.gl|goo.gl|me2.do|hometax.go.kr|bit.ly|is.gd|http|https | ||
|
|
||
| CAT11 알바/부업 사기형 | ||
| A:30:재택근무|단기 알바|쉬운 업무|문자 알바 | ||
| B:15:시급 3만원|고수익 보장|일 10만 이상|당일 정산 | ||
| C:10:누구나 가능|자격무관|당일 지급 | ||
| D:15:오픈채팅|카톡 추가|링크 클릭|접속하세요 | ||
| E:10:open.kakao.com|bit.ly|t.me|reurl.kr|han.gl|is.gd|http|https | ||
|
|
||
|
Comment on lines
+75
to
+80
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 오퍼 유도형(알바/투자) 규칙의 강한 미끼 단어 가중치 재점검
권장:
현재 데이터 파일만으로는 AND 로직을 표현하기 어렵다면, 프롬프트/파서 레벨에서 “동시 매칭 보너스”를 구현하는 방향을 검토해 주세요. Also applies to: 103-111 🤖 Prompt for AI Agents |
||
| CAT12 정부지원금 위장형 | ||
| A:30:재난지원금|방역지원금|민생안정지원금 | ||
| B:10:국세청|고용노동부|중소벤처기업부 | ||
| C:10:신청마감|신속지급|신청하기 클릭 | ||
| D:10:신분증 사본|본인 확인|제출서류 | ||
| E:10:예산소진|원 도착|예산 초과 시 부지급 | ||
| F:5:bit.ly|han.gl|is.gd|me2.do|vo.la|http|https | ||
| G:5:민생 회복|꼭 확인해주세요|확인 안 될 경우 미지급 | ||
|
|
||
| CAT13 택배 사기형 | ||
| A:30:택배|쿠팡|택배기사 | ||
| B:15:주소 오류|주소 불일치|배송지 오류|주소 확인 요망 | ||
| C:15:배송 지연|배송 실패|미수령 택배|통관번호 오류 | ||
| D:10:bit.ly|han.gl|is.gd|vo.la|me2.do|http|https | ||
| E:10:앱 다운로드|배송조회 바로가기|주소 입력 페이지 | ||
|
|
||
| CAT14 가상화폐 사기형 | ||
| A:30:소각 예정|자산 복구|소멸 예정|휴면계정 소각 | ||
| B:20:해외IP 로그인|로그인 감지|수상한 기기|기기등록 후 사용|본인이 아닐 경우|로그인 알림 | ||
| C:15:ETH|BTC|이더리움|비트코인|테더|잔여 ETH | ||
| D:15:line.me|bit.ly|me2.kr|카톡|상담 바로가기|t.me|http|https | ||
|
|
||
| CAT15 주식투자 사기형 | ||
| A:35:고수익|수익보장|원금보장|손실보상 | ||
| B:15:에넥스|덕신하우징|2차전지|바이오|유진테크놀로지 | ||
| C:5:bit.ly|t.me|open-kakao|open.kakao|han.gl|reurl.kr|is.gd|http|https | ||
| D:5:쿠폰 증정|단타 무료방|무료혜택|선착순 모집 | ||
| E:10:단타|매수|매도|수급|테마|상장특별공급|종목추천 | ||
| F:5:지금 가입|링크 클릭|바로 입장|채팅방 이동|666 | ||
| G:5:마지막 기회|안정수익|실시간 인증|장마감공개 | ||
|
|
||
| CAT16 청약 공모주 사기형 | ||
| A:30:공모주|청약|상장예정|IPO|무료배정 | ||
| B:15:미래에셋|신한증권|하나증권|증권사|청약담당자 | ||
| C:15:할인공급가|수익률|급등|이익률 | ||
| D:10:문자상담|상담전화|빠른회신|순차연락 | ||
| E:5:할인혜택|무상입고|무료거부|종목확인|IR안내 | ||
| F:5:두산로보틱스|이노스페이스|APR|에이피알 | ||
|
|
||
| CAT17 허위결제 사기형 | ||
| A:35:결제완료|승인요청|인증번호|해외승인|본인아님 | ||
| B:15:신용카드|휴대폰결제|이니시스|모빌리언스|위메프|아마존 | ||
| C:15:단축URL|의심URL|IP링크|http|https|hxxp|hxxps|bit.ly|han.gl|is.gd|vo.la|me2.do | ||
| D:15:고객센터|소비자보호|문의전화|신고요청 | ||
|
|
||
| CAT18 가족/지인 사칭형 | ||
| A:30:가족|친구|지인 | ||
| B:15:폰고장|액정깨짐|임시폰|문자접속 | ||
| C:15:급해|갚을게|부탁|수리중|지금바로 | ||
| D:10:송금|계좌이체|기프트카드|입금요청 | ||
| E:10:신분증|주민번호|카드사진|인증번호 | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,41 +1,58 @@ | ||||||||||||||||||||||||||
| from typing import List, Dict | ||||||||||||||||||||||||||
| from pathlib import Path | ||||||||||||||||||||||||||
| from app.prompts.fraud_example import FraudExample | ||||||||||||||||||||||||||
| from app.prompts.data.fraud_examples import FRAUD_EXAMPLES | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| SYSTEM_PROMPT = """ | ||||||||||||||||||||||||||
| 너는 보이스피싱 사기 탐지 전문가다. | ||||||||||||||||||||||||||
| 다음 규칙표를 사용해 입력 텍스트를 분석하고, | ||||||||||||||||||||||||||
| 1) 사기 유형(카테고리) 선택 | ||||||||||||||||||||||||||
| 2) 핵심 키워드(최소1~최대3) 추출 | ||||||||||||||||||||||||||
| 3) 점수는 최소 0점에서 최대 70점 | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| [점수 규칙] | ||||||||||||||||||||||||||
| - 규칙표는 "카테고리ID 카테고리명" 한 줄 + 그 아래 여러 룰 라인으로 구성된다. | ||||||||||||||||||||||||||
| - 룰 라인 형식: "룰ID:배점:키워드1|키워드2|...". | ||||||||||||||||||||||||||
| - 텍스트에 해당 룰의 키워드 중 1개라도 의미/표현상 매칭되면 그 룰의 배점을 가산(룰별 최대 1회). | ||||||||||||||||||||||||||
| - 유저가 입력한 'keywords'에서 점수 계산을 하고, 'additionalDescription'과 'imageContent'를 참고하여 점수 계산. | ||||||||||||||||||||||||||
| - 키워드는 의미가 같으면 띄어쓰기/대소문자/오타 등과 동의어 허용. | ||||||||||||||||||||||||||
| - 동일 카테고리에서 여러 룰이 적중할 수 있으며, 합산 후 카테고리 점수는 70을 초과하지 않는다(상한 70점). | ||||||||||||||||||||||||||
| - 최종적으로 가장 점수가 높은 카테고리를 estimatedFraudType으로 선택. | ||||||||||||||||||||||||||
| - 동점이면 적중 룰 개수가 더 많은 카테고리를 선택. 그래도 동률이면 의미상 더 근접한 쪽. | ||||||||||||||||||||||||||
| - 링크/단축URL은 http/https, bit.ly/han.gl/is.gd/vo.la/me2.do 등도 매칭으로 본다(표기 변형 허용). | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| 출력은 반드시 valid JSON 객체로만 응답. 오직 JSON만 출력. | ||||||||||||||||||||||||||
| 코드블록(```), 주석, 추가 텍스트, 설명 모두 금지. | ||||||||||||||||||||||||||
| 'estimatedFraudType' 에는 오로지 카테고리명만 넣을 것. | ||||||||||||||||||||||||||
| 아래는 응답 예시. | ||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||
| "estimatedFraudType": "<카테고리명>", | ||||||||||||||||||||||||||
| "keywords": ["<키워드1>", "<키워드2>", "<키워드3>"], | ||||||||||||||||||||||||||
| "explanation": "<왜 이 유형이고 어떤 이유로 판단하였는지 간결히 설명>", | ||||||||||||||||||||||||||
| "score": <0~70의 실수값> | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| """.strip() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| def _load_rules() -> str: | ||||||||||||||||||||||||||
| rules_path = Path(__file__).parent / "data" / "score_rules.txt" | ||||||||||||||||||||||||||
| return rules_path.read_text(encoding="utf-8") | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
Comment on lines
+38
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion 규칙 파일 매 요청 디스크 로드 — 캐싱 및 예외 처리 추가 권장 현재 매 호출마다 파일 I/O가 발생합니다. LRU 캐싱과 파일 없을 때의 명확한 예외로 신뢰성을 높이세요. 해당 범위 내 수정(diff) 및 추가 import: +from functools import lru_cache
@@
-def _load_rules() -> str:
- rules_path = Path(__file__).parent / "data" / "score_rules.txt"
- return rules_path.read_text(encoding="utf-8")
+@lru_cache(maxsize=1)
+def _load_rules() -> str:
+ rules_path = Path(__file__).parent / "data" / "score_rules.txt"
+ try:
+ return rules_path.read_text(encoding="utf-8")
+ except FileNotFoundError as e:
+ raise RuntimeError(f"규칙 파일을 찾을 수 없습니다: {rules_path}") from e📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
| def get_fraud_detection_prompt( | ||||||||||||||||||||||||||
| message_content: str, | ||||||||||||||||||||||||||
| additional_description: str, | ||||||||||||||||||||||||||
| keywords: List[str], | ||||||||||||||||||||||||||
| image_content: str, | ||||||||||||||||||||||||||
| examples: List[FraudExample] = FRAUD_EXAMPLES | ||||||||||||||||||||||||||
| ) -> List[Dict[str, str]]: | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| system = { | ||||||||||||||||||||||||||
| "role": "system", | ||||||||||||||||||||||||||
| "content": ( | ||||||||||||||||||||||||||
| "당신은 사기 탐지 어시스턴트입니다. " | ||||||||||||||||||||||||||
| "입력된 텍스트를 반드시 미리 정의된 사기 유형 중 하나로 분류하고, " | ||||||||||||||||||||||||||
| "최소 1개에서 최대 3개의 주요 위험 키워드를 추출하며, 그 이유를 설명하고, " | ||||||||||||||||||||||||||
| "위험 점수(0–100%)를 제공해야 합니다.\n" | ||||||||||||||||||||||||||
| "출력은 반드시 valid JSON 객체로만 응답하세요. 아래는 응답 예시입니다:\n" | ||||||||||||||||||||||||||
| "{\n" | ||||||||||||||||||||||||||
| " \"estimatedFraudType\": \"복권 사기\",\n" | ||||||||||||||||||||||||||
| " \"keywords\": [\"키워드1\", \"키워드2\"],\n" | ||||||||||||||||||||||||||
| " \"explanation\": \"...\",\n" | ||||||||||||||||||||||||||
| " \"score\": 92.4\n" | ||||||||||||||||||||||||||
| "}\n" | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| rules_text = _load_rules() | ||||||||||||||||||||||||||
| example_text = "".join(build_example_lines(examples)) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| example_lines = build_example_lines(examples) | ||||||||||||||||||||||||||
| assistant_content = "".join(example_lines) | ||||||||||||||||||||||||||
| assistant_content += ( | ||||||||||||||||||||||||||
| "이제 아래 입력을 같은 형식으로 분류하세요:\n" | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| assistant = { | ||||||||||||||||||||||||||
| "role": "assistant", | ||||||||||||||||||||||||||
| "content": assistant_content | ||||||||||||||||||||||||||
| system = { | ||||||||||||||||||||||||||
| "role": "system", | ||||||||||||||||||||||||||
| "content": f"{SYSTEM_PROMPT}\n\n[규칙표]\n{rules_text}\n\n[예시]\n{example_text}" | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| user = { | ||||||||||||||||||||||||||
|
|
@@ -48,7 +65,8 @@ def get_fraud_detection_prompt( | |||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return [system, assistant, user] | ||||||||||||||||||||||||||
| return [system, user] | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| def build_example_lines(examples): | ||||||||||||||||||||||||||
| example_lines = ["사기 유형 및 예시:\n"] | ||||||||||||||||||||||||||
|
|
@@ -57,11 +75,5 @@ def build_example_lines(examples): | |||||||||||||||||||||||||
| example_lines.append(f" messageContent: '{ex.message_content}'\n") | ||||||||||||||||||||||||||
| example_lines.append(f" additionalDescription: '{ex.additional_description}'\n") | ||||||||||||||||||||||||||
| example_lines.append(f" keywords: '{ex.keywords}'\n") | ||||||||||||||||||||||||||
| example_lines.append(f" imageContent: '{ex.image_content}'\n") | ||||||||||||||||||||||||||
| example_lines.append(" 출력 JSON 예시:\n") | ||||||||||||||||||||||||||
| example_lines.append( | ||||||||||||||||||||||||||
| f" {{\"estimatedFraudType\": \"{ex.type_name}\", " | ||||||||||||||||||||||||||
| f"\"keywords\": [...], \"explanation\": \"...\", \"score\": ...}}\n\n" | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| return example_lines | ||||||||||||||||||||||||||
| return example_lines | ||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
http/https 범용 토큰은 과도한 오탐 위험 — 일반 링크 토큰 제거/가중치 하향 권고
여러 규칙에서 http|https 같은 범용 토큰이 포함되어 있습니다(예: 라인 7, 29, 123). 이는 거의 모든 정상 메시지에도 존재하는 신호라 오탐을 크게 높입니다. 단축 URL/의심 도메인만 유지하고, 일반 프로토콜 토큰은 제거하거나 가중치를 크게 낮추는 것을 권장합니다.
예시로 아래와 같이 최소 수정안을 제안드립니다(패턴 유지, 오탐 감소 목표).
추가로, 일반 링크 토큰을 반드시 유지해야 한다면 가중치를 1~2로 낮춰 다른 강한 신호와의 동시 출현에서만 임계치를 넘기도록 구성하는 것을 추천합니다.
Also applies to: 29-29, 123-123
🤖 Prompt for AI Agents