Langfuseのセルフホスト:LLMオブザーバビリティ実践ガイド

AI tutorial - IT technology blog
AI tutorial - IT technology blog

従来のロギングからLLMオブザーバビリティへの移行

標準的なロギングは、500エラーのキャッチやCPUスパイクの追跡には最適です。しかし、最初のRAGベースのチャットボットをデプロイしたとき、既存のELKスタックが急に時代遅れに感じられました。従来のログでは、なぜモデルがハルシネーション(もっともらしい嘘)を起こしたのか、あるいは特定の検索ステップが単純なクエリに対してなぜ4.2秒ものレイテンシを追加したのかを説明できませんでした。

LLMアプリケーションはブラックボックスの中で動作します。効果的にデバッグするには、実行チェーン全体を把握する必要があります。これには、使用された正確なプロンプトテンプレート、ベクトルデータベースから取得されたチャンク、モデルの生出力、そして正確なトークン数が含まれます。本番環境のAIワークフローを6か月間管理してきた経験から、コストを抑えつつこれらのデータを取得するには、Langfuseが最も堅牢な方法であると確信しています。

選択肢の比較

セルフホスト構成に決める前に、AIパイプラインを監視するための3つの異なるアプローチを検討しました。

  • 標準的なロギング (ELK/Grafana): ネストされたトレースを可視化するために、大規模なカスタム開発が必要です。また、プロンプトのバージョンを並べて比較するための組み込みツールも不足しています。
  • プロプライエタリなプラットフォーム (LangSmith): 機能セットは最高峰ですが、価格体系が非常にアグレッシブです。月に100万トレースに達するプロジェクトの場合、オブザーバビリティだけで月額100ドルを超えるコストが容易にかかります。また、多くのエンタープライズ顧客は、機密性の高い内部プロンプトをサードパーティのSaaSに送信することを断固として拒否します。
  • オープンソース의 セルフホスト (Langfuse): 中間的な選択肢です。すべてのデータを独自の仮想プライベートクラウド(VPC)内に保持しながら、トレースやプロンプト管理のための専用UIを利用できます。

セルフホストのメリットとデメリット

ここでの主な動機は「制御権」です。セルフホストはトレースごとの料金を節約できますが、一方で運用上の責任が生じます。

メリット

  • データ主権: 顧客データや独自のプロンプトがインフラ外に出ることはありません。これにより、GDPRやSOC2のコンプライアンス監査が大幅に簡素化されます。
  • 予測可能な費用: 使用量に応じて変動する月額料金ではなく、小規模なNode.jsコンテナとPostgreSQLインスタンスの固定料金を支払うだけで済みます。
  • 深い統合: Langfuseをローカルで実行することで、アプリケーションとオブザーバビリティ層の間のレイテンシを低く抑えることができ、トレースのオーバーヘッドを150ms未満に保つことが可能です。

トレードオフ

  • メンテナンス: データベースのバックアップ、セキュリティパッチ、バージョンのアップグレードは自身で行う必要があります。
  • リソース割り当て: 大規模なアプリの場合、分析クエリを効率的に処理するために、Postgresに加えてClickHouseインスタンスの管理が必要になる場合があります。

本番環境に適したアーキテクチャ

1日あたり5,000〜50,000リクエストを処理するほとんどの中規模アプリケーションは、Dockerベースのセットアップで最適に動作します。データレイヤーについては、AWS RDSやDigitalOcean Managed Databasesのようなマネージドサービスを強く推奨します。マネージドDBを使用することで、手動の介入なしで自動バックアップと高可用性を確保できます。ただし、クイックスタートやローカルテストの場合は、フルスタックのDocker Composeでも十分に機能します。

コアコンポーネント

システムは以下の3つの柱で構成されます。

  1. Langfuseサーバー: APIとWebダッシュボードを提供するNode.jsアプリケーション。
  2. PostgreSQL (v16): トレース、プロンプト、ユーザーフィードバックの主要な保存先。
  3. Redis: キャッシュを処理し、バックグラウンドタスクがUIのボトルネックにならないようにします。

ステップバイステップの実装

DockerとDocker Composeがインストールされている必要があります。スムーズなパフォーマンスのために、少なくとも2 vCPUと4GBのRAMを搭載したサーバーを推奨します。

1. 設定

プロジェクトディレクトリを作成し、docker-compose.ymlファイルを追加します。本番環境では「latest」タグの使用を避け、「langfuse/langfuse:2」のようなメジャーバージョンに固定することで、自動更新によるスタックのクラッシュを防ぎます。

version: '3.5'

services:
  langfuse-server:
    image: langfuse/langfuse:2
    depends_on:
      - db
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - NEXTAUTH_URL=http://localhost:3000
      - NEXTAUTH_SECRET=ここに長いランダムな文字列を入力してください
      - SALT=別のランダムなソルト文字列を入力してください
      - DATABASE_URL=postgresql://postgres:password@db:5432/postgres
      - TELEMETRY_ENABLED=false

  db:
    image: postgres:16
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=postgres
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

docker-compose up -dを使用してスタックを起動します。http://localhost:3000でダッシュボードにアクセスし、管理者アカウントを作成してAPIクレデンシャルを生成します。

2. Pythonとの統合

統合は非常に簡単です。LangChainを使用している場合は、シンプルなコールバックを追加するだけです。生のOpenAI呼び出しを使用している場合は、SDKデコレータが最もクリーンな方法です。まず、必要なパッケージをインストールします。

pip install langfuse openai

以下のコードスニペットは、LLM関数をラップして、レイテンシ、コスト、メタデータを自動的にキャプチャする方法を示しています。

from langfuse.openai import openai
import os

os.environ["LANGFUSE_PUBLIC_KEY"] = "pk-lf-your-key"
os.environ["LANGFUSE_SECRET_KEY"] = "sk-lf-your-key"
os.environ["LANGFUSE_HOST"] = "http://localhost:3000"

def get_ai_response(user_input):
    # ラッパーがリクエスト/レスポンスのサイクル全体をキャプチャします
    response = openai.chat.completions.create(
      model="gpt-4o",
      messages=[
          {"role": "system", "content": "あなたはテクニカルアシスタントです。"},
          {"role": "user", "content": user_input}
      ],
      name="production-chat-v1",
      metadata={"env": "production", "user_id": "user_99"}
    )
    return response.choices[0].message.content

print(get_ai_response("Postgresのクエリを最適化するにはどうすればよいですか?"))

3. 出力の評価

トレースはリアルタイムでダッシュボードに表示されます。最近のデバッグセッションで、プロンプトの更新後に「役立ち度」スコアが大幅に低下していることに気付きました。Langfuseでトレースをフィルタリングしたところ、特定の検索ステップが無関係なドキュメントを2,000トークン分もコンテキストに注入していることが判明しました。このノイズがLLMを混乱させていたのです。トレースを使えば特定に5分しかかかりませんでしたが、そうでなければ手動でログを調べるのに何時間もかかっていたでしょう。

基本的な追跡を超えて

オブザーバビリティは、信頼性の高いAI製品への第一歩に過ぎません。本当の力は「スコア(Scores)」にあります。ダッシュボードで手動で回答を評価することも、LLM-as-a-judgeを使用してプロセスを自動化することもできます。すべてのトレースに関連性スコアを割り当てることで、下位5%の回答をフィルタリングできます。これにより、チームは推測をやめ、アプリケーションが実際に失敗している特定のエッジケースの修正に着手できるようになります。

単純なプロトタイプを超えようとしているなら、可視性が必要です。セルフホストのLangfuseインスタンスのセットアップは30分もかかりません。脆弱なAIの実験を、安定した本番グレードのサービスへと変貌させるために必要な透明性を提供してくれます。

Share: