AI 출판과제 - 저작권 침해 여부 판단
Go to file
hbyang 500a4a4600 feat: 프론트에 판례 적재·인용 현황 표시
판례가 적재돼 있는지, 이번 판단에 실제로 쓰였는지가 화면에 전혀 드러나지
않았다. 엔진은 적재본 545건을 모두 로드하고 판정마다 저작물 유형·법적 태그가
맞는 상위 5건을 인용하는데, 사용자는 "판례를 쓰고 있는가"를 알 수 없었다.

세 곳에 표시한다.
  헤더 배지   ● 정상 · 코퍼스 3건 · 판례 545건
  푸터        판례 적재: 545건
  판단 카드   관련 판례 사건번호   인용 3건 / 적재 545건

적재 수를 함께 보여 주는 것이 핵심이다. "인용 3건"만 있으면 판례를 3개만
쓰는 것처럼 읽히는데, "/ 적재 545건"이 붙어야 545건 중 이 건에 맞는 3건을
고른 결과임이 드러난다.

인용 0건과 판례 미적재도 구분했다. 겉보기엔 둘 다 판례가 없지만 앞은 정상
동작이고, 뒤는 엔진이 insufficient_precedent_data 를 내며 판단 자체를
보류하는 상태다. 설정 오류일 가능성이 높아 배지를 경고색으로 바꾼다.

API 는 이미 /v1/health 의 precedent_count 와 응답의 precedent_ids 로
필요한 값을 주고 있었다. 프론트만 쓰지 않고 있었으므로 서버 변경은 없다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 14:54:51 +09:00
app feat: 프론트에 판례 적재·인용 현황 표시 2026-08-20 14:54:51 +09:00
data docs: 자서전·출판물 표절 판단 근거 판례 리스트업 추가 2026-08-19 14:44:20 +09:00
docs docs: 적재본 545건의 출처 내역 추가 (컴북스 31 / 위원회 514) 2026-08-20 12:57:34 +09:00
reports 성능지표 및 레포트 업로드 . 2026-05-18 14:54:01 +09:00
scripts docs: 적재본 545건의 출처 내역 추가 (컴북스 31 / 위원회 514) 2026-08-20 12:57:34 +09:00
tests feat: 프론트에 판례 적재·인용 현황 표시 2026-08-20 14:54:51 +09:00
.dockerignore 3.5만 에피소드 기반 표절·AI·판례 분석 파이프라인 구현 2026-08-10 16:12:15 +09:00
.env.example feat: 판례 GPT 판단과 연동 가이드 최신화 2026-08-18 11:10:02 +09:00
.gitignore 3.5만 에피소드 기반 표절·AI·판례 분석 파이프라인 구현 2026-08-10 16:12:15 +09:00
docker-compose.yml 3.5만 에피소드 기반 표절·AI·판례 분석 파이프라인 구현 2026-08-10 16:12:15 +09:00
Dockerfile Claude 리뷰 기반 운영 안정성 보강 2026-08-10 16:42:17 +09:00
README.md API Key 인증 완전 제거 2026-05-14 08:58:28 +09:00
requirements.txt fix: 평가환경(python 3.9)에서 임포트 실패 해결 2026-08-19 14:02:29 +09:00

O2O 저작권 침해 여부 탐지 API

KOCCA 출판환경변화 과제 2단계 - 오투오 산출물. 자서전 본문을 입력하면 저작권 침해 여부를 판정해 법령 기반 메타 태그와 케이스 ID로 반환합니다.

기능

  • 삼중 유사도 탐지 — 표면(임베딩) + 구조(형태소 lemma 교집합) + 요소(인물·모티프) 결합 판정
  • 3단 캐스케이딩 — MinHash+LSH 1차 필터 → 정밀 비교 → 침해 유형 분류
  • 법령 기반 10종 메타 태그 — 복제권 / 공중송신권 / 배포권 / 2차적저작물작성권 / 공표권 / 성명표시권 / 동일성유지권 / 인용 표시 누락 / 자기 창작인 양 표시 / 2차적저작물 미달 가공
  • 39개 침해 케이스 자동 매핑 — 그룹 A(저자 가해) ~ X(분류체계 외)
  • 자서전 특화 처리 — 공통 표현 사전 제거 + NER 마스킹으로 오탐 방지
  • 검토 콘솔 웹 UI — 브라우저에서 본문 입력·검사·결과 분석, 코퍼스 관리
  • 코퍼스 직접 관리 — 사용자가 자서전을 직접 업로드/삭제, 인덱스 자동 재빌드
  • 배치 처리 — 비동기 잡으로 최대 500건 일괄 검사

빠른 시작

Docker

cp .env.example .env
# .env 에서 HOST/PORT/LOG_LEVEL/OPENAI_API_KEY 등 조정 (선택)
docker compose up --build

로컬 (Python 3.13 권장)

python3.13 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

# .env 의 HOST/PORT 따라 실행
python -m app.main

# 또는 일회성 override
PORT=9000 LOG_LEVEL=debug python -m app.main

# 또는 uvicorn 직접
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

접속:

  • http://localhost:{PORT}/ — 검토 콘솔 (브라우저용)
  • http://localhost:{PORT}/docs — API 명세 (Swagger)

.env 의 서버 바인딩 변수:

변수 기본 설명
HOST 0.0.0.0 바인딩 호스트
PORT 8000 포트
LOG_LEVEL info debug/info/warning/error
RELOAD false 파일 변경 시 자동 재시작 (개발용)

사용법

1. 브라우저에서 사용 (검토 콘솔)

http://localhost:8000/ 접속.

[탐지 검토] 탭

  1. 본문 텍스트 붙여넣기 (또는 샘플 시나리오 버튼 클릭)
  2. "검사 시작" → 결과 표시
    • 큰 판정 배지 (침해 여부 + 결합 유사도 %)
    • 점수 분석 (text / lemma / character / motif 4개 막대)
    • 매칭된 레퍼런스 + 법령 태그 chip (주/보조) + 케이스 ID
    • 본문에 일치 구간 하이라이트

[코퍼스 관리] 탭

  1. 좌측 폼에서 자서전 신규 등록 (제목 + 본문 또는 .txt 파일)
  2. 우측 테이블에서 등록된 자서전 확인 / 삭제
  3. 업로드/삭제 시 인덱스 자동 재빌드

2. API로 사용 (curl)

# 탐지
curl -X POST http://localhost:8000/v1/plagiarism/detect \
  -H "Content-Type: application/json" \
  -d '{
    "doc_id": "test-001",
    "text": "검사할 본문 텍스트…",
    "metadata": {"title": "작품명", "author": "저자"}
  }'

# 자서전 업로드
curl -X POST http://localhost:8000/v1/corpus \
  -H "Content-Type: application/json" \
  -d '{"title": "김OO 자서전", "text": "본문…"}'

# .txt 파일 업로드
curl -X POST http://localhost:8000/v1/corpus/file \
  -F "title=김OO 자서전" \
  -F "file=@autobiography.txt"

# 코퍼스 목록
curl http://localhost:8000/v1/corpus

# 분류체계 조회 (10종 태그 + 39 케이스)
curl http://localhost:8000/v1/taxonomy

엔드포인트 요약

Method Path 용도
GET / 검토 콘솔 (HTML)
GET /docs Swagger UI
GET /v1/health 헬스체크 + 엔진 정보
GET /v1/taxonomy 분류체계 조회
POST /v1/plagiarism/detect 단건 동기 탐지
POST /v1/plagiarism/batch 배치 잡 등록 (≤500건)
GET /v1/plagiarism/batch/{job_id} 배치 결과 조회
GET /v1/corpus 코퍼스 목록
POST /v1/corpus JSON 업로드
POST /v1/corpus/file .txt 파일 업로드
DELETE /v1/corpus/{doc_id} 삭제

응답 스키마 (탐지 결과)

{
  "doc_id": "test-001",
  "is_infringement": true,
  "confidence": 0.85,
  "extracted_elements": {
    "characters": ["..."],
    "motifs": ["..."],
    "genre": "...",
    "keywords": ["..."]
  },
  "matches": [{
    "source_doc": "ref-0001",
    "source_title": "원본 작품명",
    "similarity": 0.85,
    "tags": [
      {"tag": "reproduction", "role": "primary", "label_ko": "복제권"},
      {"tag": "citation_missing", "role": "primary", "label_ko": "인용 표시 누락"},
      {"tag": "public_transmission", "role": "secondary", "label_ko": "공중송신권"}
    ],
    "case_id": "A1",
    "case_title": "시·노래 가사 본문 무단 인용",
    "evidence_spans": [{"start": 21, "end": 34, "matched": "…"}],
    "score_breakdown": {
      "text_sim": 0.43, "lemma_sim": 0.75,
      "character_sim": 0.0, "motif_sim": 0.67,
      "lsh_jaccard": 0.07
    }
  }],
  "ccl_basis": "…",
  "autobiography_mode": true,
  "engine_version": "o2o-plagiarism-2.0.0-pdf-v1.2"
}

환경변수 (.env)

변수 기본 설명
SIMILARITY_THRESHOLD 0.85 침해 판정 임계값 (정밀도 우선)
AUTOBIOGRAPHY_MODE true 자서전 특화 전처리 (공통표현+NER)
USE_LSH_FILTER true MinHash+LSH 1차 필터
USE_LLM_EXTRACTOR false OpenAI 기반 요소 추출 (키 필요)
USE_EMBEDDING_SIMILARITY false OpenAI 임베딩 유사도 (키 필요)
OPENAI_API_KEY (빈값) 비우면 룰 기반 + TF-IDF 폴백
WEIGHT_TEXT_SIM 0.30/0.45/0.15/0.10 삼중 유사도 가중치 (합 1.0)

요청 단위 override 가능 항목:

  • options.threshold — 임계값
  • options.autobiography_mode — 자서전 모드 ON/OFF

테스트

pytest tests/ -v
# 31 passed — API, 삼중 유사도, 형태소 분석, PDF 분류체계, LSH, 자서전 필터, 다중 태그 부여

디렉토리 구조

app/
├── main.py                       # FastAPI 앱
├── api/{routes,schemas}.py       # 엔드포인트 + Pydantic 모델
├── core/{config,auth}.py         # 설정 + API Key 인증
├── engine/
│   ├── detector.py               # 탐지 파이프라인 오케스트레이션
│   ├── extractor.py              # 콘텐츠 요소 추출 (룰 또는 OpenAI)
│   ├── similarity.py             # 삼중 유사도 + TF-IDF/임베딩 백엔드
│   ├── structural.py             # 형태소 lemma 교집합
│   ├── lsh_filter.py             # MinHash+LSH 1차 필터
│   ├── autobiography_filter.py   # 자서전 공통표현 제거 + NER 마스킹
│   ├── corpus.py                 # 코퍼스 CRUD
│   └── taxonomy.py               # 10종 태그 + 39 케이스 매핑
├── jobs/store.py                 # 배치 잡 in-memory 스토어
└── static/index.html             # 검토 콘솔 UI
data/
├── reference/                    # 자서전 코퍼스 (업로드 저장 위치)
├── taxonomy/{meta_tags,cases}.json   # PDF v1.2 분류체계
└── autobiography/common_patterns.txt # 자서전 빈출 표현 사전