fix(prediction): dark_suspicion Adapter 입력 매핑 교정 (run_outputs 0 rows silent) #95

병합
htlee fix/dark-suspicion-adapter-input 에서 develop 로 1 commits 를 머지했습니다 2026-04-20 16:06:13 +09:00
소유자

변경 요약

Detection Model Registry end-to-end 검증 중 detection_model_run_outputs=0 rows 로 나오는 silent 문제 발견·수정. evaluated_count=0 메트릭이 조기 포착 — Phase 1-2 의 가시성 장치가 실전에서 역할.

원인

DarkSuspicionModel.run()ctx.inputs[*].features.gap_info.is_dark 경로로 대상을 필터했으나, 실제 AnalysisResult.features JSONB 는 gap_info 키를 포함하지 않음. 실제 스키마:

features keys (is_dark=true 선박):
  dark_suspicion_score, dark_tier, dark_patterns,
  dark_history_7d, dark_history_24h,
  gap_start_state, gap_start_sog, gap_start_lat, gap_start_lon

즉 scheduler 가 이미 compute_dark_suspicion 을 돌려 결과를 flatten 저장하므로, 2중 계산 시도가 잘못된 경로.

수정

Adapter 를 transshipment_5stage / risk_composite / pair_trawl_tier 와 동일한 관찰형 으로 재작성:

  • row.is_dark 필터 후 features.dark_suspicion_score / dark_tier / dark_patterns JSONB snapshot 기록
  • 메트릭: evaluated_count / critical_count / high_count / watch_count / none_count / avg_score
  • input_ref: {mmsi, analyzed_at, gap_min}

운영 검증 (E2E)

파일 교체 + 재기동 → 1 사이클 후:

지표
detection_model_run_outputs 3,508 rows (dark_suspicion PRIMARY)
evaluated_count 3,508
critical_count 141
high_count 467
watch_count 963
none_count 1,937
avg_score 27.78
Adapter cycle_duration_ms 17 ms
DAGExecutor done executed=1 failed=0

샘플 outputs (JSONB):

412323307 | 35  | WATCH    | [moving_at_off, repeat_high, recent_dark, unpermitted, fishing_vessel_dark, out_of_coverage]
412425839 | 40  | WATCH    | [slow_moving_at_off, ..., long_gap, out_of_coverage]
412326673 | 100 | CRITICAL | [slow_moving_at_off, sensitive_zone, ..., very_long_gap]

범위 밖 (후속 PR)

현 버전은 기존 compute_dark_suspicion 결과를 관찰 만. ACTIVE 버전 params 를 compute 함수에 런타임 주입 하는 scheduler 호출부 리팩토링은 별도 PR. 이는 5 모델 모두 동일 상태(카탈로그 + 관찰만).

테스트

  • python -m unittest prediction 기반 테스트 23/23 통과
  • 운영 파일 교체 + 재기동 (15:39:37 active)
  • 1 사이클 후 DAGExecutor 성공 + 3,508 rows 적재 확인
  • metrics 8 행 (evaluated/critical/high/watch/none/output/cycle_duration/avg_score) 정상

배포

  • 이미 운영 반영 완료 (scp + systemctl restart)
  • 다음 사이클부터 자동으로 새 row 기록 중
## 변경 요약 Detection Model Registry end-to-end 검증 중 `detection_model_run_outputs=0 rows` 로 나오는 silent 문제 발견·수정. `evaluated_count=0` 메트릭이 조기 포착 — Phase 1-2 의 가시성 장치가 실전에서 역할. ## 원인 `DarkSuspicionModel.run()` 이 `ctx.inputs[*].features.gap_info.is_dark` 경로로 대상을 필터했으나, 실제 `AnalysisResult.features` JSONB 는 `gap_info` 키를 포함하지 않음. 실제 스키마: ``` features keys (is_dark=true 선박): dark_suspicion_score, dark_tier, dark_patterns, dark_history_7d, dark_history_24h, gap_start_state, gap_start_sog, gap_start_lat, gap_start_lon ``` 즉 scheduler 가 이미 `compute_dark_suspicion` 을 돌려 결과를 flatten 저장하므로, 2중 계산 시도가 잘못된 경로. ## 수정 Adapter 를 `transshipment_5stage` / `risk_composite` / `pair_trawl_tier` 와 동일한 **관찰형** 으로 재작성: - `row.is_dark` 필터 후 `features.dark_suspicion_score / dark_tier / dark_patterns` JSONB snapshot 기록 - 메트릭: `evaluated_count / critical_count / high_count / watch_count / none_count / avg_score` - `input_ref: {mmsi, analyzed_at, gap_min}` ## 운영 검증 (E2E) 파일 교체 + 재기동 → 1 사이클 후: | 지표 | 값 | |---|---| | `detection_model_run_outputs` | **3,508 rows** (dark_suspicion PRIMARY) | | `evaluated_count` | 3,508 | | `critical_count` | 141 | | `high_count` | 467 | | `watch_count` | 963 | | `none_count` | 1,937 | | `avg_score` | 27.78 | | Adapter `cycle_duration_ms` | 17 ms | | `DAGExecutor done` | `executed=1 failed=0` | 샘플 outputs (JSONB): ``` 412323307 | 35 | WATCH | [moving_at_off, repeat_high, recent_dark, unpermitted, fishing_vessel_dark, out_of_coverage] 412425839 | 40 | WATCH | [slow_moving_at_off, ..., long_gap, out_of_coverage] 412326673 | 100 | CRITICAL | [slow_moving_at_off, sensitive_zone, ..., very_long_gap] ``` ## 범위 밖 (후속 PR) 현 버전은 기존 `compute_dark_suspicion` 결과를 **관찰** 만. ACTIVE 버전 params 를 compute 함수에 **런타임 주입** 하는 scheduler 호출부 리팩토링은 별도 PR. 이는 5 모델 모두 동일 상태(카탈로그 + 관찰만). ## 테스트 - [x] `python -m unittest` prediction 기반 테스트 23/23 통과 - [x] 운영 파일 교체 + 재기동 (15:39:37 active) - [x] 1 사이클 후 DAGExecutor 성공 + 3,508 rows 적재 확인 - [x] metrics 8 행 (evaluated/critical/high/watch/none/output/cycle_duration/avg_score) 정상 ## 배포 - 이미 운영 반영 완료 (`scp` + `systemctl restart`) - 다음 사이클부터 자동으로 새 row 기록 중
htlee added 1 commit 2026-04-20 16:06:03 +09:00
기존 DarkSuspicionModel.run() 이 ctx.inputs[*].features.gap_info.is_dark
로 대상을 필터했으나, 실제 AnalysisResult.features 는 gap_info 키를
포함하지 않고 다음으로 이미 flatten 저장됨:
  - dark_suspicion_score (0~100 int)
  - dark_tier ('CRITICAL'/'HIGH'/'WATCH'/'NONE')
  - dark_patterns (list[str])
  - gap_start_state / gap_start_sog / gap_start_lat / gap_start_lon

결과: PRIMARY 승격 + feature flag=1 적용해도 Adapter 가 한 선박도
평가하지 못해 detection_model_run_outputs 에 0 rows 적재 — E2E 검증
에서 evaluated_count=0 메트릭이 silent 조기 포착.

수정: Adapter 를 transshipment/risk/pair_trawl 과 동일한 관찰형으로 재작성.
  - row.is_dark 필터 후 기존 결과(score/tier/patterns) JSONB snapshot 기록
  - critical/high/watch/none_count + avg_score 메트릭 집계
  - input_ref: {mmsi, analyzed_at, gap_min}

운영 반영 후 1 사이클에서 3508 rows 적재 (141 CRITICAL / 467 HIGH /
963 WATCH / avg_score=27.78) 확인.

범위 밖 (후속 PR):
- compute_dark_suspicion 에 ACTIVE 버전 params 를 런타임 주입해 실제
  score/tier 재계산하는 scheduler 호출부 리팩토링. 현 상태는 params
  카탈로그 관찰까지만 (나머지 4 모델과 동일 수준).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
claude-bot 이 변경사항을 승인하였습니다. 2026-04-20 16:06:13 +09:00
claude-bot left a comment
멤버

E2E 검증에서 silent 포착 → 수정 → 3508 rows 적재 확인. 관찰형 Adapter 로 5 모델 일관. LGTM

E2E 검증에서 silent 포착 → 수정 → 3508 rows 적재 확인. 관찰형 Adapter 로 5 모델 일관. LGTM
htlee merged commit 76d3363661 into develop 2026-04-20 16:06:13 +09:00
htlee 삭제된 브랜치 fix/dark-suspicion-adapter-input 2026-04-20 16:06:13 +09:00
"로그인하여 이 대화에 참여"
No reviewers
레이블 없음
마일스톤 없음
담당자 없음
참여자 2명
알림
마감일
기한이 올바르지 않거나 범위를 벗어났습니다. 'yyyy-mm-dd'형식을 사용해주십시오.

마감일이 설정되지 않았습니다.

의존성

No dependencies set.

Reference: gc/kcg-ai-monitoring#95
No description provided.