📝 한줄 요약
AILaw는 판례의 범죄사실 문단을 문맥으로 놓고 WHO·WHEN·WHERE·WHAT에 해당하는 답 구간을 찾도록 만든 추출형 질의응답 실험이다. 문제를 구조화한 방식은 지금도 참고할 만하지만, 공개 저장소를 다시 결속해 보니 README와 데이터의 질의응답 수, 성능 그림표와 result.txt, 데이터 분할과 판례 식별자 사이에 재현성 공백이 있었다. 따라서 이 저장소는 곧바로 사용할 완성형 법률 AI라기보다, 좋은 문제 정의를 현대적인 데이터·평가·provenance 체계로 다시 구현할 때 참고할 역사적 사례로 읽는 편이 정확하다.
바쁘시면 이것만 읽어도 됩니다.
이 프로젝트가 말하는 ‘핵심정보’는 판례 전체의 법리나 판시사항이 아니라 범죄사실 문단 속 피해자·시점·장소·행위다.
각 항목을 고정 질문으로 바꾸고 정답의 시작 위치를 표시해 SQuAD형 추출 질의응답 데이터로 변환했다.
README의 결과 그림표에서는 KorBERT가 전체 F1 92, EM 86으로 Multilingual BERT의 F1 75, EM 58보다 높다.
다만 저장소의
result.txt는 F1 88.34, EM 80.81을 기록한다. 두 결과를 같은 실행으로 묶는 run ID·분할 hash·seed·checkpoint hash가 없다.README는 3,885개 질의응답쌍을 설명하 지만, 동결된
law.xlsx에는 비어 있지 않은 답 구간이 4,004개 있다.law.xlsx의 실질 데이터 행은 1,001개지만 고유 판례 제목 문자열은 404개다. 1,001을 곧바로 고유 판례 1,001건으로 읽기 어렵다.전처리는 seed 없이 행 단위로 섞은 뒤 70%와 30%로 나눈다. 같은 판례 제목의 여러 행이 학습·시험에 함께 들어갈 가능성이 있다.
공개 데이터에는 민감한 범죄사실이 포함돼 있고 저장소 최상위 라이선스는 확인되지 않는다. 원문 예시나 원본 이미지는 이 글에 재배포하지 않았다.
현대적으로 다시 만든다면 case ID 기반 그룹 분할, 데이터·split·checkpoint·결과의 manifest 결속, 출처 좌표와 사람 검토가 핵심이다.
🎯 이런 분들께 도움됩니다
판례나 계약서에서 구조화된 사실을 자동 추출하려는 법률 AI 기획자
오래된 BERT 연구 저장소를 현대 환경에서 재사용할지 판단해야 하는 개발자
모델 점수와 데이터 버전이 실제로 같은 실행에서 나온 것인지 검증하려는 연구자
공개 법률 데이터를 수집·주석·배포할 때 개인정보와 이용 조건을 함께 관리하려는 운영자
‘법률문서 핵심정보 추출’이라는 표현의 실제 범위를 제품 기능으로 명확히 쓰고 싶은 사람
이 사례의 검증 범위
이 글은 저장소가 수행한 모델 학습을 새로 재현한 성공 보고서가 아니다. 공개 저장소의 특정 commit을 동결하고 README·전처리 코드·크롤러·형태소 분석 호출 코드·엑셀 데이 터·결과 파일·저장소 트리를 서로 대조한 소스 기반 재검증 사례다.
항목
이번에 확인한 것
이번에 하지 않은 것
소스
commit 829c02c497aa…의 공개 파일과 GitHub 메타데이터
저장소 작성자의 비공개 실험 환경 추정
데이터
XLSX 구조·행 수·질의응답 수·offset 일치·중복 제목 집계
민감한 범죄사실의 본문 재게시
코드
분할 단위·seed·경로·의존성·API 전송 방식
크롤러로 판례를 다시 수집
성능
README 그림표와 추적된 result.txt의 수치 대조
비공개 KorBERT checkpoint로 재학습
재현성
결속에 필요한 run ID·hash·seed·checkpoint 확인
서로 다른 수치를 임의로 평균내거나 하나로 확정
라이선스
GitHub API의 license: null, 최상위 라이선스 파일 부재
이용허락에 관한 법률 의견 확정
ETRI KorBERT 사전학습 모델은 README 설명상 별도 사용허가와 다운로드가 필요하고 저장소에는 포함돼 있지 않다. 또한 현재 공개 스냅샷은 현대 런타임을 그대로 재현할 lockfile과 실행 manifest를 제공하지 않는다. 그래서 이번 검증은 존재하지 않는 checkpoint나 실행 조건을 꾸며 내지 않고, 공개된 증거로 확인 가능한 범위까지만 진행했다.
allw7의 다양한 단계를 보여주는 다이어그램
그림 1. 저장소 README와 전처리 코드를 바탕으로 새로 작성한 파생 카드다. 원 저장소 이미지를 복제하지 않았다.
문제 정의: 판례 전체가 아니라 범죄사실 문단의 네 가지 답
AILaw의 가장 좋은 출발점은 문제 범위를 작게 잘랐다는 데 있다. README는 판례의 ‘범죄사실’ 문단을 context로 두고, 추출하려는 정보를 question과 answer로 주석했다고 설명한다.
고정 질문은 다음 네 종류다.
질문 유형
찾으려는 답
WHO
피해자가 누구인지 나타내는 문장 내 구간
WHEN
범행 시점을 나타내는 구간
WHERE
범행 장소를 나타내는 구간
WHAT
어떤 범행이 발생했는지 나타내는 구간
이 구조는 자유로운 요약보다 검증하기 쉽다. 모델은 새로운 문장을 생성하는 대신 원문 안의 시작과 끝을 선택한다. 정답과 예측의 겹침은 F1으로, 완전 일치는 Exact Match로 계산할 수 있다.
하지만 이 장점은 범위를 정확히 표시할 때만 유지된다. WHO·WHEN·WHERE·WHAT의 사실 구간을 찾는 일과 다음 작업은 서로 다르다.
판결의 법적 쟁점과 판단 구조를 요약하는 일
적용 법조와 법리의 관계를 설명하는 일
사실인정과 법률판단을 분리하는 일
선례로서의 가치와 후속 판례 관계를 평가하는 일
사건 전체에서 실무상 중요한 내용을 선별하는 일
따라서 이 저장소의 제목에 있는 ‘핵심정보’를 법률가가 말하는 판결의 모든 핵심으로 확장해서 소개하면 기능을 과장하게 된다. 더 정확한 표현은 ‘범죄사실 문단의 4W 답 구간 추출’이다.
구현 흐름: 수집 → 주석 → SQuAD형 변환 → 두 BERT 비교
1. 판례 수집
크롤러는 리걸서치의 판례 목록을 Selenium으로 탐색하고 본문의 ‘범죄사실’ 구간을 저장하도록 작성돼 있다. README는 성범죄 677건, 살인 46건, 폭행 278건으로 합계 1,001건을 수집했다고 설명한다.
공개 코드만 으로 깨끗한 환경에서 그대로 다시 실행하기는 어렵다.
crawler/run_crawler.py는 저장소에 없는../korcl_2019/law.json을 선행 입력으로 연다../chromedriver.exe라는 Windows 고정 경로를 사용한다.창 handle과 페이지 구조에 강하게 의존하는 Selenium 코드다.
수집 당시 사이트 구조·이용 조건·접근 방식이 현재와 같은지 증명하는 snapshot이 없다.
즉, 크롤러는 당시 연구 과정을 이해하는 자료이지만 현재 수집기를 그대로 제공하는 완결된 패키지는 아니다.
2. 엑셀 주석
data/law.xlsx에는 제목, 범죄사실 문맥, 네 종류의 답 문자열과 각 답의 시작 위치가 들어 있다. 공개 예시에는 민감한 범죄 묘사가 포함되므로 이번 글에서는 원문 행을 인용하지 않고 집계만 사용했다.
추출형 QA에서는 답 문자열만 맞는 것으로 부족하다. 저장된 시작 위치에서 답 길이만큼 잘랐을 때 실제 문맥과 일치해야 한다. 이번 검증에서는 4,004개 비어 있지 않은 답 구간 가운데 1건의 WHERE offset 불일치를 발견했다. 이는 데이터 전체를 무효화하는 규모는 아니지만, 학습 전에 자동 검증해야 할 오류 유형이다.
3. JSON 변환과 분할
data-processing/preprocess.py는 엑셀 행을 SQuAD와 유사한 JSON 구조로 바꾼다. 이어 random.shuffle(dataList)를 실행하고 앞의 70%를 학습, 뒤의 30%를 시험으로 저장한다.
여기에는 두 가지 재현성 문제가 있다.
고정 seed가 없다. 같은 엑셀을 다시 실행해도 분할이 달라질 수 있다.
분할 단위가 판례가 아니라 행이다. 동일 판례 제목이 여러 행에 반복되므로 같은 사건의 다른 사실 조각이 학습과 시험에 나뉠 수 있다.
공개 저장소에는 생성된 train/test JSON이 포함돼 있지 않아 실제 논문 결과에 사용된 분할을 복원할 수 없다. 이 때문에 점수만 남아 있어도 동일 시험셋의 점수인지 확인하기 어렵다.
4. Multilingual BERT와 ETRI KorBERT
저장소는 Google Multilingual BERT와 ETRI KorBERT를 비교한다. ETRI 경로에서는 WiseNLU 형태소 분석을 거친 입력을 사용한다.
여기에도 현재 재사용 시 주의할 경계가 있다.
README의 의존성은
transformers>=4.0.0을 적고 있지만, 저장소에 포함된multilingualBERT/setup.py는 vendored Transformers 버전을2.0.0으로 표시한다.포함된
requirements.txt에는 패키지 버전 고정이 없다.tokenizing.py는http://aiopen.etri.re.kr:8000/WiseNLU로 요청하고 access key를 JSON 본문에 넣는다.저장소에는 실제 key 값이 들어 있지 않지만, 현재 환경에서 실사용 key를 평문 HTTP로 보내 는 방식은 그대로 재사용하지 않아야 한다.
ETRI 사전학습 모델은 저장소에 없고 별도 사용허가가 필요하다.
결론적으로 2026년 환경에서의 재현은 ‘예전 명령을 다시 실행’하는 작업이 아니라, 의존성과 통신·데이터 계약을 새로 고정하는 포팅 작업에 가깝다.
실제 데이터 감사: README 3,885와 XLSX 4,004
동결한 law.xlsx를 표준 라이브러리만 사용하는 감사 스크립트로 읽었다. 원문은 출력하지 않고 구조·수량·offset만 집계했다. 같은 입력에서 분석기를 두 번 실행해 JSON과 두 개의 시각 카드가 동일한 SHA-256을 유지하는 것도 확인했다.
집계 결과
항목
확인값
실질 데이터 행
1,001
고유 판례 제목 문자열
404
반복 제목 그룹
159
반복 제목 그룹에 속한 행
756
한 제목의 최대 반복 행
38
고유 범죄사실 문맥
913
완전히 같은 문맥의 추가 중복 행
88
WHO 답 구간
1,001
WHEN 답 구간
1,001
WHERE 답 구간
1,001
WHAT 답 구간
1,001
총 답 구간
4,004
답 시작 위치 누락
0
답 구간과 문맥 불일치
1
README의 설명은 WHO 1,001, WHEN 975, WHERE 908, WHAT 1,001로 합계 3,885다. 동결 XLSX와의 차이는 다음과 같다.
구분
README
동결 XLSX
차이
WHO
1,001
1,001
0
WHEN
975
1,001
+26
WHERE
908
1,001
+93
WHAT
1,001
1,001
0
합계
3,885
4,004
+119
가능한 설명은 여러 가지다. README 작성 뒤 엑셀 주석이 보강됐을 수 있고, 논문용 데이터와 공개 데이터의 버전이 다를 수도 있다. 하지만 저장소에는 이를 구분할 dataset version이나 변경 이력이 없다. 따라서 여기서는 원인을 추정하지 않고 README와 현재 commit의 XLSX가 서로 다른 수량을 말한다는 사실만 확정한다.
또한 1,001개 행에 고유 제목 문자열이 404개라는 점은 ‘1,001건’을 고유 판례 ID 수로 바로 해석하면 안 된다는 신호다. 여러 범죄사실이 같은 판례 제목 아래 반복돼 있을 수 있다. 현대 데이터셋이라면 case_id, fact_id, source_url, source_snapshot_hash를 분리해 기록해야 한다.
한국 환율 스크린샷
그림 2. README, XLSX, 결과 파일의 값을 서로 대조해 새로 작성한 파생 카드다. 각 값은 동일한 commit의 공개 파일에서 읽었지만, 그것만으로 동일 실행의 산출물이라는 결속은 성립하지 않는다.
성능표를 읽는 법: ‘KorBERT 우세’와 ‘동일 실행’은 다른 주장이다
README의 결과 그림표를 전사하면 다음과 같다.
영역
Multilingual BERT F1 / EM
KorBERT (ETRI) F1 / EM
표의 우세 시스템
ALL
75 / 58
92 / 86
KorBERT
WHO
41 / 1
91 / 77
KorBERT
WHEN
97 / 94
95 / 92
Multilingual BERT
WHERE
76 / 60
79 / 67
KorBERT
WHAT
83 / 79
88 / 85
KorBERT
이 표만 보면 KorBERT는 전체, WHO, WHERE, WHAT에서 높고 WHEN에서는 Multilingual BERT가 더 높다. README의 ‘대부분의 상황에서 좋은 성능’이라는 표현과 방향은 맞는다.
그러나 저장소의 outputDir/EtriBERT/result.txt에는 다음 값이 있다.
exact: 80.81395348837209
f1: 88.34475464984055
total: 1204
이 값은 그림표의 KorBERT ALL F1 92, EM 86과 다르다. 둘 중 하나가 틀렸다고 단정할 근거는 없다. 다른 split, checkpoint, 전처리, 실행 시점의 결과일 수 있다. 문제는 이를 구분할 정보가 없다는 점이다.
동일 실험의 결과라고 결속하려면 적어도 다음이 함께 있어야 한다.
source commit
+ dataset hash
+ train/test split hash
+ preprocessing version
+ random seed
+ model/checkpoint hash
+ 실행 명령과 환경
+ metric implementation version
+ result hash
이 결속이 없으면 ‘공개된 숫자가 있다’고는 말할 수 있지만 ‘이 코드와 이 데이터로 그 숫자를 재현할 수 있다’고 말하기는 어렵다.
좋았던 설계와 막혔던 지점
좋았던 설계
모호한 정보 추출을 고정 질문으로 바꿨다.
WHO·WHEN·WHERE·WHAT은 사용자 요구와 데이터 주석을 연결하는 명시적 계약이 된다.생성형 요약이 아니라 원문 span을 선택하게 했다.
결과를 원문 위치로 되짚을 수 있어 검증하기 쉽다.한국어 특화 전처리와 다국어 기준선을 비교했다.
단일 모델 점수만 제시하지 않고 비교 기준을 둔 점은 연구 설계상 유용하다.코드·데이터·결과 흔적을 공개했다.
완전한 재현 패키지는 아니어도 후속 검증이 가능한 최소한의 단서가 남았다.
막혔던 지점
‘핵심정보’의 의미가 제목보다 좁다.
사실 구간 추출과 법리·쟁점 분석을 분리해 설명해야 한다.데이터 버전이 결속돼 있지 않다.
README의 3,885와 XLSX의 4,004가 어느 시점의 정본인지 알 수 없다.분할이 행 단위이며 seed가 없다.
동일 판례가 양쪽 split에 들어가는 누수 가능성과 실행 간 변동이 생긴다.환경 계약이 충돌한다.
README의 Transformers 4 이상과 vendored 2.0.0이 함께 있어 깨끗한 재현 경로가 불명확하다.결과와 실행이 묶이지 않는다.
그림표와result.txt가 다른 값을 보이지만 run manifest가 없다.원문 재사용 경계가 불명확하다.
최상위 라이선스가 확인되지 않고, 수집 사이트의 당시 이용 조건과 snapshot도 저장소에서 확인되지 않는다.민감한 범죄사실을 다룬다.
공개 판결문이라도 재가공·학습·재배포 단계에서는 데이터 최소화, 비식별 상태, 접근권한, 2차 이용 목적을 별도로 검토해야 한다.
현대적으로 다시 만든다면
1. 데이터의 논리 ID부터 분리한다
case_id 판례 단위 식별자
fact_id 한 판례 안의 범죄사실 단위 식별자
question_id WHO/WHEN/WHERE/WHAT 질의 식별자
source_id 원문 URL·문서·snapshot 식별자
행 번호를 판례 ID처럼 사용하지 않는다. 같은 판례에 여러 fact가 있어도 그룹 관계를 잃지 않아야 한다.
2. split을 case_id 단위로 만든다
학습·검증·시험 분할은 case_id를 그룹으로 잡아 같은 사건이 서로 다른 split에 들어가지 않게 한다. seed와 split 파일을 고정하고 각각의 SHA-256을 manifest에 기록한다.
3. 주석 검증을 학습 전 Gate로 둔다
답 문자열이 문맥 안에 실제로 존재하는지
answer_start가 정확한지같은 질문의 중복 답이 의도된 것인지
제목·문맥·출처가 올바른 판례와 연결됐는지
비어 있는 답과 불확실한 답을 어떻게 표현할지
이번 XLSX에서 발견된 1건의 offset 불일치는 이런 Gate가 자동으로 잡아야 할 유형이다.
4. 결과를 manifest로 결속한다
{
"source_commit": "…",
"dataset_sha256": "…",
"split_sha256": "…",
"seed": 42,
"preprocess_sha256": "…",
"model_id": "…",
"checkpoint_sha256": "…",
"command": "…",
"environment_lock_sha256": "…",
"metrics_sha256": "…"
}
표 이미지는 이 manifest에서 자동 생성한다. 그러면 그림표와 결과 JSON이 서로 다른 실행을 가리키는 문제가 줄어든다.
5. ‘사실 추출’ 뒤에 법률 검토 흐름을 별도로 둔다
모델 출력은 다음처럼 원문 좌표가 있는 후보로 취급한다.
원문 판례
→ 4W 후보 span
→ source 좌표와 confidence
→ 사람 검토
→ 사실표
→ 별도 법률 쟁점·법리 분석
사실 추출 모델이 판시사항이나 법률 판단까지 했다고 표현하지 않는다. 법률 참모 흐름은 원문·행위시법·쟁점·반대검토를 별도로 수행해야 한다.
6. 공개·민감 데이터 경계를 문서화한다
수집 근거와 원문 제공처의 이용 조건
원문·파생 데이터 각각의 라이선스
비식별 처리와 민감정보 필터
학습용·평가용·공개 배포용 데이터의 차이
삭제·정정·출처 변경 시 반영 절차
공개로 열람할 수 있다는 사실만으로 재배포 권한이나 무제한 모델 학습 권한이 자동으로 생긴다고 가정하지 않는다.
이번 재검증에서 실제로 만든 것
이번 사례에서는 저장소 원문을 Library에 복제하지 않고, 공개 파일의 구조와 숫자만 검증해 다음 파생 산출물을 만들었다.
산출물
결과
개인정보 최소화 구조 감사 JSON
생성·재실행 동일
동결 XLSX 실질 행
1,001
비어 있지 않은 답 구간
4,004
offset 불일치
1
원본 비복제 파생 카드
2개
SVG XML 검증
PASS
1600×900 PNG 렌더
2개 PASS
결속한 SHA-256은 다음과 같다.
분석 JSON
92a6d5c74d8fafccd60c682d60272ee1aa9d7fc83f382fffde3f9d466a2e9bbd
범위 카드 PNG
7a8700e32cd19d84a427b4bd93a23da5db55f2025c85a3198012479470c9f7c2