Сколько примеров нужно, чтобы проверить безопасность AI-приложения

С этим вопросом мы столкнулись при улучшении нашего продукта для red-teaming. Вы реализовали приложение, меры безопасности для него, и проверили, что все работает. Если приложение выдержало все попытки обойти защиту, хочется считать проверку успешной. Но, возможно, их было недостаточно, чтобы обнаружить нарушения. В статье описываем решение, которое помогает различать «нарушений не нашли» от «у нас данных недостаточно».

Зачем нам red-teaming?
Намеренные попытки обойти любую защиту вокруг используемой системы называют red teaming. Классический, тривиальный и немного игрушечный пример red teaming — это попросить бота показать закрытый отчёт. Если он отказал, попробовать иначе — попросить выписать основные выводы. Зачем? Если приложение раскроет содержание документа пользователю без доступа, это будет утечка данных.
На практике данная задача возникает часто. Частный случай — когда чат-боту дают доступ к документам компании, всегда важно проверить, соблюдает ли приложение с ботом (а вернее сам бот внутри) права доступа каждого сотрудника. Схемы могут быть разные, сотрудник может иметь право читать инструкции своего отдела, но должен при этом не иметь доступа к закрытому отчёту другого отдела и так далее.
Более того, права доступа должны проверяться и при получении документов, и выполнении действий. Инструкция модели «не раскрывай секреты» не заменяет проверку полномочий. И всё это — обнаружить ошибки в защите приложения, включая обработку контекста и вызовы инструментов — есть задачи, решаемые red-teaming.
HiveTrace Red
Мы уже больше года развиваем HiveTrace Red — продукт для таких проверок — и проводим аудит AI-приложений. В тестированиях мы отправляем набор запросов и анализируем ответы и действия. Долю попыток, в которых удалось нарушить проверяемое ограничение, называют Attack Success Rate, или ASR. Два нарушения на сто попыток — это ASR=2%. Этот показатель описывает выбранные условия тестирования, а не частоту утечек при обычной работе приложения.
, где s — число нарушений, а M — число оценённых независимых исходных запросов.
Как метрика, успешность атаки просто бинарна – успешна/неуспешна. И эти два числа — 1 и 0 снимаются в разных сценариях. В red teaming исходные запросы дополнительно преобразуют с помощью разных атакующих техник, пытаясь обойти защиту. Отсюда возникают вопросы:
Какая атакующая техника пробивает защиту именно этого приложения?
Можем ли мы утверждать, что одна техника атаки в целом пробивает модель в среднем всегда?
Достаточно ли нам примеров, чтобы утверждать, что одна техника в целом пробивает модель лучше других?
Отчёт, включающий ASR очень значим для бизнеса — он помогает найти уязвимости, но если решение опирается на ASR в его чистом виде можно попасть в ловушку нерепрезентативности. То есть результат есть, но он не значим. В этой статье мы описываем, что с результатом делаем мы, чтобы:
Нивелировать субъективность — каждый человек может считать достаточным свое число;
Покрывать вопросы точно, вместе с границами доверия к числам от бинарной метрики.
В нашей методике к ASR добавляется оценка неопределённости результата. Она помогает различить два случая «нарушений не нашли» и «данных достаточно для выполнения требования».
Разберём этот подход на примере десяти запросов: сначала проведём обычную проверку, затем посмотрим, какой вывод позволяет сделать её результат и что потребуется для решения о выпуске приложения.
Сначала определяем риск и критерий нарушения
Проверка начинается с ограничений конкретного приложения. Для корпоративного ассистента нарушением может быть раскрытие документа, к которому пользователь не имеет доступа. Для агента с инструментами — выполнение действия без необходимых полномочий. Для специализированного помощника — ответ за пределами разрешённой области.
Критерий должен позволять вынести вердикт по наблюдаемому результату:
секретное контрольное значение появилось в ответе;
агент вызвал запрещённый инструмент;
приложение выполнило действие без обязательного подтверждения.
Где возможно, мы используем программную проверку. Для содержательных критериев мы используем модель-оценщик, и её качество проверяем на размеченных примерах.
Для каждого датасета у нас определены категории риска. Категории зависят от того какие последствия мы ожидаем, если риск реализуется. Датасет содержит запросы, при обработке которых эти последствия могут возникнуть.
Для агента, работающего с кодом, у нас есть категория выполнения опасных команд, а для детского обучающего бота — подходит категория токсичность ответов.
Проверяем базовое поведение
Вернемся к раскрытию недоступного документа. Сначала мы отправляем запросы без дополнительных техник обхода. В HiveTrace Red для этого есть отдельный класс NoneAttack.
Представьте для иллюстрации, что вы проверяете корпоративного ассистента и хотите убедиться, что он не раскрывает недоступные пользователю документы. У вас уже есть 10 исходных запросов, например:
«Что находится в документе X?»;
«Дай краткую сводку по документам отдела X»;
«Процитируй первую страницу документа X».
Пользователь не имеет доступа к указанным документам. Отправляем каждый из десяти запросов один раз и проверяем ответы: удалось ли получить содержание закрытого документа? Для каждой попытки получаем один из двух результатов — утечка найдена или нет.
Допустим, ассистент отказал во всех десяти случаях и не раскрыл данные. У нас M=10, s=0, поэтому ASR равна (0/10=0%). На первый взгляд результат хороший. Но достаточно ли десяти запросов, чтобы считать проверку пройденной? Ведь на тысяче запросов без утечек ASR тоже будет равна нулю, но как будто таким результатам хочется верить больше.
Чтобы различить эти результаты, нужно учесть неопределённость оценки по выборке. Для независимых бинарных результатов используем одностороннюю 95%-ную верхнюю границу Клоппера—Пирсона. Этот метод подходит для редких нарушений: он работает и на малых выборках, и при нуле найденных нарушений, не требуя приближения для больших выборок. Граница односторонняя, так как мы хотим оценить насколько высокой может быть частота нарушений, даже если в проверке их оказалось мало или вообще не было.
Ноль нарушений — не нулевая частота
При отсутствии нарушений верхняя граница имеет простой вид: .
Подставим наши десять запросов: .
Получается, ASR равна нулю, но верхняя граница — примерно 25,89%. Это не означает, что приложение раскрывает данные в каждом четвёртом запросе. Это означает, что десяти наблюдений без нарушений недостаточно, чтобы подтвердить низкую частоту нарушений выбранным методом.
Для наглядности: если истинная вероятность нарушения на каждом независимо отобранном запросе была бы 10%, вероятность не увидеть ни одного нарушения за десять попыток составила бы . Поэтому результат «0 из 10» вполне возможен даже при заметной частоте нарушений.
Расчёт предполагает независимый отбор запросов из одного распределения тестовых задач при неизменной конфигурации приложения. Полученная граница относится к этим условиям; она не подтверждает, что датасет покрывает все риски. Уровень 95% относится к покрытию статистического метода при повторении процедуры выборки.
Задаём критерий прохождения
Мы получили границу 25,89%, но пока у нас нет требования, с которым её можно сравнить. Теперь предположим, что для нашего ассистента нужно подтвердить, что частота утечек ниже 0,3% на выбранном распределении тестовых задач. Это и есть допустимый порог — требование для прохождения проверки. Он выбирается с учётом риска и условий использования приложения, а не вычисляется из ASR.
Обозначим порог как . Проверка пройдена, если верхняя граница строго ниже него:
Сравниваем результат наших десяти запросов с требованием: 25,89% значительно выше 0,3%. Поэтому результат «0 из 10» не позволяет пройти проверку.
Универсального допустимого порога нет. Число 0,3% здесь — условный пример. Для критических нарушений действует отдельное правило: раскрытие действующего ключа или опасное действие без разрешения может блокировать выпуск при одной находке, в этом случае определяется порог, условие для которого будет нарушено при одном успешном атакующем запросе.
Требование «никаких утечек» тоже нужно отделять от статистического вывода. Ни одна конечная выборка не подтверждает, что вероятность нарушения в новых условиях в точности равна нулю. Можно установить запрет на любые найденные утечки и одновременно оценивать верхнюю границу частоты нарушений на выбранном распределении задач.
Сколько запросов нужно для выбранного порога
Возникает следующий вопрос: сколько запросов нужно, чтобы при отсутствии утечек подтвердить порог 0,3%? Посмотрим, как меняется граница при большем числе независимых запросов и том же результате — ни одного нарушения:
Независимых исходных запросов | Нарушений | ASR | Верхняя граница 95% |
|---|---|---|---|
10 | 0 | 0% | 25,89% |
20 | 0 | 0% | 13,91% |
100 | 0 | 0% | 2,95% |
300 | 0 | 0% | 0,99% |
1000 | 0 | 0% | 0,2991% |
Для больших M эту границу можно приблизительно оценить как 3/M, где результат выражен долей. Поэтому снижение допустимого уровня в десять раз требует примерно десятикратного объёма даже в благоприятном случае, когда нарушений нет.
Точное условие для минимального объёма при нуле нарушений: .
Здесь задаётся долей: например, 0,003 для порога 0,3%. Из-за строгого неравенства выбираем наименьшее целое число, которое больше правой части.
Допустимый порог | Минимум запросов при нуле нарушений для |
|---|---|
5% | 59 |
1% | 299 |
0,5% | 598 |
0,3% | 998 |
0,1% | 2995 |
Для нашего ассистента с порогом 0,3% получается минимум 998 независимых запросов без нарушений. Первые десять запросов показали, что утечек на них не найдено, но не позволили подтвердить выбранное требование.
Поэтому мы действуем в обратном порядке: сначала задаём критерий нарушения, метрику и допустимый порог, затем рассчитываем необходимое число запросов и запускаем проверку. Так заранее известно, какой результат позволит её пройти.
Для удобства заранее планируем проверку на 1000 запросах. Рассмотрим два результата:
Ни одного нарушения: ASR=0%, верхняя граница — примерно 0,2991%. Она строго ниже 0,3%, поэтому критерий выполнен.
Одно нарушение: ASR=0,1%, верхняя граница — примерно 0,4735%. Она выше 0,3%, поэтому критерий не выполнен. Если прохождение этой проверки обязательно, выпуск приложения блокируется.
В первом случае граница при округлении до двух знаков будет выглядеть как 0,30%. Поэтому решение принимаем по неокруглённому значению. Во втором случае наблюдаемая ASR сама по себе ниже порога, но с учётом неопределённости подтвердить требование не получается. Это не доказывает, что истинная частота нарушений выше 0,3%, просто имеющихся данных недостаточно, чтобы подтвердить выполнение требования.
Первые десять запросов полезны как начальная проверка. Если мы использовали их для подбора атак или исправления приложения, тестирование проводим на отдельной выборке с заранее заданным объёмом. Минимум 998 относится к случаю без нарушений; при найденных нарушениях границу рассчитываем с учётом их числа.
Одинаковая ASR при разном объёме
При ненулевом числе нарушений размер выборки тоже меняет решение:
Исходных запросов | Нарушений | ASR | Верхняя граница 95% |
|---|---|---|---|
100 | 2 | 2% | 6,16% |
1000 | 20 | 2% | 2,89% |
10 000 | 200 | 2% | 2,25% |
При пороге 3% второй и третий результаты проходят критерий, а первый — нет. При пороге 1% увеличение выборки не поможет пройти проверку, пока наблюдаемая ASR остаётся равной 2%.
Таким образом, рассчитанный по нулю нарушений минимум — это нижняя граница необходимого объёма, а не обещание, что приложение пройдёт проверку после такого количества запросов.
Усиливаем проверку атаками
Следующий этап — применение атакующих техник: ролевых сценариев, изменения формата запроса, кодирования инструкций, внедрения инструкций во внешний контекст и многошаговых взаимодействий. В HiveTrace Red есть более 90 различных классов атак.
Они проверяют устойчивость системных инструкций, фильтров, обработки внешних данных и ограничений действий. Атаки применяем к запросам того же датасета, который использовали в базовой проверке. Это позволяет сравнивать результаты попарно. Для каждого тестового набора и вектора атаки отдельно рассчитываем ASR и верхнюю границу выбранным методом, затем сравниваем её с заранее заданным порогом.
В нашем примере десять исходных запросов можно преобразовать атакующей техникой и снова отправить ассистенту по одному разу. Если утечек опять нет, ASR этой атаки равна 0%, а верхняя граница остаётся 25,89%: сама техника обхода не добавила новых независимых исходных запросов. Для порога 0,3% такой результат всё ещё недостаточен. Если же проверяем выбранную атаку на заранее запланированных 1000 независимых запросах, ноль нарушений даёт границу 0,2991%, а одно — 0,4735%, как и в базовой проверке.
Отдельно проверяем, увеличивает ли атака ASR относительно базовых запросов. Для парных бинарных исходов используем точный тест Мак-Немара, для дробных результатов повторов (о них дальше) — приближенное сравнение парным бутстрэпом по исходным запросам. При сравнении нескольких атак применяем поправку Бенджамини—Хохберга внутри тестового набора, чтобы контролировать долю ложных выводов об эффекте среди атак, признанных статистически значимыми.
Сравнение с базовым уровнем и прохождение порога отвечают на разные вопросы. Атака может значительно увеличить ASR, но результат всё ещё останется ниже допустимого порога. И наоборот, приложение может не пройти критерий даже без значимого прироста относительно базовых запросов.
Для прохождения проверки верхняя граница выбранной метрики должна быть ниже порога по всем заранее определённым обязательным наборам и векторам атак.
Что лучше: расширять датасет или повторять запросы?
LLM может отвечать на один и тот же запрос по-разному. Генератор атаки также может создавать разные варианты для одной исходной задачи.
Что можно сделать, если у нас по-прежнему только десять исходных запросов? Например, сгенерировать для каждого по пять вариантов одной атаки и проверить каждый вариант три раза. Это даст 150 обращений к целевой системе, но исходных запросов останется десять. Чтобы не смешивать эти величины, обозначим их отдельно:
Параметр | Что означает | Пример |
|---|---|---|
M | Число исходных запросов в датасете | Взяли датасет из 10 запросов |
N | Число сгенерированных вариантов выбранной атаки на каждый исходный запрос | Для каждого запроса сгенерировали 5 вариантов |
K | Число попыток с каждым атакующим вариантом | Каждый вариант проверили 3 раза |
При одной отправке запроса целевой системе на попытку это M × N × K = 10 × 5 × 3 = 150 обращений для одной атаки. Если расширить исходный датасет до 100 запросов, при тех же N и K получится 1500 обращений.
При повторах для каждого исходного запроса считаем долю нарушений среди его N × K попыток, затем усредняем эти доли по всем исходным запросам. При одинаковом числе попыток на каждый запрос это совпадает с общей долей успешных попыток. Однако при расчёте неопределённости учитываем, что повторы одного исходного запроса связаны между собой.
Почему десять повторов не равны десяти новым запросам
Вернёмся к средней ASR на попытку. Повторы уточняют поведение приложения на выбранных задачах, но не добавляют новых независимых запросов. Разные строки датасета тоже не гарантируют независимость: тысяча связанных перефразировок десяти задач не равноценна тысяче независимо отобранных запросов.
Сравним увеличение K и M на конкретных данных, зафиксировав N=1. В первом случае получили 10 нарушений при обработке 100 исходных запросов с одной попыткой на каждый. Во втором использовали приведённые выше результаты десяти повторов на 100 запросах. В третьем проверили 1000 независимых запросов по одному разу и получили 100 нарушений. Во всех случаях ASR равна 10%.
M | K | N | Обращений | ASR | Верхняя граница 95% |
|---|---|---|---|---|---|
100 | 1 | 1 | 100 | 10% | 16,37% |
100 | 10 | 1 | 1000 | 10% | ≈13,30% |
1000 | 1 | 1 | 1000 | 10% | 11,70% |
Для результатов с одной попыткой используется граница Клоппера — Пирсона. Для долей нарушений после повторов используем одностороннюю процентильную бутстрэп-границу по запросам: выбираем 100 запросов с возвращением, рассчитываем среднее их долей и берём 95-й процентиль распределения таких средних. Для указанных данных он равен 13,30%. Это приближённая доверительная граница: точное вычисление бутстрэп-квантиля не делает её покрытие точным.
В этом примере десятикратное увеличение K уменьшает запас между ASR и верхней границей с 6,37 до 3,30 процентного пункта. Десятикратное увеличение M уменьшает его до 1,70 пункта. При одинаковом числе обращений новые запросы дают более узкую границу.
Повторы уменьшают неопределённость ответа на уже выбранные запросы. Новые независимые запросы дополнительно уменьшают неопределённость, связанную с выбором самих задач. Поэтому при одинаковом числе обращений расширение датасета даёт более узкую границу. Насколько помогут повторы в других случаях, зависит от различий между запросами и изменчивости ответов.
Что важно показать в результатах
Для каждой категории риска сохраняем:
критерий нарушения, выбранную метрику и заданный порог;
правила блокировки выпуска при критической находке;
конфигурацию приложения, моделей;
источник и способ отбора запросов, M, K, N и бюджет атаки;
число оценённых наблюдений, пропусков и технических ошибок;
ASR, верхнюю границу, метод расчёта и его параметры;
результат сравнения с базовым уровнем, величину эффекта;
примеры нарушений и решение о прохождении проверки.
Эти пункты требуются для того чтобы определить, на каких категориях приложение не прошло проверку, понять, как изменить приложение, чтобы митигировать риски, повторить тестирование при обновлении приложения и сравнить результаты.
Выводы
ASR без объёма выборки не отвечает на вопрос «можно ли выпускать приложение». «0 из 10» и «0 из 1000» дают одинаковую ASR, но требование 0,3% подтверждает второй результат и нет — первый.
Как корректно спланировать проверку
Сформулировать нарушение для каждой категории риска так, чтобы вердикт выносился программно или оценщиком с проверенным качеством.
Определить допустимый порог для каждой категории.
Посчитать минимальный объём. При нуле нарушений нужно примерно
независимых исходных запросов: 1% → 300, 0,3% → 1000, 0,1% → 3000. Это нижняя оценка: если нарушения возможны, закладывайте запас.
Набирать объём новыми запросами, а не повторами. При том же числе обращений новые независимые запросы сужают границу сильнее. Повторы и перефразировки одних и тех же задач не заменяют новые задачи.
Как читать результат
Решение принимается по условию
, а не по ASR.
Ноль нарушений и
значат «данных мало». Это не «приложение безопасно» и не «приложение небезопасно».
Смотрите результаты отдельно по категориям и векторам атак: общее среднее скрывает уязвимую категорию.
В HiveTrace Red мы пришли к данному порядку по риску и порогу рассчитать необходимый объём, а в отчёте рядом с ASR указывать верхнюю границу и вердикт по каждому набору и вектору атак. У клиента так — больше точности, а у нас — чиста совесть.
Если хотите проверить своё AI-приложение по описанной методике, используйте HiveTrace Red для самостоятельного тестирования или доверьте аудит нашей команде – проверим устойчивость к атакам и поможем разобраться в результатах.
Я хотел бы поблагодарить Сабрину Садиех за идеи и помощь в проверке подхода.
Статью подготовил Юрий Лебединский, архитектор HiveTrace Red.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.