Перейти к содержимому

Модуль XVII — песочница для симуляции и тестирования агентов

Модуль XVII — это песочница для тестирования: она прогоняет сценарий агента в изолированной эфемерной среде, детерминированно воспроизводит историческую сессию и сравнивает два варианта перед деплоем. Это собрат модуля XII (evals) — XVII выполняет в изоляции и производит выводы, XII измеряет их качество — и эти двое развязаны: ни один не импортирует другого. Эта страница — справочник по тому, что песочница делает сегодня, и по её честным ограничениям.

Песочница каталогизирует написанные оператором сценарии: последовательность входов по шагам плюс замоканные ответы инструментов и ресурсов, к которым прогону позволено обращаться. Сценарий — это синтетический фикстура — без секретов, без продакшн-хендлов — зажатый перед сохранением. На нём выполняются три потока:

  • Симуляция сценария — выполнить шаги сценария против его моков, производя пошаговые выводы (опционально оценённые против набора evals).
  • Воспроизведение (Replay) — реконструировать временную шкалу входов исторической сессии и заново прогнать её детерминированно против моков, так что тот же вход даёт тот же выход.
  • Сравнение до/после деплоя — прогнать тот же сценарий против базового и кандидатного варианта, оценить оба и записать вердикт (improved / regressed / unchanged / inconclusive) с дельтой.

Модуль владеет четырьмя сущностями: изменяемым scenario, изменяемым run (running → терминальный), пошаговым output в режиме только добавление и сравнением до/после деплоя comparison в режиме только добавление. Каждый прогон записывает, какой раннер его выполнил, был ли этот раннер isolated, было ли эфемерное состояние destroyed, пошаговые счётчики и — если был подключён скорер — набор, оценку и вердикт прохождения.

Изоляция — это свойство протокольного контракта, аттестованное на каждый прогон, а не заявление. Стандартный внутрипроцессный раннер изолирован по построению: он получает только спецификацию шагов-и-моков и не держит хендла ни к хранилищу, ни к сети, ни к какому секрету; шаг, запрашивающий ресурс, отсутствующий в моках, выдаёт детерминированный маркер промаха мока и никогда не достигает реального ресурса; состояние живёт в вызове и отбрасывается при возврате, поэтому прогон записывает destroyed. При обеспечении оператором за тем же интерфейсом стоит рантайм уровня ОС — эфемерный, упрочнённый инстанс с контролируемым egress, чей бэкенд (gVisor или микроВМ Firecracker) выбирается политикой и проходит гейт предполётной проверки. Каждый прогон записывает реальный бэкенд и его флаг isolated, так что деградировавший или переносимый бэкенд виден и аудируем, а не скрыт.

Песочница не излучает на шину событий; она производит сохранённые доказательства, которые другие модули читают без связывания с ней. Её выводы оцениваются модулем XII через адаптер, подключённый только в корне композиции — два собрата делят тонкий контракт порта, а не импорт. Её сравнение до/после деплоя — это доказательство для решения, которое модуль деплоя читает, чтобы гейтить продвижение, и оно питает базис регрессии, отслеживаемый XII. Запуск прогона, воспроизведения или сравнения — это привилегированное, тенантно-ограниченное, аудируемое действие (editor и выше для запуска; сравнение деплоя — это административное решение).

CLI может записать сгенерированные входы прямо в формат шагов для создания сценария:

Окно терминала
olivares sandbox generate --count 2 --seed-file seed.txt -o json > steps.json
olivares sandbox scenarios create --name generated --steps-file steps.json

--seed-file - читает шаблон из stdin. Опустите флаг, чтобы использовать шаблон по умолчанию. Переводы строк в файле сохраняются; используйте только синтетический текст.

POST /v1/m/sandbox/synthetic-data требует того же разрешения, что и создание сценария. Он возвращает samples, каждый с key и input, готовые к использованию как steps сценария. Сама генерация не сохраняет входы; её событие аудита содержит только число образцов. Используйте синтетический текст, а не секреты или данные продакшена.

{"subject_kind":"agent","count":2,"seed":"{{subject_kind}}:user{{index}}@example.test"}

Два входа — agent:user1@example.test и agent:user2@example.test. Единственные подстановки — {{index}} (начиная с 1) и {{subject_kind}}; остальной текст буквальный. Это локальная генерация фикстур, а не язык, сгенерированный моделью, или статистическая симуляция. Значения по умолчанию: субъект agent, число 10, шаблон {{subject_kind}}-sample-{{index}}. Число ограничено 100, субъект — 200 байтами, а шаблон и каждый сгенерированный вход — 8192 байтами. Слишком большие запросы отклоняются без возврата частичного набора образцов. Закодированный пакет также должен укладываться в лимит API сценариев 1 МиБ на запрос, включая экранирование JSON и место для ограниченных имени, описания и субъекта. Дополнительные моки и форматирование тоже учитываются в этом лимите.

Включите выбираемый модуль командой olivares modules on sandbox. Генерация, создание и выполнение сценария требуют editor или administrator; viewer может просматривать сохранённые сценарии, прогоны и выводы.

Создайте шаблон без завершающего перевода строки:

Окно терминала
printf '%s' '{{subject_kind}}:user{{index}}@example.test' > seed.txt

Сохраните этот синтетический ответ в mocks.json:

[{"resource":"agent:user1@example.test","response":"first synthetic account"}]
Окно терминала
olivares sandbox generate --count 2 --seed-file seed.txt -o json > steps.json
olivares sandbox scenarios create --name generated --steps-file steps.json --mocks-file mocks.json -o json
olivares sandbox scenarios run <scenario-id> --variant candidate -o json
olivares sandbox runs get <run-id> -o json
olivares sandbox runs outputs <run-id> -o json

Используйте ID сценария, возвращённый при создании, затем ID прогона, возвращённый при выполнении. Со стандартным раннером inproc-mock первый вход разрешается в ответ выше; второй возвращает [[mock-miss:agent:user2@example.test]]. Промах мока увеличивает steps_error, но является ожидаемым синтетическим результатом: прогон всё равно записывает status: completed, steps_total: 2, steps_ok: 1, steps_error: 1, isolated: true и destroyed: true. Запрос к реальному ресурсу не выполняется. Этот пример не запрашивает оценивание и не подтверждает рантайм уровня ОС. Сопоставление использует точный текст входа, включая переводы строк в файле шаблона.

Сценарии, прогоны и выводы остаются доступными после перезапуска движка. Выключение модуля закрывает доступ к его маршрутам без удаления сохранённых данных; повторное включение восстанавливает доступ. Эти записи ограничены тенантом: другая организация не может их читать.