Гайд · TNWS AI
Как зафиксировать срабатывание guardrail через guardrail_span
Создаём guardrail_span с полем triggered, проверяем разрешённый и заблокированный ввод и не сохраняем сам чувствительный текст.
Задача и область применения
Практическая задача — отличать выполненную проверку от фактического срабатывания ограничения. Для неё используется точный интерфейс guardrail_span(name, triggered). Ручной span нужен, когда операция выполняется вне стандартной обвязки Runner или когда требуется отдельный типизированный участок внутри общей трассы. Если SDK уже автоматически создаёт нужный span, второй такой же вручную добавлять нельзя: получите дубликаты и неверную картину длительности.
Факты проверены 12 сентября 2026 года по официальному руководству OpenAI Agents SDK по tracing и официальному API reference tracing. guardrail_span принимает имя guardrail и булево поле triggered, которое показывает факт срабатывания. Здесь нет цен, тарифов или неподтверждённых лимитов: они не влияют на контракт helper. Версию пакета фиксируйте lock-файлом и перепроверяйте сигнатуру при обновлении.
Что должно получиться
Результат — завершённый span с ожидаемым типом и полями, вложенный в корректную trace. Проверка должна читать span_data или события тестового processor, а не полагаться только на внешний dashboard. Идентификаторы генерируются SDK; жёстко заданные span_id нужны только при интеграции с системой, которая уже выдала корректный ID.
Перед началом создайте staging-проект и безопасные тестовые данные. Не используйте реальный prompt, аудиозапись клиента, токен, email или ответ внутренней системы. Поля input/output некоторых spans специально способны хранить содержимое операции, поэтому политика чувствительных данных важнее удобства отладки.
Пошаговые действия
- Установите пакет
openai-agentsв отдельное окружение и зафиксируйте версию в lock-файле. - Создайте общую trace через context manager. Он гарантирует правильные start и finish даже при исключении.
- Внутри trace откройте нужный helper span также через
with. Передайте только поля, подтверждённые API reference. - Выполните целевую операцию. Не подменяйте её искусственной задержкой в production; тестовый stub допустим только в воспроизводимом примере.
- Проверьте span_data и бизнес-результат assert-ами. Проверка одного span_id недостаточна: она доказывает создание объекта, но не корректность данных.
- Запустите негативный сценарий из отдельного раздела. Ошибка операции должна быть отличима от пустого успешного результата.
- Подключите тестовый TracingProcessor, если нужно проверить полный экспорт. Его callbacks должны быть быстрыми и потокобезопасными.
- Перед релизом выполните два параллельных workflow и подтвердите, что trace_id и parent_id не смешиваются.
Готовый код
from agents import guardrail_span, trace
def blocked(text): return "TEST-CARD" in text
for text in ["обычный запрос","номер TEST-CARD"]:
hit=blocked(text)
with trace("input_validation"):
with guardrail_span("payment_data",triggered=hit) as span:
assert span.span_data.triggered is hit
print("blocked="+str(hit))
Пример можно копировать в unit или integration test. Если он содержит заглушку ответа, замените её реальным объектом только после того, как минимальный контракт пройдёт локально. Не печатайте весь export span в общем CI-логе: там могут быть input/output. Для проверки извлекайте только разрешённые поля.
Реалистичный вход и ожидаемый результат
Вход: Два ввода: обычная строка и строка с тестовым маркером TEST-CARD.
Ожидаемый результат: Первая trace содержит triggered=false, вторая — triggered=true; полный ввод в span не записывается.
Для автоматической проверки сравнивайте тип span, поле span_data, trace_id, parent_id и факт завершения. Время выполнения нельзя сравнивать с придуманным нормативом: сеть и среда различаются. Если нужны SLO, сформируйте их по собственной статистике, а не по примеру из статьи.
Негативный тест
Проверьте пустую строку и исключение внутри валидатора. Исключение проверки нельзя автоматически считать безопасным triggered=false.
Смысл негативного теста — доказать границу ответственности helper. Tracing описывает случившееся, но не валидирует бизнес-маршрут, существование tool, корректность usage и безопасность данных автоматически. Эти инварианты обеспечивает приложение до передачи значений в span.
Как встроить в production
Создайте небольшой слой observability с функциями предметной области: record_order_lookup, record_route, record_audio_stage. Внутри они вызывают официальный helper и фильтруют разрешённые поля. Тогда разработчик не сможет случайно положить полный объект пользователя в data. Список разрешённых ключей храните рядом с политикой логирования.
Не создавайте второй ручной span поверх автоматического одноимённого span Runner. Сначала посмотрите baseline trace. Ручная инструментализация оправдана для собственного adapter, запроса к базе, внешней очереди или нестандартного этапа. Имена spans должны быть стабильными: динамический order_id в имени раздувает кардинальность; его место — в безопасных metadata или внутренней корреляции.
При исключении используйте context manager и set_error там, где нужна дополнительная классификация. После фиксации ошибки не проглатывайте исключение без явной бизнес-логики. Для чувствительных generation, function и audio spans используйте настройки исключения чувствительных данных; ручное маскирование одной строки не защищает соседние поля.
Копируемый шаблон для ревью
Тип span: guardrail_span(name, triggered)
Почему автоматического span недостаточно: <причина>
Родительская trace/span: <имя>
Разрешённые поля span_data: <список>
Тестовый вход: <без PII и секретов>
Ожидаемые поля: <точные значения>
Негативный сценарий: <ошибка или пустой результат>
Поведение исключения: <повторно выбрасывается/обработано>
Маркер чувствительных данных отсутствует в export: <да>
Параллельный тест parent_id: <пройден>
Ссылка на официальный API reference: https://openai.github.io/openai-agents-python/ref/tracing/
Шаблон отделяет телеметрию от бизнес-операции и делает ревью проверяемым.
Чек-лист финальной проверки
- Helper и его параметры сверены с документацией 12 сентября 2026 года.
- Span открыт внутри ожидаемой trace или parent span.
- Context manager гарантирует завершение при исключении.
- span_data содержит только разрешённые поля.
- В input/output нет ключей, токенов и реальных PII.
- Позитивный результат проверяется assert.
- Негативный тест отличает ошибку от пустого успеха.
- Не создаётся дубликат автоматического Runner span.
- Имена spans не содержат динамические идентификаторы.
- Параллельные traces не смешивают parent_id.
- Ошибка tracing не ломает основной workflow.
- Версия зависимости зафиксирована в lock-файле.
FAQ
Нужно ли вручную вызывать start и finish?
Нет, если helper используется через context manager with. При ручном управлении оба вызова обязательны; context manager проще и надёжнее закрывает span при исключении.
Когда передавать parent явно?
Когда span создаётся вне текущего context или нужно привязать его к конкретному trace/span. В обычном вложенном коде helper использует текущий контекст автоматически.
Можно ли записывать полный input и output?
Технически некоторые helpers это поддерживают, но решение принимает политика данных. В production лучше сохранять минимальные технические поля и отключать чувствительное содержимое там, где оно не требуется.
Почему dashboard недостаточен для теста?
Пакетный exporter может доставить события с задержкой, а визуальная проверка не подходит CI. Подключите тестовый processor и проверяйте экспортированную структуру программно.
Доступен ли tracing для ZDR-организаций?
Официальное руководство сообщает, что tracing недоступен организациям с политикой Zero Data Retention для API OpenAI. Уточните политику своего проекта до внедрения.
Читайте также
Как отследить передачу управления через handoff_span Agents SDK
Записываем ручной handoff между Router и Delivery через handoff_span и проверяем from_agent, to_agent и вложенность.
Как сохранить response_id через response_span OpenAI Agents SDK
Используем response_span для корреляции OpenAI Response без дублирования полного input/output из generation span.
Как создать generation_span для собственного model adapter
Добавляем generation_span в собственный model adapter: input, output, model_config и usage с проверяемыми значениями.
Комментарии
Пока тихо. Скажите первое слово