Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Choa0Kim/VoiceGuardian_mean-win

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

45 Commits

Repository files navigation

VoiceGuardian_mean-win

기간: 2026年01月14日 ~ 2026年02月11日 10:00

브랜치 관리는 추후에

1. GitHub 관련 명령어

0. 깃허브 파일을 clone 하기
git clone https://github.com/Choa0Kim/VoiceGuardian_mean-win.git .
1. 매일 아침 Pull 받아서 최신화 하기
git fetch
git pull origin main
2. 마무리 작업
git add .
git commit -m "Commit Message" // gitmoji -c
git push origin main

2. Gitmoji로 Commit Message 남기기

ex) ✨ Feat: LLM에게 프롬프팅 설정 완료

Icon Feat
Feat 새로운 기능 추가
🐛 Fix 버그/기능에 따른 코드 변경 시
♻️ Refactor 코드의 가독성, 효율성을 위한 코드 변경 시 (기능의 문제 X)
📝 Docs 문서 추가/수정/삭제
🔧 Chore 설정 추가/변경
Test 테스트 코드 추가/수정

3. 프로젝트 구조

.
├── app.py # Streamlit 웹 UI 진입점
├── requirements.txt # Python 의존성
├── .env.example # 환경변수 템플릿
│
├── src/
│ ├── config.py # 전역 설정 (LLM, RAG, PII, STT/TTS, LangSmith)
│ ├── main.py # CLI 실행 진입점
│ │
│ ├── agents/ # 에이전트 모듈
│ │ ├── master.py # Master Agent — 대화 흐름 총괄, 시나리오 유형 결정, 하위 에이전트 지시
│ │ ├── roleplay_agent.py # Roleplay Agent — 사기범/정상 담당자 역할 대사 생성
│ │ ├── evaluator.py # Evaluator Agent — 사용자 응답 평가 (KcELECTRA / LLM 이중 경로)
│ │ └── guardian.py # Guardian Agent — 위험 경고, 교육 메시지, 정상 시나리오 피드백
│ │
│ ├── evaluator/ # PII 탐지 모델 (KcELECTRA 파인튜닝, CPU 전용)
│ │ └── pii_model.py # beomi/KcELECTRA-base-v2022 기반 이진 분류 (Safe/PII)
│ │
│ ├── graph/ # LangGraph 워크플로우
│ │ ├── state.py # 공유 상태 정의 (VoiceGuardianState)
│ │ └── workflow.py # StateGraph 구성, interrupt 기반 노드/엣지 연결
│ │
│ ├── voice/ # 음성 처리 (STT/TTS)
│ │ ├── stt.py # OpenAI Whisper API 기반 음성→텍스트
│ │ └── tts.py # edge-tts 기반 텍스트→음성
│ │
│ ├── tools/ # 공용 도구 (여러 에이전트가 공유)
│ │ └── voice_phishing_rag.py # ChromaDB 기반 보이스피싱 뉴스 RAG
│ │
│ ├── utils/ # 유틸리티
│ │ ├── llm.py # 에이전트별 ChatAnthropic 싱글톤 관리
│ │ ├── memory.py # 단기 메모리 (10턴) + 장기 메모리 (5턴 주기 요약)
│ │ └── rag.py # RAG 컨텍스트 빌드 공통 래퍼 (search → format 통합)
│ │
│ ├── collect_news/ # 뉴스 수집 파이프라인
│ │ ├── naver_to_BS_article.py # 매일경제 뉴스 크롤링
│ │ └── with_ChromaDB.py # 크롤링 데이터 → ChromaDB 벡터 적재
│ │
│ └── make_test_set/ # 테스트 데이터셋 생성
│ ├── connet_db.py
│ └── make_json.py
│
├── Data/
│ ├── chroma_db/ # ChromaDB 벡터 데이터베이스 (로컬 파일)
│ └── news/ # 수집된 뉴스 JSON
│
└── SQLite3/ # 사용자 더미 데이터 DB

4. 시스템 아키텍처

LangGraph 기반 멀티 에이전트 워크플로우로, 4개의 에이전트 + interrupt() 기반 human-in-the-loop 구조입니다.

VoiceGuardian 워크플로우

노드 역할 LLM Temperature
Master 대화 흐름 총괄, 시나리오 유형 결정(피싱/정상), 하위 에이전트 지시 생성 0.3
Roleplay 사기범 또는 정상 기관 담당자 역할 대사 생성 (뉴스 RAG 참고) 0.8
Evaluate 사용자 응답 평가 — KcELECTRA PII 모델 또는 LLM으로 개인정보 노출 / 거절 감지 (피싱 시나리오 전용) 0.0
Guardian 위험 경고 + 교육 메시지 / 훈련 종료 피드백 / 정상 시나리오 피드백 0.5
human_input interrupt()로 사용자 입력 대기 (그래프 일시정지)

워크플로우 흐름 (interrupt 기반):

피싱 시나리오 (~70%):

[START] → master ──┬──→ roleplay → human_input → master (루프)
 ├──→ evaluate ──┬──→ roleplay (safe)
 │ └──→ guardian (danger)
 └──→ human_input (주제 선택 대기)
guardian ──┬──→ human_input (위험 경고 후 대화 계속)
 └──→ END (세션 종료)

정상 시나리오 (~30%):

[START] → master ──→ roleplay → human_input → master ─┬─→ roleplay (대화 계속)
 ├─→ guardian → END (자연 종료)
 └─→ guardian → END (오인 거절)
  • interrupt() + Command(resume=...) 구조로 전체 세션이 하나의 LangSmith trace로 추적됨
  • InMemorySaver checkpointer를 사용하여 그래프 상태를 유지
  • 사용자는 시나리오가 피싱인지 정상인지 모르는 상태에서 대응 → 종료 후 Guardian이 유형을 알려주며 피드백

종료 조건:

시나리오 유형 조건 Guardian 피드백
피싱 사용자가 사기범의 요구를 2회 거절 칭찬 + 사기 패턴 분석 + 대응 팁
피싱 최대 20턴 도달 + 거절 부족 취약점 강력 경고 + 대처법 안내
정상 업무 대화가 자연스럽게 종료 정상 전화였음 안내 + 피싱 구분법
정상 사용자가 정상 전화를 사기로 오인 거절 격려 + 정상/피싱 구분법 교육

5. 에이전트 상세

5-1. Master Agent (src/agents/master.py)

  • 전체 훈련 흐름을 관리하는 오케스트레이터
  • 사용자 입력으로부터 시나리오 주제를 추출 (LLM 기반 파싱)
  • 시나리오 유형 결정: ChromaDB 검색 후 확률적으로 피싱(~70%) / 정상(~30%) 시나리오 배정
  • 시나리오 시작 시 RAG에서 뉴스 사례를 검색하여 scenario_context에 저장
  • 피싱 시나리오: current_phase에 따라 다음 노드를 결정하는 라우팅 로직 담당
  • 정상 시나리오: LLM structured output으로 대화 자연 종료 여부와 오인 거절(False Positive)을 직접 판단

5-2. Roleplay Agent (src/agents/roleplay_agent.py)

  • scenario_type에 따라 다른 시스템 프롬프트로 대사 생성:
    • 피싱: Master의 지시 + RAG 뉴스 사례를 참고하여 사기범 역할 대사 생성. 사용자 의심/거절 시 더 강압적이거나 회유하는 자연스러운 반응
    • 정상: 실제 기관의 정당한 담당자 역할. 개인정보 요구 금지, 정중한 말투, 자연스러운 업무 대화 흐름 유지
  • 메모리 관리: 5턴마다 장기 요약 생성, 최근 10턴만 단기 메모리에 유지
  • LLM 호출 실패 시 폴백 대사로 시나리오 유지

5-3. Evaluator Agent (src/agents/evaluator.py)

  • 피싱 시나리오에서만 호출 (정상 시나리오는 Master가 직접 판단)
  • 이중 평가 경로 (PII_USE_LOCAL_MODEL 환경변수로 제어):
    • true (기본): KcELECTRA 파인튜닝 모델로 PII 탐지 + 정규식 거절 감지 (모델 실패 시 LLM 자동 폴백)
    • false: LLM(Claude) with_structured_output()으로 PII + 거절을 동시에 판별
  • 개인정보 노출 감지 (is_danger): 이름, 생년월일, 계좌번호, CVC, 비밀번호 등
  • 완곡한 거절 감지 (is_refusal): 직접 거절, 회피, 의심 표현, 전화 끊으려는 시도
  • LLM도 실패 시 정규식 최종 폴백 처리
  • state.user_input을 직접 읽어 messages에 아직 추가되지 않은 최신 입력도 평가 가능

5-4. Guardian Agent (src/agents/guardian.py)

  • 피싱 시나리오:
    • 개인정보 노출 시: 노출된 정보 지적 + 뉴스 사례 인용 + 올바른 대처법 안내
    • 거절 2회 달성 시: 칭찬 + 사기 패턴 분석 + 실생활 대응 팁 + 훈련 종료 인사
    • 최대 턴(20) 도달 + 거절 부족 시: 구체적 취약점 인용 + 실제 피해 사례 경고 + 단계별 대처법 안내 + 추가 훈련 권장
  • 정상 시나리오:
    • 자연 종료 시: 정상 전화였음 안내 + 정상/피싱 구분 포인트 교육
    • 오인 거절 시: 조심하는 것에 대한 격려 + 정상/피싱 구분법 안내 (개인정보 요구 여부, 긴급감 조성 여부 등)
  • 뉴스 기사 링크를 [LINK_N] 태그로 1:1 매칭하여 삽입

5-5. PII 탐지 모델 (src/evaluator/pii_model.py)

  • beomi/KcELECTRA-base-v2022 파인튜닝 이진 분류 모델 (label 0 = Safe, label 1 = PII)
  • CPU 전용 추론, 싱글톤 로딩
  • 지원 모델 형식:
    • 디렉토리 (from_pretrained 형식): config.json + model weights + tokenizer
    • .pt 파일: state_dict 또는 full model 체크포인트
  • PII 판정은 모델의 softmax 확률 출력이 유일한 기준 (정규식은 유형 라벨링에만 보조 사용)

5-6. 음성 처리 (src/voice/)

  • STT (stt.py): OpenAI Whisper API 기반 한국어 음성→텍스트 변환
  • TTS (tts.py): Microsoft Edge Neural TTS (edge-tts) 기반 텍스트→음성 변환
    • ThreadPoolExecutor 싱글톤으로 리소스 최적화
    • 문장 경계 기준 텍스트 절단 (_truncate_for_tts)으로 생성 속도 개선
    • 타임아웃 15초
  • Streamlit UI에서 마이크 녹음 → STT → LLM 응답 → TTS 자동 재생 흐름

6. 실행 방법

환경 설정

# 1. 의존성 설치
pip install -r requirements.txt
# 2. 환경변수 설정
cp .env.example .env
# .env 파일에 ANTHROPIC_API_KEY 입력
# (음성 기능 사용 시) OPENAI_API_KEY 입력

Streamlit 웹 UI

streamlit run app.py

CLI 모드

# 대화형 시나리오 선택
python -m src.main
# 특정 시나리오로 바로 시작
python -m src.main --topic 검찰사칭
python -m src.main --topic 카드사사칭
python -m src.main --topic 대출사기
# 구조 확인 데모 (API 키 불필요)
python -m src.main --demo

7. 환경 변수 설정

.env.example을 복사하여 .env 파일을 생성하고 값을 입력합니다.

변수명 필수 설명 기본값
ANTHROPIC_API_KEY 필수 Claude API 키
OPENAI_API_KEY 음성 기능 시 필수 OpenAI API 키 (Whisper STT용)
MASTER_MODEL 선택 Master Agent LLM 모델 claude-sonnet-4-20250514
ROLEPLAY_MODEL 선택 Roleplay Agent LLM 모델 claude-sonnet-4-20250514
EVALUATION_MODEL 선택 Evaluator Agent LLM 모델 claude-sonnet-4-20250514
GUARDIAN_MODEL 선택 Guardian Agent LLM 모델 claude-sonnet-4-20250514
PII_USE_LOCAL_MODEL 선택 PII 탐지 방식 (true=KcELECTRA / false=LLM API) true
PII_MODEL_PATH 선택 KcELECTRA 모델 경로 (디렉토리 또는 .pt 파일) models/pii_detector
PII_BASE_MODEL 선택 .pt 로드 시 베이스 아키텍처 beomi/KcELECTRA-base-v2022
PII_THRESHOLD 선택 PII 판정 임계값 (0.0~1.0, 높을수록 보수적) 0.85
TTS_VOICE 선택 TTS 음성 (Edge Neural) ko-KR-InJoonNeural
TTS_RATE 선택 TTS 말하기 속도 +0%
CHROMA_DB_PATH 선택 ChromaDB 저장 경로 Data/chroma_db
CHROMA_COLLECTION 선택 ChromaDB 컬렉션 이름 MK_NEWS_VECTOR
CHROMA_EMBEDDING_MODEL 선택 임베딩 모델 all-MiniLM-L6-v2
LANGCHAIN_API_KEY 선택 LangSmith 추적용 API 키
LANGCHAIN_TRACING_V2 선택 LangSmith 추적 활성화 false

8. RAG (ChromaDB) 설정

매일경제 뉴스 기반 보이스피싱 사례를 벡터 DB에 저장하고, 에이전트가 대사/교육 생성 시 참고합니다.

# 1. 뉴스 크롤링 (Data/news/에 JSON 저장)
python src/collect_news/naver_to_BS_article.py
# 2. ChromaDB에 벡터 적재
python src/collect_news/with_ChromaDB.py
  • 임베딩 모델: sentence-transformers/all-MiniLM-L6-v2 (ChromaDB 기본)
  • 유사도: cosine distance
  • 싱글톤 캐싱으로 앱 실행 중 임베딩 모델 1회만 로딩

RAG 데이터 흐름:

master.py ─→ utils/rag.py ─→ voice_phishing_rag.py ─→ ChromaDB
 ↑
roleplay_agent.py ─→ utils/rag.py (캐시 재활용)
 ↑
guardian.py ─→ voice_phishing_rag.py (직접 호출 — LINK 태그 매칭용 raw results 필요)

9. 참고 기사

사례1

  • 의견
    대화를 하는 과정 + 이상한 링크를 누르거나 이상한 전화번호로 전화하거나 앱설치를 요구하거나
    같은 추가적인 상황도 구현할 수 있을까?

사례2
사례3
사례4
사례5

참고 자료

About

데이콘 보이스피싱 공모전

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /