はじめに
Langfuse(ラングフューズ)は、LLM(大規模言語モデル)を活用したアプリケーションの開発、デバッグ、運用・監視を一元的に行うオープンソースの「LLMOps(LLMオペレーション)プラットフォーム」です。プロンプト管理や応答の分析、コスト監視などを提供し、開発者がAIアプリの品質を継続的に改善できるよう支援するツールです。
セルフホストでの配置もでき、ローカルLLMやwatsonx.AIなどの企業管理のLLMアプリのモニタリングにも利用できます。
Langfuseのインストール
今回も、いつもの自宅環境Windows11上のWSL2で動くUbuntuにインストールをしていきます。
- Windows 11 / WSL2 Ubuntu
- Docker Compose
- Langflow + PostgreSQL 16
- Ollama は Windows ホスト側
- Langflow から Ollama ノードで応答取得済み
1. 構成概要
LangflowとLangfuseを別Composeプロジェクトで動かし、Dockerネットワークで接続です。
[Browser]
├─ http://localhost:7860 → Langflow
└─ http://localhost:3000 → Langfuse
[Langflow container]
├─ Ollama: http://192.168.0.6:11434 など
└─ Langfuse: http://langfuse-web:3000
[Langfuse container]
└─ Ollama: http://192.168.0.6:11434 など
Langflowは環境変数にLANGFUSE_SECRET_KEY、LANGFUSE_PUBLIC_KEY、LANGFUSE_BASE_URLを設定すると、flow実行時のtraceをLangfuseへ送れます。現在はLANGFUSE_BASE_URLが推奨で、古いLANGFUSE_HOSTも互換用に残っています。
2. 公式リポジトリを取得
git clone https://github.com/langfuse/langfuse.git
cd langfuse
3. シークレットを変更
下記のコマンドでシークレット乱数を作っておき、メモしておきます。
$ openssl rand -hex 32
5dcc42346bcb405a4ee53dca5f7aa27afc2ea561247099c99e7538ad90ce1d4e
長い桁数が必要なので、上記コマンドを実行するのがお勧めです。
docker-compose.ymlファイルのENCRYPTION_KEY行の値を上記変数に変更します。
vi docker-compose.yml
一度Langfuseを起動してみます。
docker compose up
起動メッセージに異常が無ければメッセージに出ているURLに次のステップでアクセスしていきます。
Langfuse WebUIの確認
LangfuseのWebUIにアクセスします。
http://localhost:3000/
ユーザー名、メールアドレス、パスワードを設定するとダッシュボードが開きます。

Langfuse初期設定
LangfuseのWebUIから、以下を作成します。
- Organization
- Project
- API Keys
API Key画面で以下を控えます。
Public Key: pk-...
Secret Key: sk-...
Base URL: http://localhost:3000
(.env用のコピーを利用するのが便利)
ただし、Langflowコンテナから見るBase URL は localhost ではありません。
LangflowとLangfuseを同じDockerネットワークに置くので、次のURLに以降の設定で読み替えておきます。
http://langfuse-web:3000
一度Langfuseを停止
設定変更を行うにあたって、この方がスムーズにいくので、一度停止してしまいます。
docker compose down
Dockerネットワークを作る
LangflowとLangfuseを接続する共通ネットワークを作ります。
docker network create llm-observability
Langfuse側にネットワークの設定を適用する
Langfuse側の docker-compose.yml の末尾にネットワークを追加します。
networks:
langfuse-internal:
name: langfuse-internal
llm-observability:
external: true
併せて、langfuse-webは外部に出しつつ、Langfuse関連のサービスはLangfuse関連のコンテナで完結する設定にします。LangflowのPostgreSQLとの混同を避けるため、サービス名を変えておきます。
services:
langfuse-worker:
<snip>
# 依存関係のPostgreSQLの名前も変更
depends_on: &langfuse-depends-on
langfuse-postgres:
<snip>
# PostgreSQLの接続先も修正
environment: &langfuse-worker-env
NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000}
DATABASE_URL: ${DATABASE_URL:-postgresql://xxxxx:xxxxx@langfuse-postgres:5432/postgres} # CHANGEME
<snip>
networks:
- langfuse-internal
# Langfuse-webは外部公開のネットワークを追加
langfuse-web:
<snip>
# 環境変数ですべてのネットワークからの接続を許可するように変更
environment:
<<: *langfuse-worker-env
HOSTNAME: 0.0.0.0
<snip>
networks:
- langfuse-internal
- llm-observability
clickhouse:
<snip>
networks:
- langfuse-internal
minio:
<snip>
networks:
- langfuse-internal
redis:
<snip>
networks:
- langfuse-internal
# PostgreSQLは名称変更、ポートコメントアウト
langfuse-postgres:
<snip>
# ports:
# - 127.0.0.1:5432:5432
<snip>
networks:
- langfuse-internal
その後、Langfuseを再起動します。
docker compose up -d
Langflow側にLangfuseの接続設定とコンテナ内部ネットワークの設定を適用する
Langflow側のdocker-compose.ymlも下記の箇所を修正していきます。
services:
langflow:
<snip>
depends_on:
- langflow-postgres
environment:
- LANGFLOW_DATABASE_URL=postgresql://xxxxxx:xxxxxx@langflow-postgres:5432/langflow
- LANGFLOW_CONFIG_DIR=/var/lib/langflow
# Langfuse tracing
- LANGFUSE_PUBLIC_KEY=pk-lf-xxxxxxxx
- LANGFUSE_SECRET_KEY=sk-lf-xxxxxxxx
- LANGFUSE_BASE_URL=http://langfuse-web:3000
<snip>
networks:
- langflow-internal
- llm-observability
langflow-postgres:
<snip>
# ports:
# - "5432:5432"
volumes:
- langflow-postgres:/var/lib/postgresql/data
networks:
- langflow-internal
末尾にネットワークの設定を書きます。
networks:
langflow-internal:
name: langflow-internal
llm-observability:
external: true
Langflowを起動します。Langflowのdocker-compose.ymlがあるディレクトリで実行します。
docker compose up -d
LangflowからLangfuseコンテナへの接続確認をします。
$ docker compose exec langflow curl http://langfuse-web:3000/api/public/health
{"status":"OK","version":"3.173.0"}
Langfuseを使ってみよう!
簡易的な動作確認
先日の記事で紹介したLangflowのOllamaを利用したフローを適当に一度動かし、動作を確認します。

Langfuse側のダッシュボードでトレースができていればOKです。

Langfuseの機能を試してみる
テストシナリオ1:単純LLM呼び出しのTrace確認
まずは一番シンプルなフローをLangflowで作成し、動作確認してみます。
Chat Input
→ Prompt
→ Ollama
→ Chat Output
質問例:
Langflowとは何ですか?100文字で説明してください。
Langfuseで確認するポイント:
- Traceが作成されるか
- 入力プロンプトが見えるか
- LLM応答が見えるか
- 実行時間が見えるか
- エラーが出ていないか
LangfuseのTracing画面には次のような出力を確認することができました。
入力プロンプトが出ていてエラーも特に出ていないことが確認できます。

シナリオ2:失敗フローの観測
わざとOpenAIのAPIキーを間違え、先ほどと同じ質問をし、その時の動作を確認してみます。

Langfuseで確認するポイント:
- Langflow側でエラーになるか
- Langfuseに失敗traceが残るか
- どのノードで止まったか追えるか
このようにOpenAIノードでエラーが出ていることが検知されています。

スコアを有効にしてみよう
Langfuseの「Score」はUIで後から付ける方法と、API/SDKから自動で付ける方法があります。
まずUIで手動スコアを有効にする
Langfuse UIで対象Projectを開いて、以下に進みます。
Project Settings
→ Score Config
→ Add new score config
Score Configでは、スコア名と型を決めます。LangfuseではScore Configが、チーム内で同じ基準・同じ型のスコアを付けるための定義になります。UIからScoreを付ける場合は、事前に少なくとも1つScore Configが必要です。
シンプルな数字での設定はこのような設定になります。
- Score name: helpfulness
- Data type: NUMERIC
- Min: 1
- Max: 5
- Description: 回答の親切さ
または分類形式なら…
- Score name: answer_quality
- Data type: CATEGORICAL
- Categories:
- good
- partial
- bad
- Description: 回答の品質
ツール呼び出しが期待通りだったかなどの場合は、BOOLEANを使いましょう。
- Score name: tool_success
- Data Type: BOOLEAN
- Description: ツール呼び出し成功
LangfuseのScore型は NUMERIC、CATEGORICAL、BOOLEAN、TEXT の4種類です。
https://langfuse.com/docs/evaluation/scores/overview
シナリオ3:プロンプト比較
同じ質問に対して、Promptを2種類作ります。
このプロンプトのTraceにスコアを付けてみましょう。
Prompt A
次の質問に簡潔に答えてください。
質問: {input}
Prompt B
あなたは社内ITヘルプデスクです。
ユーザーの質問に対して、原因、確認方法、対応手順の順で答えてください。
質問: {input}
質問例:
VPNにつながらない場合の確認方法を教えて
Traceが出ている状態で、以下に進みます。
- 任意のTraceを開く
- Annotate
- 作成したScore Configを選択
- Score値を入力

このようにスコアを付けていきます

付与したスコアはこのように確認することができます。

まとめ
ちょっと長い記事になったので、今日はここまでにします。
SaaSのLLMOpsツールは今までもありましたが、Langfuseはセルフホストできるのが、外部サービス利用にいろいろな申請が必要な企業の検証利用やコストをあまりかけたくない個人での検証にもいいですね。
後編ではLLM-as-a-judgeにトライしてみようと思います。
後編
LangflowでLangfuse(self-host)を使ってLLMOps試す・後編 LLM-as-a-judgeを試す




