Playball Logo

Command Palette

Search for a command to run...

목차 열기

10. Backoffice Copilot — 사후 검토 워크플로우

Runtime에서 즉시 차단되지 않은 의심 세션을 사후 검토하는 workflow입니다. Human-in-the-Loop 레이어로 동작합니다.

배경

Online은 완충적으로 설계되어 있습니다.

  • 중간 등급(T1/T2) 세션은 즉시 차단하지 않고 지연·챌린지로 처리
  • 회색지대 세션이 실제 봇인지는 사후에 별도 레이어에서 판단

목적 — 온라인 방어가 완충적으로 처리한 T1/T2·throttle·VQA failure 등의 흔적을 사후 운영 데이터로 전환.

특징

항목내용
VQA 재검증❌ 하지 않음 (이미 발생한 audit와 read model 기반)
PostgreSQL 저장검토 결과 기록
Backend 전달의심(SUSPICIOUS) 세션만 제재 API로 전달
LLM 활용있으면 LLM 판단, 없으면 규칙 기반 폴백

6단계 워크플로우

[Node 1] Input Collection
    └─ ClickHouse read model 또는 fixture JSONL에서 AnalysisInput 생성
    ↓
[Node 2] Candidate Selection
    └─ Hard filter 적용 → 후보 세션 선정
    ↓
[Node 3] Session Analysis
    └─ 각 candidate별 timeline_summary + suspicious_signals 생성
    ↓
[Node 4] Review
    ├─ LLM 있으면 → LLM review output 파싱
    └─ LLM 없으면 → deterministic fallback
    ↓
[Node 5] Summary
    └─ Run-level 3줄 요약 생성
    ↓
[Node 6] Persist & Delivery
    ├─ PostgreSQL 저장 (run + session result)
    ├─ Suspicious-only backend 전달
    └─ export + validation status resolution

Node 1 — Input Collection

입력 소스선택 조건
ClickHouse read model실제 운영 환경 (primary)
Fixture JSONL테스트·개발 환경

AnalysisInput 생성

세션 목록을 분석 단위로 변환.

Node 2 — Candidate Selection

Hard filter로 후보 세션을 좁힙니다.

필터 조건

조건의미
T1 또는 T2를 봤음회색지대 세션
Block 이벤트 없음즉시 차단되지 않은 세션
Latest action ≠ BLOCK현재 차단 상태 아님
Latest tier ≠ T3현재 최고 위험 아님
Terminal outcome = NOT_BLOCKED정상 종료된 세션

효과 — 즉시 차단된 세션은 이미 방어됐으므로 제외. 완충 처리된 회색지대만 남김.

Node 3 — Session Analysis

Suspicious Signals 생성

신호조건
seen_t2T2 도달 기록
vqa_fail_count챌린지 실패 횟수
throttle_event_countthrottle 적용 횟수
latest_action_THROTTLE최근 action이 throttle
terminal_reason종료 사유

Timeline Summary 생성

시간순 이벤트를 문장으로 요약:

  • T1/T2 도달 시점
  • Throttle 횟수
  • S3 challenge failure 횟수
  • Terminal reason / outcome

Raw Fallback

요약에 UNKNOWN 필드가 있거나 suspicious signal이 없으면 제한된 decision_audit row를 추가로 읽어 보강합니다.

Node 4 — Review

LLM Review (가능할 때)

입력내용
System prompt"You are a traffic abuse analyst. Review the session timeline..."
User message세션 요약 + 신호 목록
OutputSUSPICIOUS / NORMAL / UNCERTAIN

Deterministic Fallback

LLM 없거나 timeout/error/schema invalid인 경우:

if seen_t2 OR vqa_fail_count > 0 OR throttle_event_count > 0
       OR latest_action == THROTTLE:
    result = SUSPICIOUS
else:
    result = NORMAL

왜 폴백을 두는가

이유설명
운영 연속성LLM API 키 없거나 장애여도 사후 검토가 돌아가야 함
필수 요소 아님LLM은 정확도를 높이는 도구일 뿐
단순 규칙의 충분성T2·챌린지 실패·throttle은 명백한 의심 신호

Node 5 — Summary

Run-level 3줄 요약 생성:

예시:
"2026-04-16 batch reviewed 500 candidates: 50 suspicious, 450 normal.
 Main patterns: T2 + throttle (30), VQA failure (15), rapid scanning (5).
 Recommended actions: block 10 sessions, monitor 40 sessions."

Node 6 — Persist & Delivery

PostgreSQL 저장

post_review_runs

필드의미
match_id경기 식별자
window분석 구간
candidate_count후보 세션 수
suspicious_count의심 판정 수
summary_text_json3줄 요약
status실행 상태

post_review_session_results

필드의미
match_id경기 식별자
session_id세션 식별자
review_resultSUSPICIOUS / NORMAL
evidence_summary근거 요약
session_analysis_json전체 분석 데이터
backend_delivery_status백엔드 전달 상태

Backend Delivery

대상방식
Suspicious 세션만백엔드 제재 API 호출
Normal 세션저장만 하고 전달 안 함

전달 페이로드

POST /api/v1/internal/sanctions
{
  "idempotency_key": "<unique>",
  "target": "<session_id or user_id>",
  "action": "SUSPEND",
  "reason_code": "BACKOFFICE_COPILOT_SUSPICIOUS",
  ...
}
항목의미
idempotency_key중복 제재 방지
actionSUSPEND 등
reason_code제재 사유

왜 Suspicious-only인가

이유설명
불필요 처리 방지Normal까지 전달하면 백엔드가 분석·저장 반복
잘못된 제재 위험 감소명확히 의심되는 것만 전달
중복 제재 방지idempotency key로 이미 제재된 세션 필터링

실패 처리

상황처리
Backend adapter 없음delivery_status = NOT_CONFIGURED
Backend 호출 실패delivery_status = FAILED (run persistence는 이미 완료)
중복 전달idempotency_key로 스킵

운영 설정

CLI 매개변수

매개변수기본값의미
window600초분석 구간
limit1000최대 후보 수
dry_runfalse실제 PostgreSQL 대신 in-memory 저장
require_llmfalseLLM 필수 여부

환경별 동작

환경LLMFallback
Production활성LLM 실패 시 규칙 기반
Staging활성LLM 실패 시 규칙 기반
DevLLM 키 없으면 규칙 기반만

실행 주기

CronJob으로 주기 실행 (예: 10분마다 최근 10분 window 처리).

감사 이벤트

이벤트내용
post_review_run_started실행 시작
post_review_run_completed정상 종료
post_review_run_failed실행 실패
post_review_llm_fallback규칙 기반 폴백 사용
post_review_backend_delivered백엔드 전달 성공
post_review_backend_failed백엔드 전달 실패

참조