판례가 적재돼 있는지, 이번 판단에 실제로 쓰였는지가 화면에 전혀 드러나지
않았다. 엔진은 적재본 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>
문제: 리스트업이 선별 57건만 다뤄서, "표절 탐지에 실제로 쓰이는 판례가 무엇인가"에
답할 수 없었다. 엔진이 로드하는 것은 57건이 아니라 적재본 545건 전부이고
(PRECEDENTS_PATH), 판정 1건마다 유형·태그가 맞는 상위 5건을 인용한다.
또 컴북스 제공분이 얼마나 반영됐는지가 어디에도 기재돼 있지 않았다. 데이터에는
레코드의 excel_duplicate 필드로 남아 있는데 문서에 나오지 않아, 회의에서
"우리가 준 판례는 어떻게 됐나"라는 질문에 답할 수 없는 상태였다.
컴북스 제공 고유 사건번호 142
공식 상세 페이지 미확인 → 제외 -103
엔진 라벨 부족 → 제외 -8
엔진 적재본에 포함 31 (21.8%)
이 중 리스트업 선정 10 (A 3 · B 6 · C 1)
제외된 103건은 사건번호만으로는 인용 출처가 되지 않아 적재하지 못했다. 판결문
원문이나 확인 경로를 받으면 적재 가능하므로 컴북스에 회신을 요청해야 하고, 그
목록을 Excel 시트에 그대로 실었다.
Excel 에 시트 2개 추가:
적재본 전체 545건 전수. 출처(컴북스/위원회)와 리스트업 등급을 함께 표시
컴북스 제공분 단계별 반영 내역, 적재된 31건, 회신 요청할 103건 목록
주의로 남긴 것: 컴북스 목록의 주제 분류와 실제 판시가 어긋나는 건이 리스트업에도
흘러들어갔다. 컴북스 유래 A등급 3건 중 2012다73493(깃털 공예품)은 어문 사건이
아니며 2017다212095(게임)도 마찬가지다. 인용 전 원문 대조가 필요하다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CSV 는 UTF-8 BOM 이라 Excel 에서 열리기는 하지만 받는 쪽이 그대로 읽을 수 있는
형태가 아니다. 열 너비·줄바꿈·필터가 없어 판시 요약처럼 긴 칸이 한 줄로 뭉개지고
등급별로 훑어보기도 어렵다. 전달 첨부용 통합문서를 별도로 만든다.
docs/판례_리스트업.xlsx — 5개 시트
판례 목록 57건. 등급 색상 구분, 자동 필터, 사건번호까지 틀 고정, 출처 하이퍼링크
요약·방법 검토 단계별 건수(2,085 → 545 → 57), 등급 정의, 핵심 3건
제외 사유 수집 단계 제외분과 적재본에서 뺀 유형
데이터 공백 상담 전 해소가 필요한 4개 항목 + 선덕여왕 항소심 인용 주의
상담 질의 전문가 상담용 질의 5건
표 데이터는 precedent_listup.csv 에서 읽고, 서술 시트는 PRECEDENT_LISTUP.md 를
원본으로 옮겼다. 수치를 스크립트에서 새로 만들지 않는다.
법률 의견서가 아니라 데이터 정리 결과이며 등급·쟁점 요약은 적재 판시를 근거로
부여한 것이라는 단서를 요약 시트에 함께 넣었다. 전달 시 유지해야 한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
한국저작권위원회 운영 적재본 545건을 전수 검토해 A/B/C 3등급 57건을 선정하고
제외 사유와 데이터 공백을 함께 정리했다. 표는 scripts/build_precedent_listup.py로
JSONL에서 재생성한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
계획서 p.24 가 No.3/4/7 의 평가환경을 python 3.9 로 못박았는데, 실제로는
성능지표 평가 스크립트 3종이 전부 3.9 에서 임포트조차 되지 않았다.
python:3.9-slim 컨테이너에서 재현·수정·재검증했다.
원인: config.py 와 schemas.py 가 `from __future__ import annotations` 없이
`str | None` (PEP 604) 을 썼다. 3.10 부터의 문법이라 클래스 본문이 실행되는
순간 인터프리터가 평가하며 TypeError 로 죽는다. 이 두 파일을 타고 detector /
extractor / clustering / taxonomy / jobs.store / routes / main 이 연쇄로 깨졌다.
No.7 eval_rouge.py → summarizer → core.config
No.3 eval_metadata_f1.py → extractor → api.schemas
No.4 evaluate_pairs.py → detector → api.schemas
개발환경이 3.14 라 로컬에서는 전혀 드러나지 않았다. 정답셋을 받아 측정하는
시점에 발견했다면 일정이 밀렸을 문제다.
수정은 두 가지가 모두 필요하다. future 임포트만 넣으면 pydantic 이 문자열
'str | None' 을 해석하지 못하고("Unable to evaluate type annotation"),
eval_type_backport 만 넣으면 인터프리터가 먼저 죽는다.
검증: 3.9 에서 eval_rouge.py / eval_metadata_f1.py 가 정상 실행되고 수치가
3.14 와 동일하다(ROUGE-1 recall 0.5778). evaluate_pairs.py 와 app.main 임포트도
통과. 3.14 회귀 없음.
재발 방지로 tests/test_py39_compat.py 를 추가했다. Pydantic 모델을 정의하는
모듈에 future 임포트가 있는지 AST 로 검사하므로 3.14 에서도 회귀를 잡는다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
SCOPE_AND_METRICS.md 신규. 연구개발계획서(2-4 성능지표, 나-3 개발내용,
나 성과물 목표)를 대조해 오투오 몫을 정리했다.
- 성능지표 8개 중 우리가 수치를 책임지는 것은 No.3·4·7 세 개다.
- No.4 는 재현율이 아니라 정밀도라 애매하면 표절이라 말하지 않는 쪽이
지표에 유리하다. 이 성질이 설계를 지배한다.
- 사용자 맞춤형 요약의 상세도·강조 내용 옵션이 계획서에 있는데 미구현이다.
- python 3.9 호환성 위험: 평가환경이 3.9 고정인데 config.py 와 schemas.py 가
from __future__ import annotations 없이 PEP 604 를 쓴다. 둘 다 Pydantic
모델이라 어노테이션이 런타임에 평가된다. 현재 개발환경이 3.14 라 안 드러난다.
- No.3 귀속이 오투오/고려대 사이에서 불분명해 확인이 필요하다.
AI_DETECTION.md 에 「위상과 기준」절 추가. AI 생성 판별은 성능지표 8개
어디에도 없고 계획서 개발내용에도 없다. "콘텐츠 표절 여부 AI 탐지 모듈"은
AI로 표절을 탐지하는 모듈이지 AI가 쓴 글을 탐지하는 모듈이 아니다.
따라서 정확도를 보고하지 않는다. 정답 라벨이 없는 대상에 정확도를 주장하면
검토자를 과신하게 만들 뿐이다. 대신 근거(79권 대비 문체 이례도)와
기준(실측 백분위 컷)을 명시하고, 할 수 있는 말과 없는 말을 표로 구분했다.
8장의 예시 컷이 자리표시자 값이라 실측값으로 갱신했다.
DATA_REQUEST_SPEC.md §5 요약 정답셋 가이드 보강. 다중 참조 포맷, 줄글 규격,
dev/test 분리(test 는 사람 직접 작성 — LLM 이 쓴 정답을 LLM 출력으로 맞히면
점수가 부풀고 방어할 수 없다), book 단위 누출 방지, §5.1 파일럿 절차,
§5.2 recall 정정 이력.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
계획서 p.24 수식의 분모가 참조 n-gram 수이므로 지표는 recall 인데
eval_rouge.py 는 ROUGE-1 F1 을 목표 0.65 와 대조하고 있었다. 통상 시스템
요약이 참조보다 길면 recall > F1 이므로 우리에게 불리한 자체 기준으로
채점해 온 셈이다(내장 샘플에서 recall 0.5778 vs F1 0.5539).
같은 수식이 Σ_S∈{Reference Summaries} 로 다중 참조를 전제하는데 rouge_n /
rouge_l 은 참조를 문자열 하나만 받았다. 이제 문자열도 리스트도 받는다.
참조가 1개면 기존과 완전히 같은 값이 나오며 이를 테스트로 고정했다.
--iaa 모드를 추가했다. 사람 둘이 같은 글을 요약해도 ROUGE 는 100 이 안
나오고, 그 상한이 65 보다 낮으면 어떤 시스템도 목표를 달성할 수 없다.
정답셋 300건을 만들기 전에 파일럿 20건으로 상한을 먼저 재기 위한 것이다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
보유 코퍼스 31,560건이 전부 human 라벨이라 이진 판별기를 학습할 수 없고
(train_ai_detector.py 가 exit 2 로 막는다), 조사 결과 공개된 한국어 AI 생성
판별 데이터셋도 확인되지 않았다. AI 쪽 절반을 직접 만든다.
build_ai_training_dataset.py 가 외부 호출을 금지하므로 생성은 별도 스크립트로
분리했다. 프롬프트는 이미 파생된 메타데이터만 쓰고 에피소드 본문은 어떤
경로로도 API 요청에 실리지 않는다. 주석만으로는 다음 사람이 META_COLUMNS 에
본문 컬럼을 한 줄 추가하는 것을 못 막으므로, assert_no_body_columns() 가
실행 시점에 차단하고 _build_prompt() 는 본문을 넘길 파라미터 자체가 없다.
- 길이 매칭: human 분포에서 목표 길이를 뽑아 지시하고 벗어난 결과는 버린다.
분량이 다르면 판별기가 문체가 아니라 길이를 배운다.
- 생성기 다중화: --model 반복 지정 시 라운드로빈. 1개면 그 모델만 잡는
판별기가 되므로 경고한다.
- 문체 6종을 결정적으로 배분해 한 모델의 한 문체 암기를 막는다.
- 생성문에도 human 과 같은 normalize_ocr 을 적용한다. 한쪽만 정규화하면
오염 방향만 뒤집힐 뿐이다.
- append 전용 + prompt_id 스킵으로 재개 가능. dry-run 은 파일시스템도
건드리지 않는다.
--base-url 로 사내 GPU 의 OpenAI 호환 서버를 쓰면 메타데이터조차 외부로
나가지 않는다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
학습·캘리브레이션에 쓰는 79권 코퍼스는 OCR 후처리본이라 저자 문체가 아닌
스캔·조판 흔적이 남아 있다. AI 생성 표본에는 그 흔적이 없으므로, 그대로 두면
분류기가 문체가 아니라 "OCR 흔적이 있으면 human"을 배운다. 그러면 운영에서
들어오는 깨끗한 인간 원고가 AI로 오판된다.
규칙은 추측이 아니라 코퍼스 34,105건 실측에서 뽑았다. 표본 3,000건 기준
숫자+공백+단위 94.8%, 한자 병기 99.4%, 낫표 100% 제거.
정상 한국어인 `America라는`·`3년` 형태는 건드리지 않는다.
숫자-단위 규칙은 정규식으로 밀어넣으면 `3 번지`를 `3번지`로 잘못 붙이므로
단위·접미사 화이트리스트로 판정한다.
멱등성과 "깨끗한 입력에 무해" 두 불변식을 테스트로 고정했다. 후자가 깨지면
운영 원고가 학습 코퍼스와 다르게 처리되어 정규화 자체가 새 편향이 된다.
calibrate_ai_detector_cuts.py 에 xlsx 입력과 OCR 정규화(기본 켜짐)를 추가했다.
79권 3,000건 실측 결과 low_cut 0.4286 / high_cut 0.5298, 인간 원고 기준
예상 high 비율 2.03%(설계 목표 2%)로 포화 없이 잡혔다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
AI 생성 표본이 없어 정확도를 측정할 수 없는 상태에서, 규칙 기반 휴리스틱을
실제로 쓸 수 있게 만든다. 점수의 의미를 "AI일 확률"에서 "등록 코퍼스의 인간
저작물 대비 문체 이례도"로 재정의해, 라벨 없이도 참인 진술이 되도록 했다.
덤으로 high 배지 비율이 정의상 고정되어 검토 부하가 예측 가능해진다.
- ai_detector: low_cut/high_cut 주입 지원. 둘 다 주어질 때만 적용하고,
적용되면 model_version 에 +corpus-percentile 을 붙여 컷 출처를 드러낸다.
is_stub 은 여전히 true — 컷을 맞췄을 뿐 학습된 모델이 아니다.
- calibrate_cuts/percentile/score_text_heuristic 순수 함수 추가.
- scripts/calibrate_ai_detector_cuts.py: 코퍼스 표본의 점수 분포에서 백분위
컷을 산출하고 .env 두 줄을 출력한다.
- 규칙 점수가 상단에서 clip 되어 p90=p98 이 되면 그 컷은 high 배지를 영원히
0건으로 만든다. 이 경우 .env 를 출력하지 않고 exit 3 으로 중단하며
saturated_share/distinct_scores 진단을 남긴다. 유효 표본 100건 미만은 exit 2.
- kiwipiepy 유무가 점수를 바꾸므로 실제 사용 여부를 리포트에 기록하고 경고한다.
기본값은 그대로 비활성(AI_DETECTOR_ALLOW_HEURISTIC=false)이라 켜지 않으면
동작이 바뀌지 않는다. 컷 미설정 시에는 자리표시자임을 note 로 경고한다.
테스트 180건 통과 (신규 13건).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
엔드포인트 10종 상세 사용법 + 응답 필드별 의미 + 저작권 탭 렌더링
호출 순서(detect 1회 → review_summary로 화면 구성) 정리.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
나누구 앱 저작권 탭 연동을 위해 detect 응답에 두 블록 추가:
- review_summary: 독창성%/유사도%/유사문장 건수/대조 건수/의심 유무/AI 의심도
(독창성 환산 캘리브레이션 포함 — 무관한 글은 유사도 0~5%로 눌러 표시)
- ai_generation: AI 생성 의심도 스텁(요청마다 더미, is_stub=true).
워터마킹+언어특징 분류 정식 구현 전까지 계약 확정용.
바이칼 연동용 API 양식서(docs/API_SPEC_BAIKAL.md) 추가.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
컴북스 데이터 수령 전 가능한 작업을 선행 구현. 데이터 도착 즉시
학습·검증에 착수할 수 있도록 알고리즘·평가 하니스·문서를 준비.
알고리즘/파이프라인:
- engine/clustering.py: 군집화 기반 부분 표절(요소 교체) 판별,
detect 응답에 partial_signal 필드 노출 (계획서 2단계 표절검출 고도화)
- engine/summarizer.py + POST /v1/summary: TextRank 추출적 요약 +
통합(LLM) 골격 (과제2 ② 스토리 요약/분석)
- engine/preference.py + scripts/build_preference_dataset.py:
Human Feedback 선호학습(DPO) 데이터 파이프라인 골격
평가 하니스 (정답셋 도착 즉시 측정):
- engine/rouge.py + scripts/eval_rouge.py: 요약 ROUGE (지표 No.7)
- engine/metadata_eval.py + scripts/eval_metadata_f1.py: 메타 추출 F1
(지표 No.3, KLUE NER 호환)
- engine/case_coverage.py + scripts/analyze_case_coverage.py:
39 케이스 갭 분석 → 컴북스 데이터 요청 목록 (정밀도 97% 근거)
문서:
- docs/DATA_REQUEST_SPEC.md: 요청 데이터 스펙 + 요약 정답셋/HF 라벨 가이드
- docs/INTEGRATION_INTERFACE.md: 2단계 통합 인터페이스
- docs/SW_COPYRIGHT_REGISTRATION.md: SW 저작권 등록 준비
- docs/PHASE2_PROGRESS.md, docs/CASE_COVERAGE.md
테스트 31 → 67건 전부 통과.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
docker-compose v1.x가 \${VAR:-default} interpolation을 지원하지 않아
"Invalid interpolation format" 에러 발생. v1/v2 모두 호환되도록 폴백 제거.
.env 의 PORT/HOST 등은 env_file 로 자동 주입.
- config.Settings에 host/port/log_level/reload 필드 추가
- app/main.py에 main() + __main__ 진입점 추가 (python -m app.main)
- Dockerfile: python:3.13-slim 베이스로, CMD를 python -m app.main 으로 변경
- docker-compose: env_file 사용, ports를 ${PORT} 변수화
- 환경변수 PORT=N 으로 override 가능 (uvicorn 직접 실행도 그대로 지원)