MarkdownHeaderTextSplitter

동기

많은 채팅 또는 Q&A 애플리케이션에서는 임베딩하고 벡터화하기 전에 입력 문서를 청크 단위로 나누는 것이 일반적입니다. 텍스트 청킹 후에는 종종 유사한 주제를 가진 텍스트 단편을 함께 그룹화하는 것이 바람직합니다.

예를 들어 Markdown 파일은 h1, h2 및 h3와 같은 다중 레벨 제목으로 구성됩니다. 우리는 Markdown 제목을 기반으로 동일한 제목을 가진 텍스트 단편을 구성할 수 있습니다.

본 장에서는 MarkdownHeaderTextSplitter 텍스트 분할기를 사용하여 Markdown 제목을 기반으로 텍스트 내용을 분할하는 방법을 소개합니다.

예를 들어, 이 Markdown을 분할하려면:

md = '# Foo\\n\\n ## Bar\\n\\nHi this is Jim  \\nHi this is Joe\\n\\n ## Baz\\n\\n Hi this is Molly'

레벨 1과 레벨 2 제목을 기반으로 분할하는 제목 규칙을 설정합니다:

[("#", "헤더 1"),("##", "헤더 2")]

다음은 제목을 기준으로 콘텐츠가 분할된 예시이며, 메타데이터 필드는 현재 콘텐츠 단편이 어떤 제목에 속하는지를 기록합니다:

{'content': 'Hi this is Jim  \nHi this is Joe', 'metadata': {'헤더 1': 'Foo', '헤더 2': 'Bar'}}
{'content': 'Hi this is Molly', 'metadata': {'헤더 1': 'Foo', '헤더 2': 'Baz'}}

이제 코드 작성 방법을 살펴보겠습니다.

의존성을 설치합니다:

%pip install -qU langchain-text-splitters
from langchain_text_splitters import MarkdownHeaderTextSplitter

API 참조:

  • MarkdownHeaderTextSplitter를 사용하여 텍스트 분할기 생성하기
markdown_document = "# Foo\n\n    ## Bar\n\n안녕하세요, 제 이름은 Jim입니다\n\n안녕하세요, 제 이름은 Joe입니다\n\n ### Boo \n\n 안녕하세요, 제 이름은 Lance입니다 \n\n ## Baz\n\n 안녕하세요, 제 이름은 Molly입니다"

headers_to_split_on = [
    ("#", "헤더 1"),
    ("##", "헤더 2"),
    ("###", "헤더 3"),
]

markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
md_header_splits = markdown_splitter.split_text(markdown_document)
md_header_splits
[Document(page_content='안녕하세요, 제 이름은 Jim입니다\n안녕하세요, 제 이름은 Joe입니다', metadata={'헤더 1': 'Foo', '헤더 2': 'Bar'}),
     Document(page_content='안녕하세요, 제 이름은 Lance입니다', metadata={'헤더 1': 'Foo', '헤더 2': 'Bar', '헤더 3': 'Boo'}),
     Document(page_content='안녕하세요, 제 이름은 Molly입니다', metadata={'헤더 1': 'Foo', '헤더 2': 'Baz'})]
type(md_header_splits[0])
langchain.schema.Document

각 Markdown 그룹 내에서는 어떤 텍스트 분할기도 적용할 수 있습니다.

markdown_document = "# 소개 \n\n    ## 역사 \n\n  Markdown[9]은 평문 편집기를 사용하여 서식이 있는 텍스트를 만들기 위한 경량 마크업 언어입니다. John Gruber는 2004년 Markdown을 인간 독자들에게 매력적인 마크업 언어로 만들었습니다.[9] \n\n  Markdown은 블로깅, 인스턴트 메시징, 온라인 포럼, 협업 소프트웨어, 문서 페이지 및 readme 파일에서 널리 사용됩니다. \n\n ## 부상과 분기 \n\n Markdown의 인기가 급격히 증가함에 따라 테이블, 각주, 정의 목록 등의 추가 기능이 필요하여 많은 Markdown 구현이 나타났습니다.[주석 1] 그리고 HTML 블록 안의 Markdown 등을 위한 필요성으로 주도되었습니다. \n\n #### 표준화 \n\n 2012년부터 Jeff Atwood와 John MacFarlane을 포함한 일부 인물들이 Atwood가 표준화 노력으로 특성화한 작업을 시작했습니다. \n\n ## 구현 \n\n Markdown의 구현은 12가지 이상의 프로그래밍 언어로 제공됩니다."

headers_to_split_on = [
    ("#", "헤더 1"),
    ("##", "헤더 2"),
]

markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
md_header_splits = markdown_splitter.split_text(markdown_document)

from langchain.text_splitter import RecursiveCharacterTextSplitter

chunk_size = 250
chunk_overlap = 30
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=chunk_size, chunk_overlap=chunk_overlap
)

splits = text_splitter.split_documents(md_header_splits)
splits

결과:

[Document(page_content='Markdown[9]은 평문 편집기를 사용하여 서식이 있는 텍스트를 만들기 위한 경량 마크업 언어입니다. John Gruber는 2004년 Markdown을 인간 독자들에게 매력적인 마크업 언어로 만들었습니다.[9]', metadata={'헤더 1': '소개', '헤더 2': '역사'}),
     Document(page_content='Markdown은 블로깅, 인스턴트 메시징, 온라인 포럼, 협업 소프트웨어, 문서 페이지 및 readme 파일에서 널리 사용됩니다.', metadata={'헤더 1': '소개', '헤더 2': '역사'}),
     Document(page_content='Markdown의 인기가 급격히 증가함에 따라 테이블, 각주, 정의 목록 등의 추가 기능이 필요하여 많은 Markdown 구현이 나타났습니다. 그리고 HTML 블록 안의 Markdown 등을 위한 필요성으로 주도되었습니다.  \n#### 표준화', metadata={'헤더 1': '소개', '헤더 2': '부상과 분기'}),
     Document(page_content='#### 표준화  \n2012년부터 Jeff Atwood와 John MacFarlane을 포함한 일부 인물들이 Atwood가 표준화 노력으로 특성화한 작업을 시작했습니다.', metadata={'헤더 1': '소개', '헤더 2': '부상과 분기'}),
     Document(page_content='Markdown의 구현은 12가지 이상의 프로그래밍 언어로 제공됩니다.', metadata={'헤더 1': '소개', '헤더 2': '구현'})]