Вікно Gemini на 1M замінило мені векторне сховище, але затримка й походження відповідей заперечили
Порівняння повного контексту і RAG на 500 питаннях підтримки: точність, затримка й вартість, чому важливе походження відповіді та яка гібридна схема зберегла переваги обох підходів.
Видаляємо векторну таблицю
Уявіть асистента підтримки, яким користуються дев'ять тисяч працівників компанії. Будь-яку його відповідь людина може переслати клієнтові, тож помилка чи відповідь без пояснення коштують дорого.
Під ним працює шар пошуку: чанкер, задача побудови ембедингів, векторне сховище і в самому кінці реранкер, який підкручували стільки разів, що ніхто вже не може обґрунтувати його параметри.
user ─► embed ─► vector db ─► rerank ─► 4k ctx ─► model ─► answer
▲
chunker
▲
nightly reindex
Експлуатація — це чотири сервіси й два чергові алерти, плюс баг, що постійно повертається: футер PDF тихо псує половину чанків. Водночас сам шлях запиту крихітний:
q = embed(text)
hits = db.search(q, k=8)
ctx = "\n".join(h.doc for h in hits)
ans = llm(f"{ctx}\n\nQ: {text}")
Увесь біль живе навколо цих чотирьох рядків.
І тут напрошується спокуслива думка. Gemini приймає мільйон токенів і майже ідеально їх пам'ятає, а весь корпус займає лише 640 000 токенів. Він вміщається. Тож у вівторок увечері хтось видаляє таблицю на 2,3 мільйона ембедингів і замінює весь пайплайн ось цим:
docs = load_all()
ans = gem(f"{docs}\n\nQ: {text}")
Ні чанкера, ні задачі переіндексації, ні реранкера з константою, яку ніхто не може пояснити. Це працює, і годин шість відчуття таке, ніби списав на іспиті й не попався.
Що показав наступний ранок
Затримка зростає приблизно пропорційно до розміру входу. Це не секрет, але по-справжньому це відчуваєш, лише коли починає скаржитися підтримка. Для порівняння через кожну схему прогнали 500 реальних питань. Точність оцінювала друга модель, звіряючи кожну відповідь з еталоном, написаним вручну, а шістдесят таких оцінок перевірили руками, щоб переконатися, що суддя не підсуджує.
setup p50 p95 cost/query accuracy
-----------------------------------------------------------
RAG, 4k ctx 1.9s 3.4s $0.004 71%
full stuff, 640k 28.7s 41.2s $0.81 74%
cached, 640k 9.4s 15.1s $0.11 74%
Медіана у 28 секунд — довге очікування для вікна чату. Кешування промптів цей час скорочує, і ним варто користуватися, але воно має обмеження: мінімальний розмір промпту, час життя кешу, за підтримку якого ви платите, і одна слабкість, яка тут ударила найболючіше. Корпус змінюється приблизно сорок разів на день, кожна правка скидає кеш, і цілий день пішов на те, щоб платити за повторне збирання 640 000 токенів.
Питання, яке виявилося важливішим
Точність зросла на три пункти, і це майже приховало справжню проблему. Керівниця підтримки поставила просте питання: звідки взялася ця відповідь?
Пошук дає конкретну відповідь: чанк 4112 на дев'ятій сторінці, остання правка в березні. З повним вікном модель видає впевнений абзац, зібраний десь усередині 640 000 токенів, і показати їй нічого. Назвімо це перевіркою походження. Питання не в тому, чи може модель відповісти, а в тому, чи можете ви довести, звідки взялася відповідь. Це проблема продукту, а не моделі, з тих, що закінчують кар'єри, а не спринти.
Може, просто реранкер був поганий?
Хтось одразу заперечить: налаштуйте реранкер, візьміть дешевший тариф, ріжте на чанки розумніше. Слушно, реранкер справді був посереднім. Але навіть добре налаштований реранкер передає далі вісім фрагментів і сподівається на краще, а жодне налаштування не дасть посилання на джерело з вікна, яке проковтнуло все одразу.
Схема, яка прижилася
Векторна база повернулася, а реранкер ні.
ids = db.search(embed(q), k=40)
docs = fetch(ids)
ans = gem(f"{docs}\n\nQ: {q}", cache=c)
Пошук більше не шукає відповідь. Його завданням стало звузити коло, а читає вже довге вікно.
user ─► embed ─► vector db (k=40, no rerank)
│
▼
~90k ctx + cached policy docs
│
▼
model ─► answer + doc ids
Ті самі 500 питань пройшли через того самого суддю:
hybrid, 90k ctx 3.1s 5.2s $0.021 88%
Сорок не надто відфільтрованих чанків лишають моделі простір для міркувань, тоді як реранкеру довелося б вгадувати ідеальну вісімку. І кожна відповідь несе ідентифікатори того, на що вона спиралася.
Великі вікна не вбили пошук, вони покінчили з пошуком, де все вирішує точність. Старе завдання було виснажливим: знайти вісім ідеальних чанків, бо бюджет дозволяв лише вісім. З цим завданням покінчено, і сумувати за ним ніхто не має.