o2o-plagiarism-ai/docs/IMPLEMENTATION_RUNBOOK.md

5.8 KiB

O2O 표절·AI 의심도·판례 위험도 운영 런북

안전한 제품 경계

세 결과는 서로 다른 증거를 사용하며 합쳐서 하나의 침해 확정 값으로 만들지 않는다.

  1. 유사구간 검색: 현재 등록 코퍼스 안에서 발견된 후보와 원문 위치
  2. AI 생성 의심도: 원문 문체 특징에 대한 검토 우선순위(확정 판정 금지)
  3. 법적 위험도: 등록 판례와 판단 요소에 대한 검토 보조(법률 자문 아님)

후방 호환을 위해 is_infringement 필드는 유지하지만 실제 의미는 임계값을 넘은 has_similarity_match와 같다. 신규 연동은 has_similarity_match, corpus_scope_note, legal_risk를 사용한다.

수령 데이터 실사 결과

  • XLSX 본 데이터 34,105행, 원천 도서 79권
  • 고유 에피소드 31,560개, 같은 책 내부 중복 추가 행 2,545개
  • 고유 본문 약 2,946만 자
  • 페이지/문단 원문 좌표 없음: XLSX 적재 결과는 coordinate_scope=episode

King 서버 데이터 적재

원고 데이터와 학습 산출물은 Git에 커밋하지 않는다. /app/data Docker 볼륨 아래의 runtime, models, input을 사용한다.

python -m scripts.ingest_o2o_xlsx \
  data/input/o2o_episodes.xlsx \
  --database data/runtime/corpus.sqlite3

python -m scripts.build_persistent_index \
  --database data/runtime/corpus.sqlite3 \
  --index-dir data/runtime/index

같은 DB에 신규 세그먼트만 추가한 뒤 build_persistent_index를 다시 실행하면 결과의 modeappend이며 기존 행을 다시 벡터화하지 않는다. 삭제 또는 본문 변경이 감지된 경우에만 rebuild한다.

.env에서 다음을 설정하고 재기동한다.

USE_PERSISTENT_INDEX=true
CORPUS_DB_PATH=/app/data/runtime/corpus.sqlite3
PERSISTENT_INDEX_DIR=/app/data/runtime/index
PERSISTENT_SIMILARITY_THRESHOLD=0.65
# 바이칼과 키 전달을 합의한 뒤 활성화
API_KEY=<secret-manager-or-protected-env-value>

0.65는 영속 문자 n-gram 후보 검색의 보수적인 시작값일 뿐 운영 확정값이 아니다. 삽입 복제 테스트와 79권 상호비교 오탐 분포를 측정한 뒤 버전별로 보정한다.

PDF/DOCX 원문 위치 재구축

python -m scripts.extract_source_documents \
  /mnt/data2/demo/ai_publish/data/combooks \
  --database data/runtime/source_corpus.sqlite3 \
  --chunk-size 1000 --stride 500
  • PDF: 페이지 번호와 해당 페이지 추출 텍스트의 글자 offset 저장
  • DOCX: 문단 번호와 문단 내부 글자 offset 저장
  • 텍스트가 없는 PDF 페이지는 OCR 필요 경고
  • 구형 .doc은 먼저 DOCX 또는 PDF로 변환 필요

96개 raw와 79개 처리 도서의 대응표를 검수한 후, 위치 정보가 더 정확한 source_corpus.sqlite3를 운영 코퍼스로 승격한다.

AI 탐지 학습

XLSX의 에피소드 열은 원문이 사람 작성임이 계약·생성 이력으로 확인된 경우에만 human 라벨로 사용한다. AI 데이터는 모델·프롬프트·편집 유형별 provenance와 source_group을 가져야 한다. 학습/검증은 행이 아니라 book/source group으로 나눈다.

AI 모델 파일이 없거나 단일 클래스 데이터뿐이면 API는 실제 점수를 가장하지 않고 미학습 상태를 표시해야 한다. 완전 AI, 사람 편집 AI, AI 윤문, 혼합 문서를 각각 미학습 모델·미학습 도서로 평가한다.

판례 적재

data/precedents/precedents.jsonl에는 공식 HTTPS 출처와 사건번호가 확인된 레코드만 넣는다.

python -m scripts.validate_precedents data/precedents/precedents.jsonl

현재 저장소의 판례는 스키마 동작을 확인하기 위한 최소 시드다. 2,000건 적재 완료로 표현하면 안 된다. 재배포 허용 범위 확인과 저작권 전문가의 다음 항목 라벨링이 필요하다.

  • 보호되는 표현 / 아이디어·사실·상투적 표현
  • 의거관계 판단 근거
  • 실질적 유사성 인정·부정 이유
  • 저작물 유형과 결론

엔진은 등록된 사건번호만 반환하며 판례를 자유 생성하지 않는다.

검증 게이트

  • 데이터: 79권/31,560 고유 XLSX 세그먼트 적재 수 일치
  • 증분성: 신규 문서 추가 후 index sync mode=append
  • 검색: 100/200/300/500자 복사·삽입 세트의 Recall@20 기록
  • 근거 위치: 반환한 query/source offset으로 원문 substring이 정확히 복원됨
  • 오탐: 책 단위 분리 및 자서전 공통표현 hard-negative 검수
  • AI: unseen book/model의 AUROC뿐 아니라 FPR, AUPRC, 혼합·편집 유형별 결과 기록
  • 법적 위험도: 미등록 사건번호 0건, 빠진 법적 사실을 항상 명시
  • API: CPU 작업 중 /v1/health event loop가 응답 가능

배포/롤백

  1. 테스트 통과 및 Git SHA 기록
  2. King에서 git pull --ff-only
  3. 데이터 적재/인덱싱/AI 학습은 호스트 또는 일회성 Compose 컨테이너에서 실행
  4. docker compose up -d --build
  5. /v1/health, /v1/plagiarism/detect, 코퍼스 수, 모델 준비 상태 확인
  6. 문제 시 이전 Git SHA의 이미지를 다시 빌드하되 data/runtime은 보존

Ubuntu 18.04는 지원 종료 상태이므로 OS 업그레이드 전까지 외부 공개 범위를 최소화하고, API 인증·방화벽·키 회전을 별도 운영 작업으로 완료해야 한다.

선택적 KoSimCSE

기본 CPU 이미지는 새 영속 문자 인덱스를 사용하며 torchsentence-transformers를 포함하지 않는다. 일반 PyPI의 최신 torch가 CUDA 런타임 수 GB를 함께 설치할 수 있기 때문이다. 레거시 KoSimCSE가 반드시 필요한 별도 이미지에서만 해당 Python 버전에 맞는 공식 CPU 전용 torch wheel을 먼저 설치한 뒤 sentence-transformers를 추가한다.