11장. 폐쇄망 문서 파이프라인과 폐쇄형 RAG
중복과 옛 판 거르기
냉장고에 같은 우유가 두 팩 있으면 하나는 치우고, 날짜가 지난 것은 버립니다. 문서도 같은 파일이 이름만 바꿔 두 번 올라와 있거나, 같은 규정의 옛 판이 새 판과 함께 남아 있습니다.
왼쪽은 이름만 다르고 내용(해시)이 같은 파일로, 하나만 남깁니다. 오른쪽은 제목이 같고 판이 다른 문서로, 최신 판만 남깁니다. 여기서 같은 우유 두 팩이 똑같은 파일, 날짜 지난 우유가 옛 판입니다.
두 경우 견주기
| 견줄 것 | 똑같은 파일 | 같은 문서의 옛 판 |
|---|---|---|
| 알아보는 법 | 파일 해시가 같다 | 제목이 같고 판(버전)이 다르다 |
| 그대로 두면 | 같은 조각이 검색 상위를 두 번 차지한다 | 옛 규정으로 답할 수 있다 |
| 남길 것 | 하나(이름이 원래 이름인 쪽) | 판이 가장 높은 것 |
해시로 똑같은 파일 찾기
import hashlib
from pathlib import Path
# 이름이 다른 두 공지의 해시를 견준다. 같으면 내용이 한 글자도 다르지 않다
a = hashlib.sha256(Path("intranet/notice/공지_사무실이전.html").read_bytes()).hexdigest()
b = hashlib.sha256(Path("intranet/notice/공지_사무실이전 (1).html").read_bytes()).hexdigest()
print(a[:12], b[:12], a == b)코드에 나오는 함수
| 코드 | 쉬운 뜻 |
|---|---|
Path(…).read_bytes() | 파일 내용을 바이트 그대로 읽는다. 이름이나 만든 날짜는 들어가지 않는다 |
hashlib.sha256(…) | 그 바이트로 SHA-256 지문을 잰다 |
.hexdigest() | 지문을 16진수 64글자로 적는다 |
a[:12] | 지문의 앞 12글자만 보인다 |
a == b | 두 지문이 글자 하나까지 같으면 True 다 |
이 코드가 뜻하는 것
사람의 지문으로 읽어 봅니다. 이름표를 바꿔 달아도 지문이 같으면 같은 사람입니다. 반대로 쌍둥이처럼 닮아도 지문은 다릅니다. 여기서 이름표가 파일 이름, 지문이 해시, 같은 사람이 똑같은 파일입니다.
| 줄 | 하는 일 | 쉽게 말하면 |
|---|---|---|
a = hashlib.sha256(Path("…공지_사무실이전.html")…) | 첫 공지의 지문을 잰다 | 첫 사람의 지문 |
b = hashlib.sha256(Path("…공지_사무실이전 (1).html")…) | 이름에 " (1)" 이 붙은 공지의 지문을 잰다 | 이름표만 다른 사람의 지문 |
print(a[:12], b[:12], a == b) | 두 지문의 앞부분과 같은지를 찍는다 | 지문 대조 결과 |
교안을 만든 PC 에서는 90cbc1dfe394 90cbc1dfe394 True 가 나왔습니다. 이름은 다르지만 내용은 한 글자도 다르지 않은 같은 파일이라는 뜻이니, 원래 이름인 쪽 하나만 남깁니다.
작게 줄여서 눈으로 보기
글이 똑같을 때와 빈칸 하나만 다를 때 지문이 어떻게 되는지 봅니다. 문장은 설명을 위해 지어낸 것입니다.
import hashlib
for text in ["반차는 4시간 단위", "반차는 4시간 단위", "반차는 4시간 단위"]:
h = hashlib.sha256(text.encode("utf-8")).hexdigest()
print(len(h), h[:16], repr(text))64 da1ab2bbf42ef7b7 '반차는 4시간 단위'
64 da1ab2bbf42ef7b7 '반차는 4시간 단위'
64 70a1e7c9a05583d0 '반차는 4시간 단위'| 결과 | 읽는 법 |
|---|---|
64 | 지문은 글의 길이와 상관없이 늘 64글자다 |
첫째, 둘째 줄의 da1ab2bbf42ef7b7 | 같은 글은 몇 번을 재도 같은 지문이 나온다 |
셋째 줄의 70a1e7c9a05583d0 | "4시간" 뒤에 빈칸이 하나 더 있을 뿐인데 지문이 완전히 달라졌다 |
text.encode("utf-8") 은 글자를 바이트로 바꿉니다. 해시는 바이트에서만 잴 수 있기 때문입니다. repr(text) 는 따옴표를 붙여 찍어서 빈칸의 수를 눈으로 볼 수 있게 합니다. 이렇게 빈칸 하나에도 지문이 바뀌므로, "거의 같은" 문서는 해시로 찾지 못합니다.
주의할 점
- 해시는 한 글자만 달라도 달라집니다. 띄어쓰기만 다른 "거의 같은" 문서는 해시로 못 찾습니다. 그럴 때는 정제한 글끼리 견주거나 임베딩의 유사도가 아주 높은 쌍을 사람이 봅니다.
- 옛 판을 지우지 않고 남겨야 할 때도 있습니다("작년 기준은?"). 그럴 때는 색인에서 빼지 않고 메타데이터에 판과 날짜를 붙여 검색할 때 고릅니다.