TL;DR
Pr²Graph — методология автоматического извлечения информации из политик конфиденциальности через многошаговую декомпозицию задачи на специализированные роли для LLM. Каждый шаг фокусируется на одном типе сущности: данные, цели использования, стороны, действия, связи между ними. Модель получает один сегмент текста и серию последовательных инструкций, где каждая инструкция извлекает конкретный тип информации.
Главная находка: последовательная специализация работает лучше универсальных запросов. Когда модель пытается извлечь всё сразу ("найди все данные, цели, стороны и связи между ними"), точность падает — слишком много competing objectives в одном промпте. Разбиение на 7 отдельных шагов (распознавание данных → классификация данных → распознавание целей → классификация целей → распознавание сторон → распознавание действий → извлечение связей) даёт F1-score ~0.9 против ~0.6-0.7 для универсального промпта.
Метод работает через каскад специализированных промптов: сначала модель находит упоминания типов данных в тексте, затем классифицирует их по стандартной онтологии DPV, потом находит цели использования, классифицирует их, находит стороны, определяет действия с данными, и в конце связывает всё воедино через relation extraction. Каждый шаг получает чистую задачу и чёткую JSON-схему вывода. Результаты предыдущих шагов передаются в следующие через уникальные ID.
Схема метода
СЕГМЕНТ ТЕКСТА → обрабатывается последовательно 7 промптами:
ШАГ 1: Data Entity Recognition → JSON список {text_span, start, end}
ШАГ 2: Data Classification → JSON {entity_id, DPV_class}
ШАГ 3: Purpose Entity Recognition → JSON список {text_span, start, end}
ШАГ 4: Purpose Classification → JSON {entity_id, DPV_class}
ШАГ 5: Party Recognition → JSON список {text_span, party_type}
ШАГ 6: Action Recognition → JSON список {action_type, text_span}
ШАГ 7: Relation Extraction → JSON список кортежей (ID1, ID2, relation_type)
→ Граф связей между сущностями
Каждый шаг выполняется отдельным запросом к LLM. Сегментация — по строкам политики (эмпирический баланс стоимости и точности).
Пример применения
Задача: Проверить, какие данные собирает ваш банк и для чего, чтобы понять можно ли требовать удаления части из них по GDPR.
Промпт (многошаговый):
Шаг 1 - Найти данные:
Проанализируй этот фрагмент из политики банка. Найди все упоминания типов данных, которые банк собирает.
Текст: "Мы собираем ваши ФИО, адрес, данные паспорта и историю транзакций для проверки кредитоспособности и предотвращения мошенничества."
Верни JSON:
{
"data_entities": [
{"text": "...", "start": ..., "end": ...}
]
}
Шаг 2 - Классифицировать данные:
Классифицируй найденные типы данных по стандартной таксономии DPV.
Данные: ["ФИО", "адрес", "данные паспорта", "история транзакций"]
Верни JSON с DPV-классами (например, PersonalData, FinancialData, IdentifyingData)
Шаг 3 - Найти цели:
Из того же текста найди цели использования данных.
Текст: [тот же]
Верни JSON с целями (например, "проверка кредитоспособности", "предотвращение мошенничества")
Шаг 4-7: Аналогично для классификации целей, сторон, действий и связей.
Результат:
Получишь структурированную карту: какие конкретно данные (не "персональные", а "паспорт, адрес") используются для каких конкретно целей (не "обработка", а "антифрод, скоринг"), кто их получает (первая сторона / третьи лица) и какие действия совершаются (сбор, хранение, передача). Видна полная цепочка потока данных.
Это позволяет точечно запросить удаление данных, которые используются для необязательных целей (например, маркетинг), сохранив данные для обязательных (антифрод, compliance).
Почему это работает
Проблема LLM: При сложном многоцелевом запросе ("найди данные, цели, стороны и свяжи") модель конкурирует сама с собой за attention. Разные типы сущностей требуют разных паттернов распознавания — модель пытается держать в голове все одновременно и теряет точность. Это как просить человека одновременно искать в тексте имена, даты, цифры и отношения между ними — внимание размывается.
Сильная сторона LLM: Модели отлично фокусируются, когда задача узкая и ясная. "Найди только упоминания типов данных" — модель активирует релевантные паттерны распознавания. "Классифицируй эти данные по DPV" — модель работает только с таксономией, не отвлекаясь на поиск.
Механика метода: Каскад специализированных промптов использует последовательную фокусировку вместо параллельной многозадачности. Каждый шаг решает одну задачу идеально, результаты накапливаются. Relation extraction в конце получает чистые размеченные сущности с ID — ей не нужно искать, только связывать. JSON schema в каждом промпте убирает двусмысленность вывода — модель знает точный формат.
Рычаги управления:
- Гранулярность сегментации (по строке / абзацу / всему тексту):
- По строке → больше запросов, но выше точность (меньше шума в контексте)
- По абзацу → меньше запросов, экономия токенов, но риск пропустить связи
- Целиком → дешевле, но ниже точность для длинных документов
- Порядок шагов (можно менять под задачу):
- Сначала данные → потом цели (как в оригинале) — когда данные важнее
- Сначала цели → потом данные — когда анализируешь "для чего собирают"
- Depth of classification (листья или upper levels в DPV):
- Листья онтологии → максимальная детализация (например, не "финансовые данные", а "история транзакций")
- Верхние уровни → быстрее, проще, но грубее
- JSON schema строгость:
- Жёсткая схема → стабильный парсинг, но модель может застрять если встретит corner case
- Гибкая схема → модель адаптируется, но нужен robust json-repair
Шаблон промпта
Базовый шаблон для одного шага (Data Entity Recognition):
SYSTEM:
Ты — эксперт по анализу политик конфиденциальности.
Задача: Найди в тексте все упоминания типов данных, которые организация собирает.
Типы данных включают:
- Личные данные: имя, адрес, телефон, email, паспорт
- Финансовые данные: номер карты, счета, история транзакций
- Технические данные: IP-адрес, cookies, device ID, логи
- Поведенческие данные: история просмотров, предпочтения, геолокация
- Биометрия: отпечатки, лицо, голос
Возвращай ТОЛЬКО валидный JSON без дополнительных пояснений:
{
"data_entities": [
{"text": "текстовый фрагмент", "start_pos": число, "end_pos": число}
]
}
USER:
{текст_сегмента_политики}
Базовый шаблон для классификации:
SYSTEM:
Ты — эксперт по классификации данных согласно Data Privacy Vocabulary (DPV).
Задача: Каждую найденную сущность отнеси к наиболее точному классу DPV.
Иерархия DPV (примеры):
- PersonalData
- Contact (email, phone, address)
- Identifying (passport, SSN, driver license)
- Demographic (age, gender, race)
- FinancialData
- BankAccount
- CreditCard
- Transaction
- TechnicalData
- IPAddress
- Cookie
- DeviceID
Возвращай ТОЛЬКО валидный JSON:
{
"classifications": [
{"entity_id": "ID из предыдущего шага", "dpv_class": "наиболее точный класс"}
]
}
USER:
Найденные сущности: {список_сущностей_из_шага_1}
Текст для контекста: {текст_сегмента}
Параметры:
{текст_сегмента_политики}— фрагмент документа для анализа (строка/абзац/раздел){список_сущностей_из_шага_1}— результаты предыдущего шага в формате JSON- Повторить аналогичные промпты для Purpose Recognition, Purpose Classification, Party, Action, Relations
🚀 Быстрый старт
Для работы с политикой конфиденциальности:
Вот методология многошагового анализа документа. Адаптируй под мою задачу: проанализировать политику конфиденциальности [название сервиса] и показать какие данные куда уходят.
Задавай вопросы, чтобы настроить шаги под мою задачу.
[вставить базовые шаблоны выше]
LLM спросит какие именно типы данных тебя интересуют, какая степень детализации нужна (листья DPV или категории), какой формат вывода удобен — потому что метод гибкий и адаптируется под задачу. Она возьмёт структуру из шаблонов и подстроит под твой контекст.
Ограничения
⚠️ Требует множественных запросов: 7 шагов на каждый сегмент — если политика на 100 абзацев, это 700 API calls. Дорого ($2.2 на политику в исследовании). Для длинных документов либо укрупняй сегменты (ниже точность), либо фокусируйся на критичных разделах.
⚠️ Зависимость от онтологии DPV: Метод привязан к конкретной таксономии. Если нужна своя классификация — придётся переписывать промпты классификации и адаптировать relation extraction.
⚠️ Shallow fine-tuning необходим для стабильности: Базовые модели (gpt-4o, gpt-4o-mini) без fine-tuning выдают нестабильный JSON, игнорируют schema, добавляют пояснения. Fine-tuning на 40-120 примерах фиксит это, но требует подготовки данных и API доступа к fine-tuning endpoint.
⚠️ F1-score 0.5-0.7 для non-empty segments: На сегментах, где действительно есть данные, модель ошибается в 30-50% случаев (путает классы, пропускает сущности). Для критичных задач нужна верификация человеком.
Как исследовали
Команда из Оксфорда хотела понять: могут ли LLM точно извлекать структурированную информацию из политик конфиденциальности для автоматического аудита сайтов. Они взяли датасет Policy-IE (31 политика с ручными аннотациями) и расширили его — наняли двух юристов, чтобы разметить ещё 10 политик с привязкой к стандартной онтологии DPV. Это дало 2049 размеченных сущностей: типы данных, цели использования, стороны, действия.
Затем протестировали разные LLM (gpt-4o, gpt-4o-mini, o1, o3-mini) в двух режимах: чистые модели vs shallow fine-tuning на 10-120 примерах. Измеряли F1-score для каждого из 7 шагов пайплайна. Ключевое наблюдение: для большинства задач fine-tuning давал прирост ~15-20% по F1, но иногда (Purpose Classification) базовая модель уже работала на 0.9, а fine-tuning не помог или даже ухудшил.
Почему так? Исследователи объясняют: детальные промпты с примерами schema уже достаточны для задач классификации (модель понимает таксономию), но для entity recognition (поиск в тексте) fine-tuning критичен — учит модель фокусироваться на релевантных text spans и не галлюцинировать. Вот почему Data Recognition показал F1-empty=0.95 (модель отлично понимает где данных НЕТ), но F1-non-empty=0.62 (когда данные есть, часто промахивается).
Удивительно: o1 и o3-mini (reasoning модели) оказались хуже, чем классические gpt-4o. Гипотеза: reasoning полезен для логических задач, но для pattern matching в тексте избыточен и даже мешает — модель "overthinks" вместо прямого извлечения паттернов.
Применили лучшие модели к топ-100 сайтам по Tranco. Получили граф из 11,800 data practices: 6,488 случаев first-party collection, 1,324 — third-party sharing. Самые частые данные: Contact (email/phone) и Identifying (имя, ID), самые частые цели: ServiceProvision и Advertising. Это показывает, что большинство сайтов собирают идентификаторы в первую очередь для работы сервиса и рекламы.
Практический инсайт для юзеров: политики конфиденциальности топ-сайтов показывают паттерн "собираем контакты + ID для сервиса + продаём для рекламы". Если видишь в политике "we collect your data for service improvement" без конкретики — скорее всего под этим скрывается передача третьим лицам для таргетинга.
Адаптации и экстраполяции
💡 Адаптация для анализа ToS (Terms of Service)
Тот же многошаговый каскад применим к пользовательским соглашениям. Меняем entity types:
ШАГ 1: Rights Recognition (найди права пользователя: возврат, отмена, удаление аккаунта)
ШАГ 2: Rights Classification (классифицируй по GDPR/CCPA категориям)
ШАГ 3: Obligations Recognition (найди обязательства платформы)
ШАГ 4: Restrictions Recognition (найди ограничения для юзера)
ШАГ 5: Liability Recognition (найди условия ответственности)
ШАГ 6: Relation Extraction (как права связаны с ограничениями)
Промпт для шага 1:
Найди в соглашении все упоминания прав пользователя.
Примеры прав:
- Право на возврат денег (refund policy)
- Право удалить аккаунт (account deletion)
- Право экспортировать данные (data portability)
- Право оспорить решение (dispute resolution)
Верни JSON список с текстами и позициями.
Текст: {сегмент_ToS}
🔧 Техника: Добавить шаг "Contradiction Detection" → находить противоречия
После Relation Extraction добавь финальный шаг:
SYSTEM:
Ты — аудитор политик. Найди противоречия между утверждениями.
Задача: Проверь не противоречат ли найденные data practices друг другу.
Примеры противоречий:
- "Мы не передаём данные третьим лицам" vs практика "третьи лица получают email для маркетинга"
- "Храним данные пока нужны для сервиса" vs "храним 10 лет после закрытия аккаунта"
- "Используем cookies только для работы сайта" vs "cookies для таргетированной рекламы"
Верни JSON:
{
"contradictions": [
{
"practice_1": "ID первой практики",
"practice_2": "ID второй практики",
"contradiction_type": "тип",
"explanation": "объяснение"
}
]
}
USER:
Все найденные практики: {json_всех_practices}
Это покажет где политика врёт или запуталась в формулировках.
💡 Экстраполяция: Комбинация с Dual Reflection для валидации
После каждого шага извлечения можно добавить контр-проверку вторым агентом:
Агент 1 (Extractor):
[выполняет Data Recognition как обычно]
Агент 2 (Validator):
"Проверь найденные data entities. Есть ли false positives (не-данные помечены как данные)? Есть ли пропущенные упоминания данных?"
Возвращает:
{
"false_positives": [...],
"missed_entities": [...],
"corrected_list": [...]
}
Финальный результат = corrected_list
Это повышает точность, но удваивает стоимость. Используй для критичных сегментов (например, разделы про data sharing).
Ресурсы
An LLM-enabled semantic-centric framework to consume privacy policies (2025)
- Датасет аннотаций: https://doi.org/10.5281/zenodo.15392162
- Pr²Graph для топ-100 сайтов: https://doi.org/10.5281/zenodo.15408913
- Код пайплайна: https://github.com/renyuneyun/pp-analyzer
Rui Zhao, Vladyslav Melnychuk, Jun Zhao, Jesse Wright, Nigel Shadbolt (University of Oxford)
