はじめに
2026年11月21日(土)から12月6日(日)まで開催される技術書典21で、赤煉瓦倉庫の『Databricksではじめる AIエージェントのためのデータ基盤入門』が頒布されます。私はこの本で、OpenTelemetry(OTel)で取ったトレースをDatabricksのUnity Catalogに取り込み、MLflowで見るまでを扱う章を担当しました。
この記事では、本の全体像と、担当した章で何が分かるようになるかを紹介します。
どんな本か
AIエージェントを業務で使うには、モデルだけでなく、その周りのデータ基盤が必要になります。この本は、その基盤をDatabricksでどう作るかを、250ページを超える分量で解説しています。扱っているテーマは次のとおりです。
- AI-Ready基盤の全体像
- AUTO CDCで変更履歴を取り込む
- Databricks Appsで人とエージェントをつなぐ画面を作る
- Unity GatewayでAI利用を管理する
- Lakebaseで記憶と状態を管理する
- LTAPで業務処理と分析を統合する
- OpenTelemetryとMLflowでエージェントの動作を可視化する
- Genie MigrateでSQLを変換する
- Lakehouse//RTでリアルタイム分析する
私が書いたのは、この中の可視化の章です。
担当した章: OpenTelemetry と MLflow をつなぐ
章のタイトルは「OpenTelemetry と MLflow をつなぐ ― Databricks でトレースを Unity Catalog に取り込む」です。
この章でできるようになること
多くの現場では、アプリはすでにOTelで計装されています。この章は、その計装を作り直さずにDatabricksへつなぐことを前提に書きました。読み終えると、次のことができるようになります。
- OTelで計装済みのアプリのトレースを、OTLPでUnity Catalogに取り込み、MLflowのTracing UIで見る
- 2つある取り込み経路のどちらを使うかを判断し、それぞれを設定する
- 「UIに出ない」「トークン数が合計に入らない」「属性で絞り込めない」といった問題を、OTelとMLflowの仕様の違いから切り分けて直す
前提としているのは、PythonとOpenTelemetry SDKの基本、それにDatabricksのExperiment、SQLウェアハウス、サービスプリンシパルです。TraceやSpan、Attributeといった用語は、章の最初の節でOTelとMLflowの両方の言葉を対応させながら説明しています。
章の構成
| 節 | 見出し | 扱っている内容 |
|---|---|---|
| 9.1 | 基礎概念 ― OTel と MLflow の言葉を揃える | Trace・Span・Attribute・Resourceの違いと、MLflowがスパン属性からUIの表示を組み立てる仕組み |
| 9.2 | Databricks への2つの取り込み経路 | MLflowコレクター経路とZerobus Ingest経路の比較 |
| 9.3 | MLflow UI に表示される条件 | トレースがUIに出るための条件 |
| 9.4 | 経路①の実装 ― MLflow マネージド OTLP コレクター |
@mlflow.trace とUnity Catalogのトレース保存場所を使った書き込み |
| 9.5 | 経路②の実装 ― Zerobus Ingest | テーブルの事前作成、専用トークンの発行、OTel SDKだけでの送信 |
| 9.6 | 連携時の落とし穴 ― OTel と MLflow の仕様差 | トークン集計、Inputs/Outputsパネル、sessionとuser、IDの対応、span link |
| 9.7 | 属性でトレースを絞り込む ― UI と SDK の違い | UIのフィルタ欄と search_traces で使える属性の違い |
| 9.8 | 実装チェックリスト | 確認項目と、トークンを自動で取り直す実装例 |
| 9.9 | トラブルシューティング | 症状・原因・対処の対応表と、Unity Catalogに届いているかの確かめ方 |
| 9.10 | まとめ ― どちらの経路を選ぶか | 経路ごとに向くケース |
前半で概念と2つの経路の実装を押さえ、後半で連携したときに起きる問題とその直し方を扱う構成です。
章の見どころ
本で詳しく書いている内容から、いくつか紹介します。
取り込み経路は2つあり、送り先もヘッダーも違う
OTLPでUnity Catalogにトレースを送る経路は2つあります。
- MLflowのマネージドOTLPコレクターに送る経路
- Zerobus Ingestに直接送る経路
どちらも最後は同じ形式のDeltaテーブルに書き込まれます。ただし、送り先のエンドポイントが別物で、テーブルを指定するヘッダーの名前も違います。片方のヘッダーをもう片方のエンドポイントに付けても動きません。ここが最初のハマりどころです。
経路によって、テーブルが自動で作られるかどうか、トークンの取り方、スループットの上限も変わります。章では経路ごとの仕様を表にまとめ、どちらを選ぶかの判断材料にしています。2つの経路を実際に動かして違いを確かめた記事も、以前に書きました。
UIに出るかどうかは経路では決まらない
トレースがMLflowのUIに表示される条件は、次の2つだけです。
- テーブルがExperimentのトレース保存場所に紐付いている
- root spanがある
どちらの経路で送ったかは関係ありません。実際に、OTel SDKだけで送ったトレースでも、あとからテーブルをExperimentに紐付けると mlflow.search_traces() で取得できました。
逆に言うと、Unity Catalogには届いているのにUIに出ないときは、この2つのどちらかを疑えば切り分けられます。root spanがない原因として多いのは、プロセスの終了前に force_flush と shutdown を呼んでいないケースです。
トークン量は root span の値だけが集計される
OTelのGenAIセマンティック規約の gen_ai.usage.* でトークン数を送った場合、トレース全体の合計に使われるのはroot spanの値だけです。章では次の2つのケースで確かめています。
| ケース | 設定した値 | トレースの合計 |
|---|---|---|
| A | root spanに入力150・出力42、child spanに999/999 | 192 |
| B | child spanにだけ値を設定 | 空(null) |
一方、MLflowの mlflow.chat.tokenUsage は全スパンを合算します。取り込み元によって集計の範囲が違うので、OTelで送るときはroot spanに合算値を設定しておく必要があります。この挙動は以前に記事でも検証しました。
同じ属性でも送り方によってUIの見え方が変わる
gen_ai.* 属性で入力と出力を送った場合、OTLPで取り込むとサーバー側でMLflowの入出力用の属性にコピーされ、Inputs/Outputsパネルに表示されます。MLflow SDK経由で同じ属性を付けた場合は、このコピーが行われないためパネルは表示されません。
このため、OTLPでの表示を確かめたいのにSDKで検証すると、本番と違う結果を見ることになります。章では、検証も本番と同じOTLPの経路で行う理由として、この違いを説明しています。
任意のスパン属性はUIのフィルタ欄では使えない
スパンに付けた任意の属性で、UIのフィルタ欄から絞り込むことはできません。任意の属性で絞り込めるのは、Unity Catalogに保存されているトレースに対してSDKの search_traces を使う場合です。
UIで絞り込みたい値は、スパン属性ではなくtagに持たせます。章では、session/user、tag/assessment、任意のスパン属性の3種類について、どこで絞り込めるかを図で整理しています。
そのほかの仕様差
9.6節では、上で紹介したもの以外に次の点も扱っています。
- trace メタデータに昇格するのは
session.idとuser.idだけで、会話IDのような2階層目のグルーピングはカスタムメタデータで持たせる設計になること - MLflowのトレースIDの末尾の16進部分がOTelのtrace_idそのものであること、
request_idはtrace_idの古い別名であること - span linkがUnity Catalogのトレースにも保存され、トレース画面の「リンク」タブに表示されること(SDKで読み出すにはMLflow 3.16.1以降が必要)
span linkについては、2本の記事を書いています。1本目はMLflow SDKでspan linkを張る方法、2本目はOpenTelemetry SDKだけで計装したアプリからspan link付きのトレースをUnity Catalogに送った結果です。
対象バージョン
章の内容はMLflow 3.14〜3.16系を前提にしています。経路①のコードは mlflow[databricks]>=3.14.0 を指定しています。span linkは3.16.0と3.17.2で確認しました。
頒布情報
- オンライン: 2026年11月21日(土)〜12月6日(日) 技術書典オンラインマーケット
- オフライン: 2026年11月23日(月・祝) 池袋サンシャインシティ 展示ホールD (文化会館ビル2F)
- 商品ページ: https://techbookfest.org/product/bVFXJDk8zuRg8EQdSTudCL
まとめ
担当した章の内容をまとめます。
- OTLPでUnity Catalogにトレースを取り込む経路は、MLflowのマネージドOTLPコレクターとZerobus Ingestの2つ
- 2つの経路は送り先のエンドポイントが別物で、テーブルを指定するヘッダー名も違う
- UIに出る条件は「Experimentのトレース保存場所に紐付いている」「root spanがある」の2つで、経路には依存しない
gen_ai.usage.*のトークン量はroot spanの値だけが集計される- 同じ
gen_ai.*属性でも、OTLPで送るかSDKで付けるかでInputs/Outputsパネルの表示が変わる - 任意のスパン属性で絞り込めるのはSDKの
search_tracesで、UIで絞り込みたい値はtagに持たせる
この章を書いていて一番強く感じたのは、OTelとMLflowはどちらもトレースを扱うのに、同じ言葉が指す範囲が少しずつ違うということでした。既存のOTel計装をDatabricksにつなぐとき、その違いを知っていれば、表示されない・集計されないといった問題の原因にすぐたどり着けます。章では、そのための対応表とチェックリストも用意しました。会場やオンラインマーケットで手に取ってもらえると嬉しいです。
参考リンク
- 商品ページ: Databricksではじめる AIエージェントのためのデータ基盤入門
- 技術書典21
- OpenTelemetryトレースをUnity Catalogに保存する
- MLflow トレースを OpenTelemetry にエクスポート
これまでに書いた関連記事です。
- Databricksで OpenTelemetry(OTLP)トレースをUnity Catalogに送る2つの経路と使い分け
- MLflowのトレースでトークン量が合計に出ない ― gen_ai.usage.*はroot spanだけが集計対象だった
- OpenTelemetryのspan linkをDatabricksのUnity Catalogトレースに送ってみた
- MLflowのspan linkを試してみた
- MLflowのトレースをUnity Catalogに保存してSQLで分析する ― OpenTelemetry連携ウォークスルー
- MLflowトレースをUnity CatalogにOTEL形式で保存してSQLで分析する
- MLflow 3のトレース長期保存: Unity Catalog保存 vs トレースアーカイブの違いを解説

