Гайд · TNWS AI
Как заменить tracing processors через set_trace_processors
Полностью заменяем глобальный список processors через set_trace_processors и проверяем, что события получает только заданный приёмник.
Конкретная задача и применимость
Здесь настраивается перенаправить tracing исключительно во внутренний backend с помощью точного интерфейса set_trace_processors([processor]). Это материал для Python-сервиса на OpenAI Agents SDK, где одного факта «tracing включён» недостаточно: нужна наблюдаемая и проверяемая семантика. Общая трассировка включена SDK по умолчанию, но конкретная операция из этого гайда меняет корреляцию, состав данных или способ экспорта.
Документация проверена 12 сентября 2026 года. Фактическая основа — официальное руководство по tracing и официальный API reference. set_trace_processors заменяет весь текущий список; данные перестают уходить стандартному OpenAI backend, если соответствующий processor не добавлен явно. Цены, квоты и номера версий не приводятся: для этой операции они не нужны, а версия библиотеки должна фиксироваться lock-файлом проекта.
Результат, который будем доказывать
Готовность определяется не отсутствием исключения. Нужен проверяемый признак: конкретное поле trace, событие processor, отсутствие секретного маркера или завершённый экспорт. Сначала запускайте пример на staging-проекте. В metadata не помещайте prompt, email, телефон, токены и ответы tools. Для корреляции используйте внутренний непрямой ID.
До изменения сохраните контрольную trace со стандартной конфигурацией и запишите её структуру: trace_id, имена spans, parent_id и число событий. Это baseline. После изменения сравнивайте именно ожидаемую разницу. Если одновременно обновить SDK, exporter и конфигурацию, причину изменения определить будет трудно.
Пошаговая настройка
- Создайте виртуальное окружение, установите
openai-agentsи зафиксируйте разрешённую версию в lock-файле. - Настройте ключи через переменные окружения или secret manager. Не вставляйте рабочий ключ в код, trace metadata и тестовый отчёт.
- Скопируйте пример ниже в отдельный интеграционный тест. Имена workflow и атрибуты замените на значения вашей предметной области.
- Выполните один контрольный запуск и сохраните только технические идентификаторы. Текст сообщения нужен лишь локальному assert и не должен попадать в общий лог.
- Проверьте позитивный критерий из раздела примера. Для processor считайте callbacks; для редактирования сериализуйте событие в тестовый sink; для flush проверяйте порядок закрытия контекста.
- Выполните негативный сценарий. Он должен отличать ошибочную конфигурацию от временной задержки backend.
- Запустите два параллельных trace. Их trace_id должны различаться, parent_id не должны пересекать workflows, а общий group_id допускается только если это один диалог.
- Добавьте cleanup: flush для критичного короткого job, shutdown для собственного processor и очистку тестовых данных по политике проекта.
Готовый пример
from agents import set_trace_processors, trace
from agents.tracing import TracingProcessor
class Sink(TracingProcessor):
def __init__(self): self.ended=[]
def on_trace_start(self,t): pass
def on_trace_end(self,t): self.ended.append(t.trace_id)
def on_span_start(self,s): pass
def on_span_end(self,s): pass
def shutdown(self): pass
def force_flush(self): pass
sink=Sink(); set_trace_processors([sink])
with trace("internal_only") as tr:
expected=tr.trace_id
assert sink.ended==[expected]
print(sink.ended)
В примере нет универсального «попробуйте посмотреть dashboard»: состояние проверяется программно. Для реального exporter дополните тест контролируемым sink, потому что появление записи в веб-интерфейсе может быть отложено фоновой пакетной отправкой. Не делайте сетевой запрос внутри синхронного callback processor — складывайте событие в очередь.
Реалистичный вход и ожидаемый результат
Вход: Одна trace internal_only и список только с локальным Sink.
Ожидаемый результат: Sink получает trace_id при завершении; глобальный набор processors полностью заменён.
Зафиксируйте expected как автоматический критерий. Если сравнивается trace_id, проверяйте формат и уникальность, но не жёстко заданное случайное значение. Если сравнивается набор spans, используйте тип и имя, а не время выполнения: длительность зависит от среды и сети. Если проверяется отсутствие данных, ищите уникальные маркеры во всём сериализованном событии, включая error и metadata.
Негативный тест
Передайте пустой список в тестовой среде и убедитесь, что локальный sink не получает событий. Это демонстрирует destructive-семантику set, которую нельзя путать с add.
Негативный тест важен, потому что tracing не должен ломать основной ответ агента. Сбой дополнительного exporter следует журналировать технически и обрабатывать внутри processor. При этом тест конфигурации обязан падать, если ожидаемая защита данных отключена или события отправляются не в тот проект. Разделяйте доступность observability и корректность бизнес-операции.
Производственная интеграция
Инициализируйте глобальные processors один раз при старте процесса. Повторная регистрация после каждого HTTP-запроса создаёт дубликаты. Конфигурацию отдельного run передавайте через RunConfig, когда поведение действительно относится только к нему. Глобальные set-функции меняют процесс целиком и требуют явного владельца в bootstrap-коде.
Собирайте минимальные metadata: environment, тип workflow, версия схемы, непрямой tenant ID. Полный пользовательский ввод остаётся в бизнес-системе с её правилами доступа. Для расследования связывайте записи по trace_id и внутреннему request_id, а не копируйте содержимое запроса во все системы.
Callback собственного processor должен быть потокобезопасным и быстрым. Правильная архитектура — bounded queue, фоновый exporter, счётчик отброшенных событий и ограниченное время shutdown. Не выдумывайте метрику успешности: считайте доставленные, повторённые и отброшенные записи отдельно. Ошибка очереди не должна зависать внутри Runner.
Шаблон проверки для pull request
Сценарий tracing: set_trace_processors([processor])
Workflow: <стабильное имя>
Trace/group/request ID: <непрямые ID без PII>
Ожидаемые spans/callbacks: <точный список>
Проверяемое изменение относительно baseline: <одно изменение>
Маркер чувствительных данных: <тестовая строка>
Есть ли маркер в экспортированном событии: <да/нет по политике>
Поведение при недоступном exporter: <ожидаемая ошибка/очередь>
Порядок flush/shutdown: <описание>
Повторная инициализация не дублирует processor: <проверено>
Ссылка на trace в staging: <внутренняя ссылка>
Этот шаблон можно копировать без изменения структуры. Он заставляет указать одно проверяемое изменение, границы данных и поведение отказа.
Чек-лист финальной проверки
- Название workflow стабильно и понятно команде.
- trace_id генерируется корректным helper или самим SDK.
- group_id используется только для связанных запусков.
- Metadata не содержат PII, prompt, tool output и секреты.
- Позитивный критерий проверен кодом.
- Негативный сценарий даёт ожидаемое отличие.
- Глобальная конфигурация применяется один раз при старте.
- Callback processor не выполняет долгий сетевой I/O.
- Для короткой задачи определена политика flush.
- Повторный запуск не создаёт дубликаты событий.
- Отказ tracing не подменяет результат агента.
- Источники повторно проверены 12 сентября 2026 года.
FAQ
Tracing включён автоматически?
Да, SDK включает его по умолчанию и создаёт spans для Runner, агента, генерации, tools, guardrails и handoffs. Но конкретные поля, sensitive data и processors всё равно требуют явной политики приложения.
Почему trace может появиться не сразу?
Стандартный BatchTraceProcessor отправляет данные фоновыми пачками. Если требуется гарантия сразу после job, завершите контекст trace и вызовите flush_traces. Для обычного долгоживущего процесса фоновая задержка допустима.
Можно ли использовать персональные данные как group_id?
Технически поле принимает строку, но так делать не следует. Используйте непрямой ID диалога, который раскрывается до пользователя только в вашей системе с контролем доступа.
Что произойдёт при set_trace_processors?
Текущий список processors будет заменён. Стандартный экспорт в OpenAI исчезнет, если вы явно не сохранили processor, который его выполняет. Для добавочного приёмника используйте add_trace_processor.
Доступен ли tracing при Zero Data Retention?
Официальное руководство указывает, что tracing недоступен организациям, использующим API OpenAI по политике ZDR. Не обещайте доступность, пока это не подтверждено настройками вашей организации.
Читайте также
Как добавить второй tracing processor через add_trace_processor
Подключаем дополнительный счётчик событий через add_trace_processor, не отключая стандартный экспорт трасс OpenAI.
Как измерить свой этап через custom_span в OpenAI Agents SDK
Оборачиваем поиск заказа в custom_span, записываем структурированные безопасные данные и проверяем вложенность внутри общей trace.
Как немедленно отправить трассы через flush_traces в Agents SDK
Гарантируем экспорт буферизованных трасс после фоновой задачи вызовом flush_traces в finally и проверяем правильный порядок.
Комментарии
Пока тихо. Скажите первое слово