AIツール比較

AIエージェント監視ツール比較|OTel・LangSmith

AIエージェント監視ツール比較のサムネイル

この記事の結論

AIエージェント監視はOpenTelemetryを土台に、LangSmithやPhoenixを目的別に選ぶと失敗しにくい。導入基準と実装例を整理します。

AIエージェントの監視は、APIの成功率やレスポンスタイムを見るだけでは足りません。どのモデルを呼んだか、どのツールを実行したか、検索結果をどう使ったか、途中で人間承認に止まったか、トークン消費がどの段階で膨らんだかまで追える必要があります。

結論から言うと、最初に決めるべきは「監視ツール名」ではなく「証跡の標準化」です。ベンダーロックインを避けたいチームはOpenTelemetryを土台にし、LangChain系の開発体験を重視するならLangSmith、OSSで手元検証や評価まで回したいならPhoenixを組み合わせるのが現実的です。

この記事では、OpenTelemetry、LangSmith、PhoenixをAIエージェント監視の観点で比較し、実装時に最低限入れるべきトレース設計、コード例、失敗パターンをまとめます。ベンチマーク風の架空数字は置かず、公式ドキュメントで確認できる機能と設計判断に絞ります。

この記事で参照した一次情報:OpenTelemetryのGenAI Semantic Conventionsは記事執筆時点でDevelopment扱いで、GenAIのイベント、例外、メトリクス、モデルspan、agent span、MCP向けsemantic conventionsを分けて定義しています。LangSmithはLLMアプリやAIエージェントのtrace、評価、prompt testingを扱うobservability製品として案内されています。PhoenixはOpenTelemetryを使ってAIアプリをtraceし、LlamaIndex、LangChain、OpenAIなどとの統合を持つOSS系の観測基盤として説明されています。

1. AIエージェント監視で最初に見るべきもの

従来のWebアプリ監視では、HTTPリクエスト、DBクエリ、キュー、外部API呼び出しを追えれば多くの障害を説明できます。AIエージェントでは、そこに「モデルの判断」と「ツール実行」が加わります。しかも、同じユーザー入力でも検索結果、プロンプト、コンテキスト量、モデルのバージョン、過去の会話状態で結果が変わります。監視対象が単なる処理時間から、意思決定の経路そのものへ広がるのが最大の違いです。

最低限ほしい証跡は五つあります。ユーザー入力、システム指示、モデル呼び出し、ツール呼び出し、最終出力です。ただし、個人情報や社外秘をそのままtraceへ送ると、監視基盤が新しい漏えい経路になります。入力全文を保存するか、ハッシュ化するか、要約だけにするかは、導入前に決めておく必要があります。

もう一つ重要なのが、成功だけでなく「途中の迷い」を見える化することです。RAGで何件検索したか、どのdocumentを採用したか、tool callが何回リトライされたか、timeout時に代替手段へ切り替えたか。これらが残っていないと、ユーザーから「昨日と違う答えになった」と言われたときに再現できません。

監視の目的は、かっこいいダッシュボードを作ることではありません。障害時に原因を狭める、コスト増の発生箇所を見つける、品質改善の評価データを残す、監査に耐える説明ログを作る。この四つのどれに効くかで、入れるべきツールは変わります。

  • 本番障害を早く直したい:OpenTelemetryで既存APMへ接続し、HTTP・DB・LLM・toolを同じtraceに乗せる。
  • プロンプトやagentの挙動を開発者が深く見たい:LangSmithのようなLLM特化UIを使う。
  • OSSで検証し、評価やデータセット管理も近くに置きたい:Phoenixを候補にする。
  • コンプライアンスが重い:保存項目、マスキング、retention、権限管理を先に決める。

2. 比較表:OTel・LangSmith・Phoenix

観点 OpenTelemetry LangSmith Phoenix
位置づけ 標準化されたtelemetryの共通言語。trace、metrics、logsを既存監視へ流す土台。 LLMアプリ・AIエージェントのdebug、trace、evaluation、prompt管理に寄った開発運用基盤。 OpenTelemetryベースでtraceや評価を扱うOSS系のAI observability基盤。
向いているチーム すでにDatadog、Grafana、New Relic、Cloud Monitoring等を使っているSRE/Platformチーム。 LangChain/LangGraph利用が多く、実験、評価、プロンプト改善を一つの画面で回したいチーム。 ローカル検証、OSS運用、モデルやframeworkをまたいだtrace確認をしたいチーム。
強い領域 ベンダー中立、標準化、APM連携、MCPやGenAI semantic conventionsへの追従。 LLM runの見やすさ、デバッグ体験、評価データとの接続、チームでのprompt改善。 OTLP受け口、trace可視化、評価、LlamaIndex/LangChain/OpenAI等との統合。
注意点 GenAI semantic conventionsはDevelopment項目があるため、属性名の更新に追従する運用が必要。 LangSmith固有の概念に寄るため、既存APMとの統合範囲やデータ持ち出し要件を確認する。 PhoenixとArize AXは別製品として扱われるため、導入前に使う製品とAPIを明確にする。
最初の導入 アプリの境界にtrace idを入れ、model span、tool span、retrieval spanを手で切る。 SDKやframework統合でrunを可視化し、失敗例をdataset化する。 OTLP exporterまたはintegrationでtraceを送り、ローカルで一連のflowを確認する。

選定の軸は「どれが一番高機能か」ではありません。既存の監視基盤とつなぐ必要があるならOpenTelemetryが主役です。開発者がpromptとtraceを見ながらagentを磨くならLangSmithが強いです。OSSで手元にtraceと評価の実験場を作りたいならPhoenixが合います。多くの現場では、OpenTelemetryを共通基盤にしつつ、LLM特化UIを用途別に足す構成が扱いやすくなります。

3. OpenTelemetryを土台にする理由

OpenTelemetryは「AI専用の便利ツール」ではなく、telemetryを標準化するための共通仕様と実装群です。AIエージェントの観測でも価値があるのは、Webアプリ、ジョブ、RAG、LLM、MCP tool、外部APIを同じtraceの中でつなげられる点です。ユーザーからの問い合わせ一件が、FastAPI、vector database、LLM provider、社内API、承認待ちqueueへ広がるなら、共通のtrace idがないと全体像を追えません。

OpenTelemetryのGenAI semantic conventionsは、モデル呼び出し、agent/framework span、MCP、token usageなどを扱うための語彙を整理しています。公式ドキュメント上ではDevelopment扱いの項目があり、既存instrumentationでは安定化までの移行方針としてOTEL_SEMCONV_STABILITY_OPT_INが説明されています。ここは重要で、記事やサンプルコードを丸写しして固定属性に依存するより、バージョン更新を前提に薄いadapter層を作る方が安全です。

OpenTelemetryを使うときの実務上のコツは、すべてを一気に自動計測しようとしないことです。まずはagent.run、llm.generate、tool.execute、retrieval.searchの四種類を手でspan化します。次にtoken数、モデル名、tool名、retry回数、timeout、fallback有無を属性として揃えます。最後に必要な部分だけ自動instrumentationを足すと、traceが読みやすいまま育ちます。

特にMCPを使う場合、HTTP一発の監視だけでは足りません。MCPはJSON-RPCを土台にし、stdioやStreamable HTTPなどのtransportで動きます。OpenTelemetryのMCP semantic conventionsでは、HTTP conventionsだけではMCPのmessage exchangeを十分表せないという問題意識が示されています。AIエージェントでMCP serverを増やすなら、tool名、request id、transport、成功/失敗、durationを明示的に残す設計が必要です。

OpenTelemetryを選ぶべきケース

  • 既存のSREチームがAPMやログ基盤をすでに運用している。
  • モデルproviderやframeworkを将来変える可能性が高い。
  • MCP server、社内API、RAG、ジョブqueueを横断して原因分析したい。
  • 監査やセキュリティ上、保存項目を自社ルールで厳密に制御したい。

4. LangSmithを選ぶ理由

LangSmithは、LangChainが提供するLLMアプリケーション向けのobservability基盤です。公式ドキュメントでは、AIエージェントやLLMアプリのbuild、debug、deployに関わるplatformとして説明され、request tracing、output evaluation、prompt testing、deployment管理などが並んでいます。OpenTelemetryが共通語彙なら、LangSmithは開発者の作業画面に近い道具です。

LangSmithが向いているのは、「なぜこのagentは変なtoolを呼んだのか」「このprompt変更で品質は上がったのか」「失敗例だけを集めて評価セットにしたい」といった、LLMアプリ特有の改善サイクルです。一般的なAPMでもdurationやerrorは追えますが、prompt、intermediate step、evaluationを同じ文脈で見るにはLLM特化UIの方が速い場面があります。

一方で、すべてをLangSmithだけに寄せるのは慎重に判断した方がいいです。本番全体の障害対応では、DB、cache、外部API、queue、infra metricsも一緒に見たいからです。LangSmithでLLM runを深掘りし、OpenTelemetryで全体traceへつなぐ、という分担にすると、開発者とSREの両方が同じincidentを別角度から見られます。

LangSmith導入時に先に決めるべきなのは、保存する入力・出力の粒度です。顧客データを含むpromptやtool結果をそのまま送るのか、PIIをマスクするのか、失敗runだけ保存するのか。ここを曖昧にすると、デバッグは便利でもセキュリティレビューで止まります。便利さより先にデータ分類を決めるのが本番導入の近道です。

LangSmithを選ぶべきケース

  • LangChainまたはLangGraphを主要frameworkとして使っている。
  • prompt変更、evaluation、dataset化を開発チーム内で高速に回したい。
  • LLM runの入力、出力、tool stepを非SREメンバーにも見せたい。
  • 本番監視というより、開発・検証・品質改善の速度を上げたい。

5. Phoenixを選ぶ理由

Phoenixは、Arizeが公開しているOSS系のAI observability platformです。公式ドキュメントではOpenTelemetryを通じてAI applicationsをtraceし、LlamaIndex、LangChain、OpenAIなどとのfirst-class integrationsを持つと説明されています。LLM tracingは、retrieval、embedding generation、model invocation、response generationのような処理の流れをtimelineとして残すものです。

Phoenixの強みは、OpenTelemetryに寄せながらLLMアプリ向けの画面と評価機能を持てることです。ローカルや検証環境でagentのtraceを見たい、OSSで始めたい、特定ベンダーに寄せ切る前に観測設計を試したい、といった段階で相性が良いです。開発初期の「まず見える化したい」に対して、導入の心理的ハードルが低いのも利点です。

注意点は、PhoenixとArize AXを混同しないことです。Phoenixのドキュメント自体にも、PhoenixとArize AXは別のobservability productとして案内されています。チーム内で「Arizeを入れる」とだけ言うと、OSSのPhoenixなのか、商用のAXなのか、設定項目や認証が食い違います。導入メモには製品名、endpoint、認証方式を明記しましょう。

PhoenixはOpenTelemetry Protocolでtraceを受けられるため、将来的に別backendへ流す設計とも相性があります。ただし、OSS運用ではアップデート、保管容量、認証、ネットワーク境界、backupを自分たちで見る必要があります。小さく始められることと、運用責任が消えることは別です。

Phoenixを選ぶべきケース

  • OSSでLLM traceを試したい、または検証環境を自社内に閉じたい。
  • LangChain、LlamaIndex、OpenAIなど複数の経路を同じ画面で見たい。
  • 評価やprompt experimentationも近い場所で扱いたい。
  • 将来はOpenTelemetry互換の別backendへ流す可能性がある。

6. 実装パターン:まず3つだけ入れる

ここからは、ツール選定より先に入れるべき最小実装を示します。コードは概念を伝えるためのサンプルです。実際のprovider SDK、認証、マスキング、例外処理は自社のruntimeに合わせて調整してください。

パターンA:OpenTelemetryでagent runを囲む

from opentelemetry import trace
from opentelemetry.trace import Status, StatusCode

tracer = trace.get_tracer("agentlab.order_agent")

async def run_agent(user_id: str, question: str):
    with tracer.start_as_current_span("agent.run") as span:
        span.set_attribute("app.agent.name", "order-support-agent")
        span.set_attribute("app.user.hash", hash_user(user_id))
        span.set_attribute("app.input.length", len(question))
        try:
            docs = await retrieve_documents(question)
            answer = await call_model(question, docs)
            span.set_attribute("app.retrieval.count", len(docs))
            span.set_attribute("app.output.length", len(answer))
            return answer
        except Exception as exc:
            span.record_exception(exc)
            span.set_status(Status(StatusCode.ERROR, str(exc)))
            raise

最初は公式のGenAI属性をすべて埋めるより、自社で確実に守れる属性から始めます。user_idは直接保存せずhash化し、入力全文ではなく長さや分類だけを残す設計にしています。ここにtrace idが乗れば、Web APIからLLM呼び出し、tool実行までを一つの流れで追えます。

パターンB:モデル呼び出しspanを分ける

async def call_model(prompt: str, docs: list[str]):
    with tracer.start_as_current_span("llm.generate") as span:
        span.set_attribute("gen_ai.operation.name", "chat")
        span.set_attribute("gen_ai.provider.name", "openai")
        span.set_attribute("gen_ai.request.model", "gpt-4.1-mini")
        span.set_attribute("gen_ai.request.stream", False)
        span.set_attribute("app.prompt.template", "support_answer_v3")
        span.set_attribute("app.context.doc_count", len(docs))

        response = await llm_client.responses_create(
            model="gpt-4.1-mini",
            input=build_messages(prompt, docs),
        )

        usage = getattr(response, "usage", None)
        if usage:
            span.set_attribute("gen_ai.usage.input_tokens", usage.input_tokens)
            span.set_attribute("gen_ai.usage.output_tokens", usage.output_tokens)
        return response.output_text

OpenTelemetryのGenAI conventionsでは、gen_ai.operation.name、gen_ai.request.model、gen_ai.response.model、gen_ai.usage.input_tokens、gen_ai.usage.output_tokensなどの属性が定義されています。Development扱いの仕様を含むため、SDKやcollectorのバージョンで差分が出る可能性はあります。それでも、model名とtoken usageをspanへ寄せるだけで、コスト増や遅延の原因はかなり追いやすくなります。

パターンC:tool実行とリトライを見える化する

async def execute_tool(tool_name: str, payload: dict):
    with tracer.start_as_current_span("tool.execute") as span:
        span.set_attribute("gen_ai.tool.name", tool_name)
        span.set_attribute("app.tool.payload_keys", sorted(payload.keys()))
        for attempt in range(1, 4):
            span.set_attribute("app.tool.attempt", attempt)
            try:
                result = await tool_registry[tool_name](payload)
                span.set_attribute("app.tool.success", True)
                span.set_attribute("app.tool.result_size", len(str(result)))
                return result
            except TimeoutError as exc:
                span.add_event("tool.timeout", {"attempt": attempt})
                if attempt == 3:
                    span.record_exception(exc)
                    span.set_attribute("app.tool.success", False)
                    raise

AIエージェントで事故りやすいのはtool実行です。モデルの返答が正しくても、toolのpayloadが古いschemaだったり、外部APIがtimeoutしたり、同じ操作を二重実行したりします。retry回数、idempotency key、timeout、fallbackをspanに残すと、品質問題とシステム障害を切り分けやすくなります。

パターンD:LangSmithやPhoenixへ送る前にマスキングする

import re

EMAIL = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")
PHONE = re.compile(r"0\d{1,4}-?\d{1,4}-?\d{3,4}")

def redact_text(text: str) -> str:
    text = EMAIL.sub("[REDACTED_EMAIL]", text)
    text = PHONE.sub("[REDACTED_PHONE]", text)
    return text[:4000]

def safe_trace_payload(messages: list[dict]) -> list[dict]:
    safe = []
    for message in messages:
        safe.append({
            "role": message.get("role"),
            "content": redact_text(str(message.get("content", ""))),
        })
    return safe

LLM特化ツールは便利ですが、promptとtool resultを見やすく保存できるぶん、情報管理の責任も増えます。まずマスキング関数を通し、保存上限を決め、全文保存が必要なrunだけ明示的にopt-inする設計にしましょう。監視のために秘密情報を増やすのは本末転倒です。

7. 選び方:3つの質問で決める

監視ツール選定で迷ったら、次の三つを順番に確認します。第一に、既存のAPMやSRE運用に接続する必要があるか。必要ならOpenTelemetryを外す理由はほぼありません。第二に、LLM runの中身を開発者が毎日見るか。見るならLangSmithやPhoenixのようなLLM特化UIが効きます。第三に、データをどこへ保存できるか。ここが決まらないままSaaSを入れると、後から止まります。

  1. 既存監視への統合が最優先なら、OpenTelemetryを基準にする。特定UIは後から足す。
  2. LangChain/LangGraph中心で、評価とprompt改善まで一気通貫にしたいなら、LangSmithを検討する。
  3. OSS・ローカル検証・OTLP互換を重視するなら、Phoenixで小さく始める。
  4. 本番で個人情報や顧客データを扱うなら、ツール選定より先にredactionとretentionを決める。
  5. MCP serverや社内toolが増える予定なら、tool spanとtrace context propagationを設計に入れる。

おすすめ構成は、開発初期はPhoenixまたはLangSmithでagentの挙動を可視化し、本番化の段階でOpenTelemetryを必ず挟む形です。こうしておくと、LLM専用画面の便利さを使いながら、システム全体の監視は標準的なtelemetryに寄せられます。

8. 失敗パターンと回避策

失敗1:traceを入れたのに原因が分からない

span名が全部「openai.call」や「chain.run」になっていると、画面は埋まっても分析できません。agent.run、retrieval.search、llm.generate、tool.execute、人間承認、fallbackなど、業務上の意味が分かる単位でspanを切りましょう。

失敗2:入力全文を保存してセキュリティで止まる

監視基盤はログ基盤と同じく、権限管理と保持期限が必要です。顧客名、メール、電話番号、契約情報、社内URL、API responseを保存するなら、マスキング、暗号化、閲覧権限、削除手順を先に用意します。

失敗3:token usageだけ見て品質を見ない

コスト監視は大事ですが、token数だけを最適化すると回答品質が落ちます。失敗run、ユーザー再質問、tool error、評価スコアを一緒に見ることで、安いが使えないagentを作る事故を避けられます。

失敗4:開発環境と本番環境のtrace設計が違う

開発ではLangSmith、本番では別APM、検証ではPhoenixという構成自体は問題ありません。ただしspan名、run id、user hash、tool名、prompt versionのルールが違うと比較できません。共通schemaをREADMEに書き、CIで最低限の属性を検査すると安定します。

失敗5:MCP toolをHTTP監視だけで済ませる

MCPはmessage exchangeの粒度が重要です。HTTP requestが200でも、内部のJSON-RPC tool callが失敗していることがあります。tool名、request id、paramsの分類、result size、error codeをdomain-specificに残す必要があります。

監視の失敗は、ツール選定よりも「何を記録するか」を決めていないことから起きます。最初の一週間で全機能を入れる必要はありません。まず四種類のspanと、十個前後の共通属性を定めるだけで、トラブルシュートの質は大きく変わります。

9. 導入チェックリスト

  • agent.run、llm.generate、tool.execute、retrieval.searchのspan名を固定したか。
  • prompt template version、model、token usage、tool name、retry countを取っているか。
  • 入力・出力・tool resultの保存可否をデータ分類ごとに決めたか。
  • OpenTelemetryのGenAI conventionsがDevelopment扱いであることを前提に、属性名変更に備えたadapterを置いたか。
  • LangSmithやPhoenixへ送るデータにPIIが混ざらないようredactionを通したか。
  • MCP serverを使う場合、tool call単位のtraceとerrorを残しているか。
  • 失敗runを評価datasetへ回す運用を決めたか。
  • 監視画面を見る人、incident時に判断する人、データ削除を担当する人を決めたか。

ここまで決めると、AIエージェント監視は「ツールを入れた」で終わらず、改善サイクルに乗ります。観測できるrunは評価でき、評価できるrunは改善できます。逆に、観測できないagentは、本番でユーザーから違和感を指摘されるまで問題に気づけません。

10. 公式情報・参考リンク

なお、各サービスの料金、保存期間、細かなSDK仕様は変わります。この記事では固定の料金比較や非公開ベンチマーク風の数字は出していません。導入時は必ず公式ドキュメントと契約条件を確認してください。

関連記事・次に読む

監視設計は、コンテキスト設計、信頼性設計、ストリーミング応答の設計とセットで考えると破綻しにくくなります。特に長い会話履歴やRAGを扱うagentでは、何をcontextへ入れ、何をtraceへ残し、何を保存しないかを同時に決めるのが重要です。

まとめ

AIエージェント監視では、OpenTelemetry、LangSmith、Phoenixのどれか一つを選べば終わりではありません。OpenTelemetryは共通の観測基盤、LangSmithはLLM開発体験、PhoenixはOSS寄りのAI observabilityとして、それぞれ得意領域が違います。

まずはOpenTelemetry的なspan設計でagent.run、llm.generate、tool.execute、retrieval.searchを分け、model、token、tool、retry、errorを残しましょう。その上で、開発チームが毎日見るUIとしてLangSmithやPhoenixを選ぶと、導入後の運用がぶれにくくなります。

本番導入で最も大事なのは、traceを増やすことではなく、説明できるagentにすることです。ユーザーの一件の依頼に対して、どの情報を参照し、どのモデルが、どのtoolを、何回使い、どこで失敗したのかを追える状態を作る。これがAIエージェント監視の出発点です。

11. 小さく始める導入手順

最初の一日でやることは、agentの全機能を監視することではなく、代表的な一経路を最後まで追えるようにすることです。問い合わせ受付、検索、LLM生成、tool実行、回答返却までのhappy pathにtrace idを通します。この時点ではUIの美しさより、各spanに同じrun idが入っているかを確認します。

次に、失敗しやすい経路を一つ足します。検索結果がゼロ件だった場合、toolがtimeoutした場合、モデルがtool callを要求したがschema validationに落ちた場合などです。失敗経路のtraceが読めるようになると、運用メンバーはincident時にログを手探りしなくて済みます。

三日目以降に、評価と改善へつなげます。失敗runをdataset化し、prompt versionやmodel versionごとに比較できるようにします。LangSmithやPhoenixを使う場合も、この段階で「失敗例を集めて次の実験に回す」導線を作ると、監視が単なる後追いではなく開発速度を上げる仕組みになります。

最後に、定例レビューの指標を絞ります。平均レイテンシ、p95、error率、tool retry率、入力token、出力token、ユーザー再質問率、評価NG率のように、行動につながる指標だけを見るべきです。見ても誰も直さないグラフは、監視ではなく壁紙です。

この記事を読んで導入イメージが固まってきた方へ

UravationではAIエージェント導入の研修・コンサルを行っています。

Need help moving from reading to rollout?

この記事を読んで導入イメージが固まってきた方へ

Uravationでは、AIエージェントの要件整理、PoC設計、社内導入、研修まで一気通貫で支援しています。

この記事をシェア

X Facebook LINE

※ 本記事の情報は2026年6月時点のものです。サービスの料金・仕様は変更される可能性があります。最新情報は各サービスの公式サイトをご確認ください。

関連記事