RAG для аналитики: как отвечать на вопросы «сколько» и «по всем»
Пользователь спрашивает ассистента: «Сколько договоров с автопродлением заканчивается в следующем месяце?» В поиске находятся пять подходящих договоров. Модель аккуратно считает их и отвечает: пять. Однако в базе таких договоров сорок. Для вопроса о количестве надо сначала определить полный набор строк, а уже затем писать ответ.
Почему поиск не задаёт знаменатель
Обычный RAG выбирает несколько подходящих фрагментов и передаёт их модели. Это удобно для вопроса «как работает автопродление»: достаточно действующего пункта регламента. Для «сколько договоров» каждый пропущенный договор меняет результат. Увеличение top-k только отодвигает проблему: пока выдача ограничена числом кандидатов, она не доказывает полноту набора.
Разделите два намерения: объяснить правило и посчитать объекты. В первом случае нужен поиск по текстам, во втором — запрос к реестру договоров. Если вопрос объединяет оба намерения, сначала найдите определение автопродления, затем примените согласованное условие к реестру. В ответе покажите и период расчёта, и использованное определение.
Подготовьте реестр, который можно считать
У каждой строки должны быть ID договора, дата окончания и отдельный признак автопродления. Если договор представлен несколькими строками или версиями, заранее выберите единицу подсчёта. COUNT(*) по чанкам измерит объём индекса, а не количество договоров. Для карточек с историей изменений сначала выбирают действующую версию на дату среза.
Модель может предложить параметры запроса: начало периода, конец и условие. Выполнение поручите заранее написанному запросу с параметрами. Тогда естественный язык помогает понять просьбу, а приложение сохраняет контроль над таблицами и операциями. Не надо предоставлять агенту произвольный SQL, чтобы получить три фильтра.
Посчитайте на маленьком наборе
Ниже реестр уже подготовлен: каждая строка — отдельный договор. Интервал задаётся полуоткрытым: начало включается, конец исключается. Это позволяет склеивать соседние месяцы без двойного включения граничной даты. SQLite хранит даты примера как строки YYYY-MM-DD; при таком одинаковом формате сравнение строк сохраняет календарный порядок.
import sqlite3
db = sqlite3.connect(":memory:")
db.execute("CREATE TABLE contracts(id TEXT PRIMARY KEY, ends TEXT, renew INTEGER)")
db.executemany("INSERT INTO contracts VALUES (?, ?, ?)", [
("a", "2026-11-01", 1), ("b", "2026-11-30", 1),
("c", "2026-12-01", 1), ("d", "2026-11-15", 0),
])
start, end = "2026-11-01", "2026-12-01"
ids = [r[0] for r in db.execute(
"SELECT id FROM contracts WHERE renew = 1 AND ends >= ? AND ends < ? ORDER BY id",
(start, end),
)]
assert ids == ["a", "b"]
print({"count": len(ids), "ids": ids, "start": start, "end_exclusive": end})
Как собрать окончательный ответ
Из примера получается два договора: a и b. Договор c заканчивается ровно на правой границе и относится к следующему периоду, у d нет автопродления. Передайте модели не только число, но и начало и конец периода, дату обновления реестра и список ID, доступный для проверки сотрудником. Ответ «два» без этих сведений быстро теряет смысл.
Если реестр ещё не готов, полезный первый результат проекта — таблица извлечённых полей с очередью проверки спорных договоров. Выделите статус «не определено»: отсутствие распознанного пункта не означает отсутствие автопродления. Такие строки должны быть видны в отчёте о полноте данных.
Проверяйте систему на вопросах с разными границами: пустой месяц, договор в первый день, договор на границе следующего месяца, две версии одного договора. Отдельно проверяйте перевод пользовательской просьбы в параметры. Верная арифметика по неверно выбранному периоду всё равно даёт неправильный бизнес-ответ.
Продолжить проект на практике
Когда расчёт уже определён, следующая задача — научить ассистента находить основания: правила, договоры и пояснения к показателям. В платном курсе Vector DB & RAG Developer вы соберёте RAG с цитатами и API семантического поиска, а затем проверите качество найденных документов. Эти навыки помогают связать точные данные и текстовые источники в одном приложении.
Откройте программу курса и выберите следующий этап своего проекта.
По теме: Гибридный поиск для RAG: BM25, векторы и расчёт RRF.
Продолжить на практике
- Vector DB & RAG Developer ↗
Практический курс по векторным базам данных и семантическому поиску. Вы развернёте Qdrant, Weaviate и FAISS, научитесь индексировать миллионы эмбеддингов, строить k-NN-поиск с фильтрами, объединять его с BM-25 и создавать RAG-ботов, которые отвечают на вопросы на основе ваших данных.
