Skip to content

[Feat] 외부 AI 장애 시 안전모드 (fail-safe mode) #70

Description

@kite-pp

🏷️ 이슈 유형

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

💡기능

LLM, VirusTotal, Google Safe Browsing 중 하나가 실패해도 앱 전체(분석 파이프라인)가 멈추지 않고, 나머지 신호로 보수적인 판정을 내려야 한다.

결과 화면 예시

현재 외부 URL 조회가 지연되고 있습니다.

문자 문맥 및 금융사기 규칙 분석 결과:
주의가 필요한 문자입니다.

외부 링크를 열지 말고 공식 앱에서 확인하세요.

테스트할 상황

  • LLM 응답 지연
  • VirusTotal 사용량 제한
  • Google Safe Browsing 실패
  • RabbitMQ 재연결
  • 같은 요청 중복 수신
  • FastAPI 재시작

시연 시나리오

외부 분석 서비스 1개 장애
→ 전체 분석 중단 없음
→ 정상 작동한 분석 결과로 PARTIAL 응답
→ 사용자에게 보수적인 주의 안내

담당: 진용(Spring Boot) + 기범(Python AI) + 이건(프론트)

🔍 현황 감사 결과 (기범)

기존 코드를 감사한 결과 대부분 이미 구현돼 있었고, 진짜 작업량은 예상보다 훨씬 적었다.

  • LLM 응답 지연: BedrockLlmClientasyncio.wait_for + boto3 자체 타임아웃/재시도가 이중으로 걸려있음. 타임아웃 시 LLM_TIMEOUT 에러코드로 우아하게 실패 처리(grade UNKNOWN). 테스트 있음.
  • PARTIAL + 보수적 안내 패턴: AnalysisExecutionStatus.PARTIAL + failedTracks 구조가 이미 있고, RiskScoringEngineBOTH_ENGINES_UNAVAILABLE_FALLBACK_SCORE=80, PIPELINE_FAILURE_FALLBACK_SCORE=50 같은 명시적 fail-safe(비관적 기본값) 상수로 fail-open을 방지하고 있음.
  • VirusTotal 사용량 제한 / Google Safe Browsing 실패: 코드상 처리 로직은 있었지만 테스트가 없었음(GSB는 테스트 파일 자체가 없었음) → 테스트 보강 완료.
  • 같은 요청 중복 수신(멱등성): Spring 쪽에 이미 구현·반영돼 있음 확인 (userId+clientMessageId 기준 중복 요청 시 기존 분석 결과 반환, 동시 요청은 DB unique 제약으로 차단, 분석 저장과 Outbox 생성이 같은 트랜잭션, AI 결과도 eventId 기준 중복 반영 방지). Python 쪽은 결과 이벤트 eventId를 요청 eventId 기준으로 결정론적으로 생성하고 있어(result_factory.py) 재전달이 발생해도 Spring의 eventId 기준 dedup에 자동으로 걸러짐 — 추가 작업 불필요.
  • RabbitMQ 재연결: reconnect_callbacks/close_callbacks에 로깅 핸들러 등록 완료 (PR Test(#70): VT/GSB 장애 경로 및 하이브리드 폴백 테스트 보강 #71) — 재연결 시 경고 로그, 예기치 못한 단절과 정상 종료를 구분해 기록. 토폴로지 재선언은 aio_pika가 자동 처리하므로 별도 로직 불필요.
  • FastAPI 재시작: graceful shutdown 자체는 구현됨(consumer.stop()이 in-flight task를 bounded timeout으로 정리). 타임아웃 초과 시 unacked 메시지가 재전달될 수 있으나, 멱등성이 이미 처리되어 있어 실질적 위험은 낮음 — 추가 조치 불필요로 결론.
  • (이건) PARTIAL 응답의 보수적 안내 메시지 UI 노출 — API 쪽 블로커 해소 확인됨: Spring AnalysisResponsefailedTracks가 이미 노출 중(SafeFam_BE PR Experiment(#78): Stacking 단독 운영을 위한 v2 재학습 및 성능 검증 #82, 8/8 머지). 이건한테 전달 완료, 실제 UI 구현은 프론트 저장소에서 진행.

✅ 결론

백엔드(Python) 쪽 작업은 전부 완료(PR #71 머지·배포됨). 남은 건 이건의 프론트 UI 구현뿐이며, 이는 API 블로커가 없어 바로 진행 가능한 상태.

📌 참고 사항

  • 멱등성은 Spring이 이미 처리하고 있어 이번 이슈 범위에서 제외. 단, clientMessageId가 없으면 멱등 처리가 안 된다고 하니, 실제 클라이언트가 이 값을 항상 채워 보내는지는 별도 확인 권장.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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