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 |
stub — pyproject.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]
또는 설치 후 직접 실행:
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 — 인덱스 생성¶
| 옵션 | 기본값 | 설명 |
|---|---|---|
--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 — 벌크 적재¶
| 옵션 | 기본값 | 설명 |
|---|---|---|
--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 — 설정 정보 출력¶
현재 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-uploadentry point는 dangling —pyproject.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=1env로 우회). - 운영 자동화 부재 — cron/CI 통합 없음. 정기 수집은 운영자가 수동으로 띄우는 구조. dev/prod 데이터 새로고침 SOP 별도 정립 필요.
관련 문서¶
- 수집기 (Collectors) —
semugpt-collect가 호출하는 모듈 상세 - 인덱서 (Indexers) —
semugpt-index가 호출하는 모듈 상세 - Elasticsearch — ES URL/인증 설정, 매핑
- 임베딩 —
--embed동작, 캐시 packages/data-pipeline/README.md(리포 안 직접 참조) — 패키지 자체 사용자 가이드