AI eval ツール: Phoenix — OTel 準拠の OSS オブザーバビリティ

AI eval ツール: Phoenix — OTel 準拠の OSS オブザーバビリティ

Arize Phoenix は、LLM アプリケーションのトレース・評価・実験を一体化した OSS で、OpenTelemetry 準拠のオブザーバビリティを売りにしています。

AI eval ツール連載の 3 本目として、Phoenix を取り上げます。前回まで扱った Promptfoo(CLI での YAML テスト)、LangSmith(LangChain エコシステム統合の商用 SaaS)とは、位置づけがかなり違います。Phoenix は「既存の観測スタックの延長で LLM を監視したい」というチーム向けの選択肢です。

Phoenix とは何か

Phoenix は Arize AI 社が開発している OSS(ELv2 ライセンス)で、以下 3 つを一つのプラットフォームで提供します。

  1. 本番トレース: LLM / ツール呼び出し / 検索の各ステップを span として記録
  2. オフライン評価: データセットに対して eval を回して回帰を検出
  3. 実験管理: プロンプト・モデル・リトリーバの変更を比較

ローカル(docker または pip install)でも、Kubernetes や各社クラウド(Railway / Render / GCP / Azure / AWS)でも動かせます。自己ホスト前提の構成が中心で、トレースが自社境界から出ないという点が、監査対応の必要なチームには刺さります。

Arize AX(商用版)との関係

Arize AI は、企業向けの商用 ML / AI オブザーバビリティ製品 Arize AX を提供しており、Phoenix はその OSS 版です。

LangSmith の「OSS 版が存在しない商用 SaaS」モデルとは対照的に、Phoenix 自体を無料で永続的に使い続けられます。商用版は「運用まわり」をお金で解決したいときの選択肢という切り分けです。

OpenTelemetry 準拠という設計思想

Phoenix の最大の特徴は、OpenTelemetry (OTel) を一等市民として採用している点です。独自の SDK を強制せず、OTel の tracer provider と OTLP exporter で動きます。OTLP gRPC は 4317、HTTP は 6006/v1/traces でそのまま受けられます。

計装の意味づけは OpenInference semantic conventions という Arize が主導する標準に従います。これは「LLM 呼び出しの span をどう記述するか」を定めた仕様です。

対応範囲は広く、主要プロバイダは OpenAI / Anthropic / Google GenAI / AWS Bedrock / Cohere / Mistral をカバーしています。フレームワーク側も LangChain / LlamaIndex / CrewAI / DSPy / OpenAI Agents SDK などを openinference-instrumentation-* パッケージとして提供しています。

既存の OTel 配管に差し込む例を見てみます。

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter

provider = TracerProvider()
provider.add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter(endpoint="http://localhost:4317"))
)
trace.set_tracer_provider(provider)

Datadog や New Relic、Grafana Tempo に OTel で流しているチームなら、同じ exporter を Phoenix に向けるだけで導入できます。独自 SDK を強要する SaaS 系ツールにはできない配置です。

主な機能

Traces

Phoenix UI 上で span のタイムラインを可視化します。LLM 呼び出し・ツール呼び出し・検索・chain の階層が木構造で見え、各 span の prompt / completion / token 数 / latency / cost が引けます。

Datasets

本番トレースから「気になる例」を選び、バージョン付きのデータセットに切り出せます。手で CSV を作らず、production → eval の循環を回せる設計です。

Experiments

同じデータセットに対して、プロンプト差分・モデル差分・リトリーバ差分を実験として投げて比較します。実験ごとに evaluator が自動で走り、A / B 間の差分が UI 上に並びます。

Evals

LLM-as-a-Judge で、ハルシネーション検出・QA 品質・関連性・毒性などの組み込み evaluator を使えます。Python または TypeScript でカスタム evaluator も書けます。サーバー側 evaluator として Phoenix UI 内で設定することも可能です。たとえば phoenix.evals.HallucinationEvaluator は (input, output, reference) の 3 変数を使った判定を 1 行で呼び出せます。詳細は Phoenix Evals のドキュメント を参照してください。

Embeddings Analysis

埋め込みベクトルを UMAP で可視化し、クラスタ単位でドリフトを分析します。RAG のリトリーバ品質を調べるときに有用です。

Prompt Playground

プロンプトを対話的に試し、複数モデルの出力を並べて比較する IDE です。バージョンにタグをつけて、プロンプト管理と実験に紐づけられます。

最小動作例

1. Phoenix を起動する

docker で起動する場合:

docker run -p 6006:6006 -p 4317:4317 arizephoenix/phoenix:latest

6006 は UI、4317 は OTLP gRPC です。pip でも動きます。

pip install arize-phoenix
phoenix serve

uvx 一発でも起動できます。

uvx arize-phoenix serve

いずれも http://localhost:6006 で UI が開きます。

2. OpenAI 呼び出しをトレースする

Python 側は 3 行で済みます。

import os
from phoenix.otel import register
from openai import OpenAI

os.environ["PHOENIX_COLLECTOR_ENDPOINT"] = "http://localhost:6006"

tracer_provider = register(
    project_name="my-llm-app",
    auto_instrument=True,  # インストール済み instrumentor を自動で有効化
)

client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "こんにちは"}],
)

openinference-instrumentation-openai を事前に入れておけば、auto_instrument=True が勝手に拾ってくれます。LangChain / LlamaIndex なら対応する openinference-instrumentation-* パッケージを足すだけです。

3. データセットに対して eval を回す

本番トレースから生成したデータセットに、ハルシネーション evaluator を当てる例です。

import phoenix as px
from phoenix.evals import HallucinationEvaluator, OpenAIModel, run_evals

client = px.Client()
dataset = client.get_dataset(name="production-sample-2026-03")

df = dataset.as_dataframe()
hallucination_evaluator = HallucinationEvaluator(
    model=OpenAIModel(model="gpt-4o-mini")
)

eval_results = run_evals(
    dataframe=df,
    evaluators=[hallucination_evaluator],
    provide_explanation=True,
)

結果は Phoenix UI 上の対応するトレース・データセットに紐づいて表示されます。「本番で起きた事象を、そのままオフライン eval に流す」循環がここで閉じます。

向くケース・向かないケース

向くケース

向かないケース

LangSmith との違い

同じ「LLM トレース + eval + 実験」のカテゴリでも、設計思想が対照的です。

観点 Phoenix LangSmith
ライセンス OSS (ELv2) 商用 SaaS
自己ホスト 標準 Enterprise プランのみ
計装 OpenTelemetry + OpenInference 独自 SDK(LangChain は自動)
フレームワーク連携 幅広く中立 LangChain / LangGraph に最適化
エコシステム OTel コミュニティ側 LangChain コミュニティ側

「使っているフレームワークが何か」で選べば、判断はほぼ自動です。LangChain スタックなら LangSmith、それ以外なら Phoenix。両方を評価したうえで決める、というのが実務的な進め方になります。

他 OSS との比較: Langfuse

OSS の LLM オブザーバビリティでは Langfuse が最大の対抗馬です。

OTel で既に計装している現場 → Phoenix、独自デコレータでサクッと入れたい現場 → Langfuse、という使い分けが現実的です。両方 docker 一発で立てられるので、1 日ずつ試して合うほうを選ぶのが早いでしょう。

ハマりやすい点

OTLP ポートの違い

Phoenix は 6006(UI)と 4317(OTLP gRPC)を使います。企業内で OTel collector が既に走っていると 4317 がぶつかります。PHOENIX_PORT / PHOENIX_GRPC_PORT で変更するか、collector 側で route するか決めておきます。

auto_instrument=True の落とし穴

該当する openinference-instrumentation-* パッケージがインストールされていないと、auto_instrument=True でも静かにスルーされます。トレースが出ないときは、まず「対応する instrumentor が入っているか」を確認します。

LangChain を使っている場合の二重計装

LangChain のコールバックハンドラと OpenInference instrumentor を両方入れると、同じ呼び出しが重複して span になることがあります。LangChain スタックでは openinference-instrumentation-langchain 側に寄せ、素の OpenAI SDK の instrumentor は外す構成が無難です。

ELv2 ライセンスの制約

Elastic License v2 は「Phoenix 自体を競合 SaaS として売ってはいけない」という制約があります。自社内で使う分には問題ありませんが、Phoenix をラップした商用 LLM オブザーバビリティサービスを提供する、という使い方は不可です。社内利用・自社プロダクトへの組み込みは問題ありません。

データセットの匿名化

本番トレースをそのままデータセット化すると、PII が eval 用 LLM に送られます。評価用モデルに外部 API を使う構成では、データセット作成時にマスキングを挟む設計を初期から入れておきます。

まとめ

Phoenix は、OTel で既にインフラ側を整えているチームに最もフィットする選択肢です。LLM オブザーバビリティを「新しい独自配管」ではなく、「既存配管の自然な延長」として扱える点が最大の価値になります。

次回以降は、OSS 対抗馬の Langfuse、商用の Braintrust / Humanloop、CI 統合系の DeepEval などを順に見ていきます。

関連記事


Singularity Society はテクノロジー集団として MulmoClaude / MulmoTerminal / MulmoCast を開発しています。エンジニア・起業家向けの実践プログラム BootCamp も運営しています。

この記事をシェア

関連記事

記事一覧に戻る