LangChain에서 Document loader로 읽어들인 문서의 텍스트를 적절한 길이의 chunk로 분할할 때Text splitter를 사용합니다. 지정한 문자들로 텍스트를 자르는 RecursiveCharacterTextSplitter에 이어 MarkdownHeaderTextSplitter에 대해 살펴보겠습니다.
MarkdownHeaderTextSplitter
MarkdownHeaderTextSplitter에서는 Markdown 파일에서 사용하는 #, ##, ### 등의 헤더를 기준으로 Markdown 텍스트를 분할합니다. 예제 코드를 보겠습니다.
간단한 마크다운 문자열이 있습니다.
md = """
# Title
## Chapter 1
### Sub1
content 1-1
### Sub2
content 1-2
## Chapter 2
content 2-0
## Chapter 3
### Sub1
content 3-1
### Sub2
content 3-2
"""
1단계 #, 2단계 ##, 3단계 ###까지 헤더를 사용한 문자열입니다. MarkdownHeaderTextSplitter로 분할해보겠습니다.
from langchain.text_splitter import MarkdownHeaderTextSplitter
headers_to_split_on = [
("#", "Header 1"),
("##", "Header 2"),
("###", "Header 3")
]
markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on = headers_to_split_on)
md_header_splits = markdown_splitter.split_text(md)
md_header_splits
## 출력
[Document(page_content='content 1-1', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 1', 'Header 3': 'Sub1'}),
Document(page_content='content 1-2', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 1', 'Header 3': 'Sub2'}),
Document(page_content='content 2-0', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 2'}),
Document(page_content='content 3-1', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 3', 'Header 3': 'Sub1'}),
Document(page_content='content 3-2', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 3', 'Header 3': 'Sub2'})]
위에서 headers_to_split_on을 이용해 어떤 헤더(#, ##, ###)를 기준으로 분할할지, 분할한 헤더의 이름(Header 1, Header 2, Header 3)을 무엇으로 할지 지정해줍니다. 분할한 헤더의 이름은 결과로 나온 Document 객체의 metadata에 들어갑니다. 출력 결과를 보면 지정해준 1, 2, 3단계 헤더들을 기준으로 문서를 분할한 것을 알 수 있습니다.
이번엔 2단계 헤더까지만 사용해보겠습니다.
headers_to_split_on = [
("#", "Header 1"),
("##", "Header 2")
]
markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on = headers_to_split_on)
md_header_splits = markdown_splitter.split_text(md)
md_header_splits
## 출력
[Document(page_content='### Sub1\ncontent 1-1 \n### Sub2\ncontent 1-2', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 1'}),
Document(page_content='content 2-0', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 2'}),
Document(page_content='### Sub1\ncontent 3-1 \n### Sub2\ncontent 3-2', metadata={'Header 1': 'Title', 'Header 2': 'Chapter 3'})]
결과를 보면 2단계 헤더까지만 이용해 텍스트가 나눠지고, 3단계 헤더는 page_content에 들어가 있는 것을 확인할 수 있습니다.
앞에서 봤던 RecursiveCharacterTextSplitter 또는 다른 Text splitter와 달리, 길이를 기준으로 나누는 것이 아니라 헤더를 기준으로 나누기 때문에 길이가 매우 긴 Document가 나올 수 있습니다.
MarkdownHeaderTextSplitter와 유사한 Text splitter로 HTMLHeaderTextSplitter가 있습니다. HTMLHeaderTextSplitter는 HTML 헤더를 이용해 HTML 파일을 분할합니다.