본문으로 건너뛰기

RAG CLI 도구 운영 가이드

너홀로프로 RAG (Retrieval-Augmented Generation) 운영 도구. PR-Sync-1~9 + followup (2026-05-08 자율 세션) 으로 ship. Cloud Function 의존 제거, 사용자 명시적 수동 sync, Claude Code 슬래시 커맨드로 일원화.

아키텍처 (요약)

[네트워크] [로컬] [Firestore] [Vertex AI] [findNearest]

법제처 Open API ─→ scripts/sync-law-go-kr.ts ─→ in-memory ─→ publicDocuments ─→ Vertex AI 직접 호출 ─→ findNearest (web 검색)
(download + embed + upload) publicDocumentsRaw
publicRagSyncWatermark

Claude Code 슬래시 커맨드 (사용자 직접 호출)

커맨드백엔드핵심 동작
/sync-lawscripts/sync-law-go-kr.ts법제처 → Firestore incremental sync (워터마크 기반)
/rag-statusscripts/rag-status.ts임베딩 인벤토리 + 워터마크 + 모델 drift 시각화
/rag-evalscripts/rag-eval.ts인용 환각 탐지 (verify_citations 패턴)
/rag-impactscripts/rag-impact.ts조문 영향 그래프 + mermaid (impact_map 패턴)
/rag-vs-mcp(가이드 위주)우리 RAG vs korean-law-mcp 비교
/mcp-update-watchscripts/mcp-update-watch.tsMCP GitHub 변경 분석
/neohollo(메타 hub)위 6개 통합 reference + 사용 예문

필수 환경

# 모든 CLI 공통 (또는 .env.local 에 자동 주입)
NODE_PATH=apps/web/node_modules
GCLOUD_PROJECT=neohollo-pro

# 법제처 OC 키 — env 또는 gcloud Secret Manager 자동 fallback
LAW_GO_KR_OC=<env 우선, 없으면 `gcloud secrets versions access latest --secret=LAW_GO_KR_OC`>

# Vertex AI / Firestore Admin SDK — ADC 필요
gcloud auth application-default login

핵심 흐름 (5단계 RAG 파이프라인)

┌─────────────┐ ① ┌─────────────┐ ② ┌─────────────┐ ③ ┌─────────────┐ ④ ┌─────────────┐ ⑤
│ 법제처 │ ───→ │ download │ ───→ │ 변환 │ ───→ │ embed │ ───→ Firestore 적재 ─→ │ findNearest│
│ Open API │ │ (in-memory)│ │ (어댑터) │ │ (Vertex AI) │ publicDocuments │ (web 검색) │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ publicDocumentsRaw └─────────────┘
publicRagSyncWatermark

① download (외부 → 로컬 메모리)

  • scripts/sync-law-go-kr.ts 가 법제처 lawSearch.do (목록) + lawService.do (본문)
  • 카테고리별 page=1..N 호출 (기본 N=10)
  • nativeId set diff 로 신규만

② 변환 (어댑터 SSoT 3 곳 미러)

  • scripts/lib/law-go-kr-convert.ts (CLI)
  • functions/src/law-go-kr-adapter.ts (Cloud Function — fetchAndIngestLawGoKr 만 사용)
  • apps/ops/.../adapter-law-go-kr.ts (ops paste UI)

③ embed (Vertex AI text-embedding-004 직접 호출)

  • chunk 분할 + meanPool (scripts/lib/embed-input-prepare.ts 4 곳 미러, drift gate 32 테스트 보호)
  • 429 burst 자동 재시도 (10s, 30s)
  • 차원 768

④ Firestore 적재

  • publicDocuments: 정제 + embedding.vector · version · dims
  • publicDocumentsRaw: 원본 보존 (변환 규칙 변경 시 rebuild 가능)
  • publicRagSyncWatermark/<watermarkId>: nativeId set 기록 → 다음 sync 의 incremental 기준

⑤ findNearest (web 검색)

  • web app (apps/web) Server Action 이 findNearest() 호출
  • 검색 흐름은 그대로 유지 (Cloud Function 폐기는 적재 자동 trigger 만 영향)

워터마크 (publicRagSyncWatermark)

interface WatermarkDoc {
watermarkId: string; // categoryId 또는 lawId
type: "category" | "statute";
lastSyncedAt: Timestamp;
lastSyncedNativeIds: string[]; // 다음 sync 의 set diff 기준
totalEverIngested: number;
lastRunStats: RunStats; // fetched / newIds / uploaded / embedFailed / elapsedMs / errors
}

폐기된 인프라 (PR-Sync-2/3)

  • scheduledFetchLawGoKr Cloud Scheduler cron — 폐기
  • manualIncrementalFetchLawGoKr callable — 폐기
  • onPublicDocumentCreated 자동 임베딩 trigger — 폐기
  • apps/ops/.../PublicRagScheduleStatusCard.tsx삭제
  • publicRagScheduleLog 컬렉션 — 더 안 채워짐 (기존 데이터 보존)

대체 흐름:

  • 적재 = 사용자가 /sync-law 명시 호출 (또는 ops 의 fetchAndIngestLawGoKr 단건 callable 도 유지)
  • 임베딩 = 적재 경로가 직접 처리 (sync CLI lib/vertex-embed · fetchAndIngest embedAndUpdateDoc)

데이터 카테고리 (SSoT)

판례 (scripts/law-go-kr-categories.ts)

  • core 21 카테고리 (대여금·공사·구상금·약정·임대차·양수·집행 등)
  • extra 6 카테고리 (소비대차·부당이득·내용증명·지급명령·불법행위·시효)

법령 (scripts/law-go-kr-statute-list.ts)

  • core 6 (민법·상법·민사소송법·민사집행법·이자제한법·주택임대차보호법)
  • extra 3 (헌법·형법·형사소송법)

각 카테고리/법령에 대해 lawId 또는 params (query · JO · curt · org) 명시.

사용 예시 — 운영 시나리오

일일 운영

/rag-status # 상태 점검
/sync-law # 신규 sync
/mcp-update-watch --since=$(date -u -v-1d +%Y-%m-%d) # MCP 변경 인지

새 카테고리 sync

  1. scripts/law-go-kr-categories.ts 에 카테고리 추가 (PR 별도)
  2. /sync-law --category=<신규-id> --max-new=50 시범
  3. /rag-eval --verify="<영역 5건 인용>" 환각 측정
  4. /rag-impact --statute="<핵심 조문>" 영향 그래프 검증

대량 신규 (월 1회)

/sync-law --pages=30 --target=all
# 임베딩 quota burst 시:
npx tsx scripts/reembed-public-docs.ts --only-failed --throttle-ms=500

모델 교체 (text-embedding-004 → 005)

  1. 코드 상수 교체 (scripts/lib/embed-input-prepare.ts)
  2. 일괄 재임베딩 (scripts/reembed-public-docs.ts --all)
  3. /rag-status 검증

진단 스크립트 (slash 백엔드 외)

스크립트용도
scripts/count-public-doc-embeddings.ts임베딩 인벤토리 (rag-status.ts 의 모태)
scripts/count-citation-distribution.tscitedStatutes 분포 + hub 후보
scripts/inspect-failed-embeddings.tsembeddingError 분류
scripts/migrate-embedding-field-name.ts1회용 — modelVersion → version 통합
scripts/cleanup-deleted-statutes.ts삭제 조문 정리 + 짧은 조문 임베딩 회복
scripts/reembed-public-docs.ts임베딩 일괄 재시도 (4 모드)
scripts/reembed-legacy-docs.tstenant legacyDocuments 재임베딩 백필 (--only-failed / --only-missingembeddingError 마커 소비자, 사무소 기억 학습 루프 복구)
scripts/rebuild-public-docs-from-raw.ts변환 규칙 변경 후 raw → publicDocuments 재구축
scripts/migrate-vector-storage-format.ts1회용 (2026-05-05) plain array → FieldValue.vector

검증된 데이터 (2026-05-08 기준)

  • publicDocuments: 7,853 docs (3,495 판례 + 4,358 법령)
  • 임베딩: 100% embedded · pending 0 · error 0
  • 모델: text-embedding-004 (768-dim) — drift 0 (필드명 통일 후)
  • 워터마크: 1 트랙 (interest-limit, sync 검증 완료)

관련 문서

한계 + 후속 PR 후보

  • PR-Sync-7b: impact_map 정방향 + 사무소 layer (legacyDocuments) — MCP 차별화 핵심
  • PR-Sync-8b: korean-law-mcp stdio 자동 spawn (paste 없이 자동 비교)
  • PR-A 추가: 정규화 lawName 컨텍스트 추론 (raw "제664조" 만 있을 때 lawName 추출)
  • 호·목 환각 탐지: 현재 항까지만, 호/목 단위 후속
  • 사무소 RAG 집계: tenant-isolated legacyDocuments 검색 quality 측정 (ADR 0024 V2 위에)