−25%

روی پرداخت سالانه Windows، تا ۳۱ اکتبر. مشاهده پلن‌ها

EQVPS
شروع کنید

سرور VPS برای Langfuse: ایجنت‌های AI شما چه کردند؟

خودتان Langfuse را میزبانی کنید و هر فراخوانی LLM و هر گام ابزار ایجنت‌های بی‌نظارت را ردگیری کنید. Docker Compose آزموده، اعداد واقعی RAM و پلن مناسب.

ارزش ایجنتی که ساعت سه بامداد بی‌آنکه کسی نگاهش کند کار می‌کند، دقیقاً به اندازهٔ توانایی شما در بازسازی بعدی کارهایی است که کرده. «شبانه ۳۸ دلار توکن سوزاند» صبح بدی است. «۳۸ دلار سوزاند چون ابزار جست‌وجو یک صفحهٔ خالی برگرداند و برنامه‌ریز ۴۰۰ بار دوباره تلاش کرد» باگی است که پیش از ناهار درستش می‌کنید. جملهٔ دوم به ردگیری نیاز دارد.

‏Langfuse هر فراخوانی LLM، هر prompt، گام ابزار، تعداد توکن و تأخیر را به‌شکل درختی ثبت می‌کند که می‌توانید با کلیک در آن بگردید. وقتی خودتان میزبانش باشید، این promptها و پاسخ‌ها — که اغلب دادهٔ مشتری، خروجی API و گاهی رازی جامانده در خود دارند — روی سروری می‌مانند که خودتان کنترلش می‌کنید، نه در داشبورد کس دیگری.

هزینهٔ روشن نگه داشتنش

‏Langfuse v4 یک فایل اجرایی کوچک نیست، بلکه شش کانتینر است: اپ وب، یک worker پس‌زمینه، Postgres، ClickHouse برای رویدادها، Redis و MinIO برای فایل‌ها. آن را روی یک سرور آزمایشی نصب کردیم و با پروژهٔ خالی حدود ۳٫۵ گیگابایت RAM مصرف‌شده اندازه گرفتیم. چیزی که بزرگ می‌شود ClickHouse است، چون هر spanی که می‌فرستید به آنجا می‌رود.

بار کاریپلن
چند ایجنت، ردهای چندهفته‌ایMedium-IP: ۶ vCPU، ۶ گیگابایت، ۴۵ گیگابایت (۲۰ دلار در ماه)
ناوگانی از ایجنت‌ها، تاریخچهٔ چندماههپلن‌های Pro، از ۳۲ گیگابایت RAM به بالا — با درخواست

روی پلن‌های کوچک‌تر نصب می‌شود، اما همین که ClickHouse و worker هم‌زمان حافظه بخواهند به نفس‌نفس می‌افتد. من کمتر از ۶ گیگابایت نمی‌گرفتم.

ایجنت‌ها کجا زندگی می‌کنند؟ اگر روی ماشین‌های دیگری اجرا می‌شوند، پلنی با IPv4 اختصاصی بگیرید: آن‌ها به endpoint با HTTPS نیاز دارند و در پلن NAT آدرس خروجی مال خود شما نیست و از بیرون فقط به پورت SSH می‌شود رسید. اگر ایجنت‌ها روی همین سرور اجرا شوند، Langfuse اصلاً لازم نیست رو به اینترنت باشد: برای آزمایش، Medium با NAT (۱۲ دلار در ماه) کافی است. دو موقعیت هست، آلمان و فنلاند؛ موجودی هنگام سفارش دیده می‌شود. نزدیک‌ترین را به ایجنت‌ها انتخاب کنید، نه به خودتان. هزینهٔ سرور با رمزارز و بدون 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 ببندید تا تنها ورودی، reverse proxy باشد:

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", ...} را چاپ کند. اولین اجرا مهاجرت‌های پایگاه داده را انجام می‌دهد؛ در آزمایش ما بررسی سلامت حدود ۱۵ ثانیه پس از بالا آمدن کانتینرها موفق شد.

‏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 پیش‌فرض آن را به کانتینر web نمی‌دهد، پس یک خط دیگر زیر 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» می‌گیرد. همکاران را از داخل پروژه اضافه کنید.

فرستادن ردها از یک ایجنت

‏SDK پایتون تابع‌های شما را می‌پوشاند و فراخوانی‌های تودرتو به spanهای تودرتو تبدیل می‌شوند:

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 می‌فرستد، کلیدهای شما آنجا نیستند و به یک داشبورد خالی خیره می‌مانید.

برای اینکه از ترمینال مطمئن شوید spanها رسیده‌اند:

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 و فریم‌ورک‌های ایجنت یکپارچه‌سازی دارد، پس اغلب کافی است یک import را عوض کنید به‌جای اینکه همه‌جا decorator بپاشید.

چه چیزهایی را زیر نظر داشته باشید

  • دیسک. ‏ClickHouse و MinIO هرچه بفرستید نگه می‌دارند. اینکه فضا کجا رفته را docker system df -v نشان می‌دهد. اگر promptها و پاسخ‌های بلند را ردگیری کنید، ۴۵ گیگابایت Medium-IP در چند هفته پر می‌شود، نه چند سال. ماهی یک بار بررسی کنید؛ وقتی تنگ شد، پلن Pro با ۴۰۰ گیگابایت یا بیشتر با درخواست در دسترس است.
  • به‌روزرسانی‌ها. فایل compose نسخهٔ اصلی (:4) را ثابت نگه می‌دارد. ‏docker compose pull && docker compose up -d اصلاحات درون همان نسخه را می‌آورد. پیش از تغییر نسخهٔ اصلی changelog را بخوانید: اندپوینت ردها درست در v4 ناپدید شد.
  • پشتیبان‌گیری. آنچه اهمیت دارد در volumeهای Docker است: ‏Postgres کاربران، پروژه‌ها و کلیدها را نگه می‌دارد و ClickHouse و MinIO خود ردها را. آن‌ها را طبق برنامه به بیرون از سرور کپی کنید.

آیا ماهی ۲۰ دلار می‌ارزد؟ اگر ایجنت‌هایتان بیش از این خرج توکن می‌کنند — و بیشتر ایجنت‌های بی‌نظارت می‌کنند — دانستن اینکه توکن‌ها کجا رفته‌اند همان بار اولی که یک حلقه از کنترل خارج شود، هزینه‌اش را جبران می‌کند. یک ایجنت کوچک که روزی یک بار اجرا می‌شود به هیچ‌کدام از این‌ها نیاز ندارد: یک فایل لاگ و یک شمارندهٔ توکن کافی است.

مرتبط

آماده استقرار؟ با رمزارز بپرداز، بدون KYC — در حدود یک دقیقه فعال می‌شود.

← همین حالا مستقر کن

سؤالات متداول

یک Langfuse خودمیزبان چقدر RAM لازم دارد؟

روی سرور آزمایشی ما، Langfuse v4 به‌صورت شش کانتینر اجرا شد — web، worker، Postgres، ClickHouse، Redis و MinIO — و با یک پروژهٔ خالی حدود ۳٫۵ گیگابایت RAM مصرف کرد. ClickHouse با هر span که می‌فرستید بزرگ‌تر می‌شود. پلن Medium-IP (۶ گیگابایت RAM، ۴۵ گیگابایت دیسک) آن را برای چند ایجنت به‌راحتی اجرا می‌کند؛ یک ناوگان کامل با تاریخچهٔ چندماهه به پلن Pro نیاز دارد که با درخواست در دسترس است.

آیا Langfuse به آدرس IP اختصاصی نیاز دارد؟

فقط اگر ایجنت‌ها جای دیگری اجرا شوند و ردها را از طریق اینترنت بفرستند: آن‌ها به یک endpoint با HTTPS نیاز دارند و پلن NAT از بیرون فقط پورت SSH شما را می‌پذیرد. اگر ایجنت‌ها روی همان سرور باشند، Langfuse می‌تواند روی localhost بماند و داشبورد را با تونل SSH باز می‌کنید؛ برای این کار پلن Medium با NAT کافی است.

کد اجرا می‌شود، اما داشبورد خالی می‌ماند. چرا؟

تقریباً همیشه LANGFUSE_BASE_URL تنظیم نشده است. بدون آن، SDK همه‌چیز را به ابر خود Langfuse می‌فرستد، کلیدهای نمونهٔ شما آنجا وجود ندارند و چیزی به سرور شما نمی‌رسد. آدرس خودتان را در این متغیر بگذارید.

اندپوینت ‎/api/public/traces خطا برمی‌گرداند. آیا نصب خراب است؟

نه. Langfuse v4 در حالت events-only کار می‌کند و این اندپوینت در آن غیرفعال است. داده‌ها را از ‎/api/public/v2/observations بخوانید — ما هم با همین فراخوانی مطمئن شدیم که spanهای آزمایشی‌مان رسیده‌اند.

چطور جلوی ثبت‌نام غریبه‌ها در نمونه‌ام را بگیرم؟

‏Langfuse متغیر AUTH_DISABLE_SIGNUP را می‌خواند، اما docker-compose.yml پیش‌فرض آن را به کانتینر web نمی‌رساند، پس نوشتنش فقط در ‎.env فایده‌ای ندارد. یک خط به محیط langfuse-web اضافه کنید (دستور پایین‌تر آمده)، بعد از ساختن حساب خودتان آن را true کنید تا ثبت‌نام‌های بعدی پاسخ «Sign up is disabled» بگیرند.

نظرات

هنوز نظری نیست. اولین نفر باشید.

یک نظر بگذارید

نظرات پیش از نمایش بررسی می‌شوند.