Суть
Наблюдаемость агента упирается в вопрос словаря. Можно писать трейсы вручную, придумывая свои поля, — тогда каждый инструмент визуализации придётся учить их читать. OpenInference задаёт общие семантические конвенции: как называется атрибут с промптом, как — с ответом, как считать токены, какого типа бывают спаны.
Выигрыш в том, что это надстройка над OpenTelemetry, а не отдельный мир. Один протокол собирает и классический APM (латентность, коды ответов, инфраструктура), и специфичную для ИИ телеметрию.
Как работает
Вызов агента представляется деревом спанов:
Trace (Root)
└── LLM Span
├── Tool Span
└── Retriever Span
Тип спана хранится в openinference.span.kind — по нему отличают обращение к модели от вызова инструмента и от поиска в индексе. Ключевые атрибуты: input.value, output.value, llm.token_count.prompt.
Это атрибуты OpenInference, а не OTel GenAI
И в исходном материале, и в первой версии этой заметки они были подписаны как конвенция OTel GenAI. Это неверно: input.value, output.value, llm.token_count.prompt и ключ openinference.span.kind принадлежат словарю OpenInference. У официального OTel-стандарта префикс другой — gen_ai.*.
Словарей в 2026 году сосуществует три: gen_ai.* (официальный OTel), openinference.* (Arize) и traceloop.*. Ни один не вытеснил остальные — и LangSmith, и Langfuse маппят все три. Официальный OTel GenAI в мае 2026 вынесен в отдельный репозиторий semantic-conventions-genai, но всё ещё в статусе Development.
Подключение автоматическое: библиотека сама перехватывает вызовы клиента модели, руками спаны расставлять не нужно.
from opentelemetry import trace
from openinference.instrumentation.openai import OpenAIInstrumentor
# Автоматический перехват вызовов по спецификации OTLP
OpenAIInstrumentor().instrument()
tracer = trace.get_tracer(__name__)
Что это даёт на практике
Типизация спанов превращает часть отладки в запрос к телеметрии, а не в чтение логов:
- Рост числа спанов с
openinference.span.kind == TOOLвнутри одного трейса — сигнатура зацикливания: агент долбит один и тот же инструмент без условия выхода. - Retriever-спан с пустым результатом, за которым идёт уверенный ответ модели, — сигнатура голодания RAG, то есть генерации на выдуманном основании.
- Токены на конкретном спане позволяют считать себестоимость не всего запроса целиком, а отдельного шага.
Отдельно подчёркнута связка трёх практик: семантический трейсинг, версионирование промптов и семантический кэш. Когда промпт хранится и версионируется на стороне системы трейсов, его нельзя вытащить из кода — потому что в коде его нет.
Из инструментов, которые понимают эту телеметрию: Arize Phoenix (эталонная реализация от авторов спецификации), LangSmith, Langfuse.
Два практических следствия
Про полноту поддержки у платформ. Вопрос «кто полнее поддерживает конвенции» на 2026 год потерял остроту: Langfuse, LangSmith и Phoenix говорят на OpenTelemetry, поэтому инструментировать код можно один раз и менять платформу потом (LangGraph Observability). Различие сместилось с полноты приёма трейсов на то, что платформа умеет поверх них — оценки, датасеты, self-hosting.
Про персональные данные в трейсах. Полагаться на политику хранения нельзя: трейс уходит в чужой сервис в момент отправки, и политика описывает, что там будет потом, а не то, что туда попало. Маскирование делается до отправки, тем же слоем, который чистит вход и выход модели (DLP for LLM, PII Anonymization) — иначе получается вторая, никем не охраняемая копия тех же данных, ради которой строился весь DLP-контур.
Связано с
- W3C Trace Context — как трейс переживает границы сервисов; OpenInference отвечает за содержимое спанов
- Agent Observability — общий разбор, зачем агенту трейсинг шагов
- LangSmith vs Langfuse — инструменты-приёмники этой телеметрии
- Agent Failure Modes — режимы отказа, которые ловятся именно по типам спанов
- Agent CostControl — атрибуция стоимости строится на токенах из спанов