LLM observability — это практика сбора трейсов, метрик и оценок качества для production-приложений на LLM: каждый запрос пишется как дерево span'ов (промпт, вызов модели, retrieval, tool call, ответ) с привязанной стоимостью, латентностью и скором качества. В 2026 году рынок сошёлся на трёх лидерах с разной философией. LangSmith ориентирован на команды с LangChain/LangGraph. Langfuse подходит для self-hosted и framework-agnostic стеков. Arize Phoenix заточен под OpenTelemetry-native инфраструктуру и enterprise RAG. Я веду продакшен на Langfuse уже полтора года, и ниже расскажу, что реально работает на p99=2400ms и спайках в 40 RPS.
LLM observability отличается от классического APM тем, что трейс включает промпт, retrieval-контекст, tool calls и автоматическую оценку качества (LLM-as-Judge), а не только латентность и коды ошибок.
Все три платформы поддерживают OpenTelemetry GenAI semantic conventions, но Langfuse и Arize Phoenix полностью OTel-native, а LangSmith лучше всего работает через нативный langsmith SDK с LangGraph.
Langfuse в январе 2026 куплен ClickHouse. Кодовая база MIT-лицензии активно поддерживается, миграция self-hosted развёртываний не требуется.
Для прод-приложения 1–10M трейсов/мес self-hosted Langfuse на одной node ClickHouse + Postgres стоит примерно $120 в месяц инфры. LangSmith Cloud Plus на тот же объём обойдётся около $1500.
Минимум, который нужно мерить: token cost per request, p95/p99 латентность first-token и full-response, retrieval recall@k, hallucination rate по LLM-as-Judge.
Sampling по умолчанию ставьте 100%. Снижать стоит только после того, как платите за хранение больше, чем за inference.
Что такое LLM observability и чем отличается от мониторинга
LLM monitoring отвечает на вопрос «что произошло»: вырос ли p99 латентности, скакнула ли стоимость, упал ли скор safety после релиза новой версии промпта. LLM observability отвечает на вопрос «почему». Она даёт полный трейс конкретного плохого ответа: исходный пользовательский запрос, версия промпт-шаблона, retrieved-чанки с дистанциями, вызовы tools с аргументами и результатами, финальная генерация, скор LLM-as-Judge и аннотация ревьюера. Без второго первое бесполезно. Алерт «hallucination rate +12%» без возможности открыть конкретный трейс заставляет команду делать post-mortem на пустом месте.
Классический APM (Datadog, New Relic, CloudWatch) меряет HTTP-латентность и коды ошибок, но не различает семантически правильный и семантически неправильный ответ. Trace 200 OK с галлюцинированным юридическим советом считается успехом для Datadog и катастрофой для бизнеса. Именно этот разрыв закрывают LLM-native платформы. Большинство команд в 2026 году пускают трейсы в LLM-платформу (Langfuse, LangSmith или Phoenix) и параллельно льют OTel-метрики в существующий APM для инфраструктурного слоя.
Архитектурно трейс это дерево span'ов в формате OpenTelemetry. Корневой span отвечает за обработку запроса. Дочерние делятся на retrieval (с под-span'ами на каждый источник), generation (с моделью, температурой, токенами в/из), tool calls и evaluations. Стоимость считается на уровне generation-span по справочнику цен модели, латентность считается по start/end timestamps, а качество выставляется асинхронным LLM-as-Judge, который читает span и пишет score обратно. О том, как LLM-as-Judge устроен внутри, я подробно разбирала в руководстве по оценке LLM.
Сравнение Langfuse, LangSmith и Arize Phoenix
Ниже таблица по тем измерениям, по которым реально принимают решение продакшен-команды. Я намеренно не включаю «количество интеграций»: у всех трёх их больше двадцати, и разница не критична.
Параметр
Langfuse
LangSmith
Arize Phoenix
Лицензия
MIT (OSS) + Cloud
Проприетарная, Cloud
Elastic License 2.0 (OSS) + SaaS
Self-hosted
Да, prod-ready
Только Enterprise (от $25k/год)
Да, prod-ready
Backend хранилища
ClickHouse + Postgres + Redis + S3
Managed Cloud
PostgreSQL или OTel collector
OpenTelemetry
Нативно, OTLP-эндпоинт
Адаптер, не primary path
OpenInference (расширение OTel)
LangChain/LangGraph трейсинг
Через callback, без графа
Нативный граф с replay
Через OpenInference
Prompt management
Версионирование + A/B
Версионирование + Hub
Базовое, через датасеты
LLM-as-Judge
Встроенный, на трейсах
Встроенный + offline
Phoenix evals, широкий каталог
Стартовая цена SaaS
Free 50k обзерваций/мес, Pro $59
Free 5k трейсов, Plus $39/seat
Free на Phoenix Cloud
Лучший use case
Self-hosted, framework-agnostic
LangGraph-агенты
Enterprise RAG, OTel-стандарт
Langfuse: self-hosted на ClickHouse
Langfuse это open-source платформа на стеке ClickHouse (трейсы и аналитика), PostgreSQL (метаданные, prompt-versions), Redis (очередь evals) и S3-совместимое хранилище (большие промпты и ответы). У меня в проде она крутит примерно 3M трейсов/мес на одной t3.large и managed ClickHouse Cloud за $87, плюс RDS Postgres за $30. Альтернативно можно поднять docker-compose со всеми компонентами на одной машине, для до 500k трейсов в месяц этого хватает.
Минимальная интеграция с OpenAI SDK выглядит так. Декоратор @observe() создаёт span автоматически. Вложенные вызовы LLM ловятся через monkey-patched клиент:
from langfuse import Langfuse, observe
from langfuse.openai import openai # обёртка автоматически логирует span
langfuse = Langfuse(
public_key="pk-lf-...",
secret_key="sk-lf-...",
host="https://langfuse.example.com", # ваш self-hosted
)
@observe()
def answer_question(question: str, user_id: str) -> str:
# Тег user_id попадает в span, потом по нему фильтрация в UI
langfuse.update_current_trace(user_id=user_id, tags=["prod", "faq"])
response = openai.chat.completions.create(
model="claude-opus-4-8", # через LiteLLM proxy
messages=[
{"role": "system", "content": "Ты support-ассистент."},
{"role": "user", "content": question},
],
temperature=0.2,
metadata={"prompt_version": "v17"},
)
return response.choices[0].message.content
Главная киллер-фича Langfuse это prompt management с версионированием. Промпт хранится в Langfuse, а в коде вы тянете его по имени:
Теперь в UI вы видите, на какой версии промпта какой средний скор LLM-as-Judge и какая стоимость. A/B-сплит делается лейблами: label="production" для 80% трафика, label="canary" для 20%, в коде роутер по user_id hash. Я делала отдельный разбор RAG-пайплайнов. Там показано, как этот же приём работает для версионирования retrieval-конфига.
LangSmith: трейсинг LangGraph-агентов
LangSmith это коммерческий продукт от команды LangChain. Сильная сторона одна и очень конкретная. Если ваш стек построен на LangGraph, трейс отображается как полноценный граф состояний с node-by-node diff'ами, рёбрами условных переходов и возможностью replay против другой модели. Ни Langfuse, ни Phoenix этого не дают (там трейс остаётся линейным деревом span'ов).
Минимальная настройка занимает две переменные окружения, и весь LangChain/LangGraph код начинает писать трейсы:
import os
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "lsv2_..."
os.environ["LANGSMITH_PROJECT"] = "support-agent-prod"
from langgraph.graph import StateGraph
from langchain_anthropic import ChatAnthropic
# Никаких декораторов: LangSmith ловит всё через LangChain callbacks
model = ChatAnthropic(model="claude-opus-4-8")
graph = StateGraph(AgentState)
# ... обычный LangGraph код ...
compiled = graph.compile()
result = compiled.invoke({"messages": [HumanMessage("вопрос")]})
Для не-LangChain кода есть декоратор @traceable, но опыт ощутимо менее полированный, чем нативный flow. Если вы пишете на vanilla OpenAI SDK или ваш агент это самописный цикл на FastAPI, выбор LangSmith даёт мало. Теряется главное преимущество (графы), а ценник остаётся.
Главная боль LangSmith это pricing. Plus-тариф стоит $39 за seat плюс $0.50 за 1k трейсов сверх 10k включённых. На реальной нагрузке 3M трейсов/мес это $1495 в месяц только за хранение, и self-host доступен лишь в Enterprise-плане от $25k/год. Для стартапов и средних команд экономика быстро ломается. Я ровно на этом считала бюджет в прошлом проекте, и цифры не сошлись.
Arize Phoenix: OpenTelemetry и OpenInference
Phoenix это open-source проект от Arize (которые делали ML-observability ещё до LLM-эры). Архитектурное отличие в том, что вместо собственного SDK Phoenix принимает OpenInference: расширение OpenTelemetry GenAI-spec с дополнительными атрибутами для retrieval, tool calls и embeddings. Это значит, что трейсы можно одновременно лить в Phoenix и в любой OTel-совместимый бэкенд (Jaeger, Tempo, Honeycomb), без двойной инструментации.
from openinference.instrumentation.openai import OpenAIInstrumentor
from openinference.instrumentation.langchain import LangChainInstrumentor
from phoenix.otel import register
tracer_provider = register(
project_name="rag-prod",
endpoint="https://phoenix.example.com/v1/traces", # OTLP
)
OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)
LangChainInstrumentor().instrument(tracer_provider=tracer_provider)
# Дальше любой код, использующий OpenAI SDK или LangChain.
# Каждый вызов LLM, embedding, retrieval автоматически становится span'ом.
Phoenix силён на enterprise-RAG: каталог встроенных оценок (faithfulness, answer relevance, retrieval precision/recall) больше, чем у Langfuse, и они откалиброваны в ML-стиле, с baseline-датасетами и confidence interval'ами. Подробности есть в официальной документации Phoenix Evals. Если у вас retrieval-pipeline с десятками источников и команда серьёзно занимается eval, Phoenix даёт меньше «магии», но больше контроля.
Минус: UI ощутимо менее полированный, чем у Langfuse и LangSmith, и prompt management по сути отсутствует (есть датасеты, но не версионирование шаблонов). На практике многие команды ставят Phoenix как trace-store, а prompt-versioning делают отдельно, например в Langfuse или в собственной таблице.
OpenTelemetry GenAI semantic conventions
В 2025–2026 годах OpenTelemetry SIG зафиксировал semantic conventions для GenAI. Это стандарт имён атрибутов span'ов: gen_ai.system, gen_ai.request.model, gen_ai.usage.input_tokens, gen_ai.usage.output_tokens, gen_ai.response.finish_reasons и так далее. На практике это означает, что если ваша инструментация пишет правильные атрибуты, трейс читается любым OTel-совместимым бэкендом без адаптеров.
Это даёт две вещи. Во-первых, можно переехать с Phoenix на Langfuse (или наоборот) без переписывания инструментации, поменяв только OTLP endpoint. Во-вторых, можно одной инструментацией кормить и LLM-observability (Langfuse), и инфра-APM (Datadog или Tempo). Datadog 2026 версии уже понимает gen_ai.* атрибуты и показывает токены и стоимость рядом с обычными метриками.
OpenInference от Arize это надмножество GenAI-конвенций с доп-атрибутами для RAG (retrieval.documents.N.content, embedding.embeddings.N.vector) и agent loops. Если выбираете путь «инструментация раз, бэкенд любой», смотрите OpenInference: всё стандартное OTel поведение он сохраняет.
Какие метрики реально нужны в продакшене
После полутора лет в проде у меня есть базовая «семёрка», без которой алерты бесполезны. Делю на три группы.
Латентность и доступность
p50 / p95 / p99 first-token-latency. Критично для streaming UI. Если p99 first-token больше 3s, пользователь думает, что приложение зависло.
p95 full-response latency. Нужно для не-streaming endpoint'ов и для расчёта таймаутов upstream.
Provider error rate по моделям. 429, 529, 5xx считаются отдельно от логических ошибок. Это сигнал к переключению fallback-модели.
Стоимость
Cost per request, p50/p95. Считается отдельно по моделям и по тенантам. Тяжёлый хвост по cost обычно означает retrieval, который тянет слишком много контекста.
Daily burn по моделям. Алерт на «выросло на 30% к скользящей неделе» спасал меня от утечки контекста (баг, который добавлял старые сообщения в каждый запрос) трижды.
Качество
LLM-as-Judge faithfulness. Метрика для RAG. Скор считается по выборке (sampling 5–10% трейсов, не 100%, потому что Judge тоже стоит денег).
Negative user feedback rate. Это thumbs-down кнопка в UI, привязанная к trace_id. Самый честный сигнал реального качества, всё остальное служит proxy.
Как выбрать платформу под свой стек
Три правила, по которым я бы фильтровала в 2026:
Если стек это LangGraph и бюджет не ограничен: LangSmith. Граф агента с replay экономит десятки часов отладки.
Если нужен self-host (data residency, GDPR, on-prem) или важна цена при росте трафика: Langfuse. Связка ClickHouse + Postgres держит миллионы трейсов на скромной инфре.
Если у вас уже OTel-инструментация и стек на не-LangChain (LlamaIndex, DSPy, Haystack, vanilla SDK): Arize Phoenix или Langfuse через OTLP. Phoenix даёт больше eval-каталог, Langfuse выигрывает по UI и prompt management.
Гибридный паттерн, который я вижу в проде у нескольких команд: Phoenix или Langfuse как primary trace store, плюс Datadog как infra APM с фильтрованным набором GenAI-метрик (только token usage и latency, без полных промптов). Это даёт оба слоя без двойной оплаты за хранение полных трейсов.
Если вы строите мульти-агентную систему, observability-нагрузка кратно выше: один запрос превращается в 10–50 LLM-вызовов. Подробнее о том, как трейсить такие графы, смотрите в руководстве по мульти-агентным AI-системам.
Частые ошибки при внедрении LLM observability
Список того, на чём я и команды вокруг спотыкались в первый год.
Sampling включают слишком рано. «Будем писать 10%, как в APM». Для LLM это плохо: редкие галлюцинации именно в выкинутых 90% и сидят. Начинайте с 100%, опускайте только когда стоимость хранения превышает 5% от inference-bill.
Не пишут user_id и session_id в трейс. Без них вы не сможете найти «все трейсы пользователя, который пожаловался», а это первый запрос support-команды каждый день.
Один проект на весь стек. Раздельные Langfuse-проекты для prod, staging и eval-runs обязательны, иначе аналитика отравлена eval-прогонами.
LLM-as-Judge на 100% трейсов. Дорого и шумно. Sampling 5–10% плюс триггер «если negative feedback от пользователя, обязательно прогон» работает лучше.
Игнорирование async-flush. Если в FastAPI handler возвращаете ответ до langfuse.flush(), в трейсе могут отсутствовать дочерние span'ы. Используйте background task с flush или middleware.
Часто задаваемые вопросы
Чем отличается LLM monitoring от LLM observability?
Monitoring отвечает «что произошло», давая агрегаты по латентности, стоимости, error rate. Observability отвечает «почему», давая конкретный трейс с промптом, retrieval-контекстом и tool calls для каждого плохого ответа. Без второго первое бесполезно для отладки.
Можно ли self-host LangSmith?
Только в Enterprise-плане от примерно $25 000 в год. Для всех остальных тарифов LangSmith доступен только в Cloud (managed SaaS). Если self-host критичен, выбирайте Langfuse (MIT) или Arize Phoenix (Elastic License 2.0).
Что такое OpenInference и чем оно отличается от OpenTelemetry?
OpenInference это надмножество OpenTelemetry GenAI semantic conventions от Arize, с дополнительными атрибутами для RAG (retrieved documents, embeddings) и agent loops. Полностью совместимо с OTel: span'ы читаются Jaeger, Tempo и Datadog, плюс Phoenix умеет дополнительную семантику.
Сколько стоит Langfuse в продакшене?
Self-hosted Langfuse это стоимость инфры: ClickHouse Cloud (~$87/мес для 3M трейсов), RDS Postgres (~$30/мес), S3 (~$5/мес). Cloud-тариф Pro начинается от $59/мес с 100k обзерваций. Free-тариф даёт 50k обзерваций/мес для small-проектов.
Нужен ли LLM observability, если уже стоит Datadog?
Да. Datadog 2026 версии умеет читать gen_ai.* атрибуты OTel, но не имеет prompt management, A/B-сплита по версиям промптов, встроенного LLM-as-Judge и UI для аннотации трейсов. Большинство команд держит Datadog для инфра-слоя и LLM-платформу для генеративного слоя.
Какой sampling rate выбрать для production?
Стартуйте со 100% трейсов и 5–10% LLM-as-Judge. Снижайте sampling трейсов только если стоимость хранения превышает примерно 5% от inference-bill. Для большинства команд до 50M трейсов/мес это никогда не наступит.
Практическое руководство по prompt caching в OpenAI, Anthropic и Gemini на 2026 год: цены, TTL, cache_control breakpoints, совместимость с tool use и мониторинг hit rate с примерами на Python.
Как получить гарантированно валидный JSON от LLM в 2026: Structured Outputs OpenAI, tool use в Claude, responseSchema в Gemini, Pydantic через Instructor и эвалы перед продакшном.