LLM 엔지니어링11장 · 폐쇄망 문서 파이프라인과 폐쇄형 RAG7 / 23← 이전목차다음 →MetaContents

11장. 폐쇄망 문서 파이프라인과 폐쇄형 RAG

문서 정제

장 본 채소는 흙을 털고 시든 잎을 떼고 씻은 뒤에 요리합니다. 수집한 글에도 답에 쓸모없는 것이 붙어 있습니다. 메뉴와 꼬리말, PDF 의 쪽 번호와 머리말, 중간에 끊긴 줄, 그리고 색인에 들어가면 안 되는 개인정보입니다.

메뉴와 꼬리말과 쪽 번호를 걷어 내고, PDF 에서 끊긴 줄을 잇고, 전화번호와 메일을 가리고, 겹친 빈칸을 줄이는 네 가지 손질 카드

네 카드는 정제의 손질 네 가지입니다. 틀 걷기는 쪽마다 되풀이되는 글을 빼고, 줄 잇기는 PDF 에서 폭에 맞춰 끊긴 줄을 문장으로 되돌리고, 개인정보 가리기는 전화번호와 메일을 자리표시로 바꾸고, 빈칸 정리는 겹친 빈칸과 빈 줄을 줄입니다. 여기서 흙과 시든 잎이 쓸모없는 글, 씻기가 정제입니다.

흠과 고치는 법

흠생긴 까닭그대로 두면고치는 법
메뉴, 꼬리말html 화면의 틀모든 조각에 같은 글이 섞여 검색이 흐려진다태그의 class 로 건너뛴다
쪽 머리말, 쪽 번호PDF 의 쪽마다 찍힌 글조항 가운데에 "- 1 -" 이 끼인다되풀이되는 줄과 쪽 번호 꼴의 줄을 뺀다
끊긴 줄PDF 의 줄 폭"정산" 과 "하는 방법" 이 따로 논다앞 줄이 문장 끝(.)이 아니면 잇는다
개인정보담당자 연락처아무나 묻고 받아 갈 수 있다정규식으로 찾아 [전화번호] 로 바꾼다

정규식으로 가리기

Python
import re

line = "보안 문의는 김하늘 책임(010-2468-1357, haneul.kim@example.com)에게 합니다."
# 휴대폰 번호 꼴(010-0000-0000)과 메일 주소 꼴을 찾아 자리표시로 바꾼다
line = re.sub(r"01[016789]-\d{3,4}-\d{4}", "[전화번호]", line)
line = re.sub(r"[\w.-]+@[\w-]+\.[\w.]+", "[메일]", line)
print(line)

코드에 나오는 함수

코드쉬운 뜻
reregular expression(정규 표현식, 정규식)의 줄임이다. 글자의 꼴로 찾고 바꾸는 표준 라이브러리다
re.sub(꼴, 바꿀 글, 원래 글)substitute(바꾸다)의 줄임이다. 꼴에 맞는 부분을 모두 바꿀 글로 바꾼다
r"…"raw(날것) 문자열이다. \d 의 역슬래시를 파이썬이 따로 해석하지 않고 그대로 정규식에 넘긴다
01[016789]01 다음에 0, 1, 6, 7, 8, 9 가운데 한 글자가 온다
\d{3,4}\d 는 digit(숫자) 한 글자, {3,4} 는 그것이 3개나 4개 이어진다는 뜻이다
[\w.-]+\w 는 word(낱말) 글자로 글자·숫자·밑줄이다. 이것과 점, 하이픈이 하나 이상(+) 이어진다
\.점 글자 그 자체다. 정규식에서 맨 점(.)은 "아무 글자"라서 역슬래시를 붙인다

이 코드가 뜻하는 것

서류를 복사해 돌리기 전에 연락처에 검은 매직을 칠하는 일로 읽어 봅니다. 칠하는 사람은 "010 으로 시작하는 숫자 줄", "@ 가 든 낱말"처럼 생김새를 보고 찾아 칠합니다. 여기서 검은 매직이 [전화번호], [메일] 같은 자리표시, 생김새의 규칙이 정규식입니다.

줄하는 일쉽게 말하면
line = "보안 문의는 …"연락처가 든 문장을 준비한다복사할 서류
re.sub(r"01[016789]-…", "[전화번호]", line)휴대폰 번호 꼴을 자리표시로 바꾼다전화번호에 매직 칠하기
re.sub(r"[\w.-]+@…", "[메일]", line)메일 주소 꼴을 자리표시로 바꾼다메일 주소에 매직 칠하기
print(line)가린 문장을 찍는다칠한 뒤의 서류

교안을 만든 PC 에서 이 블록은 보안 문의는 김하늘 책임([전화번호], [메일])에게 합니다. 를 찍었습니다. 번호와 메일은 가려졌지만 이름 "김하늘"은 그대로입니다. 정규식은 정해 둔 꼴만 찾기 때문입니다. 예시의 이름과 연락처는 지어낸 것입니다.

작게 줄여서 눈으로 보기

같은 전화번호 꼴이 어떤 글은 찾고 어떤 글은 놓치는지 봅니다. 번호는 모두 설명을 위해 지어낸 것입니다.

Python
import re

pattern = r"01[016789]-\d{3,4}-\d{4}"
for s in ["010-0000-1234", "011-000-1234", "02-0000-1234", "010 0000 1234", "01000001234"]:
    print(f"{s:15s}", "찾음" if re.search(pattern, s) else "못 찾음")
출력
010-0000-1234   찾음
011-000-1234    찾음
02-0000-1234    못 찾음
010 0000 1234   못 찾음
01000001234     못 찾음
결과읽는 법
010-0000-1234 찾음01, 0, 하이픈, 숫자 4개, 하이픈, 숫자 4개로 꼴에 맞는다
011-000-1234 찾음가운데 숫자가 3개여도 {3,4} 라서 맞는다
02-0000-1234 못 찾음지역 번호는 01 로 시작하지 않아 꼴 밖이다
010 0000 1234 못 찾음하이픈 대신 빈칸을 써서 꼴 밖이다
01000001234 못 찾음하이픈 없이 붙여 써서 꼴 밖이다

re.search 는 글 안 어디에서든 꼴에 맞는 곳이 하나라도 있으면 찾아 줍니다. 실제 문서에는 빈칸이나 붙여 쓴 번호도 섞여 있으므로, 가린 결과를 표본으로 보고 놓친 꼴이 있으면 규칙을 더합니다.

주의할 점

  • 정제 규칙은 문서의 형식마다 따로 겁니다. 줄 잇기를 모든 문서에 걸면, 번호 제목 다음 줄이나 표의 행까지 이어 붙어 버립니다(실습 3).
  • 정규식은 정해 둔 꼴만 찾습니다. 이름, 주민등록번호, 주소처럼 꼴이 다양한 개인정보는 따로 규칙을 더하고, 가린 결과를 사람이 표본으로 확인합니다. 개인정보를 다루는 더 넓은 방법은 21장에서 봅니다.
← 이전 절11장 · 문서 수집다음 절 →11장 · 중복과 옛 판 거르기