Как развернуть Langfuse на своем сервере: руководство
Узнайте, как самостоятельно запустить Langfuse на VPS. Разбираем настройку ClickHouse, управление хранилищем, использование фиксированных тегов образов и создание надежных бэкапов.
Зачем вообще отслеживать работу AI-агента
Вы разворачиваете Langfuse на собственном сервере, чтобы видеть, что именно агент делал во время выполнения. Langfuse — это инструмент с открытым исходным кодом для обеспечения наблюдаемости LLM (больших языковых моделей). Он записывает каждый промпт, каждый ответ модели, каждый вызов инструментов и каждый токен, а затем группирует их в единую трассировку, которую можно открыть и прочитать. Запуск на собственном VPS означает, что эти промпты никогда не покидают сервер, который вы контролируете.
Причина, по которой стоит этим заниматься, очевидна. Вы не можете исправить проблему с затратами или качеством, если не видите её источник. Счет от провайдера говорит вам, что во вторник расходы были в четыре раза выше, чем в понедельник. Трассировка показывает, какой именно запуск агента стал причиной, какой промпт вырос до 40,000 токенов и какой цикл повторных попыток сработал девять раз, прежде чем завершиться неудачей. Счет дает вам цифру. Трассировка дает вам код, который её породил.
В этом руководстве используются три термина. Трассировка (trace) — это один полный цикл работы вашего агента от начала до конца. Наблюдение (observation) — это один шаг внутри этого цикла: span для обычного кода, generation для вызова модели. Оценка (score) — это числовое значение, присвоенное трассировке на основе проверки человеком или автоматизированным оценщиком. Langfuse поддерживает OpenTelemetry (OTel), независимый от вендоров стандарт распределенной трассировки, поэтому уже имеющиеся у вас средства инструментирования могут быть направлены на него.
Что на самом деле запускается при self-hosting Langfuse
Langfuse v4 — это не один контейнер. Система состоит из двух контейнеров приложения и четырех сервисов хранения данных. На одном VPS все шесть компонентов работают на вашем оборудовании.
langfuse-webобслуживает веб-интерфейс и API для приема данных.langfuse-workerобрабатывает очередь в фоновом режиме. Он разбирает пакеты входящих данных, рассчитывает стоимость и выполняет ночные задачи по очистке данных.- Postgres хранит транзакционные данные, такие как пользователи, организации, проекты, API-ключи и промпты.
- ClickHouse хранит сами данные трассировки, то есть наблюдения и оценки. Это колоночная СУБД, оптимизированная для аналитических запросов, поэтому дашборд быстро работает даже при наличии сотен миллионов строк.
- Redis выступает в роли очереди и кэша между веб-интерфейсом и воркером.
- MinIO предоставляет S3-совместимое объектное хранилище на вашем сервере. В нем хранятся все входящие события в исходном виде и любые прикрепленные медиафайлы.
Langfuse публикует минимальные требования к ресурсам для трех компонентов, которые выполняют основную работу.
The data behind this chart
[
{
"label": "ClickHouse",
"cpu_cores": 2,
"memory_gib": 8
},
{
"label": "Langfuse web",
"cpu_cores": 2,
"memory_gib": 4
},
{
"label": "Langfuse worker",
"cpu_cores": 2,
"memory_gib": 4
}
]Только для ClickHouse требуется 8 ГиБ оперативной памяти. Веб-контейнер и воркер требуют по 4 ГиБ каждый. Это минимальные заявленные требования для 3 компонентов, которые учитывает Langfuse, при этом Postgres, Redis и MinIO также требуют дополнительной памяти. Официальное руководство по Docker Compose рекомендует использовать машину с 4 ядрами, 16 ГиБ оперативной памяти и около 100 ГиБ дискового пространства, что соответствует этим расчетам без избыточного запаса.
Не пытайтесь запустить это на тарифе с 2 ГиБ памяти. ClickHouse запустится, некоторое время будет принимать записи, а затем завершится с ошибкой во время фонового слияния, так как процесс слияния загружает большие части таблицы в оперативную память. Вы увидите, что docker compose ps сообщает о статусе контейнера clickhouse как restarting, dmesg содержит строку вида Out of memory: Killed process 1234 (clickhouse-serv), а все дашборды Langfuse возвращают ошибку 500. При меньшей нагрузке ClickHouse просто отклонит запрос и запишет в лог DB::Exception: Memory limit (total) exceeded. Восемь ГиБ памяти достаточно для одного разработчика, отправляющего несколько тысяч трассировок в день. Шестнадцать ГиБ — это объем, на который стоит ориентироваться.
Развертывание Langfuse с помощью Docker Compose
Клонируйте репозиторий. Стек, связи между компонентами и конфигурация по умолчанию находятся в файле docker-compose.yml.
git clone https://github.com/langfuse/langfuse.git
cd langfuseВсе значения, которые необходимо изменить, отмечены в этом файле как # CHANGEME. Сначала сгенерируйте три секрета приложения.
openssl rand -base64 32 # NEXTAUTH_SECRET
openssl rand -base64 32 # SALT
openssl rand -hex 32 # ENCRYPTION_KEYЗначение ENCRYPTION_KEY должно представлять собой 256 бит, записанных как 64 шестнадцатеричных символа, что и выводит команда openssl rand -hex 32. Оно используется для шифрования конфиденциальных данных в состоянии покоя, включая ключи провайдеров LLM, которые вы храните в экземпляре. Изменение этого значения после появления данных приведет к невозможности их расшифровки, поэтому считайте его постоянным с момента первого запуска. Значение SALT используется для хеширования ваших API-ключей Langfuse, поэтому его изменение сделает недействительными все ключи, которые уже используют ваши агенты.
Затем установите POSTGRES_PASSWORD, CLICKHOUSE_PASSWORD, REDIS_AUTH и MINIO_ROOT_PASSWORD. Пароль MinIO указывается в четырех местах: один раз как MINIO_ROOT_PASSWORD, затем как LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY, LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY и LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY. Если пропустить хотя бы одно, MinIO отклонит клиент с ошибкой SignatureDoesNotMatch, которая попадет в лог воркера, в то время как веб-интерфейс будет выглядеть работоспособным. Хранение этих значений в файле переменных окружения вместо отслеживаемого файла compose — это стандартная практика, описанная в файлы env и секреты Docker Compose.
Зафиксируйте теги образов перед запуском
Поставляемый файл использует теги langfuse/langfuse:4 и langfuse/langfuse-worker:4. Эти теги меняются со временем. Langfuse автоматически выполняет миграции Postgres и ClickHouse при запуске, поэтому обычная команда docker compose pull через несколько месяцев может привести к незапланированной миграции схемы базы данных, которую вы не успели забэкапить утром. Зафиксируйте обе версии в файле docker-compose.override.yml, который Compose объединит с основным файлом, чтобы последующая команда git pull не конфликтовала с вашими правками.
services:
langfuse-web:
image: docker.io/langfuse/langfuse:4.3.1
langfuse-worker:
image: docker.io/langfuse/langfuse-worker:4.3.1Версия 4.3.1 была актуальным релизом 4.3 по состоянию на август 2026 года (версия 4.4.0 уже выпущена). Проверьте страницу релизов проекта на GitHub, зафиксируйте версию, актуальную на день развертывания, и обновляйте этот номер осознанно. Образы хранилищ в поставляемом файле уже зафиксированы по мажорным версиям: postgres:17, clickhouse-server:25.12 и redis:7, и они заслуживают такого же подхода.
Запустите стек.
docker compose up -d
docker compose ps
docker compose logs -f langfuse-workerПри первом запуске выполняются миграции, поэтому подождите минуту или две, прежде чем проверять доступность. Команда docker compose ps должна показать шесть сервисов в состоянии running. Если воркер перезапускается в цикле, причина указана в его логе: CLICKHOUSE_MIGRATION_URL использует нативный протокол ClickHouse на порту 9000, а не HTTP-порт 8123. Указание порта 8123 приведет к ошибке, хотя веб-контейнер будет выглядеть исправным.
Проверьте работоспособность с самого сервера.
curl -s "http://localhost:3000/api/public/health?failIfDatabaseUnavailable=true"
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/api/public/readyОбычный вызов /api/public/health лишь подтверждает, что процесс API запущен, так как он намеренно пропускает проверку базы данных, чтобы сервис продолжал работать при кратковременных сбоях Postgres. Форма failIfDatabaseUnavailable=true — это именно то, что стоит использовать для мониторинга; она возвращает 503, если база данных недоступна. Запрос /api/public/ready возвращает 200, как только миграции завершены и контейнер готов принимать трафик. Оба варианта являются обычными HTTP-проверками, поэтому страница статуса Uptime Kuma может отслеживать их и оповестить вас о падении стека раньше, чем это заметят ваши агенты.
Настройка TLS и закрытие лишних портов
В поставляемом файле compose порт 3000:3000 открыт для веб-контейнера, а 9090:9000 — для MinIO. Оба привязаны ко всем сетевым интерфейсам. На публичном IP-адресе это означает, что любой, кто просканирует порт 3000, попадет на вашу страницу регистрации, а любой, кто просканирует 9090, получит доступ к хранилищу с вашими исходными промптами.
Правила межсетевого экрана сами по себе их не закрывают. Docker записывает собственные правила DNAT в таблицу nat, которые обрабатываются до того, как пакеты попадут в правила фильтрации ufw, поэтому ufw deny 3000 оставляет опубликованный порт открытым. Эта проблема встречается настолько часто, что для неё есть отдельное руководство: почему опубликованные порты Docker обходят ufw. Вместо этого привяжите их к loopback в вашем файле переопределения.
services:
langfuse-web:
ports:
- "127.0.0.1:3000:3000"
environment:
NEXTAUTH_URL: https://langfuse.example.com
minio:
ports:
- "127.0.0.1:9090:9000"
- "127.0.0.1:9091:9001"NEXTAUTH_URL должен содержать точный публичный адрес, включая схему, так как процесс входа формирует URL обратного вызова на основе этого значения. Если оставить http://localhost:3000 при работе за HTTPS-прокси, цикл авторизации перенаправит браузер туда, где он не сможет установить соединение.
Теперь направьте reverse proxy на 127.0.0.1:3000 и позвольте ему управлять сертификатом. Traefik в том же проекте Compose — стандартный выбор, а метки маршрутизации описаны в запуск нескольких приложений за одним reverse proxy Traefik. Caddy выполняет ту же задачу двумя строками, если Langfuse — единственный сервис на сервере. Проверьте конфигурацию с помощью curl -sI https://langfuse.example.com/api/public/ready, а затем убедитесь с другого компьютера, что соединение с curl http://YOUR_IP:3000 теперь завершается по таймауту.
Важное замечание по MinIO. Langfuse передает прикрепленные медиафайлы в браузер через подписанные URL, указывающие на этот S3-эндпоинт. Поэтому, если вы используете мультимодальные трассировки с изображениями или аудио, привязка MinIO только к loopback приведет к тому, что эти вложения не будут загружаться. Изучите страницу конфигурации хранилища объектов перед настройкой проксирования, так как эндпоинт, записанный в подписанном URL, должен совпадать с тем, который вы публикуете. На текстовые трассировки это не влияет.
Создайте свою учетную запись при первом посещении, а затем ограничьте доступ к инстансу. Установите LANGFUSE_ALLOWED_ORGANIZATION_CREATORS на свой адрес электронной почты, чтобы посторонний человек, попавший на страницу, не смог создать организацию на вашем сервере. Если вы уже используете Authentik в качестве собственного провайдера идентификации, Langfuse поддерживает стандартное подключение OIDC. В этом случае учетные записи будут управляться централизованно вместе с остальными вашими приложениями, а не храниться в списке паролей, известном только этому серверу.
Отправка первой трассировки
Создайте проект в веб-интерфейсе и скопируйте публичный и секретный ключи из настроек проекта. Python SDK считывает три переменные окружения.
export LANGFUSE_PUBLIC_KEY="pk-lf-..."
export LANGFUSE_SECRET_KEY="sk-lf-..."
export LANGFUSE_BASE_URL="https://langfuse.example.com"LANGFUSE_BASE_URL — это имя переменной в SDK v4, выпущенном в марте 2026 года. В старом коде и руководствах используется LANGFUSE_HOST. Если ваши трассировки попадают в Langfuse Cloud вместо вашего сервера, причина в не установленном base URL, так как по умолчанию используется облачный экземпляр.
pip install langfuse opentelemetry-instrumentation-anthropic anthropicimport os
from anthropic import Anthropic
from langfuse import get_client, observe
from opentelemetry.instrumentation.anthropic import AnthropicInstrumentor
AnthropicInstrumentor().instrument()
langfuse = get_client()
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
@observe(as_type="tool")
def lookup_order(order_id: str) -> str:
return f"order {order_id}: shipped"
@observe()
def handle_request(question: str) -> str:
context = lookup_order("A-1042")
message = client.messages.create(
model="claude-haiku-4-5",
max_tokens=512,
messages=[{"role": "user", "content": f"{context}\n\n{question}"}],
)
return message.content[0].text
if __name__ == "__main__":
assert langfuse.auth_check()
print(handle_request("Where is my order?"))
langfuse.flush()Декоратор @observe создает наблюдение (observation) вокруг функции, захватывает её аргументы и возвращаемое значение, а также вкладывает его в уже активное наблюдение. AnthropicInstrumentor — это инструментарий OpenTelemetry для клиента Anthropic, который превращает каждый вызов messages.create в генерацию, содержащую имя модели, использование токенов и задержку, без необходимости менять код в месте вызова.
Два вызова позволяют выполнить проверку. langfuse.auth_check() возвращает False при неверных ключах или некорректном base URL, что быстрее, чем выяснять, почему панель мониторинга пуста. langfuse.flush() блокирует выполнение до тех пор, пока не будут отправлены поставленные в очередь спаны. Это необходимо для короткоживущих процессов, так как SDK выполняет пакетную обработку в фоновом режиме, и скрипт, который завершается немедленно, прерывает отправку пакета.
Почему ClickHouse постоянно увеличивается в объеме?
Трассировки — это данные, объем которых растет быстрее всего при самостоятельном хостинге. Каждый запуск агента записывает по одной строке на каждый шаг, а входные и выходные данные сохраняются полностью. Поэтому «разговорчивый» агент с длинными промптами генерирует гораздо больше байтов в день, чем само приложение, за которым он наблюдает. Если оставить всё как есть, ClickHouse заполнит диск, а переполнение диска полностью останавливает прием данных, а не просто замедляет его.
Здесь растут два разных типа данных, и для них требуются два разных решения.
Первое — это ваши собственные данные трассировки, и решение заключается в настройке периода хранения. Откройте настройки проекта в веб-интерфейсе и установите период хранения данных в днях. Langfuse принимает значение минимум 3 дня. Ночное задание выбирает трассировки, наблюдения, оценки и медиа-активы, которые старше этого периода, и удаляет их из ClickHouse и из объектного хранилища. Заданию требуются права DeleteObject на бакет, которые уже есть у учетных данных root для MinIO в стандартном файле compose. Удаление является необратимым, поэтому сначала настройте экспорт в объектное хранилище, если вам нужна долгосрочная история. Не прописывайте вручную условия TTL для таблиц Langfuse: задание по очистке синхронизирует ClickHouse и бакет, а ручной TTL удалит данные только с одной стороны.
Выберите период, исходя из того, что вы реально используете. Анализ стоимости и качества проводится на данных, которым несколько дней, а не месяцев. 30 дней — разумный срок для небольшой команды, а 14 дней достаточно, если вы открываете трассировку только в случае сбоя.
Второе — это системные таблицы логов самого ClickHouse, и это часто становится сюрпризом, так как диск продолжает расти даже после настройки периода хранения. ClickHouse записывает trace_log, text_log, opentelemetry_span_log, metric_log и asynchronous_metric_log для собственной диагностики, они поставляются без TTL, и Langfuse их никогда не читает. Сначала выясните, куда именно уходит место на диске.
SELECT table, formatReadableSize(size) AS size, rows FROM (
SELECT table, database, sum(bytes) AS size, sum(rows) AS rows
FROM system.parts
WHERE active
GROUP BY table, database
ORDER BY size DESC
)Запустите его с помощью docker compose exec clickhouse clickhouse-client --password "$CLICKHOUSE_PASSWORD". Если системные таблицы занимают верхние строчки, отключите их с помощью конфигурационного оверлея, так как ClickHouse при запуске объединяет каждый файл в /etc/clickhouse-server/config.d/ со своей основной конфигурацией.
<clickhouse>
<trace_log remove="1"/>
<text_log remove="1"/>
<opentelemetry_span_log remove="1"/>
<asynchronous_metric_log remove="1"/>
<metric_log remove="1"/>
</clickhouse>Примонтируйте его и перезапустите ClickHouse.
services:
clickhouse:
volumes:
- ./clickhouse-config.d/system-logs.xml:/etc/clickhouse-server/config.d/system-logs.xml:roЭто остановит новые записи. Строки, которые уже находятся на диске, останутся там, поэтому освободите место явно с помощью DROP TABLE IF EXISTS system.trace_log и повторите то же самое для каждой удаленной таблицы. Если вы предпочитаете сохранить диагностику, альтернативой является агрессивный TTL для каждой таблицы вместо remove="1", что подробно описано в документации по масштабированию Langfuse.
Стоит знать еще об одной таблице. blob_storage_file_log отслеживает файлы событий, загруженные в ваш бакет. Если вы также установили политику жизненного цикла для бакета, задайте таблице соответствующий TTL, чтобы они не рассинхронизировались.
ALTER TABLE blob_storage_file_log MODIFY TTL created_at + INTERVAL 30 DAY DELETE;Также настройте простое оповещение df -h по диску с данными. Трассировки не растут равномерно. Они растут в тот день, когда вы выпускаете нового агента, и первым признаком этого не должен быть отказ в приеме данных.
Резервное копирование Postgres и ClickHouse
Резервная копия Langfuse состоит из трех частей. В Postgres хранятся пользователи, организации, проекты и API-ключи. В ClickHouse хранятся трассировки. В MinIO хранятся необработанные события. Если восстановить только Postgres, вы получите работающий вход в систему без истории. Если восстановить только ClickHouse, вы получите историю, которую никто не сможет просмотреть из-за отсутствия доступа.
Postgres представляет собой обычный pg_dump, что и рекомендуется в документации по резервному копированию Langfuse.
docker compose exec -T postgres pg_dump -U postgres postgres \
| gzip > langfuse-pg-$(date +%F).sql.gzС ClickHouse требуется больше внимания, так как каталог с данными, скопированный во время выполнения операций слияния (merges), не является консистентной резервной копией. Простой подход для одного сервера — остановить контейнер и заархивировать том.
docker compose stop clickhouse
docker volume ls | grep clickhouse
docker run --rm -v langfuse_langfuse_clickhouse_data:/data -v "$PWD":/backup alpine \
tar czf /backup/langfuse-ch-$(date +%F).tar.gz -C /data .
docker compose start clickhouseИспользуйте имя тома, которое выводит docker volume ls, а не то, что указано в YAML. В файле объявлено langfuse_clickhouse_data, но Compose добавляет к нему префикс с именем проекта, поэтому клон в каталоге с именем langfuse создаст langfuse_langfuse_clickhouse_data. Ошибетесь в этом — и docker run создаст новый пустой том без предупреждений, а ваш архив окажется пустым.
Контейнер web записывает каждое входящее событие в бакет до того, как его обработает воркер, поэтому кратковременная остановка ClickHouse в основном приводит к тому, что воркер просто повторит попытку позже. Выполняйте это в часы низкой нагрузки и старайтесь сократить время простоя. Для более нагруженных инстансов инструкция BACKUP DATABASE default TO S3(...) самого ClickHouse позволяет создать консистентную резервную копию без остановки сервера. MinIO — это третья часть, и mc mirror или репликация MinIO на внешний бакет решают эту задачу. Что бы вы ни создали, выносите это с сервера, для чего и предназначены зашифрованные резервные копии restic на VPS.
Redis не нуждается в резервном копировании. Он хранит очередь и кэш, поэтому его потеря приведет лишь к потере событий, находящихся в обработке, но не более старых данных.
Предостережение о консистентности реально, и его стоит озвучить прямо. Дампы Postgres и ClickHouse создаются в разное время, поэтому восстановление может привести к появлению записи о проекте без трассировок или трассировок, принадлежащих несуществующему проекту. Langfuse допускает такие ситуации, но старайтесь делать оба дампа одновременно и в периоды низкой активности. Бакет с событиями — это ваша основная страховка, так как Langfuse сохраняет там каждое входящее событие до начала обработки.
Хотя бы раз выполните восстановление в тестовой среде. Так вы узнаете о неверном имени тома сейчас, а не во время аварии.
На что смотреть в первую очередь
Четыре показателя заслуживают внимания в первую неделю.
- Стоимость одного трейса. Langfuse вычисляет стоимость на основе имени модели и количества использованных токенов. Отсортируйте трейсы по стоимости и изучите самый дорогой от начала до конца. Обычно причина кроется в разросшемся промпте: в контекст вставлен целый документ или история диалога, которую никто не обрезает. Как только вы увидите это, контроль расходов AI-агента превратится из догадок в инженерную задачу.
- Распределение токенов на входные и выходные. Входных токенов много, и они дешевы; выходных мало, и они дороги, а кэшированные входные данные стоят еще меньше. Тот же принцип учета описан в том, как считается использование токенов в Claude Code, и он применим к любому агенту, который вы пишете самостоятельно.
- Перцентили задержки. Медиана скрывает проблему. Тайм-ауты живут в p95 и p99, а внутри цикла агента медленный вызов инструмента на уровне p95 умножается на количество итераций.
- Неудачные вызовы инструментов. Отфильтруйте наблюдения по уровню
ERROR. Инструмент, который дает сбой в 5% случаев, незаметен в общей статистике успеха, но очень хорошо виден в трейсах, где вы наблюдаете, как модель пытается повторить запрос и тратит токены на обходные пути.
Установите период хранения данных и выберите дашборд, который будете проверять еженедельно в тот же день, когда выполняете деплой. Инструмент наблюдаемости, который никто не открывает — это база данных, заполняющая диск.
FAQ
Сколько оперативной памяти требуется для self-hosted Langfuse?
Планируйте использование 4 ядер CPU и 16 GiB оперативной памяти — это рекомендуемые параметры из руководства Langfuse Docker Compose для одной виртуальной машины, плюс около 100 GiB дискового пространства. Опубликованные минимальные требования для компонентов составляют 8 GiB для ClickHouse и 4 GiB для каждого из контейнеров web, worker, а также для Postgres, Redis и MinIO, которым требуется дополнительная память. Восемь GiB достаточно для запуска экземпляра одного разработчика. Два GiB недостаточно: ядро завершает процесс ClickHouse во время фоновых операций слияния, а dmesg показывает Out of memory: Killed process.
Почему диск ClickHouse продолжает заполняться после настройки хранения данных?
Настройка хранения (retention) распространяется только на собственные данные Langfuse. ClickHouse отдельно записывает диагностические таблицы trace_log, text_log, opentelemetry_span_log, metric_log и asynchronous_metric_log, для которых не задан TTL. Выполните запрос system.parts с группировкой по таблицам, чтобы определить самую большую из них, затем отключите неиспользуемые таблицы с помощью записи remove="1" в файле в директории /etc/clickhouse-server/config.d/, перезапустите ClickHouse и удалите существующие таблицы, чтобы освободить занятое место.
Какой минимальный срок хранения данных в Langfuse?
Три дня. Срок хранения устанавливается для каждого проекта в настройках проекта или через API проектов. Ночное задание удаляет трассировки, наблюдения, оценки и медиафайлы, которые старше указанного периода, как из ClickHouse, так и из объектного хранилища. Удаление необратимо, поэтому сначала настройте экспорт в объектное хранилище, если вам нужна история за пределами этого периода.
Нужно ли делать резервные копии и Postgres, и ClickHouse?
Да, так как они хранят разные данные. В Postgres находятся пользователи, организации, проекты и API-ключи, а в ClickHouse — сами данные трассировок. Восстановление только из Postgres даст вам пустой экземпляр, в который можно войти, но в котором ничего нет. Также делайте резервную копию бакета MinIO, так как там хранятся необработанные события, которые Langfuse сохраняет при поступлении; это наиболее близкий к первоисточнику данных компонент в стеке.
Можно ли подключить существующую настройку OpenTelemetry к self-hosted Langfuse?
Да. Langfuse v4 и его SDK версии v4 построены на базе OpenTelemetry, а инструменты Anthropic и OpenAI OTel экспортируют данные напрямую в него. В Python выполните pip install langfuse opentelemetry-instrumentation-anthropic, вызовите AnthropicInstrumentor().instrument() один раз при запуске и установите LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY и LANGFUSE_BASE_URL на ваш собственный хост. Проверьте результат с помощью langfuse.auth_check(), прежде чем искать причину отсутствия данных на дашборде.