−25%

на годовую оплату Windows, до 31.10. К тарифам

EQVPS
Начать

VPS для Langfuse: что делали ваши AI-агенты

Свой Langfuse: трассировка каждого вызова LLM и шага инструмента у агентов, работающих без присмотра. Проверенный Docker Compose, реальные цифры RAM и тариф.

Агент, который работает в три часа ночи без присмотра, ровно настолько хорош, насколько вы потом можете восстановить, что он делал. «За ночь сжёг токенов на $38» — плохое утро. «Сжёг $38, потому что инструмент поиска вернул пустую страницу, а планировщик повторил запрос 400 раз» — баг, который чинится до обеда. Для второй фразы нужны трассы.

Langfuse записывает каждый вызов LLM, промпт, шаг инструмента, число токенов и задержку в виде дерева, по которому можно кликать. Когда он стоит на вашем сервере, все эти промпты и ответы — а в них обычно и данные клиентов, и ответы API, и иногда случайный секрет — остаются у вас, а не в чужой панели.

Сколько это стоит

Langfuse v4 — не один маленький бинарник, а шесть контейнеров: веб-приложение, фоновый воркер, Postgres, ClickHouse для событий, Redis и MinIO для файлов. Мы поставили его на тестовый сервер и замерили: около 3,5 ГБ RAM при пустом проекте. Расти будет ClickHouse — туда попадает каждый шаг, который вы отправляете.

НагрузкаТариф
Несколько агентов, трассы за неделиMedium-IP — 6 vCPU, 6 ГБ, 45 ГБ ($20/мес)
Флот агентов, история за месяцыТарифы Pro, от 32 ГБ RAM — по заявке

На тарифах поменьше он установится, а потом начнёт задыхаться, как только ClickHouse и воркеру одновременно понадобится память. Меньше 6 ГБ я бы не брал.

Где живут агенты? Если на других машинах — берите тариф со своим IPv4: агентам нужен HTTPS-адрес, а на NAT-тарифе исходящий адрес не ваш собственный и снаружи доступен только SSH-порт. Если агенты работают на этом же сервере, Langfuse вообще не обязан смотреть в интернет — для пробы хватит Medium на NAT за $12/мес. Локаций две, Германия и Финляндия; доступность видна при заказе. Выбирайте ту, что ближе к агентам, а не к вам. Оплата сервера — криптой, без KYC.

Установка

На свежем Ubuntu 24.04 или Debian 12, от root. Сначала Docker:

curl -fsSL https://get.docker.com | sh

Потом сам Langfuse — с настоящими секретами вместо значений по умолчанию из compose-файла:

git clone --depth 1 https://github.com/langfuse/langfuse.git
cd langfuse

PG=$(openssl rand -hex 16); MINIO=$(openssl rand -hex 16)
cat > .env <<EOF
NEXTAUTH_URL=https://langfuse.example.com
NEXTAUTH_SECRET=$(openssl rand -hex 32)
SALT=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32)
POSTGRES_PASSWORD=$PG
DATABASE_URL=postgresql://postgres:$PG@postgres:5432/postgres
CLICKHOUSE_PASSWORD=$(openssl rand -hex 16)
MINIO_ROOT_PASSWORD=$MINIO
LANGFUSE_S3_EVENT_UPLOAD_SECRET_ACCESS_KEY=$MINIO
LANGFUSE_S3_MEDIA_UPLOAD_SECRET_ACCESS_KEY=$MINIO
LANGFUSE_S3_BATCH_EXPORT_SECRET_ACCESS_KEY=$MINIO
REDIS_AUTH=$(openssl rand -hex 16)
TELEMETRY_ENABLED=false
EOF
chmod 600 .env

У двух паролей есть пары: пароль Postgres сидит ещё и внутри DATABASE_URL, а пароль MinIO должен совпадать с тремя строками S3_..._SECRET_ACCESS_KEY. Поэтому каждый берётся из одной переменной.

Теперь ловушка. Compose-файл публикует веб-приложение на порту 3000, а MinIO на 9090 — на всех интерфейсах сразу, и порты, которые публикует Docker, проходят мимо ufw. Привяжите оба к localhost, чтобы единственным входом остался обратный прокси:

sed -i 's/- 3000:3000/- 127.0.0.1:3000:3000/; s/- 9090:9000/- 127.0.0.1:9090:9000/' docker-compose.yml
docker compose up -d
curl -s http://127.0.0.1:3000/api/public/health

Последняя команда должна вывести {"status":"OK", ...}. Первый запуск прогоняет миграции базы; у нас проверка прошла примерно через 15 секунд после того, как поднялись контейнеры.

HTTPS спереди

Направьте langfuse.example.com на IP сервера, затем:

apt install -y caddy
cat > /etc/caddy/Caddyfile <<'EOF'
langfuse.example.com {
    reverse_proxy 127.0.0.1:3000
}
EOF
systemctl reload caddy
ufw allow 22/tcp && ufw allow 80/tcp && ufw allow 443/tcp && ufw enable

Сертификат Caddy получит сам. Откройте сайт, создайте аккаунт — он станет первой организацией, — заведите проект и скопируйте его публичный и секретный ключи.

И закройте за собой дверь. Langfuse понимает AUTH_DISABLE_SIGNUP, но стандартный compose-файл не передаёт его в веб-контейнер, поэтому нужна одна строка в разделе langfuse-web:

sed -i 's|^      NEXTAUTH_SECRET: \(.*\)$|      NEXTAUTH_SECRET: \1\n      AUTH_DISABLE_SIGNUP: ${AUTH_DISABLE_SIGNUP:-false}|' docker-compose.yml
echo "AUTH_DISABLE_SIGNUP=true" >> .env
docker compose up -d

Теперь попытка регистрации получает «Sign up is disabled». Коллег добавляйте изнутри проекта.

Как агенту отправлять трассы

Python SDK оборачивает ваши функции, а вложенные вызовы превращаются во вложенные шаги:

python3 -m venv venv && . venv/bin/activate
pip install langfuse
export LANGFUSE_PUBLIC_KEY=pk-lf-...
export LANGFUSE_SECRET_KEY=sk-lf-...
export LANGFUSE_BASE_URL=https://langfuse.example.com
from langfuse import get_client, observe

langfuse = get_client()  # читает переменные LANGFUSE_*

@observe(name="fetch-prices")
def fetch_prices(pair: str) -> dict:
    return {"pair": pair, "bid": 64210.5}

@observe(name="nightly-agent-run")
def run() -> str:
    data = fetch_prices("BTC/USDT")
    return f"done: {data['pair']}"

print(run())
langfuse.flush()  # короткие скрипты завершаются раньше, чем фоновая отправка

Не пропускайте LANGFUSE_BASE_URL. Без него SDK молча шлёт всё в облако самого Langfuse, ваших ключей там нет — и вы смотрите в пустую панель.

Проверить из консоли, что шаги дошли:

curl -s -u "$LANGFUSE_PUBLIC_KEY:$LANGFUSE_SECRET_KEY" \
  "$LANGFUSE_BASE_URL/api/public/v2/observations?limit=5"

В v4 старый эндпоинт /api/public/traces отвечает ошибкой про режим events-only. Так и должно быть, установка тут ни при чём. В настоящем агенте точно так же оборачиваются вызов LLM и каждый инструмент; к тому же у Langfuse есть интеграции с популярными SDK для LLM и фреймворками агентов, так что чаще всего хватает поменять импорт, а не расставлять декораторы повсюду.

За чем следить

  • Диск. ClickHouse и MinIO хранят всё, что вы отправили. Куда ушло место, покажет docker system df -v. Если трассировать длинные промпты и ответы, 45 ГБ на Medium-IP закончатся за недели, а не за годы. Проверяйте раз в месяц; когда упрётесь, тариф Pro на 400 ГБ и больше — по заявке.
  • Обновления. Compose-файл закрепляет мажорную версию (:4). docker compose pull && docker compose up -d подтянет исправления внутри неё. Перед сменой мажорной версии читайте changelog: как раз в v4 пропал эндпоинт трасс.
  • Бэкапы. Всё ценное лежит в томах Docker: в Postgres — пользователи, проекты и ключи, в ClickHouse и MinIO — сами трассы. Копируйте их с сервера по расписанию.

Стоит ли это $20 в месяц? Если ваши агенты тратят на токены больше — а агенты без присмотра обычно тратят, — то знание, куда ушли токены, окупится в первую же ночь, когда какой-нибудь цикл пойдёт вразнос. Одному маленькому агенту, который запускается раз в день, всё это не нужно: хватит лог-файла и счётчика токенов.

По теме

Готовы развернуть? Оплата криптой, без KYC — сервер за минуту.

Развернуть →

Частые вопросы

Сколько памяти нужно своему Langfuse?

На нашем тестовом сервере Langfuse v4 — это шесть контейнеров: веб, воркер, Postgres, ClickHouse, Redis и MinIO — занял около 3,5 ГБ RAM с пустым проектом. ClickHouse растёт с каждым отправленным шагом. Medium-IP (6 ГБ RAM, 45 ГБ диска) спокойно тянет его для нескольких агентов; целому флоту агентов с историей за месяцы нужен тариф Pro — он по заявке.

Нужен ли Langfuse выделенный IP?

Только если агенты работают на других машинах и шлют трассы через интернет: им нужен HTTPS-адрес, а на NAT-тарифе снаружи доступен только ваш SSH-порт. Если агенты живут на этом же сервере, Langfuse может слушать только localhost, а панель вы откроете через SSH-туннель — для этого подойдёт и Medium на NAT.

Код отрабатывает, а в панели пусто. Почему?

Почти всегда не задан LANGFUSE_BASE_URL. Без него SDK отправляет данные в облако самого Langfuse, ваших ключей там нет, и до вашего сервера ничего не доходит. Укажите в переменной свой адрес.

Эндпоинт /api/public/traces отвечает ошибкой. Установка сломана?

Нет. Langfuse v4 работает в режиме events-only, и этот эндпоинт в нём отключён. Читайте данные через /api/public/v2/observations — именно так мы проверили, что тестовые шаги дошли.

Как закрыть регистрацию для посторонних?

Langfuse понимает AUTH_DISABLE_SIGNUP, но стандартный docker-compose.yml не передаёт эту переменную в веб-контейнер, так что одной строки в .env мало. Добавьте строку в окружение langfuse-web (команда ниже), выставьте true после того, как создадите свой аккаунт, — и дальше регистрация отвечает «Sign up is disabled».

Комментарии

Пока нет комментариев. Будьте первым.

Оставить комментарий

Комментарии проходят модерацию перед публикацией.