В эпоху, когда большие языковые модели (LLM) становятся всё более мощными и применяются во многих задачах, одна из ключевых проблем остаётся прежней — как эффективно снабжать их релевантным контекстом. Одним из популярных решений является подход RAG, где качество итогового ответа зависит от целого ряда факторов, одним из которых является качественное чанкирование исходных текстов. Сегодня мы рассмотрим одно из новых и интересных решений.
Всем привет! Меня зовут Вадим, я Data Scientist в компании Raft. В этой статье я расскажу о Chonkie — библиотеке для простого и быстрого чанкирования документов, а также на практике применю её и сравню с другими популярными решениями: LangChain и LlamaIndex.

План статьи
Введение
Сейчас при внедрении решений на базе GenAI всё чаще используются RAG подходы, которые позволяют языковым моделям получать информацию из внешних источников и формировать ответ. Обычно процесс создания и наполнения данными такой системы обычно включает в себя следующие этапы:
Формирование общей базы знаний документов
Разделение данных на наименьшие куски документов (чанки)
Векторизация чанков (перевод их в эмбеддинги)
Сохранение эмбеддингов в векторную базу данных

Качество итоговых ответов напрямую зависит от каждого из этих шагов. В данной статье мы сосредоточимся на одном из них — разбиении данных на чанки.
Проблемы популярных решений: LangChain, LlamaIndex
Конечно, существуют уже давно проверенные инструменты, такие как LangChain и LlamaIndex, которые стали уже стандартом для построения RAG-пайплайнов во многих проектах. Однако, несмотря на их популярность, подобные решения имеют свои недостатки:
Сложность и избыточные абстракции: множество уровней классов и интерфейсов (чанки, парсеры, индексы, ретриверы, цепочки и т.д.) усложняют даже простые задачи.
Проблемы с зависимостями: библиотеки тянут за собой обширный стек сторонних модулей, которые могут вызвать конфликты версий и усложнить деплой и поддержку в продакшн.
Неактуальная или неполная документация: официальные руководства и примеры часто отстают от текущих версий библиотек, содержат устаревшие API или не учитывают последние изменения в архитектуре.
Проблемы с производительностью при больших объемах: код в подобных библиотеках зачастую неоптимальный и медленный, так как основное внимание уделяется функциональности и абстракциям, а не низкоуровневой эффективности. Из-за этого при обработке больших документов пайплайны могут занимать длительное время.

Всех этих проблем хотелось бы избежать и иметь инструмент, который решает именно конкретную задачу — без перегрузки функционалом и абстракциями. В случае с этапом по разбиению данных на чанки таким инструментом может выступать Chonkie.
Что такое Chonkie и с чем его едят?
Chonkie – лёгкая и быстрая библиотека для Python и TypeScript, предоставляющая множество методов чанкирования данных. Она доступна в открытом доступе, но также имеет платную облачную версию с готовой инфраструктурой и расширенной поддержкой.
Сама библиотека достигает высокой скорости благодаря использованию оптимизаций: конвейерная и параллельная обработка документов, кэширование и предвычисления предотвращают повторные вычисления, умные циклы оценки токенов для обеспечения оптимального размера чанков, а также за счет более быстрого токенизатора tiktoken со статическими эмбеддингами Model2Vec, которые не требуют запуска модели при запросе.

В целом, Chonkie состоит из следующих компонентов:
Document – исходные данные, то есть ваш текст из документов.
Chef – этап предобработки текста: очистка, нормализация и другие шаги для подготовки данных к чанкированию. Этап опциональный, но рекомендуется для повышения качества работы чанкера.
Chunker – основной компонент, отвечающий за разбиение текста на чанки по выбранной стратегии.
Refinery – блок постобработки: объединение слишком маленьких чанков, добавление эмбеддингов или дополнительного контекста. Можно подключать несколько разных Refinery подряд.
Porters – инструменты для экспорта чанков.
Handshakes – интерфейсы для интеграции чанков с векторными базами данных.

Давайте более подробно рассмотрим каждый из этих компонентов.
Предобработка текста: Chef
На момент написания статьи в библиотеке реализован следующий функционал:
TextChef – предобработка простых текстовых файлов
TableChef – предобработка таблиц формата Markdown
MarkdownChef – обработка Markdown файлов с извлечением таблиц, кода и изображений.
Методы чанкирования
Chonkie предлагает разнообразные методы чанкирования, каждый из которых оптимизирован для определенных типов данных и задач. Ниже представлены основные из них:
TokenChunker: Разделяет текст на чанки фиксированного размера, основываясь на количестве токенов.
SentenceChunker: Делит текст по границам предложений, обеспечивая сохранение смысловых единиц в каждом чанке.
RecursiveChunker: Рекурсивно делит документы на меньшие, семантически значимые части, используя настраиваемые иерархические правила.
TableChunker: разделяет большие таблицы Markdown на более мелкие, легко управляемые фрагменты по строкам, всегда сохраняя заголовок.
CodeChunker: Делит исходный код на структурные элементы, такие как функции или классы, используя абстрактные синтаксические деревья (AST). Таким образом помогает сохранить структуру кода и облегчить его анализ.
SemanticChunker: Использует семантическое сходство для определения границ чанков, обеспечивая, чтобы каждый чанк содержал связную информацию.
SDPMChunker: Применяет метод Semantic Double-Pass Merge для деления текста, обеспечивая более точное и осмысленное разделение на чанки. Сейчас интегрирован в SemanticChunker.
LateChunker: Сначала выполняет векторизацию текста, а затем делит его на чанки, что позволяет учитывать контекст всего документа при формировании чанков.
NeuralChunker: Использует модели на основе BERT для определения оптимальных границ чанков, обеспечивая более гибкое и адаптивное разделение текста.
SlumberChunker: Агентный чанкер, который использует модели LLM, позволяющие интеллектуально анализировать структуру текста, определять оптимальные точки разделения и даже суммировать или перефразировать содержание для достижения наилучшего качества фрагментов.
Методы TokenChunker, SentenceChunker, RecursiveChunker и TableChunker доступны в базой версии библиотеки, для остальных необходимо будет доустановить соответствующие подмодули.
Постобработка: Refinery
Также библиотека предлагает методы для постпроцессинга чанков:
Overlap Refinery: добавляет перекрывающийся контекст между смежными чанками документа.
Embeddings Refinery: добавляет контекстную информацию, основываясь на эмбеддингах.
Пример применения стратегий чанкирования
Помимо инструментов выше Chonkie предоставляют специальные обертки RecursiveRules и RecursiveLevel, по которым можно задавать и настраивать свои правила чанкирования документов для сохранения смысловых блоков, учета заголовков и подзаголовков, различных разделителей. Ниже приведен пример кода, как их можно применять совместно с методами чанкирования.
from chonkie import TokenChunker, OverlapRefinery
# Исходная тестовая строка, состоящая из нескольких предложений
test_string = (
"This is the first sentence. "
"This is the second sentence, providing context. "
"This is the third sentence, which needs context from the second."
)
# Инициализация базового чанкировщика
chunker = TokenChunker()
# Разделение текста на чанки по базовым правилам TokenChunker
chunks = chunker(test_string)
# Определение иерархических правил рекурсивного разделения текста
rules = RecursiveRules(
levels=[
RecursiveLevel(delimiters=["\n\n"], include_delim="prev"), # 1-й уровень: разделение по двойным переносам
RecursiveLevel(delimiters=["."], include_delim="prev"), # 2-й уровень: разделение по точкам
RecursiveLevel(whitespace=True) # 3-й уровень: разделение по пробелам
]
)
# Инициализация OverlapRefinery — модуля для добавления перекрытий между чанками (контекста)
overlap_refinery = OverlapRefinery(
tokenizer_or_token_counter="character", # Используется подсчёт символов (а не токенов)
context_size=0.25, # Размер контекста (25% от длины чанка) добавляется к каждому чанку
mode="recursive", # Режим рекурсивного разбиения на основе заданных правил (rules)
rules=rules, # Передача определённых выше правил рекурсивного разделения
method="prefix", # Контекст добавляется как префикс — из предыдущего чанка
merge=True # Контекст встраивается прямо в текст чанка (а не хранится отдельно)
)
# Применение OverlapRefinery к ранее созданным чанкам
refined_chunks = overlap_refinery(chunks)
Интеграции эмбеддингов
Также Chonkie поддерживает интеграцию со многими поставщиками эмбеддингов:
AutoEmbeddings — автоматически выбирает наиболее подходящий обработчик эмбеддингов по названию модели.
CohereEmbeddings — использует эмбеддинги от Cohere (необходима библиотека cohere).
SentenceTransformer — предоставляет эмбеддинги от Sentence-Transformers (необходима библиотека sentence-transformers).
OpenAIEmbeddings — использует эмбеддинги от OpenAI (необходима библиотека openai).
AzureOpenAI — использует эмбеддинги от Azure OpenAI (необходимы библиотеки openai и azure-identity).
Model2VecEmbeddings — предоставляет эмбеддинги от Model2Vec (необходима библиотека model2vec).
JinaEmbeddings — предоставляет эмбеддинги от JinaAI (необходима библиотека jina).
GeminiEmbeddings — использует эмбеддинги от Google Gemini (необходима библиотека google-genai).
VoyageAIEmbeddings — предоставляет эмбеддинги от VoyageAI (необходима библиотека voyageai).
Custom — позволяет реализовать собственный обработчик эмбеддингов, создав дочерний класс и реализовав необходимые методы.
Интеграции с векторными базами данных
В Chonkie встроена интеграция с популярными векторными базами данных:
Chroma: Лёгкая и масштабируемая векторная база данных с открытым исходным кодом. Подходит для локальных и облачных решений.
Qdrant: Высокопроизводительная векторная база данных с поддержкой HNSW и фильтрации по метаданным.
Pinecone: Управляемая облачная векторная база данных, оптимизированная для быстрого поиска по векторным данным.
MongoDB: Интеграция с популярной NoSQL базой данных
Weaviate: Облачная векторная база данных с поддержкой семантического поиска и встроенной поддержкой графов.
Turbopuffer: Высокопроизводительная векторная база данных, интегрированная с Chonkie для быстрого поиска и хранения данных.
Перенос чанков: Porters
В случае, если вы ставите множество экспериментов с качеством чанков для RAG системы, то вам необходимо заранее сохранять чанки в виде артефактов для дальнейшего анализа. В этом случае, вам могут помочь Porters:
JSONPorter — экспортирует чанки в JSON формат
DatasetsPorter — экспортирует чанки в HuggingFace датасет.
Готовые рецепты: Hubbie
А что, если правила чанкирования, которые мы применяем, из раза в раз повторяются. В этом случае Chonkie предоставляет удобную утилиту Hubbie, которая позволяет делиться и загружать уже готовые правила чанкирования.
Для этого необходимо доустановить hub
pip install "chonkie[hub]"
И можно использовать следующим образом
from chonkie import RecursiveChunker
# Инициализация рекурсивного чанкера с указанием рецепта и языка
chunker = RecursiveChunker.from_recipe("markdown", lang="en")
text = "This is the first sentence. This is the second sentence, providing context. This is the third sentence, which needs context from the second."
# Применение чанкера с заданными правилами
chunks = chunker(text)
Визуализация чанков
Также Chonkie предоставляет инструмент для визуализации готовых чанков текста, который может помочь в интерпретации, насколько корректно был разбит текст для вашей задачи. Визуализировать можно как в терминале Jupyter Notebook., так и есть возможность сохранения в HTML.
Для его использования достаточно доустановить пакет
pip install "chonkie[viz]"
И можно использовать примерно следующим образом
from chonkie import Visualizer
# Инициализация Visualizer
viz = Visualizer()
# Вывод в терминал
viz.print(chunks)
# Сохранение в HTML файл
viz.save("chonkie.html", chunks)
Результаты будет выглядеть примерно следующим образом

Анализ Chonkie на практике
Чтобы оценить, действительно ли Chonkie так хорош, как утверждают его авторы, или всё же не совсем так, я решил провести собственные эксперименты. В них я сравнил эту библиотеку с другими популярными инструментами — LangChain и LlamaIndex, уделив основное внимание двум аспектам: производительности при чанкировании документов и качеству получаемых чанков.
Оценка производительности в сравнении с LangChain и LlamaIndex
Для оценки производительности я провёл эксперименты с различными методами чанкирования Chonkie и сравнил их с аналогичными методами в LangChain и LlamaIndex.
В качестве тестового материала использовалось произведение Л.Н. Толстого «Война и мир», объёмом около 3 миллионов символов.
Результаты получились следующими:
Наиболее медленным решением оказалась библиотека LlamaIndex с методами SentenceSplitter и TokenTextSplitter
Самым быстрым методом чанкирования оказался RecursiveChunker из библиотеки Chonkie, при этом добавление постпроцессинга Overlap снижает скорость, приближаясь к TokenChunker в Chonkie, с которым он становится сопоставим по производительности
В среднем методы из LangChain по зависимости числа чанков от их размеров сопоставимы с Chonkie
Ниже представлены графики производительности по библиотекам, методам чанкирования и зависимость размера чанка от времени обработки.
Графики сравнения производительности



Оценка качества в сравнении с LangChain и LlamaIndex
Для оценки качества ответов я построил RAG-систему на сокращённой версии документа Трудового кодекса РФ, по которому синтетически сгенерировал 50 вопросов и ответов. В качестве векторной базы данных использовалась Weaviate, а в роли LLM — gpt-4o-mini. Для оценок качества я использовал фреймворк DeepEval, который предоставляет метрики оценки RAG-системы через применение концепции LLM-as-Judge, где LLM выступает в роли судьи, оценивающего релевантность ответа на запрос. В частности, я использовал следующие метрики:
Answer Relevancy: оценивает, насколько ответ соответствует заданному вопросу и отвечает ли он по сути.
Faithfulness: проверяет, верен ли ответ фактам, представленным в контексте, и не содержит ли выдуманной информации.
Contextual Precision: оценивает точность использования контекста — включает ли ответ только ту информацию, которая реально содержится в контексте, без искажений или добавлений.
Contextual Recall: измеряет полноту — включает ли ответ всю важную информацию из контекста, необходимую для полного ответа.
P.S.: для RAG систем большое влияние оказывает также промпт для генерации ответа, в моем случае он вышел достаточно простым, но эффективным для поставленной задачи.
Промпт для генерации ответа LLM
You are an expert assistant and must answer **only** based on the text in <context>.
Instructions:
1) Answer in the same language as the <question>; if it cannot be detected, use Russia.
2) Style — clear, neutral, with no guesses or personal opinions.
3) Keep terminology as in the <context>.
5) Quotes — only verbatim from <context>, enclosed in quotation marks.
6) Do not add any information beyond <context>.
7) If the required information is missing, begin your reply with: "В предоставленном контексте нет достаточной информации для точного ответа."
<Context>
{context}
</Context>
<Question>
{question}
</Question>
Примеры вопросов
### Вопрос 1
**Каковы основные цели трудового законодательства?**
Целями трудового законодательства являются установление государственных гарантий трудовых прав и свобод граждан, создание благоприятных условий труда, защита прав и интересов работников и работодателей.
---
### Вопрос 2
**Что такое принудительный труд и когда он запрещен?**
Принудительный труд — выполнение работы под угрозой применения какого-либо наказания (насильственного воздействия). Принудительный труд запрещен, за исключением случаев, предусмотренных законом (военная служба, чрезвычайные обстоятельства, работа по приговору суда).
---
### Вопрос 3
**Какие принципы лежат в основе регулирования трудовых отношений?**
Основные принципы включают: свободу труда, запрещение принудительного труда и дискриминации, защиту от безработицы, обеспечение права на справедливые условия труда, равенство прав и возможностей работников, обеспечение права на своевременную и полную выплату заработной платы.
По итоговым результатам можно сделать следующие выводы:
AnswerRelevancyMetric: Лучший метод — chonkie_token (0.993); использование Overlap повышает релевантность на +1.0%.
FaithfulnessMetric: Лидирует langchain_sentence (0.893); влияние Overlap положительное, но небольшое (+0.3%).
ContextualPrecisionMetric: Наибольшее значение у langchain_sentence (0.800); добавление Overlap слегка снижает точность (-0.8%).
ContextualRecallMetric: Лучший метод — chonkie_overlap_200 (0.920); Overlap даёт небольшое снижение (-0.4%).
-
Общий рейтинг библиотек:
Chonkie — средняя оценка 0.874, показывает лучший средний результат по RAG-метрикам;
LangChain — средняя оценка 0.867, стабильно высокие показатели по Faithfulness и ContextualPrecision;
LlamaIndex — средняя оценка 0.860, формирует крупные чанки, но уступает по большинству метрик.
Влияние Overlap: положительно сказывается на релевантности и Faithfulness, но слегка снижает ContextualPrecision и ContextualRecall.

Графики методов по каждой из метрик

Выводы
В целом, Chonkie — это достаточно новый, но при этом быстрый и удобный инструмент для чанкирования данных, который сосредоточен только на одной задаче. Таким образом, он позволяет отказаться от использования более тяжеловесных решений, таких как LangChain и LlamaIndex, которые содержат множество избыточных абстракций и модулей, не всегда нужных для практических задач.
Подход с ним отражает важный принцип современного построения AI-приложений — модульность и независимость функциональных компонентов.
avshkol
Спасибо, интересная библиотека.
Корректное разделение текста на смысловые блоки очень важно и для файнтюнинга и для корректного ответа в RAG.