AI

Langfuse OpenTelemetry連携の実装|OTLP送信の設定と既存パイプラインの分岐

Langfuse OpenTelemetry連携の実装|OTLP送信の設定と既存パイプラインの分岐

既にOpenTelemetryでアプリを計装している現場が、LLMの呼び出しだけをLangfuseでも見たいとなったとき、悩みどころは「SDKを入れ直すのか、いまのパイプラインから分岐させるのか」に集約されます。LangfuseはOTLPの受け口を持っているので、後者を選べます。ここでは受け口のパスと認証の作り方、スパンの選び分け、既存の送信先との併存、セッションとユーザーの紐付け、セルフホスト時の部品と保持期間までを、2026年8月時点の一次情報で整理しました。製品としての機能や料金、LangSmithとの比較はLangfuse本体を解説した記事に譲ります。

まとめ|先に決める3点と、既存構成を壊さない分岐のかたち

決めるのは3点です。第一に、送信の経路をアプリから直に出すのかCollectorを挟むのか。第二に、Langfuseへ送るスパンをどう選ぶか。第三に、記録をどれだけの期間残すか。

受け口は /api/public/otel の1本で、扱えるのはトレースだけです。メトリクスとログの送り先は既存の基盤のまま据え置きます。通信はHTTP経由のみで、gRPCで束ねている構成はここだけHTTPに切り替えるか、Collectorで受け直す形になります。

既存のパイプラインを持っているなら、TracerProviderにプロセッサをもう1枚足す構成が扱いやすいでしょう。全スパンをAPMへ、LLM関連のスパンだけをLangfuseへ、と送り先を分けられます。両者が同じスパンを見るので、親子関係も保たれたまま残ります。

LangfuseがOTLPを受ける仕組みと2026年8月時点で使える範囲

受け口は一本だけ|OTLPのトレースだけを受け取る設計になっている

LangfuseはOTLPのバックエンドとして振る舞い、/api/public/otel でスパンを受け取ります。トレース専用のパスとして /api/public/otel/v1/traces も用意されており、シグナル別にエンドポイントを分けている構成ならこちらを指します。

受け取れるのはトレースだけという点は先に押さえてください。メトリクスとログはこのエンドポイントの対象外で、送っても取り込まれません。LLM関連の指標をダッシュボードで見たい場合、Langfuse側の画面はスパンから集計したものを使い、インフラ側のメトリクスは既存の監視基盤に置いたままにします。シグナルの区分そのものはOpenTelemetryの仕組みを整理した記事にまとめてあります。

使える通信方式はHTTPの2種類で、gRPCはまだ受け付けない

対応しているのはOTLP over HTTPで、符号化は protobuf と JSON の両方が通ります。gRPCは2026年8月時点で非対応です。

ここは構成に効きます。社内の計装をgRPCで統一していると、アプリ側のエクスポータをLangfuse向けだけHTTPに差し替える必要が出ます。エクスポータを2つ持つのが煩雑なら、Collectorでは受信側でgRPCを受けたうえで、Langfuse向けの送出だけ otlphttp エクスポータに寄せる形が現実的でしょう。

リージョンごとにホスト名が分かれ、日本向けの受け口も用意される

クラウド版のホスト名はリージョンごとに分かれています。欧州は cloud.langfuse.com、米国は us.cloud.langfuse.com、日本は jp.cloud.langfuse.com、医療情報を扱う区分は hipaa.cloud.langfuse.com です。

プロジェクトの鍵はリージョンをまたいで使えません。日本リージョンで作ったプロジェクトの鍵を欧州のホストへ送っても認証が通らないので、エンドポイントと鍵の組み合わせは環境変数の同じ場所で管理しておくと事故が減ります。

認証とヘッダの設定|Basic認証の文字列と取り込み版ヘッダの指定

公開鍵と秘密鍵をコロンで連結してbase64へ直す手順の中身

認証はBasicです。プロジェクト設定で発行する公開鍵(pk-lf- で始まる文字列)と秘密鍵(sk-lf- で始まる文字列)をコロンでつなぎ、base64へ変換した値をヘッダに載せます。

変換は手元のシェルで済みます。改行が混ざると認証が落ちるため、出力の折り返しは無効にしてください。

echo -n "pk-lf-xxxx:sk-lf-yyyy" | base64 -w 0

OTLPの環境変数は全体指定とトレース専用指定の2通りから選ぶ

設定は環境変数で完結します。全シグナル共通で指定する場合は次の形です。エンドポイントにはシグナル名を含めないパスを与えます。

OTEL_EXPORTER_OTLP_ENDPOINT="https://cloud.langfuse.com/api/public/otel"
OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic $AUTH_STRING,x-langfuse-ingestion-version=4"

既存のパイプラインが同じ環境変数で別の送り先を指しているなら、トレース専用の変数に分けます。OTEL_EXPORTER_OTLP_TRACES_ENDPOINT と OTEL_EXPORTER_OTLP_TRACES_HEADERS を使い、パスの末尾を /v1/traces まで含めた形にしてください。言語別の入口も揃っていて、Goは otlptracehttp、Javaはエージェント起動時の OTEL_TRACES_EXPORTER と OTEL_EXPORTER_OTLP_PROTOCOL、.NETは AddOtlpExporter での protobuf 指定、Rubyは設定用の初期化呼び出しで、いずれも環境変数を読み取ります。

取り込み版を指すヘッダを外すと画面への反映が最大15分遅れる

ヘッダに並べる x-langfuse-ingestion-version=4 は見落としやすい項目です。これが無いと取り込みが従来経路に落ち、画面へ出るまで最大15分の遅れが出ます。

公式のSDKを使う場合も版の下限があります。即時に反映させるには Python SDK 4.7.0 以上、JS SDK 5.4.0 以上が必要とされています。素のOTelエクスポータから送るなら、ヘッダの1行を足すだけで同じ扱いになるので、開発中の試行錯誤を考えるとまず入れておくほうが手戻りが少ないでしょう。

自動計装ライブラリでスパンを取る|SDKと素のOTelの分かれ目

PythonとTypeScriptはSDK、他の言語は素のOTelで送り出す

2026年8月時点の現行版は Python SDK が v4系、JS/TS SDK が v5系です。トレース部分はどちらもOpenTelemetryの上に作り直されており、Python は v3系から、JS は v4系からこの構造になりました。動作の下限は Python 3.9 と Node.js 20 です。

この2言語ではSDKを使うほうが手数が減ります。属性の付け替え、コンテキストの伝播、画像や音声の添付、送るスパンの選別といった処理があらかじめ入っているためです。それ以外の言語は素のOpenTelemetry APIで計装し、エクスポータの送り先をLangfuseに向けます。

JavaやGoはOpenLLMetryやOpenLITで計装の範囲を広げられる

公式SDKが無い言語でも、OTel準拠の計装ライブラリを挟めば手書きの範囲は減ります。OpenLLMetry や OpenLIT はこの用途でよく挙がる選択肢で、JavaやGoからのLLM呼び出しに gen_ai 配下の属性を付けたスパンを生成します。

ライブラリを選ぶときは、対応しているモデル提供元と、出力する属性がどの版の規約に沿っているかを確認してください。属性名は過去に複数回入れ替わっており、古い名前のままの実装が残っています。属性の体系と改名の履歴はGenAIセマンティック規約を整理した記事で扱っています。

スパンが観測記録へどう変換されるかは、属性の対応表で確かめる

送ったスパンは、Langfuse側でトレースと観測記録に組み替えられます。どの属性がどの欄に入るかは決まっており、langfuse 名前空間の属性が最も強く効きます。

画面上の項目 属性名(langfuse配下)
種別 observation.type
入力 observation.input
出力 observation.output
モデル名 observation.model.name
費用 observation.cost_details
深刻度 observation.level
トレース名 trace.name
利用者 user.id

標準規約の側からも受け取れます。モデル名は gen_ai.request.model や gen_ai.response.model、トークン数は gen_ai.usage 配下、入出力は OpenInference の input.value や MLflow の mlflow.spanInputs でも拾われます。種別を明示しなくても、モデル名の属性を持つスパンは生成として扱われる仕様です。対応表に無い属性は消えるわけではなく、メタデータの配下にまとめて残ります。

既存のOTelパイプラインとの併存|プロセッサ二枚差しとCollector分岐

TracerProviderにプロセッサを2つ並べる構成の書き方

既にTracerProviderを組んでいるなら、そこへLangfuse用のプロセッサを追加する形が素直です。既存のエクスポータは触らずに残せます。

provider = TracerProvider()
provider.add_span_processor(LangfuseSpanProcessor())
provider.add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter(endpoint=APM_ENDPOINT))
)
trace.set_tracer_provider(provider)

TypeScript側も同じ考え方で、NodeSDK の spanProcessors に2つ並べます。両方のプロセッサが全スパンを受け取り、送るかどうかを各自が判断する作りです。トレースIDは共通なので、APM側で見つけた遅いリクエストのIDをそのままLangfuseの検索欄に入れれば、同じ実行のLLM呼び出しにたどり着けます。

既定のフィルタが拾う3種類と、絞り込みを自分で書き替える方法

Langfuse側のプロセッサには既定の絞り込みが入っています。対象になるのは、Langfuse SDKが作ったスパン、gen_ai 配下の属性を持つスパン、既知のLLM計装スコープから出たスパンの3種類です。HTTPやDBのスパンは既定では送られません。

この判定はコールバックによる差し替えが可能です。Pythonは should_export_span、JSは shouldExportSpan にコールバックを渡し、既定判定の関数と組み合わせて条件を足し引きします。特定の計装スコープを除外したい、独自スコープのスパンも送りたい、といった調整はここで行います。送信量そのものを削りたい場合は、プロセッサ側の絞り込みだけでなくサンプリングの設計を整理した記事も併せて検討してください。

Collectorで受けて2つの送信先へ複製する構成と設定の勘所

アプリを何本も抱えていると、送り先の追加をアプリごとに配るのは骨が折れます。Collectorを挟めば、送信先の管理を一か所に寄せられます。

exporters:
  otlphttp/langfuse:
    endpoint: https://cloud.langfuse.com/api/public/otel
    headers:
      Authorization: Basic $AUTH_STRING
      x-langfuse-ingestion-version: "4"

パイプラインでは、既存のエクスポータとこのエクスポータをトレースの同じ経路に並べて複製する構成です。全スパンをLangfuseへ送りたくないなら、フィルタ系のプロセッサを挟んだ経路を別に立て、そちらにだけLangfuse向けのエクスポータをつなぎます。鍵はCollectorの環境変数に入るので、アプリ側へ配る秘密情報も1本減ります。標準のCollectorに入っていないコンポーネントを使う場合の配布物の作り方はCollector Contribと自作ディストロの記事にまとめました。

セッションとユーザーの紐付け|画面側の絞り込みを効かせる属性名

会話の単位はsession、利用者の単位はuserの属性で結び付ける

トレースが1本ずつ並ぶだけでは、対話の流れを追えません。会話の単位は langfuse.session.id、利用者の単位は langfuse.user.id をスパンに載せて束ねます。標準規約側の session.id と user.id でも同じ欄に入ります。

置く先はルートスパンです。子スパンにだけ付けても、トレース単位の項目には反映されません。値の設計では、利用者の識別子に生のメールアドレスを入れず、内部IDや不可逆に変換した値を使う運用が無難でしょう。トレース名やタグも langfuse.trace.name と langfuse.trace.tags で明示できます。

環境の切り分けはリソース属性とスパン属性の2か所から指定する

本番と検証を同じプロジェクトへ送ると、評価の数字が混ざります。切り分けは環境の指定で行い、プロセス全体に効かせるならリソース属性を使います。

OTEL_RESOURCE_ATTRIBUTES="langfuse.environment=staging"

リクエストごとに環境が変わる構成、たとえば共有のゲートウェイが複数の環境からの呼び出しを受ける場合は、スパン単位で deployment.environment.name を設定します。値の書式には制限があり、小文字の英数字とハイフン・アンダースコアで40字以内、先頭を langfuse で始められません。画面の絞り込みは全ビューに効くので、ここを入れておくと後から分ける手間が消えます。

入出力と費用は専用の属性名で渡すと、画面の該当欄へ載せられる

自前の計装から送る場合、入出力は langfuse.observation.input と langfuse.observation.output にJSON文字列で載せます。費用は langfuse.observation.cost_details、トークン数は langfuse.observation.usage_details です。

費用の項目を自分で入れるかどうかは、モデルの扱いが判断基準です。Langfuseに登録済みの価格表で解決できるモデルなら、トークン数だけ渡せば金額は算出されます。社内ゲートウェイ経由で独自の単価を持つ場合や、提供元の課金体系が価格表に無い場合は、費用の属性を自分で計算して載せる形になります。深刻度の langfuse.observation.level は、スパンの状態から自動で決まるため、通常は明示しなくても構いません。

セルフホストの構成と保持期間|自前で運用するときに要る部品と設定

必要な部品は4つで、S3互換ストレージは3つの用途に分かれる

自前で置く場合、アプリのコンテナ以外に4種類の基盤が要ります。メタデータを持つ PostgreSQL、トレースの分析側を担う ClickHouse、キューとキャッシュの Redis または Valkey、そしてS3互換のオブジェクトストレージです。

ストレージは用途ごとにバケットの指定が分かれています。取り込みイベント、バッチ書き出し、メディアの3つで、それぞれ専用の環境変数を持ちます。同じバケットを共有する設定も取れますが、保持や権限を別に管理したいなら分けたほうが後が楽でしょう。ClickHouseは接続文字列に加えて移行用の指定も必要で、運用の重さの大半はここに来ます。

保持期間はプロジェクト単位で決め、最小3日で夜間に削除される

保持期間はプロジェクトごとに日数を指定する方式です。下限は3日で、所有者と管理者がプロジェクト設定の画面から変更できます。多くの利用者には30日あたりが妥当な既定として案内されています。

削除は夜間にまとめて走り、トレース・観測記録・スコア・メディアが対象です。期間を過ぎたものは画面からも消えるため、監査や再学習のために原本を残す方針なら、期間内に退避させる仕組みを別に置きます。定期的な書き出しの機能があり、S3・GCS・Azure のいずれかへ同期しておけば、保持期間を短くしたまま原本を保てます。

セルフホストでは削除の権限と退避先を先に決めておく必要がある

自前運用では、保持期間の設定が動くための前提が1つあります。全バケットに対してオブジェクト削除の権限をLangfuseのロールへ付与しておくことです。読み書きだけの権限で運用していると、期間を設定しても実体が消えません。

版の管理も先に決めておきます。OTLPの受け口は 3.22.0 以降で提供され、v3系とv4系の双方で動きます。ただしクラウド版は2026年11月16日にv4へ切り替わり、v3のAPIと取り込みが止まる予定です。自己ホストのv3系はセキュリティ修正が2027年1月までとされているので、この期間を移行の計画に入れておいてください。

採用の判断|OTLP直送で足りる条件と、SDKへ寄せるべき場面の線引き

OTLP直送で足りるのは、言語と計装が先に揃っている3つの条件

OTLPへ直接送る構成で足りるのは、次の3条件が揃うときです。第一に、アプリが既にOpenTelemetryで計装済みで、TracerProviderが1か所に集約されている。第二に、LLM呼び出しのスパンに gen_ai 配下の属性が付いている、あるいは計装ライブラリが付けてくれる。第三に、記録したいのがトレースの範囲に収まり、プロンプトの本文や添付ファイルの保存までは求めない。

この条件下では、環境変数2本とプロセッサ1枚で連携が成立します。既存のAPMへの送信を止める必要も、アプリのコードを大きく書き換える必要もありません。JavaやGo、C#のように公式SDKが無い言語でも同じ手順で載せられる点も効きます。

Langfuse SDKへ寄せるべき場面は、本文と添付と伝播の3つ

逆にSDKを入れるべき場面もはっきりしています。プロンプト管理の機能を使って版を固定したい、画像や音声を含む入出力を記録に残したい、非同期のワーカーやジョブをまたいでトレースをつなぎたい、のいずれかに当てはまるときです。

とくに3つ目は素のOTelでも書けますが、コンテキストの受け渡しを自前で通す作業が発生します。PythonとTypeScriptならSDK側に用意があるので、そこだけ使って他の言語はOTLP直送にする、という混在も取れます。両者は同じデータ構造へ落ちるため、後から片方へ寄せ直すときの損失も小さくて済むでしょう。トレースを評価と費用の管理へつなぐ全体像はLLMOpsの4層構成を整理した記事を参照してください。

計装と基盤の委託時に見積書で確かめる4項目と読み取り方の中身

外部に頼む場合、見積書で確かめる項目は4つです。第一に、計装の対象範囲がLLM呼び出しだけか、検索や後処理を含むスパン木の全体か。第二に、既存の監視基盤との併存方式が、プロセッサの追加なのかCollectorでの分岐なのか。第三に、セルフホストなら4種類の基盤の構築と監視が含まれるか。第四に、保持期間と退避の設計、そして本文を残す場合の伏せ字の扱いが仕様に書かれているか。

この4つが書かれていない見積は、後から追加費用の相談になりがちです。生成AI開発・AI受託開発では、計装の設計から基盤の構築、既存の監視との接続までを一続きで引き受けています。既にOTelを運用している環境への後付けも、ここまでに挙げた分岐構成で対応できます。

よくある質問

Langfuseはメトリクスやログも受け取れますか?

2026年8月時点の受け口はトレース専用で、メトリクスとログは対象外です。LLMの利用状況をグラフで見たい場合は、Langfuse側がスパンから集計した画面を使います。インフラ側の数値は既存の監視基盤に残し、リクエスト単位の突き合わせはトレースIDで行う分担が扱いやすいでしょう。

gRPCで送れないときはどう回避しますか?

回避の道は2つあります。アプリ側にHTTP用のエクスポータをもう1本持たせるか、Collectorでもとの通信を受けてLangfuse向けだけHTTPで出し直すかです。アプリの数が多いなら後者が管理しやすく、鍵の配布も1か所で済みます。

既存のAPMに送っているスパンを二重に送ると費用は増えますか?

APM側の課金がスパン数に連動するなら、そちらへの送信量は変わらないので影響しません。増えるのはLangfuse側の取り込み量だけです。既定のフィルタはLLM関連のスパンだけを選ぶため、HTTPやDBのスパンは送られません。それでも量が多い場合は、絞り込みのコールバックで対象を狭めます。

トレースが画面に出てこないときは何を見ますか?

確認の順番は、認証文字列に改行が混ざっていないか、エンドポイントのパスがシグナル別の指定と食い違っていないか、鍵とリージョンの組み合わせが合っているか、の3点です。表示が遅いだけの場合は、取り込み版のヘッダが抜けていて最大15分の遅延が出ている可能性があります。

日本のリージョンに送っても既存のOTel構成は変えずに済みますか?

エンドポイントのホスト名を jp.cloud.langfuse.com に変えるだけで、他の設定はそのまま使えます。ただし鍵はリージョンごとに別なので、プロジェクトを作り直したうえで新しい鍵に差し替えてください。既存のAPMへの送信は影響を受けません。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.09 テックブログ IDCFクラウド(IDCフロンティア)不正アクセス・ランサムウェア:影響先・復旧・データは戻るか
  2. 2026.10.09 テックブログ ニッスイのサイバー攻撃で日水物流の入出荷停止|委託先クラウド障害に荷主が備える手順
  3. 2026.10.09 テックブログ 京王電鉄のランサムウェア被害とグループ共通基盤:決済・ポイント・予約が止まった範囲と遮断の初動
  4. 2026.10.09 テックブログ スタディサプリの不正アクセスとメールアドレス3,687件|アカウント列挙を防ぐ実装
  5. 2026.10.08 コラム 雇用保険の適用拡大:2028年10月の週10時間以上への変更と、勤怠・労務システムで直す判定ロジック

RELATED POSTS 関連記事

目次