dt-setup-openinference-migration について
`gen_ai.*` セマンティック規約を有効にして Traceloop/OpenLLMetry から OpenInference へ移行する Python アプリ向けの手順です。計装の置き換えと、個別対応が必要なデータ欠落の特定に重点を置きます。
主な機能
- 01Traceloop の取り込み方式を特定
- 02計装を OpenInference に置き換え
- 03`gen_ai.*` セマンティック規約を有効化
- 04旧属性と呼び出しパラメーターを確認
- 05メトリクスとガードレールの不足を比較
- 06ベースラインと照合して検証
活用シーン
- 01Traceloop 計装済み Python アプリの移行
- 02既存のスパンエクスポート経路の維持
- 03移行後に残る旧属性の評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dynatrace/ dynatrace-for-ai --skill dt-setup-openinference-migrationインストール後、Claude Code で/dt-setup-openinference-migrationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/baseline-and-rollback.mdderived-metrics.mddetect-traceloop.mddual-write-cardinality.mdincomplete-attribute-mappings.mdingestion-shape.mdopenpipeline-safety.md詳細
Traceloop/OpenLLMetry から OpenInference へ移行する
すでに Traceloop/OpenLLMetry を介してスパンを出力しており、gen_ai.* セマンティック規約オプションを有効にして OpenInference へ移行する必要があるアプリ向けの、移行に特化した判断プロセスです。dt-setup-genai と Detect/Validate の仕組みを共有しています。4 段階の計装/エンリッチモデル、dtctl の検証契約、複数 SDK の扱いについては、そのスキルを読み込んでください。このスキルでは異なる点、すなわち Traceloop のセットアップの特定、計装の置き換え、そして gen_ai.* が流れるようになった後も残る課題(OpenInference が引き続き出力するレガシー属性、解析されないまま残る呼び出しパラメーター、計装では捕捉されなかったガードレールのシグナル)のみを扱います。
このスキルを使用しない場合
- 移行対象となる既存の Traceloop/OpenLLMetry 計装がない場合 → dt-setup-genai (新規構築、または既存の計装を一から拡張する場合)。
- すでに OpenInference を使用しているが、セマンティック規約オプションが有効になっておらず、スパンが
llm.*/openinference.*として引き続き届く場合 → 移行ではなく、dt-setup-genai スキルを読み込み、 そのノーマライザーゲート(references/enrich-normalization.md)を使用してください。 - TypeScript/Node アプリ、または Python 以外の言語の場合 → 対象外です。このスキルのフローで 必要となるセマンティック規約オプションは、現在 Python OpenInference SDK にのみ存在します。Traceloop から移行する TypeScript アプリには、このスキルではなく、後続の dt-setup-genai のノーマライザーゲートが引き続き必要です。
このスキルが停止して確認を求める必要がある場合
- お客様のアプリケーションコードを変更する場合 — まず差分を提示し、承認を得てください。
- レガシーの
llm.*/openinference.*属性を削除するかどうか(ステップ 4a)— これは トレードオフであり、黙って適用するデフォルトではありません。 - OTel Collector の transform または OpenPipeline パイプラインをテナントにデプロイする場合 —
dt-setup-genai と同じ境界です。または、Validate で解消できるギャップが確認された場合に限り、
gen_ai_normalizer(collector プロセッサーまたは OpenPipeline パイプライン)をデプロイする場合。OpenPipeline には特別な注意が必要です。 そのルーティング設定は、テナント上のすべてのパイプラインで共有される単一のオブジェクトです。まず references/openpipeline-safety.md を読んでください。 - 計装が出力しないガードレールのシグナルを捕捉するため、アプリコードを追加する場合(ステップ 4c)。
- 認証情報 — トークンの値を表示、ログ出力、保存しないでください。
- メッセージ内容の捕捉 — OpenInference は、セマンティック規約フラグとは無関係に、デフォルトでプロンプト/応答の内容を捕捉します(Traceloop の
TRACELOOP_TRACE_CONTENTによる動作と同様です)。計装の担当が変わった後もユーザーが引き続きこれを希望するか、確認してください。
移行の流れ
baseline ─▶ detect Traceloop ─▶ ingestion shape ─▶ swap instrumentor ─▶ close semconv gaps ─▶ validate
0. ベースラインとロールバック状態を記録する
何かを編集する前に、サービスが現在出力している内容と変更を元に戻す方法を記録してください。置き換えによって属性名が変わり、ダッシュボードやアラートが参照しているメトリクスが削除される可能性があります。ベースラインクエリ、利用者の一覧、ロールバックチェックリストについては、references/baseline-and-rollback.md を参照してください。
1. 既存の Traceloop/OpenLLMetry のセットアップを検出する
これが実際に移行にあたることを確認してください。grep パターンと、パッケージ名に関する注意点(Traceloop の一部のパッケージ名は、本物の OTel パッケージと同様に opentelemetry-instrumentation-<sdk> となっています)については、references/detect-traceloop.md を参照してください。ラップしている SDK を記録してください。各 SDK に対し、ステップ 3 で対応する openinference-instrumentation-<sdk> への置き換えが必要です。
2. 取り込み形態を確認する
これはステップ 4 で実際に修正できる内容を決めるため、コードに触れる前に確認してください。カーディナリティの問題では、次の 3 つの状況は互いに置き換えられません。
- アプリ所有のトレースエクスポーター — アプリが独自の
TracerProviderを構築し、BatchSpanProcessorと OTLP エクスポーターを設定して、インストルメンターの実行前にset_tracer_provider(...)を呼び出します。エクスポーターはアプリが制御するため、その手前にコレクターを配置できます。 - インストルメンテーションのみで、OneAgent が取り込む場合 — コードではインストルメンターの
.instrument(...)のみを呼び出し、TracerProviderやエクスポーターの設定はありません。OneAgent が監視するホストでは、OneAgent がプロセスに挿入されてスパンを取得します。アプリが制御できるものは通信経路上にないため、後からコレクターで変換することはできず、取り込み後にこれらのスパンを変更できるのは OpenPipeline のみです。 - Traceloop が管理するエクスポーター — アプリが
Traceloop.init()を呼び出し、上記のシンボルがどれも見当たらない場合でも、Traceloop 自体がTracerProviderとデフォルトの OTLP エクスポーターを作成します(宛先はTRACELOOP_BASE_URL/TRACELOOP_HEADERS/TRACELOOP_API_KEYで指定)。これを OpenInference インストルメンターだけに置き換えると、エクスポート経路が気付かれないまま失われます。まず同じ宛先を使うプロバイダーとエクスポーターを明示的に追加してから、init を削除してください。init_instrumentations(...)は別のもので、2 つ目の形態と同じくインストルメンテーションのみです。
完全な検出ヒューリスティックと、各形態の具体例については、次を参照してください。 references/ingestion-shape.md。
3. インストルメンターを置き換える
- 同じプロセス内で、同じ SDK に対して Traceloop/OpenLLMetry と OpenInference のインストルメンテーションを同時に実行しないでください。すべての呼び出しが二重にラップされ、重複またはネストされたスパンが発生します。同じ変更で OpenInference を追加するときに、その SDK の Traceloop インストルメンテーションを削除(または除外)してください。
- Traceloop パッケージを、対応する
openinference-instrumentation-<sdk>パッケージに置き換えてください。現在の呼び出し形式については、examples repo の<sdk>/openinference/レシピフォルダーを確認してください。手作業で記述しないでください(dt-setup-genai スキルのexamples-index.mdを参照してください。このファイルを読むには、そのスキルを読み込んでください)。 - インストルメンターの呼び出し形式はレシピから取得し、コレクター/OpenPipeline の設定から取得しないでください。 これらの設定には
gen_ai_normalizer(llm.*/openinference.* → gen_ai.*のマッピング)が含まれています。これは semconv オプションを使わないスパン用です。このオプションを有効にすると、gen_ai.*はすでにネイティブに出力されるため、最初からノーマライザーを追加したり、それを含む設定をコピーしたりしないでください。 - semconv オプションを有効にしてください。
.instrument(config=...)にTraceConfig(enable_genai_semconv=True)を渡すか、インストルメンターが環境変数を読み取る場合はOPENINFERENCE_ENABLE_GENAI_SEMCONV=trueを設定します。どちらも Python 専用です(上記の「このスキルを使用しない場合」を参照)。これを有効にしないと、インストルメンターはllm.*/openinference.*のみを出力するため、dt-setup-genai のノーマライザー判定に戻ってしまいます。 - 複数の SDK を使うアプリ → SDK ごとに繰り返します。dt-setup-genai を読み込み、その
references/multi-sdk-apps.mdに従ってください。 - Traceloop の init を削除する前に、カスタムスパンプロセッサーやログ相関など、ほかに Traceloop 固有の属性(
traceloop.*)を読み取っているものがないか確認してください。
4. semconv オプションで埋まらない不足を補う
semconv オプションを使うと、コアとなる gen_ai.* の契約フィールドが流れるようになりますが、既知の不足が 4 つ残っており、それぞれ異なる対応が必要です。ステップ 3 の直後に Validate を実行し(ステップ 5)、その結果に基づいてこのステップを進めてください。ノーマライザー(gen_ai_normalizer)は不足に応じた代替策であり、デフォルトではありません。L3 チェックで、semconv オプションでは補われない特定の契約フィールドがまだ不足している場合にのみ追加してください。該当するフィールドをユーザーに伝え、事前に承認を得てください(コレクター/テナントの変更です)。不足が呼び出しパラメーターまたはガードレールだけの場合は、4b/4c を使用してください。
4a. デュアルライトのカーディナリティ。 semconv オプションは置き換えではなく、追加です。 有効にすると、OpenInference は同じスパンに llm.*/openinference.* の代わりではなく、それらと並行して gen_ai.* を出力します(dt-setup-genai の検証契約でも同様に定められています)。移行後のアプリで確認してください。リクエストを 1 件送信し、dtctl/DQL でスパンの属性を一覧表示して、両方の属性ファミリーが存在することを確認します。
すべてのスパンで属性数がおよそ 2 倍になります(ペイロード/ストレージのオーバーヘッド)。メトリクスのカーディナリティが増えるのは、レガシーフィールドをディメンションとして選択した場合に限られます。測定していないのであれば、削除をカーディナリティ対策として提示しないでください。gen_ai.* の存在を確認したら、レガシーセットを削除するかどうかをユーザーに尋ねてください。自分で決めてはいけません。 削除を希望する場合、その方法は手順 2 で確認した取り込み形態によって異なります。
| 取り込み形態 | 削除方法 |
|---|---|
| アプリ所有のエクスポーターで、コレクターがすでに経路上にある | OTel Collector の transform プロセッサー |
| アプリ所有のエクスポーターで、現在コレクターがない | これはデフォルトではなく、実際のトレードオフです。コレクターの追加はインフラストラクチャの変更です(dt-setup-genai の中断して確認する項目でも同じ境界が示されています)。そのため、「コレクターを導入する」と「代わりに OpenPipeline を使う」の両方を提示し、ユーザーに選択してもらいます |
| OneAgent がスパンを取り込む | OpenPipeline のみ。OneAgent と Dynatrace の間にコレクタートランスフォームを実行するものはありません |
提案する前にどちらも利用可能か確認してください。スニペットと利用可否の確認方法はこちらです。 references/dual-write-cardinality.md。
4b. 呼び出しパラメーター — コレクターまたは OpenPipeline の設定で修正可能です。 OpenInference はモデルパラメーター(temperature、top_p など)を llm.invocation_parameters の 1 つの JSON 文字列にまとめます。個別の gen_ai.request.* フィールドが設定されているか、明示的に確認してください(リファレンスにクエリがあります)。semconv オプションを使っても、値がまとめられたままになるケースが確認されています。そうであれば、手順 2 の形態で許可される仕組みを使ったパイプラインの修正で対応できます。スニペットはこちらです。
references/incomplete-attribute-mappings.md。
4c. ガードレール属性 — パイプラインの修正ではなく、カスタム計装コードが必要になる可能性が高いです。 OpenInference には標準化されたガードレール属性がありません。openinference.span.kind = "GUARDRAIL" が示すのはスパンの種類だけであり、ガードレールが作動したかどうかはプロバイダー/ライブラリごとに異なる方法で通知されるか、まったく記録されません(プロバイダーごとの表は references/incomplete-attribute-mappings.md を参照)。シグナルが一度も記録されていない場合、コレクターや OpenPipeline のトランスフォームでは復元できません。アプリ側で記録する必要があります。これはアプリコードの編集です。まず作業を止め、明示的な承認を得てください。 ガードレールの可視化が不要であれば、未対応の項目として記録しておくだけでも構いません。
4d. 派生メトリクス — 切り替え後は失われます。 OpenInference が出力するのはスパンのみです。Traceloop が出力していた gen_ai.client.token.usage と gen_ai.client.operation.duration のメトリクスは消え、AI Observability アプリのメトリクスベースのコストおよびレイテンシーのグラフからサービスが失われます。手順 0 のベースラインと比較してください。消えている場合は、取り込み形態に応じてコレクターコネクターまたは OpenPipeline のメトリクス抽出を使い、スパンから派生させます。まず確認し、コネクターがコレクターのディストリビューションに存在するか確かめてください(代替手段は Bindplane です)。references/derived-metrics.md を参照してください。
ギャップの報告 — 必須です。黙って省略してはいけません。 完了する前に、確認できた 4 つのギャップすべてについて、確認内容、提案する修正または明示的な「現状のままにする」、承認が必要な内容を記した簡潔な表をユーザーに提示してください。「未確認」は結果として認められません。リポジトリに複数のサービスやコレクター設定がある場合は、すべて確認して一度だけ尋ね、すべてに同じ判断を適用してください。あるサービスのパイプラインでは削除や展開を行い、別のサービスではそのままにすることは絶対に避けてください。
5. 検証
同じ契約、同じループです。dt-setup-genai スキルを読み込み、Validate ステップ(SKILL.md のステップ 4)と references/validate-contract.md に完全に委任して、ステップ 0 のベースラインと比較する dtctl の L1~L4 ループ全体を実行します。ここで見つかったギャップだけが、gen_ai_normalizer を追加するトリガーになります。移行固有の L3 での追加事項:4a でレガシー属性を削除した場合は、削除されていることを確認します(isNull(llm.system) など)。選択により残した場合は、共存が想定されます。4b で呼び出しパラメーターを展開した場合は、プロバイダープロファイルが要求するフィールドに値が設定されていることを確認します。L4 は 4d を対象とします。4c にはゲートがありません。属性は、ユーザーが追加を承認したために存在するか、文書化された受け入れ済みのギャップです。
参考資料
- references/baseline-and-rollback.md — ベースライン、コンシューマー、ロールバック
- references/detect-traceloop.md — grep パターン、パッケージ名に関する注意点
- references/ingestion-shape.md — 3 つの取り込み状況
- references/dual-write-cardinality.md — レガシー属性の削除
- references/incomplete-attribute-mappings.md — 呼び出しパラメーター、ガードレール
- references/derived-metrics.md — トークン使用量/期間メトリクスの再作成
- references/openpipeline-safety.md — 共有ルーティングオブジェクト、マッチャーのスコープ設定
- dt-setup-genai — 共通の Detect/Enrich/Validate の仕組みと
dtctl契約を利用するには、名前で読み込みます - Examples repo — SDK ごとの
openinference/レシピ(呼び出し形式のみ) - OTel GenAI semantic conventions —
gen_ai.*契約