RecursiveDocumentSplitter
RecursiveDocumentSplitter
주어진 구분자(separator) 목록을 텍스트에 적용해 청크(chunk)를 재귀적으로 더 작은 조각으로 나누는 컴포넌트예요.
출처: 문서
본문
| 항목 | 내용 |
|---|---|
| 파이프라인에서 가장 흔한 위치 | 인덱싱 파이프라인에서 Converters와 DocumentCleaner 다음, Classifiers 앞 |
| 필수 run 변수 | documents: 문서 목록 |
| 출력 변수 | documents: 문서 목록 |
| API reference | PreProcessors |
| GitHub 링크 | recursive_splitter.py |
개요
RecursiveDocumentSplitter는 문서 목록을 입력으로 받아 분할된 텍스트를 담은 문서 목록을 반환해요. 컴포넌트 초기화 시 다음 파라미터를 설정할 수 있어요:
split_length: 각 청크의 최대 길이. 기본 단위는 단어(word)예요. 단위를 바꾸려면split_unit파라미터를 보세요.split_overlap: 연속된 청크 사이에서 겹치는 문자 또는 단어 수.split_unit:split_length파라미터의 단위."word","char","token"중 하나일 수 있어요.separators: 텍스트 분할에 사용할 선택적 구분자 문자열 목록. 아무것도 제공하지 않으면 기본값은["\n\n", "sentence", "\n", " "]예요. 문자열 구분자는 정규 표현식으로 취급돼요. 구분자가"sentence"면 NLTK 기반 커스텀 문장 토크나이저로 텍스트를 문장 단위로 나눠요. 자세한 내용은 SentenceSplitter 코드를 참고하세요.sentence_splitter_params: SentenceSplitter에 전달할 선택적 파라미터.
split_unit="token"일 때, 소스 문서의 <|endoftext|> 같은 문자열은 일반 텍스트로 토크나이즈돼요. 청크에 보존되며 토큰 한도에 계산되죠.
구분자는 목록에 정의된 순서대로 적용돼요. 첫 번째 구분자를 텍스트에 사용하고, 지정된 chunk_size 이내에 있는 결과 청크는 유지돼요. 정의된 chunk_size를 초과하는 청크에는 목록의 다음 구분자를 적용해요. 모든 구분자를 사용했는데도 청크가 여전히 chunk_size를 초과하면, 단어 또는 문자를 카운팅 단위로 사용하는지에 따라 chunk_size를 기준으로 하드 분할이 일어나요. 이 과정은 모든 청크가 지정된 chunk_size 한도 내에 들어올 때까지 반복돼요.
사용법
from haystack import Document
from haystack.components.preprocessors import RecursiveDocumentSplitter
chunker = RecursiveDocumentSplitter(
split_length=260, split_overlap=0, separators=["\n\n", "\n", ".", " "]
)
text = """Artificial intelligence (AI) - Introduction
AI, in its broadest sense, is intelligence exhibited by machines, particularly computer systems.
AI technology is widely used throughout industry, government, and science. Some high-profile applications include advanced web search engines; recommendation systems; interacting via human speech; autonomous vehicles; generative and creative tools; and superhuman play and analysis in strategy games."""
doc = Document(content=text)
doc_chunks = chunker.run([doc])
print(doc_chunks["documents"])
# >>
# [#
# Document(id=..., content: 'Artificial intelligence (AI) - Introduction\n\n', meta: {'source_id': '...', 'parent_id': '...', 'split_id': 0, 'split_idx_start': 0, '_split_overlap': None, 'page_number': 1})
# Document(id=..., content: 'AI, in its broadest sense, is intelligence exhibited by machines, particularly computer systems.\n', meta: {'source_id': '...', 'parent_id': '...', 'split_id': 1, 'split_idx_start': 45, '_split_overlap': None, 'page_number': 1})
# Document(id=..., content: 'AI technology is widely used throughout industry, government, and science.', meta: {'source_id': '...', 'parent_id': '...', 'split_id': 2, 'split_idx_start': 142, '_split_overlap': None, 'page_number': 1})
# Document(id=..., content: ' Some high-profile applications include advanced web search engines; recommendation systems; interac...', meta: {'source_id': '...', 'parent_id': '...', 'split_id': 3, 'split_idx_start': 216, '_split_overlap': None, 'page_number': 1})
# ]
파이프라인에서 사용하기
인덱싱 파이프라인에서 RecursiveSplitter를 이렇게 사용할 수 있어요:
from pathlib import Path
from haystack import Document
from haystack import Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.converters.txt import TextFileToDocument
from haystack.components.preprocessors import DocumentCleaner
from haystack.components.preprocessors import RecursiveDocumentSplitter
from haystack.components.writers import DocumentWriter
document_store = InMemoryDocumentStore()
p = Pipeline()
p.add_component(instance=TextFileToDocument(), name="text_file_converter")
p.add_component(instance=DocumentCleaner(), name="cleaner")
p.add_component(
instance=RecursiveDocumentSplitter(
split_length=400,
split_overlap=0,
split_unit="char",
separators=["\n\n", "\n", "sentence", " "],
sentence_splitter_params={
"language": "en",
"use_split_rules": True,
"keep_white_spaces": False,
},
),
name="recursive_splitter",
)
p.add_component(instance=DocumentWriter(document_store=document_store), name="writer")
p.connect("text_file_converter.documents", "cleaner.documents")
p.connect("cleaner.documents", "recursive_splitter.documents")
p.connect("recursive_splitter.documents", "writer.documents")
path = "path/to/your/files"
files = list(Path(path).glob("*.md"))
p.run({"text_file_converter": {"sources": files}})