Чому вашому ШІ-агенту потрібен комплаєнс-шар
У лютому 2024 року я підключив ШІ-агента до пошти відділу бронювання одного клієнта. Демо пройшло чудово. Агент читав нові заявки, перевіряв календар, створював бронювання і надсилав підтвердження через SMS. За три тижні після запуску аудитор клієнта надіслав шість запитань про дані клієнтів. На п'ять я відповів. Шосте вимагало доказів: які записи агент відкривав, хто схвалив кожне вихідне повідомлення і коли видаляються листи з номерами телефонів. Чіткої відповіді я не мав. Запуск зупинився на три тижні, поки я перебудовував шар даних.
Аудит, який я одного разу провалив
Клієнт тримав сервісну компанію на шістдесят працівників і приймав близько чотирьохсот заявок на бронювання щотижня. Агент розбирав пошту чотирма інструментами: read_inbox, check_calendar, create_booking і send_sms. Я писав запити й сирі виводи інструментів в одну таблицю Postgres під назвою agent_logs у вигляді сирого тексту. Половина рядків лишилася без session id. Номери телефонів та адреси пошти лежали відкритим текстом. Команда зберігала все підряд для можливого навчання моделі.
Перед партнерською угодою прийшов зовнішній аудитор і поставив три запитання. Перше: перелічити кожен запис клієнта, який агент відкрив 12 березня. Друге: показати, хто схвалив сорок SMS, надісланих агентом за тиждень. Третє: назвати дату видалення листів з номерами телефонів.
Мої відповіді виглядали слабо. Читання за 12 березня я відновив за мітками часу, робота зайняла два дні. В SMS не було поля схвалення, агент надсилав їх за власним рішенням. Дати видалення не існувало, я її ніде не задав. Угода зсунулася на місяць. Наступні два тижні я скриптом видаляв дванадцять тисяч сирих листів і писав нотатку про зберігання на одну сторінку. Клієнт лишив мене в проєкті.
Аудитори просять записи. Наміри їх не переконують. Кожен агент тепер отримує невеликий комплаєнс-шар з першого дня, до дотику до клієнтських даних. У шарі три частини.
Шар із трьох частин: журнал викликів, строк зберігання, очищення PII
Журнал викликів інструментів
Кожен виклик інструмента потрапляє в таблицю Postgres під назвою agent_audit. Колонки: id uuid, created_at timestamptz, tenant_id text, session_id text, actor text, tool_name text, args_hash text, args_redacted jsonb, result_code text, policy_decision text, delete_after date. Я зберігаю SHA-256 хеш повних аргументів і відредаговану копію із заміною персональних даних мітками. Сирий текст клієнтів у таблицю не потрапляє. Навантаження несуть два індекси: за tenant_id з created_at і за session_id.
Actor приймає три значення: user, agent, approver. Кожне вихідне повідомлення вимагає рядка з actor approver або policy_decision auto_approved з номером правила. Інструмент надсилання відмовляється працювати без такого рядка. Коли аудитор питає, яких записів торкнувся агент, відповідає один запит: фільтр agent_audit за session_id і сортування за created_at.
Фіксований строк зберігання
Кожен рядок несе delete_after, значення за замовчуванням дорівнює created_at плюс тридцять днів. Задача pg_cron стартує щоночі о 03:00 і видаляє прострочені рядки. Конфіг клієнта скорочує вікно до семи днів для чутливих листів або подовжує бронювання до дев'яноста днів з письмовою поміткою власника даних. Значення за замовчуванням лишається тридцять днів. Видалення обліковується лічильниками за клієнтами: скільки рядків видалено, який найстаріший рядок лишився. На запитання аудиту про строки я показую рядок конфіга й лічильники за минулий місяць.
Конвеєр очищення PII
Два проходи йдуть до запису на диск. Перший прохід шукає регулярними виразами адреси пошти, номери телефонів, номери карток, IBAN і шаблони національних ID країн, де я працюю. Другий прохід проганяє текст через невелику мовну модель, яка мітить імена, адреси вулиць і дати народження у вільному тексті, включно з одруківками повз регулярки. Очищений текст іде в журнали й пам'ять агента. Оригінали йдуть у шифроване сховище з TTL сім днів за break-glass доступом, кожне читання пише власний рядок аудиту.
Перед кожним релізом я перевіряю конвеєр фіксованим набором із двохсот прикладів. Клас regex зобов'язаний показати нуль пропусків. Клас моделі зобов'язаний показати залоговану оцінку якості для порівняння з минулим релізом. Новий шаблон PII з продакшену стає новим тестом того самого дня.
Скільки коштує шар і скільки коштує витік
На новому агенті шар будується два-три робочі дні: пів дня на таблицю аудиту й індекси, пів дня на задачу видалення й конфіг, день на конвеєр очищення й набір із двохсот тестів, пів дня на механізм схвалення й контрольний запит. На наявному агенті з брудними журналами закладайте повний тиждень, включно з перенесенням старих даних і видаленням сирого архіву. Поточні витрати малі: одна таблиця, одна задача в cron і один виклик моделі на вхідне повідомлення, ціна в центах за тисячу повідомлень за поточними тарифами.
Порівняйте з рахунком, який заплатила сервісна фірма на сорок людей після інциденту слабшого за витік: близько $35,000 за юридичну перевірку, сповіщення клієнтів і три тижні переробок. Працівники тихо повернулися до ручного введення, довіра до інструмента впала. Шар коштує близько $2,500 часу розробки. Інцидент коштував у чотирнадцять разів дорожче, без урахування втраченої довіри.
Чек-лист, який можна скопіювати
Проганяйте список по поточному агенту цього тижня. Позначайте рядки або заводьте задачі.
- Створіть agent_audit з одинадцятьма колонками вище й обома індексами.
- Дайте кожній сесії стабільний session_id з першого повідомлення.
- Логуйте кожен виклик інструмента. Тихих викликів бути не повинно.
- Зберігайте args_hash і відредаговані аргументи. Сирий текст клієнтів у журнал не входить.
- Проставте delete_after у кожному рядку. Тримайте тридцять днів за замовчуванням.
- Плануйте нічну задачу видалення. Сигналізуйте про пропущений запуск.
- Додайте regex-прохід очищення з тестом із двохсот прикладів.
- Додайте модельний прохід для імен і адрес.
- Тримайте оригінали у сховищі з TTL сім днів за break-glass доступом.
- Дозволяйте вихідні надсилання лише за рядком схвалення.
- Тренуйтеся щомісяця: беріть випадкову сесію і відповідайте на три запитання аудиту швидше десяти хвилин.
- Ведіть нотатку про зберігання на одну сторінку: що зберігається, де лежить, скільки живе, хто схвалює зміни.
Я ганяю цю перевірку в перший понеділок кожного місяця. Вона займає двадцять хвилин. Вона врятувала б мій запуск лютого 2024 року.