유피테르
유피테르
🧙 AI 위자드
🏅 베스트오브베스트

판례 해설 AI에 ‘완료’ 대신 ‘BLOCKED’를 가르친 사례

📝 한줄 요약

한국 판례를 입력하면 8개의 전문 에이전트가 실무용 해설보고서를 만드는 KorLawChestra를 로컬 모델로 실제 실행했다. 판례 분석과 PDF 생성까지는 끝났지만, 같은 실행에서 검증기가 passed:false를 반환했는데도 초기 집계 영수증이 PASS_WITH_LIMITATIONS로 표시되는 모순이 드러났다. 그래서 “에이전트가 모두 끝남”과 “법률보고서로 의존 가능함”을 분리하고, 검증 실패 시 BLOCKED / DRAFT_NOT_FOR_RELIANCE로 멈추는 헤드리스 실행기·영수증·회귀 테스트를 덧붙였다.

이 사례의 공개 상태

  • 로컬 실행 가능한 프로토타입: 확인

  • 샘플 판례 분석·Markdown·PDF 생성: 확인

  • 샘플 보고서의 실무 의존 가능 상태: 아님 — BLOCKED

  • 변호사 등 사람의 최종 법률 검토: 미실시

  • 프로덕션 배포·외부 웹/커뮤니티 발행: 미실시

  • 현재 발행 범위: 로컬 Lecture Recap Library 사례게시글

바쁘다면 이것만 읽어도 된다.

  • 멀티에이전트의 8/8 done은 법률 품질 판정이 아니라 실행 상태다.

  • PDF 파일이 생겼다는 사실보다 검증 영수증의 reliance_status가 우선해야 한다.

  • VerifyAgent passed:false를 별도 gate로 읽지 않으면, 교정 뒤 findings가 비었다는 이유만으로 결과가 잘못 통과할 수 있다.

  • 판결문 데이터셋을 쓸 때는 공식 원문과 사건번호·전문·해시를 다시 닫아야 한다.

  • E0/E1/I1/H1/U0처럼 원문, 재현, 추론, 가설, 미확인을 분리해야 보고서의 문장마다 사용 범위를 정할 수 있다.

  • 이 작업은 업스트림 코드를 상업 제품에 편입한 것이 아니다. CC BY-NC 4.0 조건 아래 로컬 비상업 평가를 수행했고, 수정 패치는 이 게시글에 배포하지 않는다.

🎯 이런 분께 도움이 된다

  • 법률 문서 생성 에이전트에서 “완료”와 “의존 가능”을 구분하려는 사람

  • 판례 RAG·요약·보고서 시스템에 출처와 검증 영수증을 붙이려는 개발자

  • Streamlit 데모를 배치 실행·회귀 테스트 가능한 도구로 바꾸려는 팀

  • 로컬 LLM으로 한국어 법률 파이프라인의 구조를 검증하려는 연구자

  • 생성물의 오류뿐 아니라 잘못된 PASS 자체를 테스트하려는 법률 AI 운영자

😫 시작점: 보고서는 만들어졌지만, 무엇을 믿어야 할지 닫히지 않았다

KorLawChestra는 판례 JSON을 입력하면 PlanningAgent가 계획을 세우고, 8개 워커가 판결문을 섹션·세그먼트·Claim·쟁점·법령·보고서로 변환하는 오픈소스 프로젝트다. Streamlit 화면에는 다음 흐름이 이미 구현돼 있었다.

판례 입력
→ PlanningAgent가 DAG 작성
→ section / segment / claim / provenance
→ issue_map / legal_ref / report_planner / report
→ VerifyAgent 검토와 부분 교정
→ 보고서·쟁점 지도·Claim·법령 탭

그림 1. 로컬에서 실제 실행한 Streamlit 입력 화면이다. 공개 판결의 사건번호·선고일·당사자 표기와 원문 일부가 보인다. 로컬 경로, API 키, 개인 비밀정보는 포함하지 않았다.

화면의 구조는 좋았다. 판례를 고르고 보고서 목표를 선택한 뒤, 계획만 수립하거나 계획과 실행을 한 번에 시작할 수 있었다.

그림 2. 실제 PlanningAgent 오케스트레이션 화면이다. 입력·목표·실행을 분리하고 보고서, 쟁점 지도, Claim·Provenance, 법령·선례 탭을 제공한다.

문제는 화면 다음이었다.

  1. 기본 문서가 대규모 OpenAI 호환 추론 서버 중심이라, 보유한 로컬 Ollama 모델로 재현하는 경로가 분명하지 않았다.

  2. UI 실행 결과를 다른 사건에도 반복하거나 CI에서 검증할 헤드리스 영수증이 없었다.

  3. 판결문 입력만 있는 상태에서 실제 소송기록·행위시법·조문 원문까지 확인한 것처럼 읽힐 위험이 있었다.

  4. 무엇보다 에이전트 완료, 검증기 결과, 보고서의 실무 의존 상태가 하나의 완료 신호로 뭉칠 수 있었다.

🔒 첫 번째 전환점: 모델보다 먼저 판례 원문을 닫았다

샘플 사건은 대법원 2022. 6. 30. 선고 2022다212594 판결로 정했다. 공개 데이터셋의 한 행을 바로 신뢰하지 않고 대한민국 법원 사법정보공개포털의 공식 PDF와 대조했다.

검증 결과는 다음과 같았다.

항목

결과

공개 데이터셋 행

joonhok-exo-ai/korean_law_open_data_precedents, row 85003

공식 원문

대한민국 법원 사법정보공개포털 PDF

정규화 데이터셋 전문

2,317자

공식 PDF 전문 대응 구간

2,324자

데이터셋 coverage

0.997410

sequence ratio

0.995906

실질적 내용 차이

관찰되지 않음

관찰된 형식 차이

PDF 표지·페이지 번호·따옴표 모양

여기서 99% 이상 비슷함을 공식성으로 바꾸지 않았다. 데이터셋은 분석 입력 후보이고, 공식 판결 PDF와 그 해시는 별도 근거로 보존했다.

공개 데이터셋 행
→ 사건번호 exact match
→ 공식 판결 PDF 확보
→ NFKC·공백·페이지 표지 정규화 비교
→ 원본·정규화본 SHA-256 기록
→ 분석 입력 승인

🛠️ 두 번째 전환점: UI 데모를 재현 가능한 실행으로 바꿨다

로컬 보강판에서는 Ollama의 OpenAI 호환 /v1 엔드포인트를 사용할 수 있게 하고, 판례 1건을 선택해 명령행에서 전체 파이프라인을 실행하도록 구성했다.

실행 조건은 다음과 같이 고정했다.

model: gemma4:e4b
api_base: http://127.0.0.1:11434/v1
temperature: 0.0
seed: 7
case_number: 2022다212594
workers: 8

헤드리스 실행 결과는 한 파일이 아니라 묶음으로 저장했다.

plan.json
artifacts.json
report.json
report.md
report.pdf
verify_report.json
receipt.json

보강한 실행기는 이후 실행부터 검증 직전에 plan.pre_review.jsonartifacts.pre_review.json을 저장하도록 구현했다. 다만 이번 최초 실행 폴더에는 이 이름의 전용 체크포인트가 남아 있지 않았다. 실제 복구 실행은 기존 artifacts.jsonCHECKPOINT_REVIEW 입력으로 읽어 8개 워커를 다시 돌리지 않고 보고서 구조와 검증 상태를 재점검했다. 따라서 이번 사례에서 실증된 범위는 저장된 artifact 재검토이고, 전용 pre-review 파일 생성은 코드에 구현된 후속 경로다.

📄 실제 결과: 보고서 PDF는 만들어졌다

샘플 실행은 공인중개사의 정보 제공 의무와 중개상 주의의무를 주제로 6쪽짜리 PDF를 생성했다.

그림 3. 실제 생성된 report.pdf 첫 페이지다. 사건정보·쟁점·법령·선례가 렌더링됐고 한글 글꼴도 정상이다. 그러나 이 첫 페이지에는 BLOCKED 상태가 표시되지 않는다. 따라서 화면이 완성돼 보인다는 사실을 품질 판정으로 사용하지 않고, receipt.json을 권위 있는 상태 원장으로 삼았다.

이 지점이 사례의 핵심이다. PDF가 보기 좋게 생성됐다는 사실은 다음을 증명하지 않는다.

  • 판결문에 없는 사실을 만들지 않았는가

  • 직접 근거 문장에 locator가 붙었는가

  • 상급심과 하급심 판단이 섞이지 않았는가

  • 행위 당시 법령과 현행 법령을 구분했는가

  • 실제 소송기록에서만 알 수 있는 주장·증거를 추정하지 않았는가

  • 사람이 그대로 법률의견이나 소송서면에 사용할 수 있는가

🚨 실패: 8/8 donepassed:false가 동시에 나왔다

초기 실행의 plan.json에서는 8개 태스크가 모두 done이었다. 태스크 오류도 없고 PDF도 생성됐다. 그래서 초기 집계 영수증은 다음 상태를 기록했다.

worker_tasks: 8/8 done
task_failures: []
status: PASS_WITH_LIMITATIONS
verification_findings: 0

그러나 같은 실행의 verify_report.json은 달랐다.

passed: false
violations: 1
severity: major
check: citation_integrity
findings_after_repair: []

검증기는 문제가 있다고 판정했지만, 교정 이후 findings 배열이 비었다는 이유로 상위 집계가 passed:false를 독립적인 차단 신호로 읽지 못한 것이다. 검증 결과가 사라진 것이 아니라, 상태 집계가 잘못 통과시킨 것이었다.

이 오류는 단순한 문장 품질 문제보다 위험하다. 사용자는 PDF와 PASS_WITH_LIMITATIONS를 보고 “제한은 있지만 써도 되는 보고서”로 오해할 수 있기 때문이다.

그림 4. 실제 plan.json, 초기·복구 receipt.json, verify_report.json, 테스트 결과에서 수치와 상태만 파생한 카드다. 제품 UI 캡처가 아니다. 8/8 done은 실행 완료이고, BLOCKED는 의존 불가 판정이다.

🧯 수리 1: passed:false를 독립 gate로 만들었다

상태 판정은 다음 순서로 바꿨다.

태스크 실패 또는 산출물 무결성 실패
→ FAIL

보고서 없음 또는 검증 미실행
→ NOT_RUN

검증기 passed:false
→ BLOCKED

critical/major 검증 지적
→ BLOCKED

단일 판결문만 있고 공식 행위시법·기록이 닫히지 않음
→ PASS_WITH_LIMITATIONS + DRAFT_NOT_FOR_RELIANCE

사람 검토와 필수 원자료까지 닫힘
→ 별도 Human Gate에서만 승격 검토

다음 실패 클래스를 회귀 테스트에 넣었다.

  • 검증기가 false인데 findings가 빈 경우도 BLOCKED

  • 직접 근거 E0에 locator가 없으면 fail-closed

  • 중요한 coverage가 비면 BLOCKED

  • 검증 자체가 없으면 NOT_RUN

  • integrity 오류가 있으면 FAIL

  • 깨끗한 단일 판결문 실행도 자동으로 실무 의존 가능 상태가 되지 않음

총 16개 테스트를 실제 실행했고 모두 통과했다.

🧭 수리 2: 문장마다 근거 성격을 분리했다

보고서가 법원 판시와 분석자의 제안을 한 목소리로 말하지 않도록 다섯 코드를 사용했다.

코드

의미와 예시

E0

확인한 공식 원문·기록에서 직접 확인 — 판결 주문, 원문 직접 인용

E1

공식 문서가 다른 기록·판단을 명시적으로 재현 — 상급심이 재현한 원심 판단

I1

확인 단서에서 도출한 분석적 추론 — 전제와 경쟁 설명이 있는 분석

H1

가설·실무 제안·반사실 — 체크리스트, 전략적 대안

U0

자료 부재·충돌로 미확인 — 다음 확보 자료와 함께 표시

이 구분은 신뢰도 점수가 아니다. 그 문장이 어디에서 왔고, 어떤 방식으로 사용할 수 있는지를 나타내는 출처 관계다.

예를 들어 판결문에 당사자의 주장이 보이지 않는다고 해서 “그 주장을 하지 않았다”고 쓰지 않는다.

금지: 당사자는 해당 주장을 하지 않았다.
대체: 접근 가능한 판결문에는 해당 주장의 기재가 확인되지 않는다 [U0].

판결문이 증거 내용을 요약했다고 해서 증거 원본을 확인한 것으로 쓰지도 않는다.

금지: 해당 증거 원본에서 사실을 확인했다.
대체: 판결문에 증거의 취지가 재현되어 있으나 원본은 확인되지 않았다 [E1].

⚖️ 수리 3: ‘실무용’이라는 말을 출력 계약으로 바꿨다

실무용 보고서가 되려면 섹션이 많기만 해서는 부족하다. 최소한 다음 객체와 gate가 필요하다고 정리했다.

사건·심급 그래프
+ 행위시법 / 판결 당시 법 / 현행 비교
+ 사실·절차 타임라인
+ 쟁점·요건·입증책임
+ 당사자 주장과 법원 응답
+ 증거의 가용성·진정성·관련성·한계
+ 심급별 주문·판단·이유
+ 최강 반론과 반사실 민감도
+ 미확인 사항과 다음 확보 자료
+ permitted / prohibited use
+ checked artifact SHA-256

현재 헤드리스 실행기는 이 계약의 부분 최소 구현이다. 계약을 문서화했다고 전체 구현이 끝난 것은 아니다. 특히 공식 법령 원문·행위시법·경과규정·후속 판례·하급심 원문·실제 소송기록은 별도 어댑터와 사람 검토가 필요하다.

🔄 Before vs After

항목

업스트림 중심 흐름 → 로컬 보강 후

입력

Streamlit JSON 업로드 → UI와 사건번호 exact 선택 CLI 병행

모델 경로

대규모 OpenAI 호환 서버 중심 → Ollama 호환 로컬 구조 검증 경로 추가

실행 결과

화면과 보고서 중심 → 계획·중간산출물·보고서·검증·영수증 묶음

중단 복구

전체 재실행 가능성 → 저장된 artifact 독립 재검토와 후속 pre-review 체크포인트 구현

출처

판례 텍스트 내부 provenance → 공식 원문 URL·원본/정규화 해시·비교 manifest

근거 표현

원문·요약·분석 혼합 가능 → E0/E1/I1/H1/U0 분리

완료 판정

워커 완료와 검증 결과가 섞일 수 있음 → execution / QA / reliance 상태 분리

검증 false + findings 빈 상태

잘못 통과 가능 → 무조건 BLOCKED

단일 판결문 결과

실무 보고서처럼 보일 수 있음 → DRAFT_NOT_FOR_RELIANCE 유지

테스트

구조 실행 중심 → 잘못된 PASS를 포함한 16개 회귀 테스트

🧩 얻은 결론: 오케스트레이터의 핵심은 더 많이 쓰는 것이 아니라, 멈출 줄 아는 것이다

이 사례에서 가장 인상적인 부분은 8개의 워커 자체가 아니었다. PlanningAgent, DAG, Blackboard, 중간 산출물, 부분 교정 구조는 이미 좋은 출발점이었다.

실무에 가까워지는 데 필요했던 것은 오히려 다음의 분리였다.

실행 완료 ≠ 검증 통과
검증 통과 ≠ 법률적으로 정확함
법률적으로 정확함 ≠ 현재 사건에 적용 가능함
현재 사건에 적용 가능함 ≠ 외부 제출 승인

판례 해설 AI가 신뢰를 얻으려면 “무엇을 생성했는가”뿐 아니라 다음을 함께 말해야 한다.

  • 어떤 공식 원본을 사용했는가

  • 어느 문장이 직접 근거이고 어느 문장이 추론인가

  • 무엇을 확인하지 못했는가

  • 어떤 상태에서 자동으로 멈췄는가

  • 누가, 어느 해시의 산출물을 최종 승인했는가

📋 재사용 가능한 체크리스트

원본과 사건 식별

[ ] 사건번호·법원·선고일을 exact match로 고정했다.
[ ] 공식 판결 원문 URL과 원본 SHA-256을 보존했다.
[ ] 데이터셋·OCR·정규화본과 공식 원문 차이를 기록했다.
[ ] 상급심·하급심·환송심을 하나의 판단으로 섞지 않았다.

생성과 provenance

[ ] 직접 인용과 법원 요약, 당사자 주장, 분석자 추론을 분리했다.
[ ] E0/E1에는 source와 locator가 있다.
[ ] H1 실무 제안이 법원 판시처럼 보이지 않는다.
[ ] U0에 불명 사유와 다음 확보 조치가 있다.

실행과 상태

[ ] worker done과 QA status를 별도 필드로 기록한다.
[ ] verifier passed:false를 findings 수와 무관하게 차단한다.
[ ] 보고서·검증·receipt가 같은 artifact hash를 가리킨다.
[ ] PDF·웹 화면에 reliance status를 눈에 띄게 표시한다.
[ ] 사람 승인 전 DRAFT_NOT_FOR_RELIANCE를 유지한다.

공개와 라이선스

[ ] 업스트림 커밋과 라이선스를 명시했다.
[ ] 비상업 조건 코드를 상업 시스템에 그대로 편입하지 않았다.
[ ] 공개 글에 로컬 경로·API 키·개인정보·비공개 기록을 넣지 않았다.
[ ] 실제 캡처와 파생 증거 카드를 캡션에서 구분했다.
[ ] Library 발행과 외부 웹/커뮤니티 게시를 별도 승인 단계로 둔다.

🧱 남은 한계와 다음 단계

이 사례는 다음을 입증한다.

  • 공개 판례 1건을 공식 원문과 대조해 입력할 수 있었다.

  • 로컬 모델로 8개 워커 전체와 PDF 생성을 실제 실행했다.

  • 초기 상태 집계의 모순을 재현하고 BLOCKED로 수리했다.

  • 관련 회귀 테스트 16개가 통과했다.

그러나 다음은 입증하지 않는다.

  • 다른 사건·재판유형에서도 같은 법률 품질이 나온다는 것

  • 모델이 판례 법리를 정확히 해석했다는 것

  • 현재 사건에 적용할 행위시법과 경과규정을 닫았다는 것

  • 실제 소송기록·증거 원본을 검토했다는 것

  • 변호사 등 법률전문가가 최종 승인했다는 것

  • 프로덕션 서비스로 배포·운영했다는 것

특히 실제 PDF 첫 페이지에 BLOCKED 상태가 보이지 않는 것은 남은 UI 결함이다. 다음 버전에서는 모든 PDF·Markdown·웹 화면에 상태와 금지 용도를 워터마크 또는 상단 배지로 일관되게 전달해야 한다.

🔗 출처와 재현 범위

로컬 보강 코드는 업스트림 HEAD를 기준으로 한 비상업 평가용 미커밋 작업트리다. 이 게시글은 코드 패치나 모델 파일을 배포하지 않으며, 방법·실패·검증 경계를 사례로 기록한다.


최종 판정: 파이프라인 구현과 실패 차단 수리는 확인됐지만, 샘플 법률보고서는 BLOCKED / DRAFT_NOT_FOR_RELIANCE다. 사람의 법률 검토와 공식 법령·소송기록 확인 없이 법률의견, 소송서면, 대외 제출물로 사용해서는 안 된다.

뉴스레터 무료 구독