# K-Law 대법원 판결 일치도 벤치마크 — 재현 가이드
이 문서는 K-Law 방법론 v15.1을 기준선(baseline)으로, 대법원 민사 판결 300건을 이용해
개발 세트(100건)에서 방법론을 10라운드에 걸쳐 갱신하고, 이번 1차 갱신(v15.2)의 근거를
제3자가 그대로 재현·검증할 수 있도록 절차·명령·해시를 기록한다.
**상태**: 개발 세트 1라운드 실행이 진행 중이며, 이 문서의 "라운드 결과" 절은 완료 후
갱신된다. 그 전까지 이 페이지의 모든 수치는 절차 설명이지 최종 실증 결과가 아니다.
**면책**: 이 저장소의 다른 문서와 마찬가지로, 여기 수록된 데이터는 자체 실험 결과이며
제3자의 검증을 거치지 않았다. 인용·이용 전에 직접 재현해 확인할 것을 권한다.
---
## 0. 전체 구조
```
표본 수집(300건) → 결과 라벨링(유지/파기) → 개발 세트 100건 선정(10라운드×10건)
→ 사건 개요 작성(식별정보 제거, Claude Sonnet 5)
→ 라운드 1: v15.1로 10건 시험·채점 → 오류 분석 → 방법론 패치안(v15.2) 작성
→ 라운드 2: v15.2로 10건(표본 밖) 시험 → … 라운드 10까지 반복
→ 최종 방법론으로 100건 전체 재실행(참고용, 표본 안 성능)
```
핵심 원칙: **각 라운드의 예측은 그 라운드 시작 시점의 방법론으로, 아직 보지 않은
10건에 대해 이루어진다.** 그래서 라운드별 정확도는 표본 밖(out-of-sample) 수치이며,
방법론이 특정 사건에 맞춰 과적합될 위험이 구조적으로 제한된다. 방법론 갱신은
같은 유형의 오류가 2회 이상 나타나거나, 1건이라도 원리 수준으로 일반화되는
구조적 결함일 때에만 한다(임의 규칙 추가 금지).
---
## 1. 판례 수집 방법
### 1.1 출처와 대상
- 법제처 국가법령정보센터 Open API(open.law.go.kr)의 판례(`target=prec`) 엔드포인트.
- 대상: 대법원 민사 `다` 판결, 선고일 2025-06-12 ~ 2026-07-09, 300건(사법공보 등재분
중 최신순). 판결이 아닌 결정 20건은 별도 표시하여 제외(`_excluded/`).
- 사건마다 2심·1심 판결문을 연결해 함께 수집했다(2심 확보 167/300, 1심 확보 113/300).
하급심을 못 찾는 주된 사유는 하급심 판결이 법제처 DB에 없는 경우다.
### 1.2 API 호출 형식
검색과 본문 조회는 별개 엔드포인트다. 아래는 실제 응답 필드로 확인한 형식이다.
```
# 목록 검색
GET https://www.law.go.kr/DRF/lawSearch.do
?OC={발급받은 ID}&target=prec&type=XML&query={검색어}&curt={법원명}
&prncYd={선고일자 범위, YYYYMMDD~YYYYMMDD}&display={건수, 최대 100}&page={페이지}
# 본문 상세
GET https://www.law.go.kr/DRF/lawService.do
?OC={발급받은 ID}&target=prec&ID={판례일련번호}&type=XML
```
- `OC`는 open.law.go.kr에서 무료로 신청해 발급받는 사용자 식별자다(이 연구에서는
`openhash` 계정 사용). 신청 시 호출 서버의 공인 IP 또는 도메인을 함께 등록해야
하는 경우가 있으니, 재현 시 자신의 서버 환경으로 다시 등록해야 한다.
- 응답은 XML이며, 본문 상세 응답의 `PrecService.판례내용` 필드에 전문이 `
`로
줄바꿈되어 들어 있다.
### 1.3 수집·라벨링 스크립트
아래 스크립트로 수집부터 라벨링까지 재현한다(PowerShell 5.1, ASCII 전용).
이 문서와 함께 저장소에 커밋된 스크립트는 `scripts/` 폴더에 있다. 라벨링(`catalog_cases.ps1`),
방법론 갱신(`patch_method_r01*.mjs`), 사건 개요 생성(`overview_writer.mjs`), 가상 판결
실행(`klaw_runner.mjs`), 불일치 사건 묶음(`pack_round.ps1`)은 이 저장소에 원문이
공개되어 있다. 초기 수집 스크립트(`fetch_civil_prec.ps1` 등 원 수집·선정 스크립트)는
별도 커밋으로 이어서 공개할 예정이며, 그 전까지는 위 API 형식과 `data/labels.csv`의
사건 ID 목록으로 동일 표본을 직접 재수집할 수 있다(1.2절 참고).
주문(판결 결과)에서 유지/파기 이분 라벨과 6개 세부 유형(상고기각·상고각하·전부파기환송·
일부파기환송·파기자판·파기이송)을 정규식으로 추출했다. 결과는 `data/labels.csv`.
---
## 2. 수집된 판례 다운로드
전체 판결문 원문(300건, 대법원+2심+1심)은 용량과 저작권 표시 관행상 이 저장소에
재게시하지 않는다. 다만 대법원 판결문은 저작권법 제7조에 따라 저작권 보호 대상이
아니므로, 1.2절의 API와 아래 ID 목록으로 누구나 동일한 300건을 그대로 재수집할 수
있다. 이 저장소가 공개하는 것은 **메타데이터와 분류 태그**이며, 재현에는 이것으로
충분하다.
| 파일 | 내용 | 행수 |
|---|---|---|
| `data/labels.csv` | 사건ID·사건번호·선고일·주문 라벨·이분 라벨 | 300 |
| `data/chain.csv` | 대법원-2심-1심 연결(하급심 확보 여부·법원명·사건번호) | 300 |
| `data/catalog.csv` | 위 둘을 병합하고 아래 3절 태그를 붙인 전체 카탈로그 | 320(제외 20건 포함) |
| `data/tag_counts.csv` | 태그별 건수 | — |
| `data/split/dev.csv` | 개발 세트 100건(사건ID·라운드) | 100 |
| `data/split/test_pool.csv` | 나머지 시험 풀 200건 | 200 |
| `data/split/split_info.txt` | 분할 절차 요약(시드, 날짜 하한 등) | — |
**무결성 확인**: `data/split/dev.csv`의 SHA-256은
`19BDA7BD6695027E69679E80BCA9160CE7B3756AFD70C1D2F05F32913F53C350`이다. 내려받은
파일의 해시가 이와 다르면 표본이 달라진 것이므로 결과를 비교하지 말 것.
각 판결문 원문을 API로 직접 받으려면 `data/labels.csv`의 `id`·`date` 열로 1.2절의
본문 상세 호출을 반복하면 된다.
---
## 3. 판례 분류(태깅) 방법
`scripts/catalog_cases.ps1`이 300건(+제외 20건)에 아래 태그를 기계적으로 붙인다.
원본은 옮기지 않고 복사만 하므로 여러 번 실행해도 안전하다.
| 태그 | 의미 |
|---|---|
| `split:dev / pool / excluded` | 개발 100건 / 나머지 시험 풀 200건 / 판결이 아닌 결정 20건 |
| `round:r01..r10` | 개발 세트 내 라운드 |
| `role:dev / supp_test_2nd / supp_test_concl_only / excluded` | 개발용 / 2심 보유 보조시험용 / 결론만 가능 / 제외 |
| `outcome:keep / reverse` | 대법원 결과(유지=기각·각하 / 파기) |
| `label:dismissed / rejected / full_remand / partial_remand / transfer / self_judgment` | 세부 6유형 |
| `chain:full / second_only / supreme_only` | 확보한 심급 조합 |
| `recency:R1..R4` | 선고 시기 등급(2026-03+ / 01~02 / 2025-12 / 그 이전). 오염 위험 판정이 아니라 표식일 뿐 — DeepSeek 학습 시점은 미공개 |
| `month:YYYYMM`, `flag:prior_remand` | 선고월, 환송 후 재상고 여부 |
| `gap1:*`, `gap2:*` | 1심·2심 누락 사유(DB 미등재, 법원명 불일치 등) |
| `appeal_court:high / district` | 2심 법원 유형 |
| `first_type:panel / single / small_claims` | 1심 사건 종류 |
실행: `powershell -File catalog_cases.ps1 -Root <작업 폴더>` (기본값은 `$env:USERPROFILE\klaw-bench`).
출력은 `catalog\catalog.csv`, `catalog\tag_counts.csv`, `catalog\tags_reference.txt`,
그리고 사건별 판결문 묶음(`cases\pool\keep|reverse\\`, `cases\excluded\\`)이다.
---
## 4. 방법론 갱신용 개발 세트 100건 선정
- 시드 20260924, 선고일 하한 2025-12-01(`-MinDate 20251201`)로 `select_dev.ps1`을
실행해 100건(유지 40 + 파기 60)을 뽑는다. 대법원 결과의 실제 비율(유지 28% /
파기 72%)과 다른 40/60 층화 비율을 쓴 이유는, 유지 사건이 10라운드 모두에
최소 표본 수를 유지하도록 하기 위함이다(균형 표본 — 기준선 정확도 계산 시
이 차이를 보정해야 한다. 5절 참고).
- 100건을 10라운드로 나누고, 각 라운드는 유지 4 + 파기 6으로 구성한다.
- 나머지 200건은 시험 풀로 남긴다. 그중 2심 판결문이 있는 67건(파기 48 + 유지 19)은
원심 대비 K-Law의 판단을 비교하는 보조 시험에 쓸 수 있다.
- 기준선(항상 파기 예측): 개발 세트 60%, 전체 300건 72%. 최다 단일 유형(상고기각)은
전체의 35.7%.
---
## 5. 라운드 실행 절차 (10건씩, 매 라운드 방법론 갱신)
### 5.1 사건 개요 작성 (`overview_writer.mjs`)
대법원 전문·2심·1심 판결문을 입력해 Claude Sonnet 5로 두 가지 개요를 만든다.
- **검토용**: 당사자/사건의 경위/청구와 주장/원심의 판단 요지 — 원심 판단까지 포함.
- **독립용**: 원심 판단 요지를 제외 — K-Law가 독립적으로 판단하도록.
식별정보 제거 규칙(요약): 이름·상호·지명은 A·B로 일반화, 날짜는 연 단위까지만(월·일
표기 금지), 공항·도시 등 구체적 장소명 금지, 언론 보도·사회적 관심 서술 금지,
금액·수치 등 법적 판단에 필요한 사실은 유지. 대법원의 판단·파기/기각/환송 표현·
상고이유는 어떤 개요에도 포함하지 않는다(결론 누출 방지). 규칙을 기계적으로 검사해
위반이 있으면 최대 2회까지 자동으로 다시 쓰게 한다(자동 수정 루프, `hard_remaining`
필드로 기록).
### 작성 모델과 계정 (2026-09-25 갱신)
개요는 원래 Claude Sonnet 5로만 작성했으나, Anthropic 콘솔 크레딧이 반복적으로
소진되면서(Pro 구독과 콘솔 크레딧은 별개 결제) 비용 문제로 DeepSeek을 대체 경로로
추가했다(`overview_writer.mjs --provider=deepseek`, 모델 `deepseek-flash`).
이때 쓰는 DeepSeek 계정은 **가상 판결 생성(`klaw_runner.mjs`)에 쓰는 계정과 별개**
(`DEEPSEEK_OVERVIEW_API_KEY` 환경변수, `DEEPSEEK_API_KEY`와 다름)다. 같은 모델
계열(DeepSeek)이 개요 작성과 가상 판결 예측을 모두 맡는 사건이 존재하게 되므로,
한계 절(§7)에서 이 교차 가능성을 별도로 다룬다. 각 개요 파일(`overview/.json`)의
`generator` 필드(`anthropic:claude-sonnet-5` 또는 `deepseek:deepseek-flash`)와
`generator_note`에 어느 경로로 작성됐는지 사건별로 기록되며, `overview/index.csv`의
`generator` 열로 일괄 확인할 수 있다.
```
node overview_writer.mjs --round=N
```
### 5.2 가상 판결 생성·채점 (`klaw_runner.mjs`)
방법론 원문(저장소 루트의 `klaw_vX_Y.md` — 파일명이 내부 버전과 일치하도록 관리한다.
현재 `klaw_v16_2.md`)과 출력형식 문서를 system 프롬프트로 고정해(라운드 내내 동일 →
API 프롬프트 캐시 재사용), DeepSeek(`deepseek-flash`)로 STEP 0→A→B→C를 차례로
호출한다. STEP B의 주문을 규칙 기반으로 추출해 실제 결과와 대조한다.
```
node klaw_runner.mjs --round=N --tag=rNN --concurrency=3 --budget-scale=3
```
`--method`를 생략하면 저장소 루트에서 `klaw_v[숫자_숫자].md` 패턴 파일을 스캔해
버전 숫자가 가장 큰 파일을 자동으로 채택한다(`resolveLatestMethod()`, 세 브라우저
앱의 GitHub API 버전 스캔과 동일한 규칙). 특정 과거 버전으로 시험하고 싶을 때만
`--method=klaw_v15_1_r01_FROZEN.md` 처럼 명시한다. `--version`·`--format`도
생략 가능(버전은 파일명에서 자동 추출, 형식은 `가상판결_출력형식_v13_3.txt` 기본값).
- `--budget-scale`(기본 3): STEP별 토큰 상한을 운영값의 3배로 늘린다. 시험에서
thinking 모드의 추론 토큰이 사건마다 4천~1만 개로 크게 변동해 운영 예산(STEP A
14,000 등)에서 반복적으로 절단됐기 때문이다. 상한을 늘려도 과금은 실사용 토큰
기준이라 비용이 비례해 늘지 않는다.
- 운영(desktop.html)과 다른 점: 후속 질문에 답하지 않음, 분석 단계 예산 확대,
사건번호는 `SIM-` 접두사, thinking을 기본으로 켬.
### 5.3 방법론 갱신 규칙
- 라운드 결과에서 **불일치 사건만** 원인을 분석한다(`pack_round.ps1`로 실제 판결문·
가상 판결·개요를 묶어 낸다).
- 같은 유형의 오류가 2회 이상 나타나거나, 1건이라도 원리 수준(법조문·판례법리 차원)
으로 일반화되는 구조적 결함이면 방법론을 패치한다. 단순 표현 개선은 갱신하지 않는다.
- 패치는 `patch_method_rNN.mjs` 스크립트로 적용한다. 각 편집은 "찾을 문장이 원문에
정확히 한 번 있을 때만" 적용되며, 그렇지 않으면 스크립트가 중단된다(동결본을
실수로 다른 버전과 섞어 패치하는 사고 방지). 모든 변경은 `patch_log.md`에 사건ID·
원인·조문 근거와 함께 자동 기록된다.
- 갱신본은 운영 저장소 루트의 방법론 파일에 곧바로 병합하지 않고 별도 경로
(`method/dev/` 등)에서 관리하다가, 여러 라운드에 걸쳐 회귀 없이 검증된 뒤에만
다음 버전으로 승격한다.
- **파일명 = 내부 버전 규칙**: 방법론 파일명은 표제의 내부 버전과 항상 일치시킨다
(`klaw_v16_1.md`처럼). 버전을 정본에 승격할 때는 `git mv klaw_vX_Y.md
klaw_vX2_Y2.md`로 파일명도 함께 갱신한다 — `klaw_runner.mjs`와 세 브라우저 앱
(`benchmark.html`·`desktop.html`·`webapp.html`)이 모두 파일명 패턴에서 버전
숫자를 읽어 가장 큰 값을 자동 채택하므로, 이 한 번의 `git mv`만으로 어디서도
코드를 고치지 않고 가상 판결문 작성 프로세스 전체가 최신 버전을 호출하게 된다.
옛 파일명(과거 버전)은 지우지 않고 `method/dev/`나 커밋 히스토리로만 남긴다 —
`methodology-history.html`의 "당시 원문" 링크는 특정 커밋을 그대로 가리키므로
영향받지 않는다.
### 5.4 자기 검증(STEP V) 실험 — 폐기
1라운드에서 "STEP B 직후 결정론적 규칙으로 과잉 파기 신호(확신도 미달, 근거 없는
판단누락 주장 등)를 잡아 STEP V로 재검토를 강제"하는 장치를 시험했다. 결과는
발동 4건 중 개선 0건, 정답→오답 악화 2건으로 **채택하지 않았다**. 이 절도 재현성
문서의 일부로 남긴다 — 같은 방향의 자기 검증을 다시 시도하는 연구자가 동일한
실패를 반복하지 않도록 원인과 결과를 함께 공개한다(`scripts/patch_method_r01b.mjs`,
`patch_log.md`의 "STEP V" 항목).
### 5.5 v15.1 → v15.2 (1차 갱신)
개발 세트 1라운드 8건 중 불일치 1건(사건 622917: 실제 상고기각 / K-Law 예측
일부파기환송)을 분석해 구조적 결함 4곳을 확인했다.
1. `0-1-π`(원심 판단 구조화): 원심 요지에 언급이 없는 쟁점을 "원심이 판단하지
않았다"로 해석해 재구성한 [추론] 항목을 파기 근거로 그대로 인용.
2. `A-2-2-κ`(상고심 3단계 분류): 사실오인형·혼합형의 사실 부분을 기본값으로
"파기환송 후 환송심"으로 보내, 법리오해가 없어도 환송 쪽으로 기울게 함.
3. `B-4-β`(법리오해-결론 정당성 분리 심사): 판단누락 인정에 필요한 최소 요건
(원심이 판단하지 않았다는 명시적 진술)이 없었음.
4. `강제규칙 19`(심급 판단 경계): 사실심 전권사항의 기본값이 "원칙적으로
파기환송"으로 되어 있어, 민사소송법 제432조(사실심 기속)와 반대 방향이었음.
네 곳 모두 "원심이 적법하게 확정한 사실은 존중하고, 파기·환송은 입력에서 명시적으로
확인되는 판단누락·심리미진에 한한다"는 하나의 원리로 수정했다(민사소송법 제431·
432·434조 근거). 패치 스크립트: `scripts/patch_method_r01.mjs`. **버전 표기**: 이
연구의 방법론은 v15.1을 기준선으로 삼고, 이번 1차 갱신을 **v15.2**로 번호를 매긴다.
1라운드 표본 밖 재검증이 끝나기 전까지 v15.2는 초안(draft) 상태이며, 운영
(klaw.hondi.net)에는 반영하지 않는다.
---
## 6. 재현 시 필요한 것
- open.law.go.kr에서 발급받은 자신의 OC 식별자(무료).
- Anthropic API 키(`overview_writer.mjs`) — Claude Pro/구독과 별개의 콘솔 크레딧 필요.
- DeepSeek API 키(`klaw_runner.mjs`) — `deepseek-flash` 모델.
- Node.js 20+, PowerShell(스크립트는 Windows PowerShell 5.1 기준. 다른 OS에서는
Node.js `.mjs` 스크립트만으로도 개요 작성·가상 판결 실행이 가능하다).
## 7. 알려진 한계
- DeepSeek(`deepseek-flash`)의 학습 시점이 공개되지 않아, 개발 세트 사건이 그
학습 데이터에 포함됐는지 확인할 수 없다. 개요에서 식별정보를 제거해 유추 근거를
최소화했으나, 사건의 고유한 사실관계 자체가 단서가 될 가능성은 남는다.
- 일부 사건은 개요 작성과 가상 판결 예측을 모두 DeepSeek(서로 다른 계정)이 맡는다
(위 "작성 모델과 계정" 참고). 각 API 세션은 서로 격리되어 있어 실시간 정보 공유는
없지만, 공급자가 API 로그를 향후 모델 재학습에 사용하는 경우에 한해 개요 작성
세션의 내용이 시간이 지나 검증용 모델의 학습 데이터에 흘러들 이론적 경로가 남는다.
이 지연은 모델 재학습 주기 단위(수개월 이상)로 예상되며, 이 실험이 수행되는 기간
안에 실제로 발생했을 가능성은 낮다고 보지만 배제하지는 않는다. 어떤 사건이 이
경로를 거쳤는지는 `generator` 필드로 전부 추적 가능하다(§5.1).
- 평가자(일치도 판정)가 대법원의 판단을 이미 알고 있는 Claude이므로, Claude
계열 모델은 비교 대상에서 제외했다.
- 개발 세트는 유지 40 / 파기 60으로 층화한 균형 표본이며, 전체 모집단의 실제
비율(유지 28% / 파기 72%)과 다르다. 정확도를 모집단 기준으로 해석하려면
가중치 보정이 필요하다.
- 방법론 갱신은 소표본(라운드당 10건, 때로 단일 사건)에서 촉발되므로, 통계적
유의성이 아니라 원리적 정합성(법조문·판례법리 근거)으로 정당화한다. 이는
의도된 설계이며, 최종 검증은 갱신에 쓰이지 않은 시험 풀에서 이루어진다.
## 8. 학습 오염(암기) 검증
**배경**: 개발 세트 100건 중 "완전 일치"(승패·법리뿐 아니라 **금액까지** 정확히
일치) 사건이 2건 발견됐다 — 621985(1라운드, 위자료 500만원 완전 일치), 619445
(3라운드, 91,803,279원 소수점까지 완전 일치). §7이 이미 지적한 "학습 데이터
포함 여부를 확인할 수 없다"는 한계상, 추론이 아니라 암기(해당 판결을 학습
데이터에서 그대로 재현)일 가능성을 배제할 수 없어 직접 검증했다.
**방법(직접 암기 질의, 2026-10-03)**: `memorization_probe.mjs` — 사건의 사실
관계·당사자·청구원인을 전혀 제공하지 않고, **사건번호·선고일만** 제시한 뒤
(생성에 쓴 것과 동일한 `DEEPSEEK_API_KEY`/`deepseek-flash`로, 완전히 새로운
대화에서) "주문·금액·핵심 법리를 아는 대로 말하라, 모르면 모른다고만 답하라"고
질의했다.
**결과**: 두 사건 모두 **"모른다."** 한 줄로만 응답 — 사건번호만으로는 금액·
법리·결론 어느 것도 재현하지 못했다. 암기의 직접 증거는 발견되지 않았다.
**보강 근거(시간 경계)**: 두 사건의 선고일은 각각 2026. 4. 9.(619445)와
2026. 5. 8.(621985)로 매우 최근이며, `deepseek-flash`의 공개되지 않은 학습
컷오프를 넘어섰을 가능성이 높다 — 애초에 암기가 구조적으로 어려운 사건일
수 있다는 점에서 직접 질의 결과와 방향이 일치한다.
**한계**: "모른다"는 응답이 실제 무지가 아니라 안전 기본값(모른다고 답하도록
유도된 지시 패턴)일 가능성은 완전히 배제되지 않는다 — 더 결정적인 구분은
②시간 경계 분리(컷오프 전후 사건의 정확도 비교)와 ③섭동 테스트(부차적 사실을
바꿔 결론이 따라 바뀌는지 확인)이며, 두 방법 모두 소수 사건으로는 통계적
힘이 부족하다.
**다음 단계**: 추가 200건 수집 시 선고일을 모델 학습 컷오프 전후로 의도적으로
섞어 샘플링해 시간 경계 분리 비교를 설계한다(§4 개발 세트 선정 절차에 반영
검토). "완전 일치" 사건이 재발하면 섭동 테스트를 우선 적용해 재확인한다.