Більшість команд досі створюють свій перший конвеєр пошуку однаково. Вони обирають фіксований ліміт токенів, можливо, 512, розбивають документи на однорідні блоки та завантажують ці блоки у векторну базу даних. На невеликому наборі даних із простими запитаннями це виглядає магічно. У реальних умовах усе розвалюється.
Юридичні контракти розриваються на безглузді фрагменти, коли пункт розрізається посеред речення. Документація API перетворюється на «шумний суп», якщо один чанк поглинає три непов'язані функції. Запити в службу підтримки втрачають логічний зв'язок через відсутність перекриття між сегментами. Результат передбачуваний: величезна затримка, низька повнота та відповіді, які змушують генератор галюцинувати.
Ми повністю переробили наш рівень пошуку. Результатом став стрибок повноти з 78% до 95%, скорочення затримки на 62% та конвеєр, який нарешті працює як справжня інфраструктура, а не як «хак на вихідні». Ось що справді спрацювало.
Розумне чанкування: структура важливіша за токени
Перша помилка — припускати, що кожен документ написаний однією мовою. Чанк у 512 токенів має сенс для художнього тексту і майже ніде більше. Ми перейшли до стратегії, яка враховує анатомію джерела.
Для юридичних документів ми використовуємо рекурсивне чанкування. Алгоритм спочатку намагається розділити текст за високорівневими межами, такими як розділи та статті. Якщо розділ все ще занадто довгий, він шукає підрозділи, потім абзаци, а потім речення. Це зберігає логічну вкладеність пунктів. Угода про неконкуренцію залишається цілісною. Визначення не змішуються з умовами відшкодування збитків.
Документація API потребує чанкування з урахуванням структури. Сигнатура функції, таблиця її параметрів та приклад запиту мають бути разом. Розбиття за фіксованою кількістю токенів часто залишає параметри в одному чанку, а приклади — в іншому. Замість цього ми виконуємо чанкування за об'єктами документа. Один чанк містить повний ендпоінт або одну функцію. Тоді пошуковий механізм може повернути самодостатнє посилання, яке дійсно відповідає на запитання.
Запити в службу підтримки природним чином підходять для семантичного чанкування. Замість того, щоб розрізати текст на межі токенів, ми визначаємо, де змінюється тема. Запит, який починається зі скарги на вхід у систему, а потім переходить до питання щодо оплати, розбивається на два зв'язні фрагменти. Кожен фрагмент містить необхідні метадані, і моделі більше не потрібно вгадувати, яка саме проблема цікавить користувача.
Внутрішні вікі ще хаотичніші. У них змішані текст, таблиці, діаграми та вбудовані гілки обговорень. Для них ми використовуємо агентне чанкування. Мала мовна модель читає текст наперед і вирішує, де закінчується тематично завершена одиниця. Це коштує трохи дорожче під час завантаження даних, але позбавляє людину рутинної роботи з ручного налаштування правил для кожного нового формату сторінок.
Гібридний пошук: перестрахуйтеся з усіх боків
Векторний пошук чудово вловлює розмиті значення. Запитайте про повільне завантаження, і він із радістю поверне абзаци про затримку та пропускну здатність. Але він відомий тим, що псує точні збіги. Якщо розробник шукає код помилки ERR_CONNECTION_REFUSED, щільні вкладення часто сприйматимуть його як загальний шум.
BM25, класичний алгоритм пошуку за ключовими словами, робить протилежне. Він точно знаходить конкретні рядки та рідкісні терміни, проте пропускає семантичні нюанси. Запит про підписання угоди може ніколи не виявити контент, тегований як «виконання контракту».
