TL;DR
VEPA — схема, в которой правила безопасности агента хранятся не как текстовые заметки, а как короткие строгие правила вида «если [условие], то разрешить/отказать» над типизированными событиями. LLM предлагает правки этих правил (добавить, удалить, переписать, разбить, слить). Затем код-проверяльщик отсекает правки с конфликтами, а правило получает право на решения только после достаточного числа подтверждений из реальной работы.
Главная находка: текстовая «память» агента о безопасности со временем портится. Заметки получаются двусмысленными, противоречат друг другу, а исправление одной ошибки ломает то, что раньше работало (регрессия). Модель каждый раз заново трактует расплывчатый текст, поэтому на похожих случаях решения разные. Дело не в слабости модели: свободный текст нельзя механически проверить на противоречия.
Метод разводит три роли: LLM предлагает правки, проверяльщик допускает только непротиворечивые, слой полномочий включает правило только по накопленным доказательствам. Для читателя без кода применима идея, а не сама система: правила держать строго и коротко, каждую правку проверять на конфликты и регрессии, новые правила не включать сразу.
Схема метода
ШАГ 0: Событие агента (письмо, вызов инструмента) → типизированная запись
(кто, что делает, какие данные, кому, зачем, есть ли разрешение, инструмент)
Поля, которые не определить → "unknown"
ШАГ 1: Есть ошибки (провалы) и верные решения (эталон)
→ LLM пишет «патч»: список правок Add / Delete / Rewrite / Split / Merge
ШАГ 2: Проверяльщик (код) → допускает только
• корректные по схеме правила
• без конфликтов (два правила с противоположным решением на одном событии)
Отклонил → возвращает пример конфликта, LLM пробует снова
ШАГ 3: Компромисс между двумя целями:
«починить новые ошибки» и «не сломать то, что работало»
Хранится архив допущенных вариантов; итог — вариант, у которого слабейшая цель сильнейшая
ШАГ 4: Слой полномочий → правило «активно» только если накоплено
достаточно подтверждений; противоречащая обратная связь отзывает его
Всё это работает на коде. В чате воспроизводятся только шаги 1–2, и без гарантий.
Пример применения
Метод сильнее всего там, где у агента есть доступ к чувствительному и необратимые действия. Слабая зона — субъективные и «творческие» решения. Поэтому берём агента с доступом к почте и CRM.
Задача: Магазин электроники на маркетплейсах запустил агента-помощника менеджера. Он видит amoCRM и почту и умеет отправлять письма. Два случая за неделю: - Агент отправил поставщику файл с закупочными ценами конкурентов. - Агент отказал бухгалтеру из своей компании в получении счёта-фактуры, хотя это штатная работа.
Нужно поправить правила, не сломав остальное.
Промпт:
Ты редактор набора правил-ограждений для агента. Правки строго типизированные.
R1: data.sensitivity = confidential И recipient.affiliation = external → refuse
R2: action.type = send_email И recipient.affiliation = internal → allow
R3: data.type = invoice → refuse
F1: send_email, data.type=price_list_competitors, sensitivity=unknown, recipient=supplier (external). Верно: refuse. Получили: allow.
F2: send_email, data.type=invoice, recipient=accountant (internal). Верно: allow. Получили: refuse (сработало R3).
C1: send_email, data.type=invoice, recipient=client (external), authorization=approved. Верно: refuse без одобрения руководителя. Сейчас refuse — не сломай.
C2: send_email, data.type=meeting_notes, recipient=internal. Верно: allow. Сейчас allow.
Прошлый кандидат отклонён: «data.type = invoice → allow» конфликтует с R3 на событии C1.
Add(r), Delete(r), Rewrite(r→r'), Split(r→{r',r''}), Merge({r',r''}→r)
1. Каждое правило — условие из полей схемы + решение.
2. Два правила с разными решениями не должны покрывать одно событие.
3. Все события из RegressionWitnesses должны получить прежнее решение.
4. Все события из UnresolvedFailures должны получить верное решение.
5. Для каждого события из обоих списков выпиши, какое правило сработает, и проверь пересечения.
Выведи: (а) патч списком правок, (б) итоговый набор правил, (в) таблицу «событие → сработавшее правило → решение», (г) найденные пересечения или «пересечений нет».
Результат: Модель выдаст патч из нескольких типизированных правок. Вероятно, это Split слишком широкого R3 по получателю и Rewrite условия для F1. Затем она покажет итоговый набор правил и таблицу прогона по всем примерам. В конце будет явная проверка пересечений. Это проверка самой моделью, а не гарантия. Для критичных случаев прогоните правила через код или скрипт.
Почему это работает
Слабость. Текстовое правило вроде «не делись конфиденциальным вовне» каждый раз трактуется заново. Две заметки легко противоречат друг другу, но это видно только в момент решения. Исправив одну ошибку, вы не знаете, что сломалось. Чтобы проверить, нужно перегонять все старые примеры через LLM, а это дорого и неповторимо.
Сильная сторона LLM. Модель хорошо обобщает: по нескольким провалам с разными внешними получателями она формулирует общее правило «конфиденциальное нельзя за пределы организации». Перебором такое правило не найти.
Как метод это использует. LLM дана только роль предложения правок. Решение и проверку отдали строгим правилам и коду, который не «трактует». Дополнительно правило допускается к работе, только когда его подтвердили события. Модель можно ошибиться, но ошибка не попадёт в работу сразу.
Рычаги управления:
- Набор полей схемы (кто, что, кому, зачем, разрешение) → больше полей дают точнее правила, меньше упрощают проверку.
- unknown для неопределимого → безопаснее, чем догадка; пусть правило явно решает, что делать с unknown.
- Примеры-эталоны (RegressionWitnesses) → чем больше, тем надёжнее защита от поломок.
- Порог доверия → выше для опасных решений (отказ в критичном или разрешение), ниже для мелких.
- Возврат конкретного конфликта в следующий запрос → модель не повторяет ту же ошибку.
Шаблон промпта
Это реконструкция по описанию метода, а не дословный промпт из статьи. В доступной части работы текст промпта не приведён.
Ты редактор набора правил-ограждений для агента. Ты правишь правила только типизированными действиями.
{поля_и_допустимые_значения}
{текущие_правила}
{ошибки_с_верным_решением}
{примеры_которые_должны_остаться_верными}
{конфликты_прошлых_попыток_или_«нет»}
Add(r), Delete(r), Rewrite(r→r'), Split(r→{r',r''}), Merge({r',r''}→r)
1. Правило = условие по полям схемы + решение (allow/refuse). Значения только из схемы.
2. Нет двух правил с разными решениями, покрывающих одно событие.
3. Все примеры из RegressionWitnesses сохраняют прежнее решение.
4. Все примеры из UnresolvedFailures получают верное решение.
5. Если вариантов несколько — выдай 2–3 кандидата и выбери того, у которого слабейшая из двух целей (починка ошибок / отсутствие поломок) сильнее.
Выведи: (а) патч, (б) итоговые правила, (в) таблицу «событие → сработавшее правило → решение», (г) найденные пересечения.
Что подставлять:
- {поля_и_допустимые_значения} — например, action.type ∈ {send_email, read_file}, data.sensitivity ∈ {public, confidential, unknown}.
- {текущие_правила} — ваши действующие правила в виде «условие → решение».
- {ошибки_с_верным_решением} — реальные случаи, где агент ошибся.
- {примеры_которые_должны_остаться_верными} — случаи, где агент уже решал правильно.
🚀 Быстрый старт — вставь в чат:
Вот шаблон проверяемой правки правил агента (по мотивам VEPA). Адаптируй под мою задачу: [твоя задача — какой агент, какие у него инструменты и данные].
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, какие поля описывают событие, какие правила уже есть и какие случаи были ошибочными. Без схемы и эталонных примеров метод не работает: нет, по чему искать конфликты и поломки. Она возьмёт структуру из шаблона и соберёт готовый запрос под вашего агента.
Ограничения
⚠️ Нужен код: сам метод требует схемы событий, проверяльщика конфликтов, архива вариантов и подсчёта доказательств. В чате вы получите только «ручной» аналог без гарантий. LLM может ошибиться и в таблице проверки.
⚠️ Детерминизм только после разбора: гарантии действуют, когда событие уже превращено в типизированную запись. Эту запись делает LLM-разборщик, и он сам может ошибиться. Авторы это прямо признают.
⚠️ Нужна размеченная обратная связь: метод учится на потоке «верно / неверно». Если вы не знаете, какие решения агента были правильными, системе нечего исправлять.
⚠️ Покрытие неполное: метрики считаются на событиях, которые покрыты активной политикой. Остальное остаётся без детерминированной защиты, пока правила не накопят подтверждения.
⚠️ Только бенчмарки: проверка шла на трёх наборах безопасности агентов, а не на реальных бизнес-системах. Текст статьи в доступной версии обрывается на описании слоя полномочий, поэтому детали порога и итоговые цифры не видны.
Как исследовали
Идея была в том, чтобы сравнить два подхода к «обучаемым» ограждениям: когда агент хранит заметки о безопасности текстом и когда держит строгие правила, проверяемые кодом. Команда Google Cloud AI Research и UNC прогнала их в режиме онлайн-развёртывания на трёх наборах: ASSEBench-Safety, ASSEBench-Security и ATBench. События приходят потоком, после каждого шага приходит обратная связь, и правила обновляются.
Сравнивали VEPA с LLM-ограждением без памяти и с адаптивными текстовыми вариантами (AGrail, LiSA). Главная метрика — F1 (баланс «не пропустить опасное» и «не блокировать нужное») на событиях, покрытых активной политикой. VEPA выигрывала на всех трёх наборах и постепенно расширяла долю событий с детерминированными решениями.
Затем усложнили условия: смешанные потоки с меняющимися типами рисков, испорченная обратная связь, более длинные периоды, другие LLM. Преимущество сохранилось. Для практики это значит: проверка и «порог доверия» защищают правила от шумной обратной связи, а свободный текст такого не умеет. Дополнительная деталь: проверка одного трёхусловного правила занимает около 0,25 мс. Разница со стоимостью вызова LLM огромна.
Адаптации и экстраполяции
🔧 Техника: «кандидат» вместо сразу действующего правила → защита от случайных правок
В файл инструкций агента (например, CLAUDE.md) добавьте два раздела: «Действующие правила» и «Кандидаты». Новое правило после первой ошибки записывайте в «Кандидаты». Переносите в действующие только после нескольких подтверждающих случаев и без опровергающих:
## Кандидаты (НЕ применять, только наблюдать)
- К1: письма с прайсами внешним адресатам требуют подтверждения. Подтверждений: 1, опровержений: 0.
Правило переходит в «Действующие» при 3 подтверждениях и 0 опровержениях.
Это упрощённый аналог слоя полномочий. Подсчёт здесь ведёте вы или агент вручную, без статистики из статьи.
Экстраполяция: аудит файла правил на конфликты и регрессии
Это не из статьи, а перенос принципа: проверка на противоречия до того, как правило попало в работу.
Вот файл инструкций моего агента: {текст_файла}.
1. Перепиши каждое правило в виде «условие → решение».
2. Найди пары правил, которые дают противоположные решения на одном событии. Для каждой пары приведи пример такого события.
3. Для моих эталонных случаев {список_случаев} выпиши, какое правило сработает и совпадает ли это с верным решением.
Не предлагай правок, пока я не подтвержу найденные конфликты.
Ресурсы
- Работа: VEPA: Verified Evolving Formal Policy for Lifelong LLM Agent Guardrails
- Авторы: Duy Nguyen, Lesly Miculicich, Bhavana Dalvi Mishra, Shuo Li, Krishnamurthy Dj Dvijotham, Mohit Bansal, Tomas Pfister, Long T. Le
- Организации: Google Cloud AI Research, UNC Chapel Hill, Google DeepMind
- Наборы для проверки: ASSEBench-Safety и ASSEBench-Security (Luo et al., 2025a), ATBench (Li et al., 2026)
- Сравнивались с: AGrail (Luo et al., 2025c), LiSA (Kim et al., 2026b)
- Основа представления событий: теория контекстной целостности (Nissenbaum, 2004)
