본문으로 건너뛰기

ADR 0062: Platform RAG 법제처 전량 열거 — 큐레이션 → 전체 corpus 전환

배경

Platform RAG 는 지금까지 Pack 도메인 기반 큐레이션 카테고리 (검색어·참조조문 필터) 로만 법제처 데이터를 수집했다 — 판례 15,893 / 법령 34종 / 해석례 765 / 헌재결정례 820. 2026-07-03 실측한 법제처 Open API 의 전체 규모 대비 커버리지:

target법제처 전체보유 (당시)커버리지
판례 (prec)168,92515,8939.4%
현행법령 (law)5,595개 법령34개 법령0.6%
법령해석례 (expc)8,7757658.7%
헌재결정례 (detc)38,4438202.1%

CTO 지시 (2026-07-03): "법제처가 우리의 유일한 소스인데 왜 그 일부만 가져오나 — 전량 수집하라." 큐레이션은 기술 한계가 아니라 초기 설계 선택이었고, API 는 쿼리 없는 전량 페이지네이션을 정식 지원함을 실측으로 확인했다 (깊은 page 전 구간 응답).

결정

  1. sync CLI 에 --enumerate 전량 열거 모드 추가. 쿼리 없는 전체 페이지네이션으로 target 의 법제처 공개분 전량을 회수한다. 큐레이션 데일리 경로 (syncCategory 등) 는 무변경 — 전량 층과 큐레이션 층은 dedup (court+caseNumber / 안건번호 / 헌재 사건번호) 으로 이중 적재가 차단된다.
  2. 워터마크 id-set 샤딩. 판례 169K nativeId 는 Firestore 문서 1 MiB 한도를 초과 (~1.35 MB) → publicRagSyncWatermark/enum-{target} meta + enum-{target}--ids-{n} 샤드 (30K/샤드, isIdShard: true) 분리. 순수 로직 SSoT scripts/lib/watermark-shards.ts.
  3. 수집·임베딩 분리 (--skip-embedding). Vertex online 임베딩 quota 가 전 리전 5 req/min 으로 강등돼 있음을 재확인 (textembedding-gecko 항목으로 집계, 셀프 증액 불가) — online 경로로 21.6만 건 임베딩은 100일+ 라 불가능. 문서 적재 (fetch → convert → dedup → upload) 를 먼저 완주하고, 임베딩은 별도 backfill:
    • 적재분은 embeddedAt 없음 + embeddingError: null → rag-status pending 분류
    • backfill 경로 = Vertex batch prediction (별도 quota, 대량 설계 — 후속 PR) 또는 reembed-public-docs.ts --only-missing (online, quota 회복 시) 또는 영업팀 quota 증액
  4. 단계 실행 강제. --enumerate--target=prec|expc|detc 단일 지정만 허용:
    • Phase E1: expc 8.8K + detc 38.4K — 라이브러리 검색·인용 전용 (ADR 0054) 이라 docgen merge 무위험. 선행 실행.
    • Phase E2: prec 169K — sourceType=court_precedent 는 docgen 두 RAG 결합 (ADR 0041) 에 직접 편입되므로 rag-eval 회귀 + findNearest latency 실측 + ragMergeQuality 텔레메트리 게이트 를 수집 전·중·후 통과해야 한다.
    • Phase E3: 현행법령 5,595개 — 법령→조문 분해 구조가 달라 (statute 파이프라인이 고정 법령 리스트 전제) 별도 PR. E2 latency/품질 학습 후 착수.

재시도 의미론 (enum 층)

  • 적재 성공 · dedup · 영구 변환실패 → knownIds 포함 (영구 skip)
  • 일시 실패 (본문 fetch 예외 · 임베딩 실패 · 적재 실패) → knownIds 미포함 → 다음 run 자연 재시도
  • 본문 미공개 (prec, 선고 2년 내만) → knownIds 포함 + pendingBody (캡 5K · TTL 180d). 2년 초과 미공개는 영구 stub 으로 간주 (법제처가 본문 비공개 선택) — 열거 꼬리의 0001.01.01 junk 데이터도 이 게이트가 방어. 회수는 --reset-watermark 재열거.
  • initial pass 는 enumNextPage 커서 resume (20 page 마다 체크포인트), 완료 후 incremental 은 최신순 정렬을 이용해 연속 3 page 전부 known (+최소 20 page) 이면 조기 종료.

지켜지는 것 / 바뀌는 것

  • 지켜지는 것: 법고을 직접 크롤링 금지 (ADR 0054 — 본 결정은 법제처 공식 Open API 의 정식 페이지네이션 사용). 큐레이션 데일리 sync (core 카테고리 + pendingBody 재시도) 는 그대로 — 최신 판례의 본문 지연 공개 흡수는 데일리 층이 계속 담당. ADR 0054 의 "expc·detc 는 라이브러리 전용, docgen merge 는 rag-eval 게이트 후" 원칙 유지.
  • 바뀌는 것: "Pack 도메인 큐레이션이 Platform RAG 의 범위" 라는 ADR 0039 전제 → 전량 corpus 위에 큐레이션이 케이던스 층으로 공존. general-civil (ADR 0052) 같은 목록 외 사건의 RAG 커버리지가 근본적으로 확대된다.

리스크 · 게이트

  1. docgen 품질: prec 169K 편입 시 balanced findNearest 후보 pool 이 10배 — distractor 위험. 기존 anisotropy 방어 (hard-gate + 0.3 backstop) 위에 Phase E2 게이트 (rag-eval 前後 비교) 필수. 악화 시 sourceType 별 findNearest 는 유지한 채 enum 층에 별도 sourceType tag 나 quality filter 도입 여지.
  2. findNearest latency/비용: Firestore KNN 은 exact scan — corpus 10배 시 쿼리 latency 실측 필요 (E1 완료 후 47K 시점, E2 중간 100K 시점 측정). 임계 초과 시 Vertex AI Vector Search 이전 검토가 트리거된다.
  3. 임베딩 backfill 규모: 21.6만 건 — batch prediction PR 이 실질 관문. 병행 옵션 = GCP 영업팀 quota 증액 문의 (셀프 서비스 상한 5 로 막혀 있음).

검증 (2026-07-03 라이브)

  • expc enum 5건 적재 (임베딩 동반) → 워터마크 meta + 샤드 구조 정합 확인
  • resume: 2차 run 이 known=5 skip 후 다음 5건 처리
  • --skip-embedding 5건 → embeddedAt 없음 + embeddingError: null (pending 분류) 확인
  • 큐레이션 기수집분과 dedup 충돌 0 (이중 적재 차단 동작)
  • 가드: --target=all|law 거부, --skip-embedding 단독 사용 거부
  • 순수 로직 14 테스트 (apps/web/__tests__/scripts-watermark-shards.test.ts)