dt-setup-genai について
Python と TypeScript の GenAI アプリに Dynatrace テレメトリーを導入するための判断フローです。経路選択、スパンの補強、検証を扱い、機微な変更の承認境界も示します。
主な機能
- 01ネイティブ OTel と代替経路の選択
- 02SDK と既存計装の検出
- 03会話コンテキストによるスパン補強
- 04dtctl によるテレメトリー検証
- 05メッセージ内容の取得設定に関する指針
活用シーン
- 01新しい Python または TypeScript GenAI アプリの計装
- 02未対応 SDK の実装方針の選択
- 03スパンが Dynatrace の要件を満たすか確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dynatrace/ dynatrace-for-ai --skill dt-setup-genaiインストール後、Claude Code で/dt-setup-genaiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/enhance-existing.mdenrich-normalization.mdexamples-index.mdmulti-sdk-apps.mdno-native-instrumentation.mdvalidate-contract.md詳細
Dynatrace 向けに GenAI アプリを計装する
これは、dynatrace-oss/dynatrace-ai-agent-instrumentation-examples にあるフレームワーク別レシピの共通の判断プロセスです。以下では examples repo と呼びます。このプロセスを切り出し、examples repo がまだ対応していない SDK にも適用できるようにしています。どのレシピの形式を選ぶべきか、その理由、そして SDK/言語を問わず「完了」がどのような状態かを説明します。スパンが流れるようになったら、dt-obs-genai を読み込んで分析します。
このスキルを使わない方がよい場合
- すでに計装済みで、GenAI テレメトリをクエリ/デバッグしたい場合 → dt-obs-genai。
- SDK のレシピはすでに把握していて、コピー&ペーストできるコードだけが必要な場合 → examples repo に直接進んでください。このスキルが判断するのは、どのレシピ形式が該当するかであり、レシピそのものを置き換えるものではありません。
- アプリが Python または TypeScript ではない場合 → このスキルの対象外です。
このスキルが必ず作業を止めて確認を求める場合
- お客様のアプリケーションコードを編集する場合 — まず差分を提示し、承認を得てください。
- 認証情報 — Dynatrace トークンとプロバイダーキーはお客様が作成します。トークン値を表示、ログ出力、保存してはいけません。環境変数またはシークレットストアを介してのみ参照してください。
- お客様のテナントに OpenPipeline パイプラインをデプロイする場合。
- このスキルでは推測できないプロバイダー設定 — Azure のデプロイ名/API バージョン、Ollama のモデルタグ、Bedrock のリージョン/プロファイル。
- 実行環境にコレクターを追加する場合 — 設定ではなくインフラストラクチャに関わるため、対象外です。
- メッセージ内容のキャプチャを有効にする場合 — デフォルトでは無効です。ユーザーから依頼があった場合に限り有効にしてください。
プロンプト/完了テキストには PII や機密データが含まれる可能性があり、有効化の設定は SDK 固有です。
一部の計装ライブラリでは
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=trueを使用します。一方、環境変数では制御できず、デフォルトで有効になる場合もあるフレームワークネイティブのフラグ(例:pydantic-ai のInstrumentationSettings(include_content=...))を使うものもあります。OpenInference はデフォルトで内容をキャプチャします。また、Traceloop/OpenLLMetry のopentelemetry-instrumentation-<sdk>パッケージはTRACELOOP_TRACE_CONTENTを読み取り、デフォルトは ON で、OTel 標準の変数は無視します。気づかないうちにキャプチャが有効な状態でリリースしないよう、SDK の実際の切り替え設定を確認してください。必要に応じて、マスキングについて合意してください。
4 つのステップ
detect ─▶ instrument ─▶ enrich ─▶ validate
│ │
└──────────── feedback loop ───────┘
(validate failure → fix in enrich or instrument)
1. 検出
コードに触れる前に、何を計測するのかを特定します。
入力:
- 依存関係マニフェスト(
pyproject.toml/requirements.txt/package.json)— 存在する LLM SDK、エージェントフレームワーク、またはオブザーバビリティ SDK(OpenAI、Anthropic、Bedrock、LangChain/LangGraph、CrewAI、MCP サーバー/クライアント、Langfuse など)。アプリは複数に依存している場合があります。references/multi-sdk-apps.md を参照してください。 - ホストですでに Dynatrace OneAgent が動作しているかどうか(
oneagentプロセス/パッケージの有無)。動作している場合、OneAgent は一般的な HTTP/SDK 呼び出しをコード変更なしで自動計測するため、その後のすべての手順が変わります。 - アプリにすでに何らかの OTel 設定があるかどうか — 既存のグローバルな
TracerProvider、既存のTraceloop.init()/インストルメンター呼び出し、または既存のカスタムスパンコード。
出力: SDK ごとのルーティングキー (framework/SDK, existing-instrumentation-state)(複数ある場合は references/multi-sdk-apps.md を参照)、分岐の判断(以下)、および SDK ごとの native-OTel yes/no の判断(ステップ 2)。
native-OTel とフォールバックの判断方法: 純粋な OTel パス(ネイティブな gen_ai.*)がある SDKを優先します。該当するパスがない SDK は OpenInference にフォールバックします。これによって一連の流れが完了するのは、gen_ai.* を出力する場合のみです(Python の semconv デュアルライト、ステップ 2)。それ以外の場合はノーマライザーのゲートで停止します。次の順に確認し、最初に該当した時点で終了します。
- SDK が
references/examples-index.mdにあるか確認します。opentelemetry/のレシピが掲載されていれば、これが最短ルートです。使用してください。 - SDK が掲載されていない場合は、OpenTelemetry registry とベンダー SDK のドキュメントを確認し、ネイティブな OTel/
gen_ai.*サポート(例:otelエクストラ、span_exporter/トレーサープロバイダーフック、または組み込みの semconv 属性)があるか調べます。見つかった場合は、それを使ってインストルメントします(ステップ 2)。 - ネイティブな OTel パスがない場合 → OpenInference。 examples-repo のレシピに従い、対応する
openinference-instrumentation-<sdk>パッケージを使ってインストルメントします。それも存在しない場合は、gen_ai.*スパンを手動で記述します(references/no-native-instrumentation.md)。 OpenInference によって一連の流れが完了するのは、gen_ai.*を出力する場合のみです — semconv デュアルライトが有効な Python インストルメンター(ステップ 2)が該当します。それ以外(TS/node、古いバージョン、未設定)の場合、スパンはllm.*/openinference.*のままとなり、このスキルはノーマライザーのゲート(references/enrich-normalization.md)で停止してから再開します。
2. インストルメント
スパンの出力を設定します。純粋な OTel パスを優先し、ネイティブな OTel パスがない場合に限り OpenInference にフォールバックします。このフォールバックによって一連の流れが完了するのは、gen_ai.* を出力する場合(以下の semconv デュアルライト)のみです。それ以外の場合は Validate の前にノーマライザーのゲートで停止します。
- Pure OTel(推奨、エンドツーエンドでサポート)。 ネイティブの OTel 計装パッケージ、またはフレームワーク独自の OTel 統合機能から
gen_ai.*を直接出力し、Dynatrace OTLP エンドポイント(ホストとスコープのルールは以下の共通形式を参照)に直接エクスポートするか、コレクター経由でエクスポートします。多くのエージェントフレームワークやベンダー SDK にはこの機能が付属しているか、カスタムのspan_exporterを指定できます。現在の一覧はこの場所ではなく、examples リポジトリにあります。⚠️ Traceloop/OpenLLMetry のものではなく、正式に OTel で公開されているインストルメンターを優先してください。Traceloop/OpenLLMetry は上流でサンセットしたと報告されているため、新たな計装には使用しないでください(すでに利用しているアプリは、既存環境の拡張または移行として扱います)。また、デフォルトでメッセージ内容のキャプチャが有効になります。使用するパッケージとルーティング方法については、references/examples-index.md §1a を参照してください。 - フォールバック = OpenInference。 ネイティブな OTel 経路がない場合は、examples リポジトリのレシピにある対応する
openinference-instrumentation-<sdk>パッケージ(OpenAIInstrumentor、AnthropicInstrumentorなど)を使用します。初期化する前に、ドキュメントに記載された設定を使って、その SDK でデフォルト有効になっているメッセージ内容のキャプチャを明示的に無効にしてください。OTel 標準の環境変数に頼ってはいけません。キャプチャを無効にできない場合は、リクエストを実行する前に中止して確認してください。 Python のインストルメンターは、ネイティブの場合と同様に検証できるよう、両方に書き込めます。それ以外の場合(TS/node、古いバージョン、または未設定の場合)、スパンはllm.*/openinference.*のままとなり、ユーザーがノーマライザーを適用するまで、スキルは「検証」の前に停止します(references/enrich-normalization.md)。OpenInference パッケージもない場合は、手動でスパンを記述します(references/no-native-instrumentation.md)。 - OneAgent が存在する場合: この手順をスキップしてください。コードを変更する必要はなく、OneAgent が自動的に計装します。Smartscape で別のアプリと統合されずに個別のエンティティとして作成されるよう、アプリ/サービスには一意のタイトル(例:
FastAPI(title=...))のみを設定してください。
グリーンフィールドモードでの共通形式(OneAgent を使用しない場合): アプリで既存のパッケージマネージャーに合わせます。新規作成する場合(Python)は、デフォルトで**uv**を使用します。
- 少なくとも
service.nameを含むResourceを作成し、それを使ってTracerProviderを作成します。gen_ai.agent.nameなどのエージェント識別属性はResourceレベルではなくスパンレベルに設定します。GenAI ビューとエージェントのクイックフィルターはスパンから属性を読み取るため、Resourceではなく、スパンの作成時またはスパンプロセッサー内で設定してください(「拡張」を参照)。 - スパンプロセッサーと OTLP エクスポーターを設定し、Dynatrace に直接、またはローカルの OTel Collector(
http://localhost:4318)に送信します。後者は、「拡張」で先に変換が必要な場合に使用します。エンドポイントの形式はエクスポーターによって異なり、互換性はありません。- コレクターの
otlphttpエクスポーターにはベースパス($DT_ENDPOINT/api/v2/otlp)を指定します。/v1/<signal>はエクスポーターが自動的に追加します。 - SDK ネイティブのエクスポーター(例:Python の
OTLPSpanExporter(endpoint=...)、Node のOTLPTraceExporter)は、エンドポイントを POST URL としてそのまま使用します。完全な$DT_ENDPOINT/api/v2/otlp/v1/traces(または/v1/metrics、/v1/logs)を渡してください。そうしないと 404 が返されます。 ヘッダー:Authorization: Api-Token $DT_API_TOKEN。トークンのスコープはopenTelemetryTrace.ingestに加え、必要に応じてmetrics.ingest/logs.ingestを指定します。トークンの値を表示、ログ出力、保存しないでください。
- コレクターの
- インストルメンター/SDK の初期化は、アプリの最初の LLM 呼び出しより前に行います。リクエストハンドラー内で遅延初期化しないでください。また、セッション/会話の相関情報を付与できるよう、呼び出しをラップしてください(「拡張」を参照)。
入力: 手順 1 のルーティングキーとネイティブ OTel の選択結果、DT_ENDPOINT/DT_API_TOKEN またはコレクターのエンドポイント、サービス名。
出力: スパンを出力する実行中のアプリ。gen_ai.* を直接出力する(Pure OTel)か、ユーザー側のノーマライザー適用を待つ llm.*/openinference.* を出力します。
3. 強化
スパンを gen_ai.* セマンティック規約に完全準拠させ、横断的なコンテキストを追加します。
経路にかかわらず必ず実施すること:
- メトリクスのエクスポートを デルタテンポラリティ(
OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta)に設定します。Dynatrace は累積メトリクスを 400 エラーで拒否します。 - メッセージ内容のキャプチャ(
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=SPAN_ONLYまたはSPAN_AND_EVENT、フレームワークネイティブのフラグ、OpenInference のデフォルトで有効なキャプチャ)は、 中断して確認する判断事項です。上記を参照してください。承認後、gen_ai.input.messages/gen_ai.output.messagesが出力されることを確認します。 - 安定した会話 ID を会話ごとに一度だけ設定し、リクエストごとに再生成しないでください。
gen_ai.conversation.idを設定先とします。ネイティブの仕組みがある場合はそれを優先してください (例:pydantic-ai はインストルメンテーションを通じて、実行/メッセージ履歴からgen_ai.conversation.idを導出します)。それ以外の場合、自分でスパンを作成するなら、呼び出し箇所で 言語固有のスパン変更 API を使用します(Python ではset_attribute、Node ではsetAttribute。例: ネイティブインストルメンテーションがない場合の手動スパン経路)。呼び出し箇所でハンドルを取得できないまま 内部でスパンを作成する自動インストルメンテーションのベースラインパッケージでは、言語固有のスパンプロセッサ フック(Python ではon_start、Node ではonStart)を登録し、スパンがエクスポートされる前に属性を設定します。 この仕組みは、インストルメンターが出力しない属性でアプリから設定できるものなら、どれにでも使用できます。 マルチエージェントアプリでは、すべてのエージェント/サブエージェント呼び出しに同じ ID を引き継いでください。 そうしないと、実行ごとに別々の ID が出力され、会話はtrace.idだけを共有する断片に分かれてしまいます。 OpenInference ユーザーの場合:using_attributes(session_id=...)が出力するのはgen_ai.conversation.idではなくsession.idです。そのため、 正規化ルールで実際にマッピングされることを確認してください。 - エージェントフレームワークでは、ネストされたスパン(crew/workflow → agent → task/tool)を想定してください。
継続時間メトリクスは
gen_ai.operation.nameではなく、スパン名/スパン種別から導出します。CrewAI は 3 つすべての階層でinvoke_agentを設定するため、これを使うとすべてが 1 つのヒストグラムにまとめられます。
フォールバック経路(OpenInference)— ユーザー側での正規化ゲート: semconv のデュアルライトに
対応していない場合(TS/node、古いバージョン)、スパンは gen_ai.* ではなく llm.*/openinference.* として
届くため、正規化されるまで Validate は合格できません。また、この手順はスキルがユーザーに代わって実行できません。
サンプルの正規化設定(collector の gen_ai_normalizer または OpenPipeline。詳しくは
references/enrich-normalization.md を参照)を提示し、適用済みとの確認を得てから
Validate を再開してください。
入力: ステップ 2 の生スパン — gen_ai.*(純粋な OTel)、またはユーザー側の正規化を待つ
llm.*/openinference.*(フォールバック)。
出力: 会話の相関付けに対応した gen_ai.* 準拠のスパンと、導出されたエージェント/ワークフローの継続時間または
トークン使用量メトリクス。
4. 検証する
既知のコントラクトに照らして、パイプラインがエンドツーエンドで動作することを確認します。目視で判断しないでください。
dtctl が主要な検証ループです。 Dynatrace で出力されたスパンをクエリするため、アサーションを機械的かつ繰り返し実行できます。手順全体、コントラクトの固定、重大度のルールは、references/validate-contract.md に記載されています。
入力: 手順 2~3 で計装した、実行中のアプリです。OpenInference にフォールバックする場合は、通常のノーマライザーが適用されたことをユーザーが確認したあとにのみ、Validate を開始します(Enrich のゲート)。そうしないと、以下のすべてのチェックが、マッピングされていない llm.* スパンで失敗します。
手順:
- アプリに実際のリクエストを送信します。
dtctlがインストールされていることを確認します(dtctl version)。インストールされていない場合は、続行する前にdtctl READMEからインストールします。dtctlで生成されたスパンをクエリします。service.nameでフィルタリングします。references/validate-contract.md にある、そのまま使えるdtctl queryを参照してください。 (dtctlが利用できない場合の手動フォールバック:AI Observability アプリの Explorer または Distributed Tracing アプリで、同じfetch spansDQL を使用します。クエリ構文については dt-dql-essentials を読み込みます。ただし、dtctlが提供する再現可能なアサーションは使えません。)- アプリのプロバイダーに一致するコントラクトプロファイルで宣言された必須フィールドとメトリクスをアサートします。最低限、
gen_ai.provider.name/gen_ai.systemのいずれかが必要です(両方のうちいずれか一方。gen_ai.provider.nameの出力を推奨します)。gen_ai.operation.nameは、選択したプロファイル/シナリオで必須とされていない限り推奨項目として扱い、推論/プロバイダー固有のフィールドは、そのプロファイルで適用対象とされている場合にのみ適用します。重大度(失敗または警告)とプロバイダーごとのプロファイルについては、references/validate-contract.md を参照してください。 出力: コントラクトに対する合格/不合格です。失敗した場合、修正すべき箇所は Enrich(属性マッピングの不足または誤り)または Instrument(SDK/コレクター設定の誤り)です。Validate 自体ではありません。Validate は検出のみを行い、修正はしません。修正後、同じdtctlクエリを再実行して確認します。
OneAgent の場合: 手順 1~4 は変わりません。引き続き dtctl でクエリします。ただし、失敗した場合に振り分ける Instrument/Enrich の手順はありません。修正できない OneAgent バージョンの制限(報告してください)か、手順 2 のエンティティタイトルが一意でないこと(修正してください)のどちらかです。Validate に合格したら、分析のために dt-obs-genai を読み込みます。
新規作成と既存環境の拡張
どちらの分岐でも同じ 4 つの手順を実行します。違いは、Detect で検出するものと、Instrument で変更できる範囲です。既定では既存環境を拡張し、新規作成は例外的なケースに限定します。
既存環境の拡張 — 対象が既存のリポジトリ、アプリケーション、テンプレート、サンプル集、ワークフロー、または構成である場合です。追加を依頼された特定のファイルやサンプルがまだ存在しない場合も含みます。維持すべきコントラクト(同種の実装、計装のセットアップ、ビルド/依存関係の規約、テストハーネス、デプロイ設定)があるため、それに準拠し、別のものを並行して作らないでください。 新規作成の「一般的な構成」をそのままコピーするのは安全ではありません。 新しい Resource/TracerProvider を作成すると、既存のものが暗黙に置き換えられ、アプリが必要とするスパンが失われる可能性があります。ケースごとの詳細と、サービス名の衝突に関するルールは、references/enhance-existing.md を参照してください。
新規作成 — 維持すべき既存のリポジトリコントラクト、同種の実装、計装のセットアップ、ビルド規約、テストハーネス、デプロイ設定がない場合に限り適用されます。その場合にのみ、Instrument は既存のものを上書きするリスクなく、新しい Resource/TracerProvider/エクスポーターを作成できます。判断に迷ったら、既存環境の拡張として扱います。 新しいものをひな型から作るのではなく、既存のものに合わせてください。
参考資料
- dynatrace-oss/dynatrace-ai-agent-instrumentation-examples — このバックボーンの基になった、フレームワークごとの具体的なレシピ
- OTel GenAI semantic conventions — このスキルが計装の対象とする
gen_ai.*属性の仕様 - OpenTelemetry registry — ステップ 1 のネイティブ OTel とフォールバックの判断に使用します
- references/examples-index.md — ルーティングキーから examples リポジトリの具体的なレシピへの対応表
- references/enrich-normalization.md — OpenInference のフォールバックゲート。Validate を通過する前に正規化が必要な場合(および semconv フラグによってスキップされる場合)と、ユーザーが適用する既成の正規化設定(collector / OpenPipeline)を説明します
- references/multi-sdk-apps.md — アプリが複数の LLM SDK に依存している場合に Detect/Instrument/Enrich を実行する方法
- references/no-native-instrumentation.md — SDK 用のパッケージ化された計装が存在しない場合の暫定策として、手動で純粋な OTel
gen_ai.*スパンを作成する方法 - references/enhance-existing.md — 既存の計装を強化する各ケースの詳しい説明
- references/validate-contract.md — 仕様(
mainで確認)、dtctlの検証ループ、失敗/警告の重大度、any-of ゲート、プロバイダープロファイル、派生メトリクスの遅延について説明します