Тестовые данные для AI-агентов должны сохранять сложность рабочей задачи и при этом не переносить в стенд лишние сведения из production. Простая замена имени клиента не решает проблему: идентифицирующие детали остаются в переписке, вложениях, ссылках, временных метках и связях между таблицами. Агент способен собрать их вместе в ответе или сохранить в своей истории.
Надёжный набор начинается с описания проверяемого поведения. Команде нужно знать, какие свойства данных вызывают ошибку, а не копировать всё окружение «для реалистичности». Ниже — практическая процедура выбора синтетики, маскирования и отдельных представлений, с проверкой полезности и риска раскрытия. Это инженерные рекомендации, а не юридическое заключение о статусе конкретного набора.
Сначала опишите задачу, которую должен решить агент
Возьмём агента, который ищет просроченные обращения и готовит черновик ответа. Для проверки нужны даты, статусы, ответственные, несколько языков и противоречивая история изменений. Настоящие имена клиентов, телефоны и тексты договоров обычно не нужны. Если начать с этих требований, набор получится меньше и понятнее копии всей базы.
Для каждого сценария запишите вход, ожидаемое действие и проверяемый результат. Например, обращение без срока должно попасть в отдельную группу, закрытое — исключиться из отчёта, а чужой проект — оставаться недоступным. Такие свойства можно воспроизвести искусственно и проверить точным сравнением идентификаторов.
Отдельно нужны случаи, где агенту следует отказаться от вывода. Неполная выборка, неизвестная дата и недоступное вложение не должны превращаться в уверенное заключение. Если тестовый набор содержит только аккуратные заполненные карточки, система научится проходить демонстрацию, но не реальную работу с неоднозначными данными.
Составьте карту минимально необходимых полей. Рядом укажите, какое свойство каждого поля влияет на сценарий: длина строки, уникальность, наличие часового пояса, принадлежность организации. Это помогает обосновать преобразование. Вместо расплывчатого требования «сохранить реализм» появляется список конкретных ограничений, который можно проверить после генерации.
Выберите между синтетикой, маскированием и отдельной проекцией
Синтетический набор создаётся по правилам сценария без копирования исходных записей. Он хорошо подходит для регрессионных тестов и воспроизводимых пограничных случаев. Его слабое место — неполная модель реального разнообразия. Поэтому генератор должен развиваться вместе с найденными дефектами, а не оставаться десятком идеальных объектов.
Статическое маскирование изменяет отдельную копию данных перед передачей на стенд. Динамическое преобразует выдачу для определённого пользователя или роли. Выборка через отдельные представления ограничивает поля и может менять форму модели. PostgreSQL Anonymizer документирует несколько таких способов, каждый со своими условиями применения. Документация PostgreSQL Anonymizer.
Для агента особенно важно, какой путь остаётся за пределами маски. Если тестовая роль видит безопасное представление, но инструмент позволяет произвольный SQL к исходной таблице, ограничение легко обойти. Доступ нужно выдавать только к предусмотренной проекции, а лишние инструменты и учётные записи исключать из конфигурации.
Комбинированный подход часто удобнее одного универсального. Основной набор синтетический, отдельные структурные характеристики берутся из безопасных агрегатов, а редкий дефект воспроизводится вручную созданным примером. Любой перенос содержимого из production требует отдельного решения о допустимости, месте обработки и проверке результата. Само слово «тестовый» не делает копию безопасной.
Псевдонимизация не доказывает невозможность восстановления
Если каждому клиенту присвоить стабильный заменитель, связи сохранятся. Но стабильность позволяет сопоставлять записи между наборами, а оставшиеся признаки могут раскрыть исходный объект. Поэтому замена прямого идентификатора не является доказательством полной анонимности. Для технического тестирования это полезный инструмент, но его границы нужно понимать.
Обычный хэш адреса или телефона тоже не решает задачу автоматически. Пространство возможных значений может быть предсказуемым, и злоумышленник способен сравнивать заранее вычисленные варианты. Если требуется стабильное соответствие, выбирают контролируемый механизм и защищают ключ или таблицу соответствий. При этом связь с исходным набором всё равно остаётся отдельным активом.
Документация PostgreSQL Anonymizer описывает разные стратегии подстановки, обобщения, шума и хэширования. Они сохраняют разные свойства и имеют разные ограничения. Например, случайный шум при многократной выдаче не следует считать универсальной защитой исходного числового значения. Стратегии маскирования.
Для набора агента полезно задать вопрос: можно ли по сочетанию должности, даты встречи, суммы и текста определить конкретного человека или клиента? Ответ зависит от доступной дополнительной информации. Поэтому проверка охватывает сочетания полей, а не только регулярные выражения для email. Для юридической оценки обезличивания нужен отдельный анализ применимых требований и контекста обработки.
Сохраняйте связи и бизнес-ограничения
Агент может правильно читать каждую строку и всё равно ошибаться на связях. Например, заказ ссылается на клиента другой организации или документ указывает на отсутствующий проект. Часть таких случаев нужна как негативные примеры, но случайное разрушение всех связей делает набор непригодным для проверки нормального сценария.
Определите, какие идентификаторы должны меняться совместно. Если заменяется клиент, одинаковое отображение применяется в заказах, обращениях и платежных записях внутри выбранного набора. Для разных окружений соответствие обычно разделяют, чтобы не создавать бессрочный универсальный ключ сопоставления.
Сохраняйте ограничения, которые влияют на код: уникальность, обязательность, допустимые статусы, валюты, длину и формат строк. Если каждое имя заменить одним словом, можно случайно нарушить уникальный индекс или, наоборот, скрыть ошибку длинного значения. Для проверки интерфейса нужны и короткие, и длинные строки, а для фильтра — пустые и необычные значения.
Отдельно проверьте агрегаты. Если сценарий сравнивает сумму строк с итогом документа, независимая случайная замена чисел разрушит инвариант. Лучше сгенерировать строки и вычислить итог либо согласованно преобразовать связанные значения. Список сохраняемых инвариантов должен быть частью версии набора, чтобы после изменения маски команда понимала, какие проверки остаются осмысленными.
Пример минимальной синтетической схемы
Для проверки поиска обращений можно создать небольшую самостоятельную схему. Следующий SQL показывает идею и использует только вымышленные значения; его не следует запускать против production. Реальные права и миграции стенда настраиваются отдельно.
CREATE TABLE demo_tickets (
organization_id text NOT NULL,
id text PRIMARY KEY,
subject text NOT NULL,
status text NOT NULL,
due_at timestamptz
);
INSERT INTO demo_tickets VALUES
('demo-a', 'case-01', 'Проверить учебный отчёт', 'open',
'2026-10-20T10:00:00Z'),
('demo-a', 'case-02', 'Нет срока исполнения', 'open', NULL),
('demo-b', 'case-03', 'Обращение другой организации', 'open',
'2026-10-19T10:00:00Z');
Этот набор проверяет просрочку, отсутствие срока и изоляцию организаций. Ожидаемый результат зависит от зафиксированного тестового времени. Если использовать текущие часы без контроля, тест изменит поведение через несколько дней и перестанет быть воспроизводимым. Время передают как явную зависимость или фиксируют относительно параметра запуска.
Сам SQL не обеспечивает изоляцию организаций: её должен реализовать тестируемый слой доступа, роль или политика базы. Наличие organization_id лишь даёт данные для проверки. Именно поэтому полезно иметь строку другой организации с похожими полями — она обнаружит фильтр, который случайно забыли применить.
После базового набора добавьте одинаковые даты, несколько страниц, удалённую связанную запись и конфликт версий. Каждый новый объект должен объяснять конкретный сценарий. Тогда набор остаётся читаемым, а ошибка теста указывает на определённое поведение, а не на случайную комбинацию тысяч сгенерированных строк.
Тексты и вложения требуют отдельного преобразования
В свободном тексте сведения часто скрываются вне очевидных полей. Описание обращения может цитировать письмо, содержать адрес в подписи, номер договора и внутреннюю ссылку. Табличное маскирование контактов не меняет эти копии. Для агента именно текст нередко становится основным источником контекста.
Поэтому для большинства регрессионных сценариев лучше писать вымышленные тексты, сохраняющие нужную структуру. Например, длинная переписка с противоречивыми сроками проверяется искусственным диалогом. Уникальные формулировки настоящего клиента обычно не нужны для воспроизведения логической ошибки и могут служить идентифицирующим признаком.
Вложения анализируются отдельно: метаданные документов, скрытые листы, комментарии, история правок, изображения и OCR. Замена видимого имени файла не очищает содержимое. Если сценарий посвящён извлечению данных из PDF, создайте учебный PDF с вымышленными таблицами и намеренными особенностями вёрстки. Так команда контролирует ожидаемый ответ и источник каждого значения.
URL тоже не должны вести к живым объектам. Используйте тестовые домены и заглушки, которые не запускают внешние запросы и не открывают реальные документы. Не сохраняйте подписанные ссылки production в учебном наборе: они могут продолжать действовать после копирования. Политика вложений должна включать и источник файла, и место его сохранения после обработки агентом.
Стенд не должен выполнять реальные внешние действия
Даже полностью синтетические строки могут содержать адрес, на который тест отправит письмо, или webhook, который запустит настоящий процесс. Поэтому подготовка данных связана с изоляцией интеграций. Тестовый агент получает отдельные подключения, а внешние отправки направляются в контролируемые приёмники.
Проверьте почту, платежи, уведомления, календари и загрузку файлов. Для каждого канала задайте разрешённый адрес назначения либо тестовый адаптер. Одной переменной ENV=test недостаточно, если worker использует сохранённую конфигурацию организации или секрет из общего хранилища.
Синтетический набор также не должен включать действующие токены, cookies и пароли. Их исключают до передачи на стенд, а не надеются скрыть в интерфейсе. Для проверки обработки секретов используйте специально созданные нерабочие маркеры и убедитесь, что они не попадают в ответы и журналы.
Если нужно испытать реальный API, выделите отдельный тестовый аккаунт и ограниченные объекты. Подтвердите допустимые действия до запуска агента и проверяйте последствия после. Такое испытание дополняет локальный набор, но не отменяет его воспроизводимость. Подробно границы окружений разобраны в материале про dev, stage и production для агентов.
Подготовьте воспроизводимый конвейер набора
У набора должны быть версия схемы, версия генератора, исходные параметры и перечень ожидаемых свойств. Если используется случайность, фиксируйте seed для повторяемого запуска. При этом seed не должен быть производным от реальных персональных данных. Цель — воспроизводимость теста, а не скрытый способ восстановить production.
Для маскируемой копии задайте место преобразования внутри разрешённого контура. Не выгружайте сначала исходную базу на рабочую станцию, чтобы потом решить, как её очистить. Временные файлы, логи и промежуточные дампы требуют такой же политики доступа, как исходные сведения.
Связанные таблицы получают из согласованного состояния. Документация PostgreSQL объясняет, как различается видимость данных на уровнях изоляции; отдельные последовательные чтения не всегда дают единую картину. Для экспорта выбирают поддерживаемый способ согласованного снимка и проверяют ссылки после преобразования. Изоляция PostgreSQL.
После сборки выполняются две независимые группы проверок: полезность для сценариев и отсутствие запрещённого содержимого. Проход только одной группы недостаточен. Безопасный, но бессмысленный набор не проверяет продукт; полезная, но раскрывающая копия создаёт другой дефект. Результат конвейера содержит оба статуса и причины, по которым передача набора разрешена или остановлена.
Проверяйте отсутствие исходных данных и пригодность
Проверку утечек начните с полей: нет настоящих адресов, действующих секретов, исходных идентификаторов и внутренних URL, запрещённых для стенда. Затем переходите к свободному тексту и вложениям. Регулярные выражения помогают найти типовые шаблоны, но не доказывают отсутствие любой чувствительной информации.
Полезна контрольная приманка в специально подготовленном учебном источнике. Уникальный маркер помещают в поле, которое должно удаляться, затем проверяют его отсутствие во всём выходном наборе, истории запуска и артефактах. Это проверяет конкретный путь очистки. Для реального production-массива нельзя объявить универсальную безопасность только потому, что один маркер исчез.
Пригодность проверяют через инварианты и ожидаемые ответы. Все допустимые ссылки разрешаются, суммы сходятся, присутствуют нужные классы ошибок, а изоляция скрывает чужую организацию. Набор не должен состоять только из положительных случаев; отсутствие данных и отказ доступа также имеют ожидаемые результаты.
Проверки обязаны замечать пустой выход. Если генератор упал и создал ноль записей, сообщение «чувствительных данных не найдено» ещё не означает успешной подготовки. Сначала подтверждается наличие ожидаемого набора и контрольных сценариев, затем оценивается очищение. Неизвестный результат сканирования отмечается отдельно и не превращается в разрешение на передачу.
Сквозной пример: проверка агента перед подключением CRM
Команда хочет испытать агента, который готовит сводку по сделкам без следующего действия. Сначала выбираются проверяемые свойства: разные статусы, несколько ответственных, просроченная дата, отсутствие даты и закрытая сделка. Для доступа нужны две организации и пользователи с различающейся видимостью внутри одной из них.
Затем создаётся синтетическая CRM с вымышленными компаниями и текстами. Локальные идентификаторы в разных организациях намеренно совпадают, чтобы обнаружить ошибку изоляции. В одном комментарии находится недоверенная инструкция о выгрузке контактов. Ожидаемое поведение агента — анализировать комментарий как данные и не расширять задачу.
Часть сделок распределяется на несколько страниц. Последняя содержит единственную запись без следующего действия. Это проверяет, что агент не ограничился первой страницей и не объявил отсутствие проблем преждевременно. Отдельный сценарий обрывает продолжение и требует результата «проверка неполная» вместо уверенной сводки.
Для записи используется черновик в тестовой системе. Отправка уведомлений выключена на уровне адаптера, а не только текстовой инструкции. После генерации кода или ответа проверяются изменённые объекты и журналы. При повторном запуске система не должна создавать второй одинаковый черновик для той же версии сделки.
После прохождения сценариев команда подключает ограниченный реальный тестовый аккаунт, если это необходимо для проверки формата API. Production-данные не становятся обязательной ступенью. Реальная интеграция проверяет совместимость транспорта и прав, а синтетический набор остаётся источником точных ожидаемых результатов и повторяемых регрессий.
Отдельные представления подходят не для каждого сценария
Маскирующее представление удобно, когда тесту нужен ограниченный набор полей и другая форма выдачи. Документация PostgreSQL Anonymizer показывает подход с отдельными views и выдачей доступа к ним. Важно, чтобы тестовый пользователь не сохранял параллельный доступ к исходным таблицам. Masking Views.
Проверьте также функции, служебные схемы и экспорт. Инструмент, который умеет выполнять произвольные административные запросы, может выходить за рамки предусмотренной проекции. Поэтому тестовая роль должна иметь ровно те возможности, которые нужны сценарию, а не широкие права ради удобства настройки.
Для проверок записи отдельное представление иногда не сохраняет требуемую семантику приложения. Тогда лучше независимая синтетическая база со своей схемой и ограничениями. Нельзя считать, что успешное чтение замаскированного view доказывает корректность создания документов, транзакций и конфликтов версий.
Выбор фиксируют в паспорте набора: какие сценарии он подтверждает и какие остаются за пределами. Например, безопасная проекция годится для поиска и группировки, но не для испытания производительности всей базы. Честно ограниченный набор полезнее универсального стенда, на котором разные команды делают несовместимые выводы.
Где Codenik помогает удержать границы доступа
Codenik выступает как управляемый слой доступа между агентом и инструментами корпоративных систем. Для тестирования важно, чтобы тестовые подключения, права и секреты были отделены от рабочих. Агент должен получать предусмотренные данные и действия, а аудит — показывать, какой контекст использовался.
Это не означает автоматического обезличивания любого источника. Генерацию синтетики, преобразование вложений и проверку исходных значений нужно организовать отдельно либо подтвердить наличие соответствующего механизма в конкретной интеграции. На пилоте проверяйте реальный путь выдачи, включая историю агента, файлы и журналы.
Свяжите программу с классификацией данных, тестированием агентов и DLP для агентов. Классификация определяет ограничения, набор воспроизводит поведение, а контроль выдачи помогает заметить нарушение. Ни один из этих механизмов не заменяет остальные.
Практический старт — один бизнес-сценарий, небольшой синтетический набор и проверяемые ответы. Добавляйте сложность по найденным дефектам: большие тексты, страницы, конфликт версий, чужая организация. Если новая запись не проверяет конкретное поведение, стоит уточнить её назначение до увеличения объёма базы.
Для сопровождения назначьте владельца набора и дату пересмотра. Изменение схемы приложения может добавить новое чувствительное поле, которое старый конвейер не преобразует. Поэтому неизвестные поля не должны автоматически попадать в экспорт. Сначала обновляют карту данных, затем правила преобразования и проверки. Это особенно важно для JSON-полей, где новые атрибуты появляются без отдельной миграции таблицы.
Артефакты неудачных тестов также входят в охват: скриншоты, трассы, ответы инструментов и сохранённые диалоги. Если набор передаётся между командами, вместе с ним передают паспорт и ограничения использования. Получатель должен понимать, какие свойства сохранены и какие выводы по этим данным делать нельзя. Так повторное использование не превращает ограниченный учебный пример в неофициальную копию корпоративной информации.
Частые вопросы о тестовых данных для AI-агентов
Можно ли дать агенту копию production после замены имён? Одной замены недостаточно для оценки безопасности. Сведения могут оставаться в текстах, связях и вложениях. Сначала определите необходимые свойства сценария, затем выберите преобразование и проверьте результат по всему пути данных.
Всегда ли синтетика лучше? Она удобна для воспроизводимых тестов и исключает прямое копирование исходных записей, но может не отражать важное разнообразие. Её полезность подтверждают сценариями и постепенно дополняют по реальным классам дефектов, воспроизводя их вымышленными примерами.
Нужно ли сохранять настоящие идентификаторы? Обычно достаточно согласованных искусственных идентификаторов. Если сценарий требует сопоставления с источником, таблица соответствий становится отдельным чувствительным объектом и не передаётся агенту по умолчанию. Причину такого сопоставления нужно обосновать.
Как доказать, что набор полезен? Назвать ожидаемые ответы и инварианты до запуска. Проверить, что агент находит нужный объект, соблюдает доступ, замечает неполноту и не выполняет лишнее действие. Просто успешный ответ модели не подтверждает качество данных.
Что сделать в первую очередь? Выберите один отчёт, перечислите поля, от которых зависит решение, и создайте несколько связанных вымышленных объектов с негативными случаями. Проверьте отсутствие реальных секретов и внешних адресатов, затем выполните сценарий через тот же слой доступа, который будет использоваться в рабочем процессе.
Источники
Материал проверен 22 октября 2026 года. Примеры архитектуры и процедуры — авторские рекомендации.