# Langfuse: LLM Observability — зачем нужна и как настроить

> Практическое руководство по Langfuse: трейсинг LLM-вызовов, prompt management, cost tracking, evaluations. Self-hosted за 15 минут, production-паттерны.
> Author: Roman Belov · Published: 2026-02-22 · Source: https://futurecraft.pro/ru/blog/llm-observability-langfuse/

LLM-вызовы в production нужно трейсить, [промпты — версионировать](/ru/blog/prompt-engineering-system/), расходы — контролировать. Стандартные APM-инструменты здесь не помогут: ответы недетерминированы, каждый вызов стоит денег, а 200 OK ничего не говорит о качестве результата. Это отдельная категория observability.

Langfuse — open-source платформа (MIT) для LLM observability. Self-hosted без ограничений, 22 000+ звёзд на GitHub, 23 миллиона установок SDK в месяц. В этом руководстве — установка, трейсинг, prompt management, cost tracking и evaluations.

> **Примечание:** статья описывает self-hosted Langfuse v2. Для актуальной v3-инсталляции см. [пошаговый гайд](/ru/blog/langfuse-step-by-step/).

## LLM Observability: четыре компонента

Если вы работали с APM (Application Performance Monitoring), LLM observability покажется знакомой. Но есть три важных отличия:

**Недетерминизм.** Один и тот же промпт при temperature > 0 даёт разные ответы. Нельзя просто сравнить expected vs actual — качество приходится оценивать статистически.

**Стоимость за вызов.** HTTP-запрос к собственному API стоит доли цента. Один вызов GPT-5.4 с контекстом на 10 000 токенов — 3-5 центов. При 1 000 пользователей в день разница между хорошим и плохим промптом — сотни долларов в месяц.

**Качество вывода.** 200 OK ничего не говорит о качестве ответа. Модель может вернуть грамматически правильный, но фактически бесполезный текст. Нужны метрики качества, а не только метрики доступности.

Четыре компонента LLM observability:

```
┌─────────────────────────────────────────────────────┐
│                  LLM Observability                   │
├──────────┬──────────┬──────────────┬────────────────┤
│ Tracing  │   Cost   │   Prompt     │  Evaluation    │
│          │ Tracking │  Management  │                │
├──────────┼──────────┼──────────────┼────────────────┤
│ Что      │ Сколько  │ Какой промпт │ Насколько      │
│ произошло│ стоило   │ в продакшене │ хороший ответ  │
└──────────┴──────────┴──────────────┴────────────────┘
```

Langfuse покрывает все четыре. Можно начать с одного (обычно tracing) и добавлять остальные по мере роста.

## Почему Langfuse

На рынке LLM observability пять-шесть платформ. Вот чем выделяется Langfuse:

**Open-source (MIT).** Код на GitHub, self-hosted версия без ограничений. Нет vendor lock-in — исходники и данные всегда у вас.

**Self-hosted бесплатно.** Никаких лимитов на количество трейсов. Для небольших и средних команд self-hosted на одной VM — дешевле любого SaaS.

**Не привязан к фреймворку.** LangSmith заточен под LangChain — с другими стеками работать сложнее. Langfuse работает с любым LLM-провайдером: OpenAI, Anthropic, open-source модели через LiteLLM, Vercel AI SDK.

**Активно развивается.** За последний год: SDK v3 на OpenTelemetry (нативная совместимость с любой OTEL-инструментацией), встроенный [MCP-сервер](/ru/blog/mcp-production-custom-servers/) (управление промптами прямо из IDE), observation-level evaluations, dataset versioning. Рост с 10 000 до 22 000 звёзд за 10 месяцев.

**Сравнение (кратко):**

| | Langfuse | LangSmith | Helicone |
|---|---------|-----------|----------|
| Open-source | MIT | Нет | Apache 2.0 |
| Self-hosted | Бесплатно, без лимитов | Enterprise only | Да |
| Framework lock-in | Нет | LangChain | OpenAI-first |
| Prompt management | Да + MCP | Да | Да (beta) |
| Free tier (cloud) | 50k obs/мес | 5k traces/мес | 100k req/мес |

## Установка за 15 минут: self-hosted

Минимальные требования: Docker и 2 ГБ RAM. Langfuse упаковывает всё в один docker-compose.

```yaml
# docker-compose.yml
services:
  langfuse:
    image: langfuse/langfuse:2
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://postgres:postgres@db:5432/langfuse
      NEXTAUTH_SECRET: your-secret-key-change-me
      SALT: your-salt-change-me
      NEXTAUTH_URL: http://localhost:3000
    depends_on:
      - db

  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: langfuse
    volumes:
      - langfuse_data:/var/lib/postgresql/data

volumes:
  langfuse_data:
```

```bash
docker compose up -d
```

Через минуту Langfuse доступен на `localhost:3000`. Создайте аккаунт, проект, скопируйте API-ключи.

### Первые трейсы через Python SDK

```bash
pip install langfuse
```

```python
from langfuse import Langfuse

langfuse = Langfuse(
    public_key="pk-lf-...",
    secret_key="sk-lf-...",
    host="http://localhost:3000"  # ваш self-hosted URL
)

# Создаём трейс
trace = langfuse.trace(name="chat-response", user_id="user-123")

# Логируем LLM-вызов
generation = trace.generation(
    name="gpt-5.4-response",
    model="gpt-5.4",
    input=[{"role": "user", "content": "Порекомендуй кафе в Москве"}],
    output="Вот несколько вариантов...",
    usage={"input": 42, "output": 128},
)

langfuse.flush()
```

Откройте Langfuse UI — трейс появится в списке с данными о модели, токенах и latency.

### Автоматическая инструментация через LiteLLM

Ручное логирование — для понимания механики. В продакшене лучше автоматизировать. Если вы используете [LiteLLM как прокси к LLM-провайдерам](/ru/blog/multi-provider-llm-architecture/), Langfuse подключается одной строкой:

```python
import litellm
litellm.success_callback = ["langfuse"]

# Каждый вызов автоматически попадёт в Langfuse
response = litellm.completion(
    model="gpt-5.4",
    messages=[{"role": "user", "content": "Привет"}],
    metadata={
        "trace_name": "chat-response",
        "trace_user_id": "user-123",
        "generation_name": "greeting",
        "tags": ["production", "chat"],
    }
)
```

LiteLLM сам отправит в Langfuse: модель, токены, стоимость, latency, input/output. Вы пишете обычный LLM-вызов, Langfuse заполняется автоматически.

Для OpenAI SDK есть drop-in replacement:

```python
from langfuse.openai import openai

# Используйте как обычный OpenAI SDK
# Все вызовы автоматически трейсятся
client = openai.OpenAI()
response = client.chat.completions.create(
    model="gpt-5.4",
    messages=[{"role": "user", "content": "Привет"}],
)
```

## Трейсинг: что внутри LLM-вызова

Трейс в Langfuse — это дерево операций. На верхнем уровне — trace (один запрос пользователя). Внутри — generations (LLM-вызовы) и spans (промежуточные шаги: retrieval, preprocessing, postprocessing).

```
Trace: "generate-itinerary"
│
├── Span: "validate-input" (12ms)
│
├── Generation: "analyze-request" (GPT-5.4, 340 tokens, $0.003)
│
├── Span: "search-places" (Foursquare API, 800ms)
│
├── Generation: "build-itinerary" (GPT-5.4, 2100 tokens, $0.018)
│
└── Generation: "validate-result" (GPT-5.4-mini, 450 tokens, $0.001)
```

Что видно в UI для каждой generation:
- **Input/Output** — полный промпт и ответ
- **Model** — какая модель использовалась
- **Tokens** — input, output, total
- **Cost** — стоимость в долларах (автоматически по модели)
- **Latency** — время ответа
- **Metadata** — произвольные поля (user ID, feature, session)

Три вещи, которые трейсинг показывает сразу:

**Паттерн 1: скрытые повторные вызовы.** Retry-логика в коде может вызывать модель 2-3 раза на один запрос пользователя. Без трейсинга вы видите только финальный ответ. С трейсингом — каждый вызов со стоимостью.

**Паттерн 2: model mismatch.** Предполагается GPT-5.4-mini для быстрых ответов, но один эндпоинт тянет GPT-5.4. В трейсинге модель видна по каждому вызову — фильтр по полю model сразу покажет, где что-то не так.

**Паттерн 3: latency bottleneck.** В цепочке из четырёх LLM-вызовов один занимает 80% времени. Без spans вы знаете только общее время. С ними — точно видно, куда оптимизировать.

## Prompt Management: версионирование без деплоя

Стандартный подход: промпт зашит в код. Изменение требует PR → code review → merge → deploy. A/B тест двух промптов — два деплоя.

Langfuse выносит промпты из кода: код загружает их по имени через API. Изменение промпта в UI применяется к следующему запросу без деплоя.

```python
# Загрузка промпта из Langfuse
prompt = langfuse.get_prompt("travel-assistant")

# Компиляция с переменными
compiled = prompt.compile(
    destination="Москва",
    preferences="вегетарианская кухня"
)

# Использование в LLM-вызове
response = litellm.completion(
    model="gpt-5.4",
    messages=compiled,
    metadata={"langfuse_prompt_name": "travel-assistant"}
)
```

Каждое изменение промпта — новая версия. Langfuse хранит всю историю: кто, когда, что изменил. Можно откатить одним кликом.

### Fallback-паттерн

Langfuse — внешний сервис. Он может быть недоступен. Промпт нужен всегда.

```python
try:
    prompt = langfuse.get_prompt("travel-assistant", label="production")
    messages = prompt.compile(destination=city)
except Exception:
    # Если Langfuse недоступен — fallback на хардкод
    messages = [
        {"role": "system", "content": FALLBACK_SYSTEM_PROMPT},
        {"role": "user", "content": f"Порекомендуй кафе в {city}"},
    ]
```

Для production этот паттерн обязателен. Langfuse ускоряет итерацию над промптами, но не должен быть single point of failure.

### MCP-сервер: промпты из IDE

С ноября 2025 Langfuse поддерживает MCP (Model Context Protocol). Подключив MCP-сервер к Claude Code, Cursor или другому AI-ассистенту, вы можете читать и редактировать промпты прямо из IDE.

```json
{
  "mcpServers": {
    "langfuse": {
      "type": "http",
      "url": "https://your-langfuse.com/api/public/mcp",
      "headers": {
        "Authorization": "Basic base64(publicKey:secretKey)"
      }
    }
  }
}
```

Зачем: вместо переключения между IDE и браузером, AI-ассистент видит текущие промпты, предлагает изменения и может применить их через MCP — всё в одном рабочем потоке.

## Cost Tracking: сколько стоит каждая фича

Langfuse автоматически считает стоимость каждого LLM-вызова по модели и количеству токенов. Встроенная таблица pricing обновляется с каждым релизом (GPT-5.5, Claude Opus 4.8 — поддержка в день выхода).

В дашборде вы видите:
- **Total cost** за период
- **Cost per trace** — средняя стоимость одного запроса
- **Cost per user** — сколько тратит конкретный пользователь
- **Cost per model** — распределение расходов между моделями

### Паттерн: per-feature cost tracking

Добавляя теги или metadata к трейсам, вы группируете расходы по фичам:

```python
trace = langfuse.trace(
    name="itinerary-generation",
    tags=["feature:itinerary", "tier:premium"],
    user_id="user-123",
)
```

Фильтр по тегу `feature:itinerary` в дашборде покажет, сколько стоит именно генерация маршрутов. Отдельно — чат, отдельно — рекомендации, отдельно — саммаризация.

### Паттерн: синхронизация расходов в свою БД

Langfuse API позволяет программно получить стоимость:

```python
# Получить все трейсы пользователя
traces = langfuse.fetch_traces(user_id="user-123")

# Суммировать стоимость
total_cost = sum(t.total_cost or 0 for t in traces.data)

# Записать в свою БД для лимитов, биллинга, аналитики
db.update_user_spending(user_id="user-123", amount=total_cost)
```

Это нужно, если у вас есть лимиты на LLM-расходы per user (freemium, credits) или вы хотите показывать пользователю его потребление.

## Evaluations: качество ответов в числах

Трейсинг показывает, что произошло. Evaluations показывают, насколько хорошо.

### LLM-as-a-Judge

Автоматическая оценка через LLM: одна модель оценивает ответы другой. Langfuse поддерживает это из коробки.

Настраивается в UI: выбираете evaluator template (relevance, helpfulness, toxicity), целевой набор трейсов — Langfuse прогоняет оценку по каждому. Результат — score от 0 до 1, привязанный к трейсу.

### Observation-Level Evaluations (новинка 2026)

Раньше оценка привязывалась только к trace целиком. Но в цепочке из четырёх LLM-вызовов проблема может быть в одном конкретном шаге. С февраля 2026 можно оценивать каждый observation (generation, span) отдельно.

Пример: в pipeline "analyze → search → generate → validate" evaluator для `generate` проверяет фактическую корректность, а для `validate` — соответствие формату. Разные evaluators для разных шагов.

### Datasets: регрессионное тестирование промптов

Dataset в Langfuse — набор пар input/expected_output. Изменили промпт — прогоняете dataset, сравниваете scores с предыдущей версией. Если качество упало — откатываете.

С декабря 2025 поддерживается версионирование datasets: каждое изменение (добавление, удаление, обновление item) создаёт новую версию. Можно запустить эксперимент на конкретной исторической версии для воспроизводимости.

```python
# Создаём или обновляем dataset
langfuse.create_dataset(name="travel-queries")

langfuse.create_dataset_item(
    dataset_name="travel-queries",
    input={"query": "Кафе в центре Москвы"},
    expected_output="Список из 5+ кафе с адресами",
)

# Запуск эксперимента
dataset = langfuse.get_dataset("travel-queries")
for item in dataset.items:
    response = run_my_pipeline(item.input)
    item.link(
        trace_id=response.trace_id,
        run_name="prompt-v3-test",
    )
```

В UI Langfuse вы увидите сравнение run'ов: prompt v2 vs v3, с scores по каждому item.

## Production Checklist

### Self-hosted vs Cloud

| Критерий | Self-hosted | Cloud |
|----------|------------|-------|
| Стоимость | Только инфраструктура (~$10-20/мес VPS) | Core $29/мес, Pro $199/мес |
| Данные | Остаются у вас | На серверах Langfuse |
| Обслуживание | Вы обновляете, бекапите, мониторите | Всё включено |
| Лимиты | Нет | 50k obs/мес (бесплатно), далее по тарифу |
| Подходит для | Команды с DevOps, compliance-требования | Быстрый старт, маленькие команды |

Для большинства production-проектов self-hosted выгоднее: $15/мес за VPS vs Cloud Core от $29/мес. Но self-hosted = ваша ответственность за uptime и бекапы.

### Мониторинг самого Langfuse

Langfuse — внешняя зависимость для ваших LLM-вызовов (prompt management). Если он падает — промпты не грузятся. Два паттерна:

1. **Health check.** `/api/public/health` возвращает статус. Добавьте в мониторинг (Zabbix, Uptime Robot, Grafana).
2. **Fallback промпты.** Каждый `get_prompt()` обёрнут в try/catch с fallback на хардкод. Langfuse может лежать — приложение продолжает работать.

### Retention и cleanup

Трейсы занимают место в PostgreSQL. 1 000 трейсов в день — ~300–400 МБ в месяц (зависит от размера промптов и ответов). Настройте автоматическое удаление старых трейсов:

```sql
-- Удалять трейсы старше 90 дней
DELETE FROM traces WHERE created_at < NOW() - INTERVAL '90 days';
```

Или используйте встроенные настройки retention в Langfuse Cloud.

### Минимальный production-сетап

```
┌─────────────────────────────────────────┐
│            Ваше приложение               │
│                                          │
│  LLM-вызов → LiteLLM → OpenAI/Anthropic │
│       │                                  │
│       │ metadata (trace_name,            │
│       │  user_id, tags)                  │
│       ▼                                  │
│  LiteLLM callback → Langfuse            │
└─────────────────────────────────────────┘
         │
         ▼
┌──────────────────┐
│ Langfuse (Docker) │
│                   │
│ • Трейсы          │  ← автоматически
│ • Стоимость       │  ← автоматически
│ • Промпты         │  ← управление в UI
│ • Evaluations     │  ← настройка в UI
└──────────────────┘
```

Промпты загружаются из Langfuse при каждом вызове (с кешем). Трейсы отправляются асинхронно — не блокируют основной поток. Стоимость считается автоматически по модели и токенам.

## Итог

Langfuse закрывает четыре задачи одним инструментом: трейсинг, cost tracking, prompt management и evaluations. Self-hosted версия бесплатна и разворачивается за 15 минут. Интеграция через LiteLLM или OpenAI drop-in — одна строка кода.

Минимальный путь: подключить трейсинг к одному endpoint, посмотреть данные за неделю. Этого достаточно, чтобы оценить полезность инструмента для конкретного проекта.

**Ссылки:**
- [Langfuse GitHub](https://github.com/langfuse/langfuse) — исходный код и self-hosted установка
- [Langfuse Docs](https://langfuse.com/docs) — документация
- [LiteLLM + Langfuse](https://langfuse.com/docs/integrations/litellm) — интеграция
- [Langfuse Changelog](https://langfuse.com/changelog) — все обновления

---

*Нужна помощь с LLM observability и настройкой Langfuse? Я помогаю стартапам внедрять AI-решения и строить продукты — [belov.works](https://belov.works).*
