| from typing import List |
| from langchain_text_splitters import RecursiveCharacterTextSplitter |
| from langchain_core.documents import Document |
|
|
| def get_text_splitter(chunk_size: int = 1000, chunk_overlap: int = 200) -> RecursiveCharacterTextSplitter: |
| """ |
| Returns a RecursiveCharacterTextSplitter configured for medical documents. |
| |
| Why chunking is required: |
| 1. Context Windows: LLMs have a fixed context window limit (e.g., 4k tokens for Phi-3 Mini). |
| We cannot pass an entire 50-page PDF at once. |
| 2. Precision vs Recall: |
| - Smaller chunks (precision) allow the retriever to find exact answers and reduce distraction/hallucination. |
| - Overlap (recall) ensures context is not broken across chunks (e.g., a diagnosis spanning two paragraphs). |
| |
| The RecursiveCharacterTextSplitter splits by paragraphs, then sentences, then words, |
| preserving semantic meaning better than a simple character splitter. |
| """ |
| return RecursiveCharacterTextSplitter( |
| chunk_size=chunk_size, |
| chunk_overlap=chunk_overlap, |
| length_function=len, |
| add_start_index=True, |
| ) |
|
|
| def split_documents(documents: List[Document], chunk_size: int = 1000, chunk_overlap: int = 200) -> List[Document]: |
| """ |
| Splits a list of LangChain Document objects into smaller chunks. |
| Metadata (like filename and page number) from the parent document is preserved in all child chunks. |
| """ |
| splitter = get_text_splitter(chunk_size, chunk_overlap) |
| return splitter.split_documents(documents) |
|
|