Commit Graph

34 Commits

Author SHA1 Message Date
94a660dc35 feat: finalize report at 9-eojeol threshold
기준을 9어절(35자)로 확정하고 문서를 그 기준으로 다시 만든다.
중복 제거 + 9어절 재실행 결과는 검사 대상 6087건, 침해의심 80건이다.

9어절 근거는 문서쌍 전수 대조다. 545문서 148,240쌍을 모두 대조하니
100어절(390자)까지 올려도 18쌍이 계속 겹친다. 겹침이 0이 되는 어절 수는
없다. 10~15어절에서 27쌍으로 고정되어 더 줄지 않는데, 오탐이라면 기준을
올릴수록 계속 줄어야 한다. 즉 그 지점부터 남는 것은 실제 유사 원고다.
상투어 노이즈는 4->5어절에서 대부분 걷히므로 9어절이 실질적 하한이다.

배포 파일을 하나로 합친다. 원문 대조 시트를 결과보고에 넣어 의심 80건의
원문을 같은 파일에서 볼 수 있게 하고, 숫자가 맞지 않는 중복 제거 전
파일 두 개는 배포 위치에서 내린다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 14:29:30 +09:00
bf3bd5b99b feat: sweep exact-span threshold from 3 to 9 eojeol
상무님 요청대로 어절 기준을 3~9로 바꿔가며 재판정한다. 기준값은 검색
후보를 바꾸지 않고 채택 여부만 정하므로, 후보 판정재료를 한 번 남겨두면
7회 실행 없이 오프라인에서 전부 계산할 수 있다. 27자로 재계산한 값이
실제 실행 결과 85건과 일치해 방식을 검증했다.

배치 스크립트에 하드코딩돼 있던 80 을 걷어낸다. --min-exact-span 을 줘도
이 줄이 설정을 읽지 않아 값이 적용되지 않았다.

겹침률 측정도 바로잡는다. 앞서 7어절 0% 로 봤던 것은 4만 쌍에서 히트가
0~1건이라 해상도가 없었고, 그 1건조차 같은 문서 내부의 반복이었다.
15만 쌍으로 늘리고 엔진과 같이 자기 문서 쌍을 빼면 9어절에서도 4.0% 다.
겹침이 사라지는 지점은 없으므로 '오탐 0 인 최저점' 논리는 성립하지 않는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 13:27:10 +09:00
f4fab1089e feat: fold duplicate analysis into the report workbook
별도 파일을 늘리지 않고 기존 결과보고 워크북에 '중복 원고' 시트로 넣는다.
중복 제거 후 재실행하면 28건이 결과에서 사라지므로, 사라지기 전에 어떤
문서 사이의 중복이었는지 원문째로 남겨야 나중에 같은 제출자의 재제출인지
다른 제출자의 표절인지 확인할 수 있다.

--no-excerpt-sheet 로 원문 대조 시트 없이 중복 시트만 붙일 수 있게 했다.
결과보고는 원문 없는 배포판이라 이 경로를 쓴다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 10:44:18 +09:00
76c710c6ef feat: support dedup rerun and configurable exact-span threshold
상무님 지적 두 가지를 검증 가능한 형태로 만든다.

1) 중복 원고: 코퍼스 6343건 중 247그룹 503건이 중복이고, 침해의심 103건
   중 28건이 여기서 비롯됐다. 다만 247그룹 중 234그룹이 서로 다른 문서
   사이의 중복이라 같은 제출자의 재제출인지 다른 제출자의 표절인지 아직
   모른다. 지우기 전에 원문째로 남기도록 build_duplicate_report.py 를 둔다.

2) 연속 일치 기준 80자: 근거 없이 잡힌 초기값이다. 무관한 원고 4만 쌍을
   대조해 재보니 3어절 100%, 4어절 99.8%, 5어절 47%, 7어절 0% 오탐이다
   (한 건을 6343건과 대조하는 효과 반영). 관행인 3~5어절은 쓸 수 없고
   7어절 = 공백 포함 27자가 오탐 0% 를 유지하는 최저점이다.

배치에 --exclude-segments 와 --min-exact-span 을 추가한다. 중복은 질의와
색인 양쪽에서 함께 빼야 한다. 한쪽만 빼면 지운 원고가 여전히 상대로 잡힌다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 10:29:27 +09:00
e89cd23ed6 feat: report original text and judgment criteria for review
검토자가 침해 여부를 눈으로 판별하려면 원문이 있어야 하고, 어떤 조건으로
걸렸는지 알아야 한다. 두 가지를 워크북에 싣는다.

- extract_suspected_excerpts.py: 코퍼스 DB(읽기 전용)에서 질의·상대 원문과
  일치 구간을 뽑는다. 킹서버 기본 python 이 3.6 이라 이 파일만 구문을 맞췄다.
- '판정 기준' 시트: 3개 OR 조건과 결합유사도 가중치, 조건별 충족 현황
- '원문 대조' 시트: 판정 사유 컬럼으로 각 건이 걸린 조건을 표시

판례 표기도 바로잡는다. USE_LLM_LEGAL_JUDGE=false 는 LLM 법적 판단만
끈 것이고 판례 검색은 규칙 기반으로 늘 동작한다. legal_risk.assess() 가
점수 하한 없이 상위 5건을 붙이므로 매칭 미탐지 건에도 판례가 채워진다.
한 줄에 뭉쳐 두면 모순으로 읽혀 판례 검색과 법적 판단을 분리해 적었다.

원문이 담긴 산출물은 gitignore 로 제외한다. 필요하면 위 스크립트로
코퍼스에서 다시 뽑을 수 있어 저장소에 영구 보존할 이유가 없다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 09:49:50 +09:00
87fc98119d feat: add reporting xlsx builder for infringement batches
배치 산출 JSONL은 엔진 내부 값(retrieval_backend, legal_judgment_method,
case_id 등 전 건 단일값 컬럼 포함)까지 22컬럼을 담고 있어 그대로 공유하면
오독을 부른다. 원본 JSONL을 건드리지 않고 보고에 필요한 컬럼만 추려
재생성하는 별도 스크립트를 추가한다.

- 침해 판별 결과: 전수 8컬럼, 의심 건 우선 정렬
- 의심 건 상세: 침해유형 한글화 + 관련 판례 연결
- 요약 통계: 근거 스팬 보유 건수와 해석 유의사항
- 1차_vs_2차 비교: 근거 스팬/커버리지 병기, 상위 N 절단 제거

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 13:46:31 +09:00
8717fa4425 feat: add isolated gpu embedding review batch 2026-09-02 09:58:59 +09:00
cbeb1e1084 feat: support sharded infringement batches 2026-09-02 09:28:38 +09:00
c35c5aabfc feat: add anonymized infringement batch reporting 2026-09-02 09:23:45 +09:00
9e365e6b68 feat: AI 의심도 모델의 학습 범위 노출 2026-08-21 09:06:26 +09:00
480f00702f feat: 전달 파일 전용 정책과 AI 표본 품질 감사 추가 2026-08-21 08:44:22 +09:00
40eede2566 feat: 요약 검수 패킷과 수기집 원본 수집 도구 추가 2026-08-20 17:24:39 +09:00
9f62ed877a chore: AI 생성 설정 provenance 기록 2026-08-20 17:22:14 +09:00
d0b5876ae5 feat: GPU 생성 작업 샤딩 지원 2026-08-20 17:19:41 +09:00
78e9f8648a fix: AI 표본 생성 재개 시 목표 건수 보존 2026-08-20 17:18:03 +09:00
265a388389 fix: AI 표본 생성기의 pandas 의존 제거 2026-08-20 17:15:35 +09:00
aabd7844d8 feat: 로컬 GPU AI 표본 병렬 생성 지원 2026-08-20 17:13:19 +09:00
946e9e9474 feat: 수령 자서전 데이터 파이프라인과 맞춤 요약 추가 2026-08-20 16:59:17 +09:00
5386222f1b feat: 전체 판례 검색과 판례 탭 추가 2026-08-20 16:20:37 +09:00
fa15117df7 fix: 판례 등급을 런타임 인용에 반영 2026-08-20 16:05:24 +09:00
a45c79211c docs: 적재본 545건의 출처 내역 추가 (컴북스 31 / 위원회 514)
문제: 리스트업이 선별 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>
2026-08-20 12:57:34 +09:00
ba1a0bbc2f docs: 판례 리스트업 배포용 Excel 추가
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>
2026-08-20 11:36:47 +09:00
66a21f8fd2 docs: 자서전·출판물 표절 판단 근거 판례 리스트업 추가
한국저작권위원회 운영 적재본 545건을 전수 검토해 A/B/C 3등급 57건을 선정하고
제외 사유와 데이터 공백을 함께 정리했다. 표는 scripts/build_precedent_listup.py로
JSONL에서 재생성한다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 14:44:20 +09:00
3da7a0a5f2 fix: 요약 ROUGE를 계획서 수식에 맞춤 (F1 → recall, 다중 참조)
계획서 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>
2026-08-19 13:54:22 +09:00
dc6c0f5d0f feat: AI 생성 표본 제작 스크립트
보유 코퍼스 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>
2026-08-19 13:54:21 +09:00
45355910fa feat: OCR·조판 아티팩트 정규화와 백분위 컷 캘리브레이션
학습·캘리브레이션에 쓰는 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>
2026-08-19 13:53:59 +09:00
ee2f85a2d9 feat: 판례 GPT 판단과 연동 가이드 최신화 2026-08-18 11:10:02 +09:00
a530d2139f AI 의심도 백분위 캘리브레이션 (학습·지표 없이 운영)
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>
2026-08-11 09:05:48 +09:00
725e44e999 Claude 리뷰 기반 운영 안정성 보강 2026-08-10 16:42:17 +09:00
ce50e89089 3.5만 에피소드 기반 표절·AI·판례 분석 파이프라인 구현 2026-08-10 16:12:15 +09:00
0472ae1f8a 2단계 고도화 선행 작업: 군집화·요약·평가환경·데이터 스펙 (데이터 수령 전)
컴북스 데이터 수령 전 가능한 작업을 선행 구현. 데이터 도착 즉시
학습·검증에 착수할 수 있도록 알고리즘·평가 하니스·문서를 준비.

알고리즘/파이프라인:
- 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>
2026-06-18 13:16:07 +09:00
cfa3d1b7cf 성능지표 및 레포트 업로드 . 2026-05-18 14:54:01 +09:00
4913bf3ecc API Key 인증 완전 제거
사내 운영 전제로 X-API-Key 인증을 전면 제거.
- app/core/auth.py 삭제
- routes.py에서 Depends(require_api_key) 모두 제거
- config.Settings에서 api_keys / api_key_set 제거
- .env / .env.example에서 API_KEYS 제거
- docker-compose.yml에서 API_KEYS 환경변수 제거 (KOSIMCSE_MODEL 추가)
- UI(index.html)에서 DEFAULT_API_KEY 상수 + X-API-Key 헤더 모두 제거
- scripts/sample_curl.sh, sample_python.py에서 키 헤더 제거
- tests: test_detect_requires_api_key → test_detect_no_auth_required로 갱신
- README: 인증 컬럼 제거, curl 예시에서 헤더 제거
2026-05-14 08:58:28 +09:00
3b69bdf0f0 Initial commit: O2O 저작권 침해 여부 탐지 API
PDF v1.2 요구사항 반영 완료:
- 10종 법령 메타 태그 + 39개 케이스 분류체계
- 3단 캐스케이딩: MinHash+LSH → 삼중 유사도 → 분류
- 자서전 특화: 공통 표현 사전 제거 + NER 마스킹
- KoSimCSE 한국어 임베딩 (자체 산출물 방어)
- 보수적 임계값 0.85
- 검토 콘솔 UI (탐지 + 코퍼스 관리 탭)
- Docker 배포 패키지 + 31개 테스트 통과
2026-05-13 11:20:17 +09:00