arize-instrumentation について
アプリケーションに Arize AX tracing を追加する開発者向けスキルです。コードベースを先に分析し、確認後に実装する二段階の手順を採用し、業務ロジックの維持と認証情報の安全な扱いを重視します。
主な機能
- 01既存コードと tracing の事前調査
- 02言語とフレームワークに応じた連携方式の選択
- 03自動計装の優先
- 04ツール呼び出し向け CHAIN と TOOL span の追加
- 05環境変数による認証情報の参照
活用シーン
- 01既存アプリケーションへの Arize AX tracing の追加
- 02コード変更前のサービスと tracing 設定の評価
- 03Agent のツール呼び出しを trace span として可視化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ github/ awesome-copilot --skill arize-instrumentationインストール後、Claude Code で/arize-instrumentationを入力して読み込まれたか確認します。
同梱ファイルreferences/ax-profiles.md
詳細
Arize 計装スキル
ユーザーがアプリケーションに Arize AX トレーシングを追加したい場合に、このスキルを使用します。エージェント支援型トレーシングのセットアップおよび Arize AX トレーシング — エージェントセットアッププロンプトに従い、2 段階のエージェント支援型フローを実行してください。
クイックスタート(ユーザー向け)
ユーザーから「トレーシングをセットアップして」または「アプリに Arize を計装して」と依頼された場合は、次のように始められます。
https://arize.com/docs/PROMPT.md の手順に従い、必要に応じて私に質問してください。
その後、以下の 2 つのフェーズを実行してください。
基本原則
- 変更よりも調査を優先する — コードを変更する前に、コードベースを理解してください。
- ビジネスロジックを変更しない — トレーシングの追加は、純粋に機能を追加するものです。
- 利用可能な場合は自動計装を使用する — 手動スパンは、インテグレーションでカバーされないカスタムロジックにのみ追加してください。
- 既存のコードスタイルとプロジェクトの規約に従ってください。
- 出力は簡潔にし、本番環境を重視する — 余分なドキュメントやサマリーファイルは生成しないでください。
- 生成するコードに認証情報の値を直接埋め込まないでください — 必ず環境変数を参照してください(例:
os.environ["ARIZE_API_KEY"]、process.env.ARIZE_API_KEY)。これには API キー、スペース ID、その他のシークレットが含まれます。これらはユーザー自身の環境に設定するものであり、エージェントはシークレットの生の値を出力してはなりません。
フェーズ 0:環境の事前確認
コードを変更する前に、次のことを行います。
- リポジトリ/サービスの対象範囲が明確であることを確認します。モノレポの場合、リポジトリ全体を計装対象と決めつけないでください。
- 検証に必要なローカルの実行環境を特定します。
- パッケージマネージャーとアプリの起動コマンド
- アプリが長時間実行されるものか、サーバーベースか、短時間で終了する CLI/スクリプトか
- 変更後の検証に
axが必要か
axがインストールされているか、またはそのバージョンを事前に確認しないでください。後で検証にaxが必要になったら、その時点で実行してください。失敗した場合は、references/ax-profiles.md を参照してください。- ユーザーが指定したスペース ID、プロジェクト名、プロジェクト ID を、決して黙って置き換えないでください。CLI、コレクター、ユーザー入力の内容に食い違いがある場合は、その不一致を具体的な阻害要因として提示してください。
フェーズ 1:分析(読み取り専用)
このフェーズでは、コードを書いたりファイルを作成したりしないでください。
手順
-
依存関係マニフェストを確認し、技術スタックを特定します。
- Python:
pyproject.toml、requirements.txt、setup.py、Pipfile - TypeScript/JavaScript:
package.json - Java:
pom.xml、build.gradle、build.gradle.kts - Go:
go.mod
- Python:
-
ソースファイル内のインポート文をスキャンして、実際に使用されているものを確認します。
-
既存のトレーシング/OTel を確認します。
TracerProvider、register()、opentelemetryのインポート、ARIZE_*、OTEL_*、OTLP_*環境変数、またはその他のオブザーバビリティ設定(Datadog、Honeycomb など)を探します。 -
対象範囲を特定します。モノレポや複数サービスのプロジェクトでは、どのサービスを計装するかユーザーに確認してください。
特定する項目
| 項目 | 例 |
|---|---|
| 言語 | Python、TypeScript/JavaScript、Java、Go |
| パッケージマネージャー | pip/poetry/uv、npm/pnpm/yarn、maven/gradle、go modules |
| LLM プロバイダー | OpenAI、Anthropic、LiteLLM、Bedrock など |
| フレームワーク | LangChain、LangGraph、LlamaIndex、Vercel AI SDK、Mastra など |
| 既存のトレーシング | OTel またはベンダーのセットアップ |
| ツール/関数の使用 | LLM のツール使用、関数呼び出し、またはアプリが実行するカスタムツール(例:エージェントループ内) |
重要なルール: LLM プロバイダーとともにフレームワークが検出された場合は、まずフレームワーク固有のトレーシングドキュメントを確認し、必要なモデルスパンとツールスパンがすでに記録されるなら、フレームワーク標準のインテグレーション方法を優先してください。プロバイダーの計装を別途追加するのは、フレームワークのドキュメントで必要とされる場合、またはフレームワーク標準のインテグレーションに明らかな不足がある場合に限ります。アプリがツールを実行し、フレームワークのインテグレーションがツールスパンを出力しない場合は、各呼び出しの入出力が記録されるよう、手動で TOOL スパンを追加してください(以下の トレースの拡充を参照)。
フェーズ 1 の出力
簡潔な要約を返します:
- 検出した言語、パッケージマネージャー、プロバイダー、フレームワーク
- 提案するインテグレーションの一覧(ドキュメントのルーティングテーブルに基づく)
- 検討が必要な既存の OTel/トレーシング
- モノレポの場合:計測を提案するサービス
- アプリで LLM のツール使用/関数呼び出しが行われている場合: 各ツール呼び出しが入力/出力とともにトレースに表示されるよう、手動で CHAIN スパンと TOOL スパンを追加する旨を記載します(トレースが疎になるのを防ぎます)。
ユーザーがアプリをすぐに計測するよう明示的に依頼しており、対象のサービスがすでに明確な場合は、フェーズ 1 の要約を簡潔に提示してから、直接フェーズ 2 に進みます。対象範囲が曖昧な場合や、ユーザーが最初に分析を依頼した場合は、確認を待ちます。
インテグレーションのルーティングとドキュメント
サポートされているインテグレーションとドキュメント URL の正式な一覧は、エージェント設定プロンプトにあります。検出したシグナルを実装ドキュメントに対応付ける際に使用してください。
- LLM プロバイダー: OpenAI、Anthropic、LiteLLM、Google Gen AI、Bedrock、Ollama、Groq、MistralAI、OpenRouter、VertexAI。
- Python フレームワーク: LangChain、LangGraph、LlamaIndex、CrewAI、DSPy、AutoGen、Semantic Kernel、Pydantic AI、Haystack、Guardrails AI、Hugging Face Smolagents、Instructor、Agno、Google ADK、MCP、Portkey、Together AI、BeeAI、AWS Bedrock Agents。
- TypeScript/JavaScript: LangChain JS、Mastra、Vercel AI SDK、BeeAI JS。
- Java: LangChain4j、Spring AI、Arconia。
- Go: 現時点ではファーストパーティの自動計装パッケージはありません。OpenTelemetry Go SDK を使用し、手動計装に従って OpenInference 属性を手動で設定してください。
- プラットフォーム(UI ベース): LangFlow、Flowise、Dify、Prompt flow。
- フォールバック: 手動計装、すべてのインテグレーション。 full routing table in PROMPT.md にある完全なルーティングテーブルから、一致するドキュメントページを取得し、正確なインストール手順とコードスニペットを確認してください。必要に応じて、ドキュメントを探す際のフォールバックとして llms.txt を使用してください。
注:
arize.com/docs/PROMPT.mdとarize.com/docs/llms.txtは、Arize チームが管理する Arize 公式ドキュメントページです。このスキル向けに、正式なインストールスニペットと統合ルーティングテーブルを提供しています。これらは、同じ組織が運営する信頼できる URL であり、サードパーティのコンテンツではありません。
フェーズ 2:実装
フェーズ 1 の分析について、ユーザーの確認を得てからのみ先に進みます。
手順
- 統合ドキュメントを取得する — 一致するドキュメント URL を読み、インストール手順と計装手順に従います。
- コードを書く前に、検出したパッケージマネージャーを使用してパッケージをインストールする:
- Python:
pip install arize-otelとopeninference-instrumentation-{name}(パッケージ名ではハイフン、インポートではアンダースコアを使用します。例:openinference.instrumentation.llama_index)。 - TypeScript/JavaScript:
@opentelemetry/sdk-trace-nodeと、該当する@arizeai/openinference-*パッケージ。 - Java:OpenTelemetry SDK と
pom.xmlまたはbuild.gradleのopeninference-instrumentation-*。 - Go:
go get go.opentelemetry.io/otel go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp— まだ自動計装機能はないため、エージェントがスパンに OpenInference 属性を手動で設定します。otlptracehttp.WithEndpoint("otlp.arize.com")(US)またはotlptracehttp.WithEndpoint("otlp.eu-west-1a.arize.com")(EU)と、otlptracehttp.WithHeaders(map[string]string{"space_id": ..., "api_key": ...})を使ってエクスポーターを接続してください —https://スキームを付けず、ホスト名のみを渡します。最近の OTel Go モジュールには Go ≥ 1.23 が必要です —go mod tidyによってツールチェーンのバージョンが上がる場合があります。
- Python:
- 認証情報 — ユーザーには Arize API Key と Space ID が必要です。既存の
axプロファイルにARIZE_API_KEYとARIZE_SPACEがあるか確認してください —.envファイルは絶対に読み込まないでください:ax profiles showを実行して既存のプロファイルを確認します。- プロファイルがない場合は、API キーとスペースの設定を案内する対話型ウィザードを起動する
ax profiles createを実行するようユーザーに案内します。詳細は CLI profiles docs を参照してください。 - ユーザーが API キーを手動で見つける必要がある場合は、https://app.arize.com にアクセスし、設定ページに移動するよう案内してください(プレースホルダー ID を含む組織固有の URL は使用しないでください。新規ユーザーには解決できません)。
- 認証情報が設定されていない場合は、環境変数として設定するようユーザーに指示してください — 生成するコードに生の値を埋め込んではいけません。生成する計装コードでは、
os.environ["ARIZE_API_KEY"](Python)、process.env.ARIZE_API_KEY(TypeScript/JavaScript)、またはos.Getenv("ARIZE_API_KEY")(Go)を必ず参照してください。 - プロファイルの設定とトラブルシューティングの全手順については、references/ax-profiles.md を参照してください。
- 計装を一元化する — 単一のモジュール(例:
instrumentation.py、instrumentation.ts、instrumentation.go)を作成し、LLM クライアントを作成する前にトレースを初期化します。 - 既存の OTel — すでに TracerProvider がある場合は、Arize を追加のエクスポーターとして追加します(例:Arize OTLP を使った BatchSpanProcessor)。ユーザーから依頼がない限り、既存の設定を置き換えないでください。
実装ルール
- まず自動計装を使用し、必要な場合にのみ手動スパンを追加します。
- 汎用的な OpenTelemetry の配線を追加する前に、リポジトリ固有のネイティブな統合方法を優先します。フレームワークにエクスポーターや可観測性パッケージが用意されている場合は、文書化された不足がない限り、まずそれを使用します。
- 環境変数がない場合も適切に処理し、クラッシュさせずに警告を出します。
- **インポート順序:**トレーサーを登録 → インストルメンターをアタッチ → その後に LLM クライアントを作成します。
- **プロジェクト名属性(必須):**プロジェクト名がない場合、Arize は HTTP 500 でスパンを拒否します。
service.nameだけでは受け付けられません。TracerProvider のリソース属性として設定します(推奨 — 一か所で設定でき、すべてのスパンに適用されます)。- Python:
register(project_name="my-app")が自動的に処理します(リソースに"openinference.project.name"を設定します)。スパンを別のプロジェクトにルーティングするには、arize.otelのset_routing_context(space_id=..., project_name=...)を使用します。 - **TypeScript:**Arize は
"model_id"(公式 TS クイックスタートに記載)と、@arizeai/openinference-semantic-conventionsのSEMRESATTRS_PROJECT_NAMEを使った"openinference.project.name"(手動計装のドキュメントに記載)の両方を受け付けます。どちらも使用できます。 - Go:
attribute.String("openinference.project.name", "my-app")をresource.New(...)に渡し、sdktrace.WithResource(res)で適用します。Go SDK にはこのためのヘルパーがないため、各 TracerProvider に手動で設定する必要があります。
- Python:
- **CLI/スクリプトアプリ — 終了前にフラッシュ:**プロセスの終了前に、
provider.shutdown()(TS)/provider.force_flush()の後にprovider.shutdown()(Python)/tp.Shutdown(ctx)(Go)を呼び出す必要があります。呼び出さない場合、非同期 OTLP エクスポートが破棄され、トレースが表示されません。 - アプリでツール/関数を実行する場合:手動の CHAIN + TOOL スパンを追加します(下記のトレースの拡充を参照)。これにより、各ツール呼び出しとその結果がトレースツリーに表示されます。追加しない場合、トレースは簡素になり(LLM API スパンのみで、ツールの入出力が表示されません)。
トレースの拡充:ツールの使用とエージェントループの手動スパン
自動インストルメンターでは、なぜこれを行わないのですか?
**プロバイダーのインストルメンター(Anthropic、OpenAI など)は、LLM のクライアント(HTTP リクエストを送信し、レスポンスを受け取るコード)のみをラップします。**インストルメンターが確認できるのは次の内容です。
- API 呼び出しごとに 1 つのスパン:リクエスト(メッセージ、システムプロンプト、ツール)とレスポンス(テキスト、tool_use ブロックなど)。
アプリケーション内でレスポンスを受け取った後に起きることは、確認できません。
- ツールの実行 — コードがレスポンスを解析し、
run_tool("check_loan_eligibility", {...})を呼び出して、結果を取得します。これはプロセス内で実行されます。インストルメンターには、run_tool()や実際のツール出力を参照するフックがありません。ツールの結果を返す次の API 呼び出しは、単なる別のmessages.createスパンです。インストルメンターには、メッセージの内容がツールの結果であることも、ツールが何を返したかもわかりません。 - エージェント/チェーンの境界 — 「1 回のユーザーターン → 複数の LLM 呼び出しとツール呼び出し」という考え方は、アプリケーションレベルの概念です。インストルメンターには個別の API 呼び出ししか見えず、それらが同じ論理的な
run_agentの実行に属していることはわかりません。
そのため、TOOL スパンと CHAIN スパンは手動で(または、ツールとチェーンを把握している LangChain/LangGraph などのフレームワークインストルメンターによって)追加する必要があります。追加すると、同じ TracerProvider を使用するため、LLM スパンと同じトレースに表示されます。
ツールの入力/出力が欠落した簡素なトレースにならないようにするには:
- エージェント/ツールのパターンを検出します。LLM を呼び出し、次に 1 つ以上のツールを(名前と引数で)実行し、ツールの結果を使って再び LLM を呼び出すループです。
- 同じ TracerProvider を使って手動スパンを追加します(例:
register()の後にopentelemetry.trace.get_tracer(...)を使用):- CHAIN スパン — エージェントの実行全体(例:
run_agent)をラップします。openinference.span.kindを"CHAIN"、input.valueをユーザーメッセージ、output.valueを最終的な返信に設定します。 - TOOL スパン — ツールの呼び出しごとにラップします。
openinference.span.kindを"TOOL"、input.valueを引数の JSON、output.valueを結果の JSON に設定します。スパン名にはツール名を使用します(例:check_loan_eligibility)。
- CHAIN スパン — エージェントの実行全体(例:
OpenInference 属性(Arize でスパンを正しく表示するために使用してください):
| 属性 | 用途 |
|---|---|
openinference.span.kind | 適切な値を選択してください。生のプロバイダー API 呼び出し(OpenAI、Anthropic など)には "LLM"、オーケストレーションやエージェントループの境界には "CHAIN"、ツールや関数の実行には "TOOL"、ベクトルストアや検索の参照には "RETRIEVER"、埋め込み API の呼び出しには "EMBEDDING"、より大きなチェーン内にネストされた自律的なサブエージェントの実行には "AGENT"、リランク API の呼び出しには "RERANKER"、ガードレールやポリシーチェックには "GUARDRAIL"、オンライン評価の呼び出しには "EVALUATOR" を使用します。 |
input.value | 文字列(例:ユーザーメッセージまたはツール引数の JSON) |
output.value | 文字列(例:最終的な返信またはツール結果の JSON) |
LLM スパンの属性(スパンが実際の LLM 呼び出しである場合、上記の 3 つに加えて設定してください):
| 属性 | 用途 |
|---|---|
llm.model_name | モデル識別子(例:"gpt-4o-mini") |
llm.provider / llm.system | プロバイダー名(例:"openai"、"anthropic") |
llm.input_messages.{i}.message.role | i 番目の入力メッセージのロール:"system" / "user" / "assistant" / "tool" |
llm.input_messages.{i}.message.content | i 番目の入力メッセージのテキストコンテンツ |
llm.output_messages.{i}.message.role | i 番目の出力メッセージのロール |
llm.output_messages.{i}.message.content | i 番目の出力メッセージのテキストコンテンツ |
llm.token_count.prompt | int — プロンプト/入力トークン数 |
llm.token_count.completion | int — 補完/出力トークン数 |
llm.token_count.total | int — 合計トークン数 |
Python と TypeScript では、これらの名前は openinference-semantic-conventions パッケージを通じて提供されます。Go では、上記の文字列を手動で入力する必要があります。
Python のパターン: グローバルなトレーサーを取得し(Arize と同じプロバイダー)、コンテキストマネージャーを使用して、ツールスパンが CHAIN スパンの子になり、LLM スパンと同じトレースに表示されるようにします:
from opentelemetry.trace import get_tracer
tracer = get_tracer("my-app", "1.0.0")
# In your agent entrypoint:
with tracer.start_as_current_span("run_agent") as chain_span:
chain_span.set_attribute("openinference.span.kind", "CHAIN")
chain_span.set_attribute("input.value", user_message)
# ... LLM call ...
for tool_use in tool_uses:
with tracer.start_as_current_span(tool_use["name"]) as tool_span:
tool_span.set_attribute("openinference.span.kind", "TOOL")
tool_span.set_attribute("input.value", json.dumps(tool_use["input"]))
result = run_tool(tool_use["name"], tool_use["input"])
tool_span.set_attribute("output.value", result)
# ... append tool result to messages, call LLM again ...
chain_span.set_attribute("output.value", final_reply)
Go のパターン: グローバルな TracerProvider(otel.SetTracerProvider で登録)からトレーサーを取得し、tracer.Start でスパンをネストして、ツールスパンが CHAIN スパンの子になるようにします。
短命なプロセスにとって重要: スパンの開始後に
log.Fatalf/os.Exitを呼び出さないでください。遅延実行されるtp.Shutdown(ctx)がスキップされ、実行中の CHAIN/LLM スパンがフラッシュされなくなります。代わりにlog.Printfとmainからのreturnを使用し、tp.Shutdown(ctx)はmainの先頭で遅延実行されるように維持してください。
import (
"context"
"encoding/json"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
)
var tracer = otel.Tracer("my-app")
func runAgent(ctx context.Context, userMessage string) string {
ctx, chainSpan := tracer.Start(ctx, "run_agent")
defer chainSpan.End()
chainSpan.SetAttributes(
attribute.String("openinference.span.kind", "CHAIN"),
attribute.String("input.value", userMessage),
)
// ... LLM call ...
for _, toolUse := range toolUses {
ctx, toolSpan := tracer.Start(ctx, toolUse.Name)
argsJSON, err := json.Marshal(toolUse.Input)
if err != nil {
toolSpan.RecordError(err)
}
toolSpan.SetAttributes(
attribute.String("openinference.span.kind", "TOOL"),
attribute.String("input.value", string(argsJSON)),
)
result := runTool(toolUse.Name, toolUse.Input)
toolSpan.SetAttributes(attribute.String("output.value", result))
toolSpan.End()
// ... append tool result to messages, call LLM again ...
}
chainSpan.SetAttributes(attribute.String("output.value", finalReply))
return finalReply
}
その他のスパンの種類と属性については、手動インストルメンテーション を参照してください。
検証
以下の条件をすべて満たした場合にのみ、計装が完了したものとみなしてください。
- トレースの変更後も、アプリのビルドまたは型チェックが成功する。
- 新しいトレース設定でアプリが正常に起動する。
- スパンが生成されるはずの実際のリクエストを少なくとも1回実行する。
- Arize で生成されたトレースを検証するか、アプリ側の成功と Arize 側の失敗を区別できる具体的な阻害要因を示す。
実装後:
- アプリを実行し、LLM 呼び出しを少なくとも1回発生させます。
arize-traceスキルを使用してトレースが届いたことを確認します。何も表示されない場合は、少し待ってから再試行します。スパンに想定されるopeninference.span.kind、input.value/output.value、および親子関係が含まれていることを確認します。- トレースがない場合は、
ARIZE_SPACEとARIZE_API_KEYを確認し、トレーサーがインストゥルメンターやクライアントより先に初期化されていることを確かめ、otlp.arize.com:443への接続を確認して、アプリまたはランタイムのエクスポーターログを調べ、スパンがローカルで出力されているもののリモートで拒否されているかどうかを判断します。デバッグにはGRPC_VERBOSITY=debugを設定するか、register()にlog_to_console=Trueを渡します。よくある落とし穴:(a)プロジェクト名のリソース属性がないと HTTP 500 で拒否されます。service.nameだけでは不十分です。Python:register()にproject_nameを渡します。TypeScript:リソースに"model_id"またはSEMRESATTRS_PROJECT_NAMEを設定します。Go:resource.New(...)にattribute.String("openinference.project.name", "my-app")を追加します。(b)CLI/スクリプトのプロセスが OTLP エクスポートのフラッシュ前に終了します。終了前にprovider.force_flush()、続けてprovider.shutdown()(Python/TS)を呼び出すか、tp.Shutdown(ctx)(Go)を呼び出します。(c)CLI で表示されるスペース/プロジェクトと、コレクター向けに設定されたスペース ID が一致しないことがあります。認証情報を暗黙に書き換えず、不一致を報告してください。 - アプリがツールを使用する場合は、ツールの呼び出しと結果が確認できるよう、
input.value/output.valueを含む CHAIN スパンと TOOL スパンが表示されることを確認します。
CLI またはアカウントの問題で検証が阻まれた場合は、最後に具体的な状況を示してください。
- アプリの計装状況
- 最新のローカルトレース ID または実行 ID
- エクスポーターログにローカルでのスパン出力が記録されているかどうか
- 失敗の原因が認証情報、スペース/プロジェクトの解決、ネットワーク、コレクターによる拒否のいずれか
トレーシングアシスタント(MCP)の活用
IDE 内で詳しい計装ガイダンスを利用するには、次の機能を有効にできます。
- Arize AX Tracing Assistant MCP — 計装ガイド、フレームワークの例、サポートを利用できます。Cursor では、Settings → MCP → Add を選択し、次を使用します。
"arize-tracing-assistant": { "command": "uvx", "args": ["arize-tracing-assistant@latest"] } - Arize AX Docs MCP — 検索可能なドキュメントを利用できます。Cursor では次を選択します。
"arize-ax-docs": { "url": "https://arize.com/docs/mcp" }
その後、次のように質問できます。「このアプリを Arize AX で計装してください」、「トレースをもっと細かく制御できるように、手動で計装できますか?」、「スパンから機密情報をマスキングするにはどうすればよいですか?」
詳しいセットアップについては、エージェント支援トレーシングのセットアップを参照してください。
参照リンク
| リソース | URL |
|---|---|
| エージェント支援トレーシングのセットアップ | https://arize.com/docs/ax/alyx/tracing-assistant |
| エージェントセットアップ用プロンプト(全ルーティング+フェーズ) | https://arize.com/docs/PROMPT.md |
| Arize AX ドキュメント | https://arize.com/docs/ax |
| すべてのインテグレーション一覧 | https://arize.com/docs/ax/integrations |
| ドキュメントのインデックス(llms.txt) | https://arize.com/docs/llms.txt |
今後の利用に備えた認証情報の保存
references/ax-profiles.md § 今後の利用に備えた認証情報の保存を参照してください。