Перейти к содержанию
Публикация AiManual

Обсервабельность AI-агентов: как отслеживать вызовы LLM, работу с файлами и инструментами

Как настроить observability для AI-агентов: какие данные собирать, почему Opik и trajectory tab не всегда подходят, и как собрать локальный стек на Seq, Jaeger,

Коротко

Что будет в материале

  1. 01

    Зачем нужна обсервабельность AI-агентов

  2. 02

    Какие данные нужно собирать для observability AI-агентов

  3. 03

    Почему существующие инструменты не всегда подходят

  4. 04

    Собираем локальный observability-стек: Seq, Jaeger, Grafana

Зачем нужна обсервабельность AI-агентов

AI-агент выполняет цепочку действий: получает задачу, формирует промпт для LLM, вызывает инструменты, читает и записывает файлы, возможно, делегирует часть работы субагентам. Каждый шаг может пойти не так: модель вернёт неверный JSON, инструмент упадёт с ошибкой, файл окажется недоступен. Традиционный мониторинг показывает только общие метрики: загрузку CPU, потребление памяти, статус процесса. Он не отвечает на вопрос, почему агент выдал неправильный ответ или застрял в цикле повторных попыток.

Обсервабельность для агентов означает сбор детальных данных о каждом внутреннем действии: какие промпты отправлялись в LLM, какие ответы получены, какие инструменты вызваны с какими аргументами, какие файлы затронуты. Эти данные позволяют воспроизвести проблему, найти узкое место и понять, как улучшить агента. Без них отладка превращается в гадание по логам уровня INFO, где нет нужного контекста.

Разница с классическим мониторингом принципиальная. Мониторинг отвечает на вопрос «система работает?», обсервабельность - на вопрос «почему система ведёт себя так?». Для агентных систем второй вопрос критичен, потому что поведение определяется не только кодом, но и качеством промптов, доступностью внешних сервисов, корректностью данных.

Какие данные нужно собирать для observability AI-агентов

Чтобы диагностировать ошибки и улучшать агента, нужно фиксировать пять категорий данных: вызовы LLM, вызовы инструментов, работу с файлами, действия субагентов и метаданные сессии. Рассмотрим каждую.

Вызовы LLM: промпты, ответы, токены и latency

Для каждого обращения к языковой модели сохраняйте полный промпт, включая системные сообщения и историю диалога. Это позволит воспроизвести запрос и понять, почему модель дала тот или иной ответ. Фиксируйте ответ модели, используемую модель, параметры вызова (температура, max_tokens), задержку (latency) и количество токенов во входе и выходе. Если используется платный API, добавляйте стоимость вызова. Для локальных моделей стоимость неактуальна, но latency и потребление ресурсов важны для оптимизации.

Пример структуры лога вызова LLM:

{
  "event": "llm_call",
  "session_id": "sess_123",
  "model": "gpt-4o",
  "prompt": "...",
  "response": "...",
  "temperature": 0.7,
  "max_tokens": 1024,
  "latency_ms": 850,
  "input_tokens": 1200,
  "output_tokens": 300,
  "cost_usd": 0.012,
  "timestamp": "2026-09-08T10:15:30Z"
}

Вызовы инструментов и работа с файлами

Инструменты - частый источник ошибок: неверные аргументы, таймауты, неожиданные ответы. Для каждого вызова инструмента логируйте имя, переданные аргументы, возвращённый результат или ошибку, время выполнения. Для файловых операций фиксируйте путь, тип операции (чтение, запись, удаление), размер файла, хэш содержимого (если файл не слишком большой). Это помогает выяснить, почему агент не смог прочитать файл или передал неверные данные в инструмент.

Пример лога вызова инструмента:

{
  "event": "tool_call",
  "session_id": "sess_123",
  "tool_name": "web_search",
  "arguments": {"query": "observability AI agents"},
  "result": "...",
  "error": null,
  "latency_ms": 1200,
  "timestamp": "2026-09-08T10:16:05Z"
}

Действия субагентов и контекст их вызовов

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

Метаданные сессии: идентификатор сессии, идентификатор пользователя, версия агента, временные метки начала и окончания. Эти поля нужны для фильтрации и агрегации при анализе.

Почему существующие инструменты не всегда подходят

Готовые решения для LLM observability, такие как Opik, покрывают базовые сценарии, но часто не дотягивают до специфики агентов. Встроенные просмотрщики траекторий, например trajectory tab в dsh, удобны для отладки одной сессии, но не масштабируются для продакшена.

Ограничения Opik для агентных систем

Opik ориентирован на LLM-приложения: он хорошо логирует вызовы моделей, но агенты добавляют слой инструментов и файлов. Возможности кастомной инструментации ограничены: сложно добавить свои метрики, теги, события. Для небольших проектов Opik может быть избыточен, а для сложных агентных систем - недостаточно гибок. Например, если нужно логировать каждый вызов кастомного инструмента с детальными аргументами, Opik потребует обходных путей.

Trajectory tab в dsh: удобно, но не масштабируется

Trajectory tab показывает последовательность шагов агента в удобном виде, но это ручной просмотр. Нет возможности агрегировать данные по сотням сессий, строить графики, настраивать алерты. Для продакшена нужно централизованное хранилище с поиском и аналитикой. Trajectory tab подходит для разовой отладки, но не для постоянного мониторинга.

Собираем локальный observability-стек: Seq, Jaeger, Grafana

Практичное решение - собрать стек из open-source инструментов: Seq для логов, Jaeger для распределённых трейсов, Grafana для метрик и дашбордов. Все три компонента запускаются в Docker-контейнерах и легко интегрируются с агентом.

Настройка Seq для сбора структурированных логов

Seq принимает логи в формате JSON через HTTP или специализированные клиенты. Логируйте каждый вызов LLM, инструмента, файловую операцию как отдельное событие с полями. Затем в Seq легко искать по полям, строить запросы, создавать алерты. Например, можно найти все сессии, где вызов инструмента завершился ошибкой, или все вызовы LLM с latency больше 2 секунд.

Для отправки логов из Python можно использовать библиотеку seqlog или просто HTTP-запросы. Пример отправки лога:

import requests
import json

log_entry = {
    "event": "llm_call",
    "session_id": "sess_123",
    "model": "gpt-4o",
    "prompt": "...",
    "response": "...",
    "latency_ms": 850
}
requests.post("http://localhost:5341/api/events/raw", data=json.dumps(log_entry), headers={"Content-Type": "application/json"})

Трассировка с Jaeger: визуализация цепочек вызовов

Jaeger реализует стандарт OpenTelemetry. Каждый шаг агента (вызов LLM, инструмента) - это span с тегами. Родительский span - сессия агента. Jaeger показывает дерево вызовов с таймингами, что позволяет находить узкие места и ошибки. Например, видно, что субагент потратил 3 секунды на вызов LLM, и это замедлило всю сессию.

Для инструментации агента используйте OpenTelemetry SDK. Пример создания span в Python:

from opentelemetry import trace
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

resource = Resource(attributes={"service.name": "my-agent"})
trace.set_tracer_provider(TracerProvider(resource=resource))
jaeger_exporter = JaegerExporter(agent_host_name="localhost", agent_port=6831)
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(jaeger_exporter))
tracer = trace.get_tracer(__name__)

with tracer.start_as_current_span("llm_call") as span:
    span.set_attribute("model", "gpt-4o")
    # выполнение вызова LLM
    span.set_attribute("latency_ms", 850)

Метрики и дашборды в Grafana

Метрики экспортируйте в Prometheus, а Grafana используйте для создания дашбордов: количество запросов, доля ошибок, среднее время ответа LLM, распределение по инструментам. Это даёт общую картину здоровья системы. Пример метрик: счётчик вызовов LLM, гистограмма latency, счётчик ошибок инструментов.

Для экспорта метрик из Python используйте библиотеку prometheus_client. Пример:

from prometheus_client import Counter, Histogram, start_http_server

llm_calls = Counter('llm_calls_total', 'Total LLM calls')
llm_latency = Histogram('llm_latency_seconds', 'LLM call latency')

@llm_latency.time()
def call_llm(prompt):
    llm_calls.inc()
    # вызов LLM
    return response

start_http_server(8000)  # метрики доступны на :8000/metrics

Все три инструмента можно связать: Seq хранит детальные логи, Jaeger - трассировки, Grafana - агрегированные метрики. При анализе инцидента сначала смотрите дашборд, затем спускаетесь к трассировке, а детали ищете в логах.

Альтернативы: OTEL-совместимые сервисы и веб-интерфейсы

Если локальный стек не подходит, рассмотрите другие варианты.

OTEL-совместимые облачные сервисы

OTEL (OpenTelemetry) - стандарт для сбора телеметрии. Существуют облачные сервисы, совместимые с OTEL: Grafana Cloud, Honeycomb, Datadog. Они принимают данные от агентов, предоставляют мощные аналитические возможности, алерты, интеграции. Плюсы: быстрый старт, нет необходимости поддерживать инфраструктуру. Минусы: стоимость, зависимость от внешнего сервиса, возможные проблемы с конфиденциальностью данных. Подходит для команд, которые не хотят администрировать свой стек.

Самописный веб-интерфейс со списком сессий

Для полного контроля можно создать простой веб-интерфейс, который показывает список сессий агента, а при клике - детальную трассировку (логи, вызовы). Это требует разработки, но позволяет реализовать именно те функции, которые нужны: анализ паттернов, сравнение сессий, экспорт данных. Такой подход оправдан, если у вас специфические требования, которые не покрываются готовыми решениями.

Критичный функционал: кастомная инструментация и анализ паттернов

При выборе или создании observability-решения для агентов обратите внимание на две ключевые возможности.

Кастомная инструментация: добавляем свои метрики и события

Агенты могут иметь специфические метрики: количество вызовов определённого инструмента, частота ошибок при работе с файлами, распределение latency по типам запросов. Возможность добавлять их без изменения ядра системы - важное требование. Например, вы хотите отслеживать, как часто агент вызывает инструмент web_search и сколько раз этот вызов завершается ошибкой. В Seq вы можете логировать событие с полем tool_name и затем строить запросы. В Jaeger можно добавить тег к span. В Prometheus - создать отдельный счётчик.

Анализ паттернов: выявляем повторяющиеся ошибки

Повторяющиеся последовательности действий, которые приводят к ошибкам, - ценный сигнал. Например, если агент часто вызывает неверный инструмент после определённого ответа LLM, это паттерн. Его можно выявить, агрегируя трассировки. Инструмент должен позволять искать похожие последовательности и визуализировать их. В Seq можно использовать корреляцию событий по session_id и искать частые комбинации. В Jaeger можно анализировать деревья вызовов. Для более сложного анализа может потребоваться собственный скрипт, который обрабатывает данные из Seq или Jaeger.

Как использовать observability для улучшения агента

Собранные данные - это основа для непрерывного улучшения агента. На основе анализа можно:

  • Улучшать промпты: видеть, где модель ошибается, и корректировать инструкции.
  • Корректировать логику инструментов: если инструмент часто вызывается с неверными параметрами, добавить валидацию или изменить описание для LLM.
  • Обновлять документацию: если агент неправильно интерпретирует документацию, сделать её более явной.
  • Оптимизировать хуки: если хуки выполняют лишние действия, упростить их.

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

Подробнее о построении агентов и их архитектуре читайте в статье «Строим своего AI-агента: полный разбор архитектуры и практические советы». О визуализации оркестрации агентов рассказывает обзор GraphArc. Если интересует проблема роста числа инструментов, обратите внимание на кейс monday.com.

Подписаться на канал