콘텐츠로 이동

CLI 레퍼런스

packages/data-pipeline은 typer 기반 Python CLI 3개를 entry point로 노출한다. 모든 명령은 uv run(또는 패키지 설치 후 직접) 으로 호출되며, 별도의 worker/queue 없이 로컬에서 실행된다. 자세한 옵션은 각 명령에 --help로 확인 가능.

엔트리 포인트 요약

명령 모듈 역할
semugpt-collect semugpt_pipeline.cli.collect:app 외부 소스에서 데이터 수집 (18개 서브명령)
semugpt-index semugpt_pipeline.cli.index:app ES 인덱스 생성 + 벌크 적재 (create / bulk)
semugpt-process semugpt_pipeline.cli.process:app 법령 파일 병합 등 데이터 변환 (merge / info / key-pair)
~~semugpt-upload~~ semugpt_pipeline.cli.upload:app stubpyproject.toml에 등록되어 있으나 cli/upload.py 파일 없음. 실행 불가

공통 호출 패턴

cd packages/data-pipeline

# 의존성 설치 (Selenium 포함)
uv sync --extra selenium

# CLI 실행
uv run semugpt-collect {source} [options]
uv run semugpt-index {create|bulk} --index {source} [options]

또는 설치 후 직접 실행:

pip install -e .
semugpt-collect tribunal --max-items 100

semugpt-collect 서브명령

카탈로그

서브명령 출처 주요 옵션
laws law.go.kr 법령 API --category (단일), --all, --year, --format
precedents law.go.kr 공동활용 --query, --max-count, --by-keywords, --tax-type, --all-tax-types, --include-content, --legacy
counsel call.nts.go.kr --tax-type, --all, --format
glossary taxlaw.nts.go.kr --page-size, --max-pages, --headless/--no-headless, --format
old-and-new law.go.kr 신구법 --query, --tax-laws, --all, --max-items
three-way law.go.kr 3단 비교 --law-id, --all
enforcement taxlaw.nts.go.kr --law-name, --headless/--no-headless, --format
written-inquiry taxlaw.nts.go.kr --query, --max-count, --year, --all, --include-detail, --format
nts-precedent taxlaw.nts.go.kr/pd/ --law-name, --save-every, --max-pages, --parallel, --dry-run, --convert, --progress
patch-precedent-ids (후처리) --law-name, --all, --use-api, --parallel, --dry-run, --update-es, --es-url
patch-tt-urls (후처리) --limit, --dry-run, --delay, --es-url, --data-dir
basic-rules taxlaw.nts.go.kr --law-name, --parallel, --save-every, --progress, --convert, --format
taxoffice taxoffice.co.kr --board, --all, --max-per-board, --format
tribunal tt.go.kr --max-items, --save-every, --progress, --convert, --headless/--no-headless
supreme-court law.go.kr (target=prec) --max-items, --save-every, --progress, --convert
scourt scourt.go.kr --max-items, --format (pdftotext 필요)
accounting kasb.or.kr --board, --all, --max-per-board, --save-every, --progress, --convert, --headless/--no-headless
list-categories (메타) 가용 카테고리/세목 키 목록 출력

공통 옵션 패턴

옵션 의미
--max-items N, --max-count N, --max-pages N 수집 상한 (테스트/부분 수집)
--save-every N N건마다 JSONL 파일에 fsync (중단 대비)
--progress 진행 상태만 출력하고 종료
--convert JSONL → 인덱서 호환 JSON 변환
--dry-run 실제 수집 없이 시뮬레이션
--headless/--no-headless Selenium Chrome headless 모드 (디버깅 시 --no-headless)
--parallel N ThreadPoolExecutor로 N개 동시 (대용량 수집)
--format json\|csv 출력 형식 (대부분 기본 json)

사용 예

# 양도소득세 관련 판례 100건 (본문 포함)
uv run semugpt-collect precedents -q 양도소득세 -n 100 --include-content

# 조세심판원 결정례 (Selenium, 진행 상태 확인)
uv run semugpt-collect tribunal --progress
uv run semugpt-collect tribunal -n 500

# 서면질의 2023년분 전체
uv run semugpt-collect written-inquiry --year 2023

# NTS 판례 31개 법령 병렬 수집 (3 워커)
uv run semugpt-collect nts-precedent --parallel 3

# 3단 비교 전체 세법
uv run semugpt-collect three-way --all

# NTS 판례 ID 패치 (AJAX API 방식, ES 업데이트 포함)
uv run semugpt-collect patch-precedent-ids --all --use-api \
  --update-es --es-url 'http://elastic:uiti0701%21@localhost:9200'

semugpt-index 서브명령

create — 인덱스 생성

uv run semugpt-index create --index {key} [--es-url URL]
옵션 기본값 설명
--index / -i laws 생성할 인덱스 (SUPPORTED_INDEXES 중 하나)
--es-url env ES_URL 또는 http://localhost:9200 Elasticsearch URL

지원 인덱스 키 (15종): laws, relations, precedents, enforcement, glossary, counsel, old-and-new, threeway, written-inquiry, basic-rules, taxoffice, tribunal, supreme-court, accounting, scourt.

bulk — 벌크 적재

uv run semugpt-index bulk --index {key} [options]
옵션 기본값 설명
--index / -i laws 적재 대상 인덱스 키
--data-dir / -d 인덱스별 기본값 (예: data/laws) JSON 데이터 디렉토리
--es-url env ES_URL 또는 http://localhost:9200 ES URL
--batch-size / -b 100 bulk API 배치 크기
--dry-run off 실제 인덱싱 없이 시뮬레이션
--embed off OpenAI 임베딩 생성 포함 (비용 발생)
--model / -m text-embedding-3-large 임베딩 모델
--api-key env OPENAI_API_KEY OpenAI API 키

--embed가 꺼져 있으면 content_vector 필드는 null로 저장된다 → kNN 검색 미작동.

사용 예

# 인덱스 생성
uv run semugpt-index create --index laws \
  --es-url 'http://elastic:uiti0701%21@localhost:9200'

# 벌크 적재 + 임베딩
uv run semugpt-index bulk --index laws --embed \
  --es-url 'http://elastic:uiti0701%21@localhost:9200'

# 사용자 디렉토리 지정 + 작은 배치
uv run semugpt-index bulk --index tribunal \
  --data-dir /tmp/tribunal-test \
  --batch-size 50 --embed

# dry-run으로 문서 변환 결과만 확인
uv run semugpt-index bulk --index counsel --dry-run

semugpt-process 서브명령

merge — 법령 파일 병합

여러 카테고리 디렉토리의 법령 JSON을 하나로 병합한다.

uv run semugpt-process merge {category_dir} \
  --category TRANSFER_INCOME \
  --topic INCOME_V2 \
  --output merged_transfer_income
옵션 설명
{category_dir} (positional) 카테고리 디렉토리
--category / -c 카테고리명 (TaxCategory enum)
--topic / -t 토픽명
--output / -o 출력 파일명 (확장자 제외)

info — 설정 정보 출력

uv run semugpt-process info

현재 Settings (data_dir, laws_dir, request_delay, law_api_base_url 등)를 콘솔에 출력.

공통 환경 변수

변수 사용 곳 기본값
ES_URL semugpt-index http://localhost:9200
ES_USERNAME / SEMUGPT_ES_USERNAME create_es_client (없음)
ES_PASSWORD / SEMUGPT_ES_PASSWORD create_es_client (없음)
OPENAI_API_KEY semugpt-index --embed (없음, 필수)
SEMUGPT_REQUEST_DELAY Settings 0.5초
SEMUGPT_DATA_DIR Settings.data_dir ./data

dev ES 자격증명은 URL 임베드 방식 권장:

# 권장: URL에 user:pass 임베드 (! 는 %21로 URL-encode)
--es-url 'http://elastic:uiti0701%21@localhost:9200'

# 또는 env로 전달
export ES_USERNAME=elastic
export ES_PASSWORD='uiti0701!'  # 따옴표 필수 (shell ! 회피)

base64 인증 헤더 직접 생성:

# curl 등 직접 호출용 — printf 사용 (echo -n은 ! 깨짐)
printf 'elastic:uiti0701!' | base64
# → ZWxhc3RpYzp1aXRpMDcwMSE=

전형적인 운영 시나리오

신규 인덱스 초기 구축

# 1. 데이터 수집
uv run semugpt-collect tribunal --save-every 50

# 2. 진행 상황 확인
uv run semugpt-collect tribunal --progress

# 3. (필요 시) JSONL → JSON 변환
uv run semugpt-collect tribunal --convert

# 4. ES 인덱스 생성
uv run semugpt-index create --index tribunal \
  --es-url '<url>'

# 5. 임베딩 포함 적재
uv run semugpt-index bulk --index tribunal --embed \
  --es-url '<url>'

# 6. 백엔드에서 검색 검증
curl 'https://semu-gpt-dev.bootalk.co.kr/conversations/stream' ...

매핑 변경 후 재적재 (수동, 운영 위험)

# 1. 인덱스 삭제 (운영 시 위험 — 검색 다운타임)
curl -X DELETE 'http://.../tax-tribunal' -H 'Authorization: Basic ...'

# 2. 매핑 변경 (indexer 코드 수정)
# 3. 재생성
uv run semugpt-index create --index tribunal --es-url ...

# 4. 재적재 (임베딩은 SQLite 캐시 hit → OpenAI 호출 미발생)
uv run semugpt-index bulk --index tribunal --embed --es-url ...

알려진 이슈 / 개선 예정

  • semugpt-upload entry point는 danglingpyproject.toml에 등록되어 있으나 cli/upload.py 미존재. 실행 시 ModuleNotFoundError. pyproject에서 제거 또는 stub 구현 필요.
  • CLI에 reindex / drop 명령 없음 — 매핑 변경 시 curl -X DELETE 수동 호출 필요. 운영 위험을 줄이는 alias/saved-search 자동화 미구현.
  • --embed 비용 알람 없음 — 대량 적재 시 OpenAI 비용 surprise 가능. 캐시 hit/miss 통계 출력 옵션 미구현.
  • --parallel 옵션 인덱서에 없음 — 수집기는 --parallel을 지원하나 semugpt-index bulk는 단일 프로세스. 대량 임베딩 시 시간 소요.
  • CLI 출력 = rich 색상 — 파이프/리다이렉트 시 ANSI escape가 섞일 수 있음. CI 사용 시 --no-color 옵션 없음 (NO_COLOR=1 env로 우회).
  • 운영 자동화 부재 — cron/CI 통합 없음. 정기 수집은 운영자가 수동으로 띄우는 구조. dev/prod 데이터 새로고침 SOP 별도 정립 필요.

관련 문서

  • 수집기 (Collectors)semugpt-collect가 호출하는 모듈 상세
  • 인덱서 (Indexers)semugpt-index가 호출하는 모듈 상세
  • Elasticsearch — ES URL/인증 설정, 매핑
  • 임베딩--embed 동작, 캐시
  • packages/data-pipeline/README.md (리포 안 직접 참조) — 패키지 자체 사용자 가이드