Короткий ответ: не просить модель выдавать чанки текстом. Просить номера
границ. Так устроен
agmind-rag-splitter-ru —
LoRA-дообучение t-tech/T-lite-it-2.1, которое получает документ,
заранее разбитый на нумерованные юниты, и возвращает JSON с индексами
границ и темой. Рядом лежат
GGUF-сборки и —
редкий случай —
обучающий корпус
целиком. Полный разбор — с пайплайном разметки, промптом и кодом оценки —
в лонгриде на Хабре; все числа
ниже — цитаты оттуда, не клеймы нашего реестра.
Что не так с чанкером, который пишет текст
Генерация молча «улучшает» исходник: ё превращается в е, «ёлочки» — в прямые кавычки, пробелы нормализуются, а иногда возвращается фраза, которой в документе не было. Для RAG это не косметика: чанк перестаёт совпадать с источником побайтно, ломаются офсеты и цитирование, а индекс постепенно наполняется текстом, которого никто не писал. Вторая причина прозаичнее — цена: переписать документ стоит на порядок больше выходных токенов, чем назвать точки разреза; полный ответ сплиттера на тестовом документе — 35 токенов JSON .
Как это устроено
Детерминированную часть делает хост: проза режется на предложения через
razdel.sentenize, таблицы и блоки кода остаются цельными атомарными
юнитами, markdown-заголовки — отдельные юниты. Модель отвечает
{"splits": [...], "topic": "..."}, хост режет исходный текст по этим
индексам — каждый собранный чанк по построению является подстрокой
источника. Таблица при этом выживает целиком, если парсер выше по потоку
выделил её корректно: семантические сплиттеры рвут таблицы посреди строк,
потому что соседние строки похожи по эмбеддингам и сигнала смены темы там
не бывает.
Зачем опубликован корпус
Обучающие данные чанкеров обычно закрыты — проверить, что модель считает
границей, невозможно. Здесь разметка дистиллирована из самостоятельно
развёрнутого DeepSeek-V4-Flash под грамматикой guided_json, прогнана
через жёсткие фильтры и выложена целиком. После фильтрации — около 17 тыс. примеров из веб-прозы, технических текстов с кодом и синтетических таблиц, плюс синтетический доклад в 12 тыс.
Статья честно фиксирует и собственную нестыковку: README обещал разметку при температуре 0, код размечал при 0.2 —
задокументировано как есть, без оправданий задним числом.
Что показали замеры
Оба билда возвращали валидный JSON на 100% запросов; boundary-F1 у bf16 — 0.656 точно и 0.821 в пределах ±1 юнита, у GGUF Q5_K_M — 0.639 и 0.817 . Перепроверка на полном отложенном наборе из 1500 документов дала 0.665/0.825 и 0.661/0.826 — разница от квантизации на уровне шума . На Strix Halo девятиюнитный документ режется примерно за 1.2 секунды целиком . Главная оговорка статьи сохранена и здесь: это согласие с метками учителя, а не доказанное качество RAG — downstream-оценка hit-rate и faithfulness для v1 не проводилась. Из ограничений: модель слегка пересегментирует вслед за учителем, огромные таблицы вынесены за скобки осознанно, а испорченную парсером структуру сплиттер не восстановит.
Что дальше
В v2 датасет вырос до 28 тыс. примеров по шести типам источников, появился отложенный эталон из 140 юридических документов вне домена, размеченных консенсусом двух независимых моделей с арбитражем . Идентичность актуального релиза — на странице артефактов; полная история v1 — на Хабре. Числа здесь — авторские измерения одной лаборатории против меток собственного учителя; что наш протокол потребовал бы от них для реестра — отдельный отчёт.