Почему обычный кэш здесь не работает

Обычный кэш отвечает только на точное совпадение ключа. Для него вопросы «Как вернуть товар?» и «Какие правила возврата?» различны. Семантический кэш сравнивает векторные представления запросов и может вернуть ранее подготовленный ответ для близкой формулировки. В FAQ, внутренней поддержке и сервис-деске это способ не запускать заново всю цепочку embedding → поиск документов → генерация.

Но цена промаха у такого кэша выше, чем у кэша картинки или CSS. Два похожих вопроса могут требовать разных ответов из-за филиала, договора, роли сотрудника, даты документа или предыдущей реплики. Поэтому семантический кэш нельзя ставить перед RAG как безусловный ускоритель. Это отдельный слой принятия решения с жёсткими границами применимости.

Документация Redis описывает запись кэша как запрос, его embedding, ответ и метаданные: tenant, язык, версия модели и признаки безопасности. Microsoft приводит простой контрпример для разговорного контекста: одинаковая фраза «А какое второе по величине?» может означать разное после разных предыдущих вопросов. Вывод практический: одна только близость векторов не доказывает, что ответ можно переиспользовать.

Что именно можно кэшировать

Для небольшого бизнеса полезно разделить три разных механизма:

  • точный кэш — один и тот же нормализованный запрос при неизменных данных;
  • семантический кэш — близкие по смыслу запросы в строго одном контексте;
  • prefix/KV cache инференс-сервера — повторное использование вычислений модели, но не готового бизнес-ответа.

Семантический кэш лучше всего подходит для стабильных справочных ответов: режим работы, инструкция по оформлению заявки, состав стандартной услуги, общий порядок возврата. Плохие кандидаты — остатки, цены, статусы заказов, персональные данные, расчёты, юридически значимые решения и любые ответы, зависящие от текущего состояния CRM или ERP.

Полезное правило: если ответ безопасно напечатать как заранее утверждённую карточку, его можно рассматривать для кэша. Если перед ответом требуется транзакция, проверка прав или запрос свежих данных, кэш должен хранить максимум план обращения к системе, но не готовый результат.

Архитектура с двумя воротами

Надёжная схема содержит мягкое и жёсткое сравнение.

Сначала приложение формирует контекстный ключ. В него входят tenant или организация, роль и группа доступа, язык, канал, версия системного промпта, версия embedding-модели, версия генеративной модели, класс политики безопасности и версия набора знаний. Эти поля проверяются точным фильтром. Запись из другого пространства даже не участвует в векторном поиске.

Только после этого выполняется поиск близкого запроса. Порог сходства настраивается на реальных вопросах, а не берётся из примера библиотеки. Кандидат должен пройти дополнительные условия:

  • не истёк TTL;
  • версия знаний совпадает с активной;
  • права пользователя не уже прав, с которыми создавался ответ;
  • ответ ранее прошёл проверку и не содержит персонализированных фрагментов;
  • запрос не относится к классу «только свежие данные»;
  • диалоговый контекст либо включён в ключ, либо для этого маршрута запрещён.

При любом сомнении система делает cache miss и запускает обычный RAG. Промах увеличивает задержку; ложное попадание возвращает неверный или чужой ответ. В бизнес-системе эти ошибки неравноценны, поэтому порог выбирают в пользу безопасного промаха.

Как не обслужить вчерашнюю правду

TTL ограничивает время жизни, но сам по себе не решает свежесть. Инструкция может измениться через минуту после заполнения кэша. Нужна адресная инвалидизация.

Каждая запись должна хранить идентификаторы документов или версию снимка базы знаний, на которых основан ответ. Когда документ обновлён, удалён или потерял доступность, публикационный конвейер отправляет событие инвалидизации. Кэш удаляет связанные ответы или меняет активную версию знаний, делая старые записи недоступными.

Практичный вариант для первого пилота — версионировать не каждый фрагмент, а небольшой домен: `returns-v17`, `hr-policy-v9`, `service-catalog-v24`. Обновление домена мгновенно переводит чтение на новую версию, а старые записи удаляются фоном. Это проще проверить, чем сложный граф зависимостей, и позволяет откатиться.

Отдельно нужен ручной `delete by id` для ошибочного ответа. Redis показывает такую адресную операцию в интеграционных примерах. Полная очистка кэша остаётся аварийной кнопкой, а не обычным способом обновления.

Изоляция и журналирование

Семантический кэш фактически становится базой готовых ответов. Поэтому он наследует требования к данным RAG: минимальные права сервисной учётной записи, шифрование, сроки хранения, резервирование и аудит.

Критически важно фильтровать tenant и права внутри запроса к индексу, а не после получения ближайшего вектора. Иначе система сначала извлекает чужую запись и лишь затем пытается её отбросить; это усложняет анализ утечек и создаёт риск ошибки в прикладном коде.

В журнал не следует писать полный запрос и полный ответ по умолчанию. Для эксплуатации достаточно идентификаторов, версий, расстояния, результата hit/miss, причины отказа, времени ответа и хэша нормализованного запроса. Содержимое включают только для ограниченной выборки с отдельным доступом и сроком хранения.

Как измерить экономику без самообмана

Главная метрика — не hit rate. Высокая доля попаданий может означать слишком широкий порог и много неверных ответов. Нужны как минимум четыре показателя:

  • доля безопасных попаданий на размеченной выборке;
  • доля ложных попаданий, особенно между разными намерениями и правами;
  • экономия времени и вычислений на один принятый ответ;
  • доля ответов, отозванных после изменения документов.

Модельный расчёт для пилота: 20 000 вопросов в месяц, 30% потенциальных повторов, стоимость полной цепочки условно 1 рубль, lookup кэша — 0,05 рубля. При 80% подтверждённых безопасных попаданий среди кандидатов экономия составляет около 4 560 рублей в месяц: `20 000 × 0,30 × 0,80 × (1 − 0,05)`. Это не обещание рынка, а иллюстрация. Из неё ещё нужно вычесть инфраструктуру, разработку, контроль качества и стоимость ошибки.

Для локальной модели прямые расходы на токены могут быть нулевыми, но остаются очередь, GPU-время и p95 задержки. Если нагрузка мала и оборудование простаивает, семантический кэш может не окупить сложность. Начинать стоит с измерения повторяемости запросов, а не с покупки отдельной платформы.

Пилот за две недели

Соберите 300–500 обезличенных вопросов из одного стабильного процесса. Разметьте пары: «можно переиспользовать», «похожи, но ответ различается», «нужны свежие данные», «запрещено кэшировать». Особенно ценны опасные почти-дубликаты: одинаковый товар в разных регионах, одна должность в разных юрлицах, одинаковая фраза после разных реплик.

Первую неделю запускайте кэш в теневом режиме: он предлагает кандидата, но пользователь получает обычный ответ RAG. Сравнивайте ответы и причины расхождения. После настройки разрешите попадания только для одного низкорискового домена, добавьте TTL, версию знаний и мгновенный kill switch.

Критерий запуска формулируется заранее. Например: ни одного межтенантного попадания, не более 0,5% ложных попаданий на контрольной выборке, 100% удаления тестовых записей после смены версии и измеримое улучшение p95. Порог — бизнес-решение, а не универсальная цифра.

Что сделать руководителю

Попросите команду показать не диаграмму hit rate, а пять вещей: состав точного контекстного ключа, перечень запрещённых классов данных, механизм инвалидизации, тест почти одинаковых вопросов и аварийное отключение. Если хотя бы один пункт отсутствует, семантический кэш пока является экспериментом.

Для малого бизнеса разумный следующий шаг — двухнедельный теневой пилот на одном FAQ-домене. Он быстро покажет повторяемость запросов и реальную экономию, не превращая ускоритель в новый источник устаревших или чужих ответов.