Добавить chunker.py

This commit is contained in:
2026-05-28 09:27:11 +00:00
parent 8c08255a98
commit b76e55d57c
+86
View File
@@ -0,0 +1,86 @@
# chunker.py
"""
Модуль для разбиения больших текстов на небольшие части (чанки)
с помощью RecursiveCharacterTextSplitter из LangChain.
Используется в процессе загрузки документов в Qdrant:
1. Читаем исходный файл.
2. Разбиваем его на чанки, чтобы каждый чанк не превышал заданную длину.
3. Возвращаем список строк (чанков) и метаданные для каждого чанка
(например, номер чанка и оригинальный заголовок).
"""
from pathlib import Path
from typing import List, Tuple
from langchain_text_splitters import RecursiveCharacterTextSplitter
def split_document(
file_path: str | Path,
chunk_size: int = 1000,
chunk_overlap: int = 200,
) -> List[Tuple[str, dict]]:
"""
Разбивает содержимое файла на чанки.
Parameters
----------
file_path : str | Path
Путь к текстовому файлу (может быть .txt, .md и т.п.).
chunk_size : int, default=1000
Максимальная длина одного чанка в символах.
chunk_overlap : int, default=200
Количество пересекающихся символов между соседними чанками.
Returns
-------
List[Tuple[str, dict]]
Список кортежей (чанк, метаданные). Метаданные включают:
- `source`: путь к файлу,
- `chunk_index`: порядковый номер чанка в документе.
"""
# Читаем файл
path = Path(file_path)
if not path.is_file():
raise FileNotFoundError(f"Файл не найден: {file_path}")
text = path.read_text(encoding="utf-8")
# Создаём splitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=chunk_size,
chunk_overlap=chunk_overlap,
length_function=len,
)
# Получаем чанки
chunks = splitter.split_text(text)
# Формируем список с метаданными
result: List[Tuple[str, dict]] = []
for idx, chunk in enumerate(chunks):
metadata = {
"source": str(path.resolve()),
"chunk_index": idx,
}
result.append((chunk, metadata))
return result
# Пример использования (можно закомментировать при импорте)
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print("Usage: python chunker.py <file_path> [chunk_size] [chunk_overlap]")
sys.exit(1)
file = sys.argv[1]
size = int(sys.argv[2]) if len(sys.argv) > 2 else 1000
overlap = int(sys.argv[3]) if len(sys.argv) > 3 else 200
for chunk, meta in split_document(file, size, overlap):
print(f"--- Chunk {meta['chunk_index']} ({len(chunk)} chars) ---")
print(chunk[:200] + "...\n")