Чому відповіді RAG здаються повними, коли пошук у Azure DevOps доводить їх неповність
Усунення прогалин у повноті даних у системі Azure DevOps RAG з використанням графів: детерміністичні перевірки тегів, прогулянки по графу, обмеження контексту та інструменти запитів лише для читання.
Система, яка завантажує історію Azure DevOps у базу даних у вигляді графа, може відповідати на запитання щодо проектів, власників та завершених робіт, надаючи зрозумілий текст та посилання, які можна клікнути. Деякий час цього виявлялося достатньо — поки відповіді не почали перевірятися за примітивною базою: безпосереднім запитом до Azure DevOps. Саме між відполірованою відповіддю та повним списком і відбувається тихе провалення процесу отримання повної інформації. Щоб подолати цю прогалину, знадобилися детерміновані кроки, вимірювальні тести та низка корекцій, які самі по собі створили нові проблеми.
Запитання, яке виявило прогалину
На початкові запитання надходили чисті, добре обґрунтовані відповіді без значних вигадок. Ширший запит — «Яка робота з ШІ виконується в цій організації?» — також виглядав нормально: кілька абзаців, кілька посилань, нічого очевидно неправильного. Те саме запитання, передане через az boards query — метод brute-force без жодної інтелектуальної сортування — повернуло десятки результатів, про які не згадувалася вдосконалена відповідь. Групи інформації про оцінку асистентів для програмування, порівняння витрат на моделі чи виправлення помилок у певному інструменті відсутні були, оскільки їх формулювання мало спільного з запитом, і вони ніколи не потрапляли до верхньої частини списку результатів семантичного пошуку.
Цей тип невдачі легко пропустити: добре рангована відповідь — це не те саме, що повна відповідь, і система не надає жодних ознак, які б показали, яку саме ви отримали.
Запит, який допомагав лише іноді
Першою ідеєю було наказати моделі бути обережнішою — щодо загальних запитань перевіряти теги категорій перед відповіддю, замість того щоб покладатися лише на пошук. Це іноді допомагало. Однак однаковий формулювання запитань призводило до різної поведінки моделі: іноді вона перевіряла теги, а іноді проходила повз них. У самому запитанні нічого не змінювалося — лише те, чи було дотримано цієї інструкції в конкретному етапі.
Інструкція для мовної моделі є лише підштовхом, а не гарантією. Коли важлива повнота інформації, ретельність не може залежати від того, чи вирішить модель у момент виконання бути ретельною чи ні.
Зробити шлях детермінованим
Наступна зміна припинила запитування. Код завжди перевіряє теги для кожного широкого запиту, незалежно від того, чи вважає модель це необхідним. Лише це дозволило зменшити кількість елементів у групі точних даних з приблизно половини до близько семи з шістнадцяти — що краще, але все ще недостатньо. Далі були зроблені кроки на основі конкретних прогалин, виявлених під час тестування, а не припущень:
Один із кроків полягає у пошуку серед результатів пошуку за тегами повторюваних імен та фраз, які зустрічаються двічі або тричі, а потім у прямому пошуку цих імен — таким чином назва продукту з’являється навіть тоді, коли ніхто не запитував про неї прямо, як тільки невелика група, що її містить, вже є у видимості.
Крок, який враховує стосунки між елементами графа, а не лише їхнє формулювання, оскільки елементи, що є «братами» чи «сестрами», можуть мати спільного батька, не маючи жодних спільних слів у назві. Елемент із назвою, схожою на назву тестового репозиторію з типовими завданнями на програмування, може зовсім не містити інформації про ШІ у власному тексті та пов’язуватися з іншими елементами лише через ієрархію.
Крок для репозиторіїв, які не мають тих самих тегів категорій, що й елементи роботи, і в іншому випадку залишилися б невидимими для шляхів, заснованих на тегах.
Крок для людей, після того як запитання на кшталт «Як часто двоє співробітників працювали разом?» призводили до впевнених хибних відповідей.
Кожен з цих кроків закривав певну прогалину. Зрештою найскладніший випадок із шістнадцятьма елементами було повністю вирішено — не частково, а цілком.
Більше отриманого контексту погіршувало відповіді
Протиінтуїтивно, коли якість пошуку покращилась настільки, що кількість елементів у базі моделі зросла з кількох сотень до понад тисячі, відповіді стали коротшими та менш повними. Модель не зламалась; вона просто почала писати менше, незважаючи на наявність більшої кількості корисного матеріалу. Після досягнення певного об’єму якість відповідей не зростає разом із розміром контексту — вона погіршується. Показники пошуку покращились, тоді як показники кінцевих відповідей погіршились протягом того самого експерименту. Рішенням не було «додати більше», а знайти межу та дотримуватися її.
Рішення проблеми прозорості, яке призвело до перевантаження вузьких запитань
Коли модель узагальнювала справжній матеріал замість того, щоб назвати його, у новому розділі відповідей перелічувалися знайдені, але не названі елементи, тож нічого не зникало безслідно. Перша версія додавала у відповіді на конкретні запитання понад тисячу слабко пов’язаних елементів, оскільки генератор списків не міг розрізнити точні збіги від загальних „шумових“ тегів. Широка категорія збирала все, що було хоча б віддалено пов’язане, та вважала це однаково важливим для показу.
Стабільним рішенням було не лише встановлення числового ліміту. Це також означало розділення двох типів „знайдених, але не названих“ елементів: невеликий набір точних збігів, які мали завжди відображатися, та великий набір елементів із слабко позначеними тегами, які потребували чесного ліміту та примітки про наявність ще більшої кількості таких елементів. Саме це розрізнення мало більше значення, ніж сам ліміт.
Надання моделі інструментів — з захисними механізмами
Корисне запитання визначило подальшу роботу: чому людина може відповісти на те, що не може система, якщо обидві бачать одні й ті самі дані? Люди можуть створити новий запит, коли наявні інструменти не підходять, та перевіряють відповіді, які здаються сумнівними. У моделі не було жодної з цих можливостей. Їй надали інструмент для створення власного запиту до бази даних з обмеженими правами читання — база даних забезпечувала обмежені права читання, запит мав часові обмеження та ліміт за розміром результатів.
Знадобилося ще два раунди. Коли було поставлено запит про те, як часто співпрацюють дві згадані особи, модель спочатку припустила наявність спільного прізвища через одночасне згадування, отримала порожній результат та замість того, щоб поставити під сумнів цей результат, зробила припущення на основі непов’язаних коментарів. Правило стало таким: спочатку перевести кожне ім’я у його точний запис, а порожній самозапит розглядати як доказ того, що запит неправильний, а не як ознаку нульової кількості.
Під час наступної спроби були вирішені проблеми обох осіб, було виконано правильний запит, отримано двадцять п’ять спільних елементів — проте кількість все одно не була вказана, оскільки кожне фактичне твердження вимагало ідентифікатора посилання, а обчислена кількість його не мала. Суворе дотримання правил щодо посилань призвело до відхилення правильної відповіді. Була потрібна пряма виняткова норма: обчислену кількість можна було просто вказати без ідентифікатора джерела.
Жодна з цих невдач не була ознакою нездатності; обидві були результатом правильного виконання інструкцій, які не охоплювали цю ситуацію. Це розрізнення має більше значення, ніж здається на перший погляд.
Як тестування залишалося чесним
Альтернативний факт не був перевіркою на наявність потрібного настрою. Для найскладнішого клустера спочатку було перелічено шістнадцять відомих елементів з повного пошуку, а потім оцінювалося їх кількість після кожної зміни результату пошуку: скільки з них з’явилося у кінцевій відповіді, скільки було процитовано, а скільки просто видалено. Саме ця таблиця оцінок надала значення виразам „сім із шістнадцяти“ та згодом „шістнадцять із шістнадцяти“. Без зовнішнього повного списку фраза „виглядає завершеною“ є лише естетичним оцінюванням.
Впорядкування процесу обробки без перевантаження моделі
Детерміністичні кроки все одно потребують певного порядку. Спочатку розширення тегів збільшує набір кандидатів; потім видобуток імен поглиблює цей набір; прогулянки по графах додають структурних сусідів; кроки, пов’язані з репозиторіями та людьми, заповнюють прогалини у модальностях. Лише після створення цього набору верхня межа розміру дозволяє обмежити те, що потрапляє до запиту. Зміна цього порядку — вимога до моделі бути ретельною ще до створення набору — призводить знову до проблеми корекції. Робота над повнотою — це проектування потоку обробки даних, а не використання кращих прикметників у системному запиті.
Цитати проти обчислених фактів
Правило „цитування кожного твердження“ захищає від вигадування інформації, коли модель цитує елементи роботи. Воно стає шкідливим, коли модель виконує арифметичні операції чи об’єднує результати з інструментів. Розділення „цитованого твердження“ від „обчисленої суми“ у інструкціях дозволило відновити показник двадцяти п’яти співпраць, не послаблюючи дисципліни щодо цитування для наративних тверджень. Системи RAG, що використовують інструменти, потребують обох правил, викладених чітко.
Стан справ
Чистий запит до бази даних за своєю конструкцією є вичерпним: не може бути пропущено жодної відповідної рядка. Він також не може пояснювати, групувати чи описувати значення — він повертає список, а не відповідь. Тепер система порівнює повноту цього запиту з складними випадками, які були знайдені та протестовані, водночас пояснюючи результати прозово з перевіреними джерелами. Цей результат вимірюється, а не припускається.
Це не вирішена проблема. Кожне з вищезазначених рішень існує тому, що виникла певна несправність під час перевірки відповідей за допомогою щось повного критерію. Цей метод виявляє прогалини, але не доводить, що вони більше немають. Після зазначених змін знову з’явився новий тип запитання, пов’язаний із посиланням, яке використовувалося для підтримки твердження про певну особу, хоча цей джерело нічого про неї не говорило — це було виявлено, але на момент написання ще не виправлено. Ця закономірність триває: перевіряється те, що здається повним, і з’являється щось нове.
Чесний підсумок полягає не у тому, що „проблема повноти RAG вирішена“. Це означає, що кожна конкретна прогалина, яку можна було знайти та перевірити, була усунена із наведенням показників до та після. Неможливо обіцяти, що більше не буде прогалин, і жодна система такого типу не повинна створювати таких уявлень. Фраза „модель зазвичай правильно робить“ не є основою для надійності — саме слово „зазвичай“ є причиною помилок у критичних ситуаціях.