Skip to content

[Feat] 분석 결과를 증거 카드(evidence card) 형태로 시각화 #64

Description

@kite-pp

🏷️ 이슈 유형

  • feat : 새로운 기능 추가
  • fix : 버그 수정
  • refactor : 동작 변경 없는 구조 개선
  • docs : README 등 문서 추가/수정
  • chore : 설정, 빌드, 의존성 패키지 변경
  • 기타 : 설명 추가 작성

💡기능

분석 결과를 위험 점수 하나로만 보여주는 대신, 어떤 신호 때문에 위험하다고 판단했는지를 사용자가 이해할 수 있는 "증거 카드" 형태로 시각화. 예:

위험도 92점 · 매우 위험

탐지된 위험 신호

[기관 사칭]
국민은행을 언급했지만 공식 도메인이 아닙니다.

[행동 압박]
"즉시", "오늘까지" 등 판단을 재촉합니다.

[위험 URL]
단축 URL의 최종 목적지가 의심스럽습니다.

[개인정보 요구]
계좌 또는 인증 정보 입력을 유도합니다.

그 아래 분석 출처도 간단히 표시:

문자 문맥 분석     위험 88
URL 분석          위험 95
금융 규칙 분석     위험 80

중요한 점: 일반 사용자가 이해할 수 있는 표현을 사용 (예: "Gemini가 88점을 줬다"처럼 내부 기술 이름을 그대로 노출하지 않음).

담당: 이건(프론트) + 기범(Python AI, 이 저장소)

📐 v1 범위 (확정)

이미 파이프라인에 존재하는 구조화된 신호만 카드화하고, LLM 트랙은 재설계 없이 단일 카드로 그대로 노출한다. LLM 프롬프트를 바꿔 다중 구조화 지표를 뽑아내는 건 범위 밖(추후 v2 후보).

카테고리 소스
[기관 사칭] app/analysis/institution/analyzer.pyinstitution_match.mismatch
[개인정보 요구] app/analysis/rules/analyzer.py의 계좌번호(_RE_ACCOUNT_NUMBER)/카드번호(_RE_CARD_NUMBER) 패턴 매치
[위험 URL] has_malicious_domain_pattern / URL 트랙 악성 판정
[행동 압박] URGENCY_KEYWORD_CATEGORIES 매치
[AI 판단] LLM(text_analysis.reason) 원문 그대로 노출 — 모델명 등 내부 기술 정보는 절대 노출하지 않음

contribution_breakdown(llm/hybrid_url/rules)은 이미 3분할 점수를 갖고 있으므로, 사용자 노출 시 "문자 문맥 분석 / URL 분석 / 금융 규칙 분석" 라벨로만 매핑하면 되고 추가 계산 로직은 필요 없다.

🛠️할 일 목록

  • EvidenceCategory enum 및 evidence-item 스키마(category, title, description) 정의 (PR Feat(#64): 분석 결과를 사용자 언어 증거 카드로 변환 (v1) #69)
  • analyze_pipeline 출력(institution_match, 계좌/카드 패턴, URL 악성 여부, urgency_categories, LLM reason)을 evidence 리스트로 변환하는 로직 추가 (PR Feat(#64): 분석 결과를 사용자 언어 증거 카드로 변환 (v1) #69) — rules/analyzer.pyhas_account_or_card_pattern/urgency_categories를 구조화 필드로 추가로 노출하는 것도 포함
  • contribution_breakdown 필드를 사용자 노출용 라벨로 매핑 — Spring PR #102에서 ScoreBreakdown 필드 자체를 textScore/urlScore/rulesScore로 정리하고 값도 rawScores 기준으로 변경하면서 해결됨 (Python 쪽 별도 작업 불필요)
  • evidence 리스트 API 계약 확정 — Spring PR #102(저장·REST 노출) + Python PR Feat(#64): RabbitMQ 이벤트에 evidenceCards 필드 추가 #75(RabbitMQ evidenceCards 매핑) 완료, 양쪽 배포됨
  • (이건) evidence 리스트 + 3분할 점수를 받아 카드/막대 UI 구현 — 백엔드 블로커 없음, 프론트 이슈 #81에 정리함

📌 참고 사항 / 제약 조건

  • 사용자에게 노출되는 모든 텍스트는 일반인이 이해할 수 있는 표현으로 작성한다 — "Gemini", "Naive Bayes" 등 내부 기술/모델 이름을 그대로 노출하지 않는다.
  • v1은 기존에 이미 검증된 신호(규칙 엔진, URL 분석, 기관 도메인 대조)만 카드화한다. LLM이 다중 구조화 지표를 직접 반환하도록 프롬프트를 재설계하는 작업은 별도 범위(v2 후보)로 미룬다.
  • API 계약(필드명/타입)은 #57의 institutionMatch 합의 작업과 함께 진용에게 리뷰 요청하는 것을 권장한다 (같은 RuleAnalysisDetail/RabbitMQ 이벤트 확장 작업이므로 따로따로 진행하면 배포 조율 비용이 중복됨).

Refs #57

🔌 Spring API 계약 제안 (진용 리뷰 요청)

Python 쪽(PR #69, 머지·배포됨)에서 다음 스키마로 이미 구현·응답 중입니다. REST(/api/analyze)의 SmishingAnalysisResponse.evidence에는 바로 노출되고 있지만, RabbitMQ 이벤트(AnalysisResultPayload)에는 아직 필드가 없어서 Spring에 전달되지 않습니다. #57의 institutionMatch 때와 같은 패턴으로 계약을 맞추고 싶습니다.

현재 Python 구현 (참고용)

class EvidenceCategory(str, Enum):
    INSTITUTION_IMPERSONATION = "INSTITUTION_IMPERSONATION"
    PERSONAL_INFO_REQUEST = "PERSONAL_INFO_REQUEST"
    DANGEROUS_URL = "DANGEROUS_URL"
    URGENCY_PRESSURE = "URGENCY_PRESSURE"
    AI_JUDGMENT = "AI_JUDGMENT"

class EvidenceItem(BaseModel):
    category: EvidenceCategory
    title: str          # 예: "기관 사칭"
    description: str    # 예: "국민은행을 언급했지만 공식 도메인이 아닙니다."

제안하는 RabbitMQ 필드 위치

institutionMatch는 규칙 엔진 전용 신호라 ruleAnalysis 하위에 넣었지만, evidence는 규칙/URL/텍스트(AI) 트랙을 모두 아우르는 결과라서 AnalysisResultPayload 최상위 필드로 제안합니다.

public record EvidenceCard(
    String category,   // 위 5개 값 중 하나
    String title,
    String description
) {}

// AnalysisResultPayload에 추가
List<EvidenceCard> evidence
  • 0~5개 사이 가변 리스트 (해당 신호가 없으면 카드 자체가 없음)
  • 신호가 하나도 없으면 빈 리스트 []

⚠️ 이름 충돌 주의

Spring AnalysisResultEvent에는 이미 textAnalysis.evidence: List<String> (LLM이 반환하던 옛날 문자열 리스트)가 존재합니다. JSON 경로는 다르지만(payload.evidence vs payload.textAnalysis.evidence) 같은 이름이라 헷갈릴 수 있어서, 최상위 필드명을 **evidenceCards**로 다르게 제안합니다. 이름은 진용 선호대로 맞춰도 무방합니다.

합의 필요한 부분

  1. 최상위 필드명 (evidence vs evidenceCards 등, 기존 textAnalysis.evidence와 구분)
  2. category 값을 Java에서 enum으로 받을지 String으로 받을지
  3. schemaVersion1.0 유지 제안 (순수 추가 필드, institutionMatch 때와 동일 논리)
  4. 배포 순서도 institutionMatch와 동일하게 Spring 먼저 반영 → AI 배포 제안

합의 후 진행할 작업 (Python 측)

  • AnalysisResultPayloadevidence 필드 추가 (RabbitMQ 스키마)
  • result_factory.py에서 build_evidence() 결과를 RabbitMQ 이벤트로 매핑
  • 관련 테스트 추가

Metadata

Metadata

Assignees

Labels

featNew feature or functional additions to the application

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions