이전 포스팅에서
RAG를 이용한 민법 챗봇을 개발하고
까지 해보았다.
이제 청킹과 메타데이터를 이용해 조금 더 효율적으로 다뤄볼 것이다.
Chunking
기존에는 각 판례 전체를 하나의 덩어리로 처리했지만 이럴경우 큰 문제가 있다.
한 판례가 수백 줄에 걸쳐 이어지는 긴 텍스트로 존재할수도 있다.
하지만 GPT 계열 LLM은 토큰 한도가 존재하므로, 이렇게 긴 텍스트를 그대로 임베딩하거나 검색에 사용하는 건 비효율적이다.
그래서 판례별로 잘게 나누면 데이터를 효율적으로 임베딩하고 검색 정확도를 높일 수 있다.
즉 청킹(Chunking) 이 필요하다.
LangChain의 RecursiveCharacterTextSplitter 사용하여 청킹할것이다.
Metadata
이떄 또다시 문제가있다.
우리는 gpt에게 프롬포트로 넘길때 참고한 판례의 판례번호를 알려달라고 했다.
그러나 청킹을 하다 보면 하나의 판례가 여러 청크로 쪼개진다.
이때 각각의 청크는 개별로 저장되기 때문에, 판례번호, 사건번호, 선고일 뿐만 아니라 제목도 잃어버릴 수 있다.
검색 결과가 나왔는데 “이 판례가 어떤 사건인지 모른다”면 사용성이 떨어질 것이다.
그래서 각 chunk에 다음 정보를 붙여줄 것이다.
- 판결 제목 (title)
- 사건번호 (case_number)
- 선고일 (decision_date)
- 전체 판례명 (full_case_name)
이를 통해 후처리 시 다시 판례 정보를 묶거나,
검색 결과에 출처를 명확히 표기할 수 있게 됨.
또한 메타데이터에는 검색 필터링 등을 통해 검색효율을 향상시킬수 있다는 엄청난 장점이 있다.
Metadata의 장점
- 검색 품질 향상
→ 판례 본문뿐 아니라, 사건번호나 제목 키워드로도 검색 가능 - 검색 필터링 가능
→ 예: “2010년 보증 관련 판례만 찾아줘” → decision_date, title 기반 필터 가능 - 출처 명확화
→ LLM 응답 마지막에 “(참고 판례: 대법원 2010.1.1 선고 2000다12345 판결)” 같은 문구 추가 - 구조화된 데이터베이스 구축 가능
→ Elasticsearch 같은 검색엔진에 인덱싱하거나
→ 프론트엔드에서 사건번호/날짜/주제 필터 제공 가능
판례별로 잘라둔 데이터에 다음 메타데이터를 추출하는 함수를 적용하자
제목은 줄의 맨 앞에서 줄바꿈 이나 ( 나오기전까지의 텍스트 + 앞부분의 공백무시
사건번호 형식은 다음과같이 올수있기에 참고하여 정규식을 구성하엿다.
[연도][사건구분기호][일련번호]
ex) 2020다12345, 2017누4567, 2011마345, 2008다카8765
# 판례 메타데이터 추출 함수
def extract_metadata(chunk_text: str) -> dict:
metadata = {}
title_match = re.match(r"^\s*([^\n(]+)", chunk_text)
if title_match:
metadata["title"] = title_match.group(1).strip()
info_match = re.search(r"\(([^)]+선고\s+([0-9]{2,4}[가-힣]{1,2}[0-9]{2,6})[^)]*)\)", chunk_text)
if info_match:
metadata["full_case_name"] = info_match.group(1).strip()
metadata["case_number"] = info_match.group(2).strip()
date_match = re.search(r"([0-9]{4})\.\s*([0-9]{1,2})\.\s*([0-9]{1,2})", info_match.group(1))
if date_match:
year, month, day = date_match.groups()
metadata["decision_date"] = f"{year}-{int(month):02d}-{int(day):02d}"
return metadata
첫번째 데이터는 목차라서 의미없는 데이터이기 때문에 제거하였다
이때 청크 길이는 1000자 overlap은 100자로 두었다.
너무 짧으면 판례 문맥 부족 → 잘못된 요약/추론 가능
할 수 있기 떄문에 적절하게 설정해주어야 한다.
Overlap은 중요한 단어/문장이 자르기 경계에 걸릴 때 문맥 손실을 줄여준다.
# --- 청크 및 Document 생성 ---
clean_chunks = preprocess_raw_text(raw_text)[1:] # 첫 번째 청크 제거(목차)
# documents = [Document(page_content=chunk) for chunk in clean_chunks]
documents = [
Document(page_content=chunk, metadata=extract_metadata(chunk))
for chunk in clean_chunks
]
# 2. LangChain 텍스트 분할기 사용하여 추가 chunking
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
split_documents = text_splitter.split_documents(documents)
# 상위 10개 분할 문서 확인
for i, doc in enumerate(split_documents[:10]):
print(f"\n--- Document {i+1} ---")
print(f"[Metadata] {doc.metadata}")
print(f"[Content]\n{doc.page_content[:300]}...") # 300자 미리보기
결과
--- Document 1 ---
[Metadata] {'title': '민법의 법원:관습법', 'full_case_name': '대법원 2003. 7. 24. 선고 2001다48781 전원합의체 판결', 'case_number': '2001다48781', 'decision_date': '2003-07-24'}
[Content]
민법의 법원:관습법 (1)
(대법원 2003. 7. 24. 선고 2001다48781 전원합의체 판결)
<쟁점>
제정민법이 시행되기 전에 존재하던 ‘상속회복청구권은 상속이 개시된 날부터 20년이 경과하면
소멸한다’는 관습에 관습법으로의 효력을 인정할 수 있는지 여부
<판결요지>
[1] 사회의 거듭된 관행으로 생성한 어떤 사회생활규범이 법적 규범으로 승인되기에 이르렀다고
하기 위하여는 그 사회생활규범은 헌법을 최상위 규범으로 하는 전체 법질서에 반하지 아니하는
것으로서 정당성과 합리성이 있다고 인정될 수 있는 것이어야 ...
--- Document 2 ---
[Metadata] {'title': '민법의 법원:관습법', 'full_case_name': '대법원 2005. 7. 21. 선고 2002다1178 전원합의체 판결', 'case_number': '2002다1178', 'decision_date': '2005-07-21'}
[Content]
민법의 법원:관습법 (2)
(대법원 2005. 7. 21. 선고 2002다1178 전원합의체 판결 )
<쟁점>
종중 구성원의 자격을 성년 남자만으로 제한하는 관습법의 효력 여부
<판결요지>
[1] 관습법이란 사회의 거듭된 관행으로 생성한 사회생활규범이 사회의 법적 확신과 인식에 의하
여 법적 규범으로 승인·강행되기에 이른 것을 말하고, 그러한 관습법은 법원(法源)으로서 법령에
저촉되지 아니하는 한 법칙으로서의 효력이 있는 것이고, 또 사회의 거듭된 관행으로 생성한 어떤
사회생활규범이 법적 규범으로 승인되기에 이르렀다고 하...
--- Document 3 ---
[Metadata] {'title': '민법의 법원:관습법', 'full_case_name': '대법원 2005. 7. 21. 선고 2002다1178 전원합의체 판결', 'case_number': '2002다1178', 'decision_date': '2005-07-21'}
[Content]
니하며, 정치·경제·사회·문화 등 모든 영역에서 여성에 대한 차별을 철폐하고 남녀평등을 실현하는
방향으로 변화되어 왔으며, 앞으로도 이러한 남녀평등의 원칙은 더욱 강화될 것인바, 종중은 공동
선조의 분묘수호와 봉제사 및 종원 상호간의 친목을 목적으로 형성되는 종족단체로서 공동선조의
사망과 동시에 그 후손에 의하여 자연발생적으로 성립하는 것임에도, 공동선조의 후손 중 성년 남
자만을 종중의 구성원으로 하고 여성은 종중의 구성원이 될 수 없다는 종래의 관습은, 공동선조의
분묘수호와 봉제사 등 종중의 활동에 참여할 기회를 출생에서 ...
--- Document 8 ---
[Metadata] {'title': '신의성실의 원칙:강행법규 위반과의 관계', 'full_case_name': '대법원 2000. 6. 9. 선고 99다70860 판결', 'case_number': '99다70860', 'decision_date': '2000-06-09'}
[Content]
신의성실의 원칙:강행법규 위반과의 관계 (1)
(대법원 2000. 6. 9. 선고 99다70860 판결 )
<쟁점>
사립학교법 제28조 제2항의 입법 취지 및 사립학교 경영자가 위 규정에 위반한 매도나 담보제
공이 무효라는 사실을 알고서 매도나 담보제공을 한 후 스스로 그 무효를 주장하는 것이 권리남용
내지 신의성실의 원칙에 위배되는지 여부
<판결요지>
사립학교법 제28조 제2항, 같은법시행령 제12조가 학교법인이 학교교육에 직접 사용되는 학교법
인의 재산 중 교지, 교사 등은 이를 매도하거나 담보에 제공할 수 없다고 규정...
--- Document 9 ---
[Metadata] {'title': '신의성실의 원칙:강행법규 위반과의 관계', 'full_case_name': '대법원 2013. 12. 18. 선고 2012다89399 전원합의체 판결', 'case_number': '2012다89399', 'decision_date': '2013-12-18'}
[Content]
신의성실의 원칙:강행법규 위반과의 관계 (2)
(대법원 2013. 12. 18. 선고 2012다89399 전원합의체 판결 )
<쟁점>
노사가 정기상여금을 통상임금에서 제외하기로 합의하고 이를 전제로 임금수준을 정한 경우, 근로
자가 노사합의의 무효를 주장하며 정기상여금을 통상임금에 포함하여 산정한 추가 법정수당을 청구하
는 것이 신의성실의 원칙에 위배되는지 여부
<판결요지>
단체협약 등 노사합의의 내용이 근로기준법의 강행규정을 위반하여 무효인 경우에, 무효를 주장
하는 것이 신의칙에 위배되는 권리의 행사라는 이유로 이를 배척...
--- Document 10 ---
[Metadata] {'title': '신의성실의 원칙:실효의 원칙', 'full_case_name': '대법원 1990. 8. 28. 선고 90다카9619 판결', 'case_number': '90다카9619', 'decision_date': '1990-08-28'}
[Content]
신의성실의 원칙:실효의 원칙
(대법원 1990. 8. 28. 선고 90다카9619 판결 )
<쟁점>
조건부 징계해고처분을 받고 의원면직된 후 10년 남짓 경과된 뒤에 조건부 징계처분 등이 무효
이므로 원고는 피고의 사원임의 확인을 구하는 소를 제기한 것이 신의칙에 위반되는지 여부
<판결요지>
권리행사가 이른바 신의칙에 반하는 결과가 되어 허용되지 않는 경우라는 것은 권리자의 주관적
인 동기가 고려되지 않는다 하더라도 그에게 권리행사의 기회가 있어서 이를 현실적으로 기대할
수가 있었음에도 불구하고 행사하지 않은 경우에 한하는...
메타데이터에 정보들이 잘 저장되었다.
이제 응답에 이 메타데이터의 정보들을 추가해보자
{
"answer": "해당 조건 하에서는 보증인의 책임 범위가 제한됩니다... (참고 판례: 대법원 2005. 11. 25. 선고 2005다35554 판결)",
"metadata": {
"title": "근보증의 책임범위 제한",
"case_number": "2005다35554",
"decision_date": "2005-11-25"
}
}