DocumentLengthRouter

DocumentLengthRouter

DocumentLengthRouter는 content 필드의 길이를 기준으로 문서를 서로 다른 출력 연결로 라우팅해요.

출처: 문서

본문

Overview

threshold init 파라미터를 설정할 수 있어요. content가 None이거나 content의 길이가 임계값보다 작거나 같은 문서는 "short_documents"로 라우팅되고, 나머지는 "long_documents"로 라우팅됩니다.

DocumentLengthRouter의 일반적인 사용 사례는 스캔된 페이지나 이미지처럼 비텍스트(non-text) 내용을 담은 PDF에서 얻은 문서를 처리하는 것이에요. 이 컴포넌트는 빈 문서나 저내용(low-content) 문서를 감지해 OCR을 수행하거나, 캡션을 생성하거나, 이미지 임베딩을 계산하는 컴포넌트로 라우팅할 수 있습니다.

Usage

On its own

from haystack.components.routers import DocumentLengthRouter
from haystack.dataclasses import Document

docs = [
    Document(content="Short"),
    Document(content="Long document " * 20),
]

router = DocumentLengthRouter(threshold=10)

result = router.run(documents=docs)
print(result)

# {
# "short_documents": [Document(content="Short", ...)],
# "long_documents": [Document(content="Long document ...", ...)],
# }

In a pipeline

다음 인덱싱 파이프라인에서 PyPDFToDocument 컨버터가 PDF 파일에서 텍스트를 추출합니다. 그다음 DocumentSplitter로 문서를 페이지 단위로 분할합니다. 그리고 DocumentLengthRouter가 짧은 문서를 텍스트를 추출하는 LLMDocumentContentExtractor로 라우팅해요. 이는 특히 비텍스트·이미지 기반 페이지에 유용합니다. 마지막으로 모든 문서가 DocumentWriter로 보내져 Document Store에 기록됩니다.

from haystack import Pipeline
from haystack.components.converters import PyPDFToDocument
from haystack.components.extractors.image import LLMDocumentContentExtractor
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.preprocessors import DocumentSplitter
from haystack.components.routers import DocumentLengthRouter
from haystack.components.writers import DocumentWriter
from haystack.document_stores.in_memory import InMemoryDocumentStore

document_store = InMemoryDocumentStore()

indexing_pipe = Pipeline()
indexing_pipe.add_component("pdf_converter", PyPDFToDocument(store_full_path=True))
# setting skip_empty_documents=False is important here because the
# LLMDocumentContentExtractor can extract text from non-textual documents
# that otherwise would be skipped
indexing_pipe.add_component(
    "pdf_splitter",
    DocumentSplitter(split_by="page", split_length=1, skip_empty_documents=False),
)
indexing_pipe.add_component("doc_length_router", DocumentLengthRouter(threshold=10))
indexing_pipe.add_component(
    "content_extractor",
    LLMDocumentContentExtractor(
        chat_generator=OpenAIChatGenerator(model="gpt-4.1-mini"),
    ),
)
indexing_pipe.add_component(
    "document_writer",
    DocumentWriter(document_store=document_store),
)

indexing_pipe.connect("pdf_converter.documents", "pdf_splitter.documents")
indexing_pipe.connect("pdf_splitter.documents", "doc_length_router.documents")
# The short PDF pages will be enriched/captioned
indexing_pipe.connect(
    "doc_length_router.short_documents",
    "content_extractor.documents",
)
indexing_pipe.connect("doc_length_router.long_documents", "document_writer.documents")
indexing_pipe.connect("content_extractor.documents", "document_writer.documents")

# Run the indexing pipeline with sources
indexing_result = indexing_pipe.run(
    data={"sources": ["textual_pdf.pdf", "non_textual_pdf.pdf"]},
)

# Inspect the documents
indexed_documents = document_store.filter_documents()
print(f"Indexed {len(indexed_documents)} documents:\n")
for doc in indexed_documents:
    print("file_path: ", doc.meta["file_path"])
    print("page_number: ", doc.meta["page_number"])
    print("content: ", doc.content)
    print("-" * 100 + "\n")

# Indexed 3 documents:
#
# file_path:  textual_pdf.pdf
# page_number:  1
# content:  A sample PDF file...
# ----------------------------------------------------------------------------------------------------
#
# file_path:  textual_pdf.pdf
# page_number:  2
# content:  Page 2 of Sample PDF...
# ----------------------------------------------------------------------------------------------------
#
# file_path:  non_textual_pdf.pdf
# page_number:  1
# content:  Content extracted from non-textual PDF using a LLM...
# ----------------------------------------------------------------------------------------------------

더 알아보기 (Learn more)