2026年5月5日に公開・更新された Microsoft developer platform の「Fix get_caller_pairs: resolve userId across all channels」は、UIや管理画面の変更ではなく、OpenTelemetryのテレメトリで使われる userId の取得ロジックを修正する変更です。結論から言うと、これまで aad_object_id がない非TeamsチャネルやA2A呼び出しで userId が空になりやすかった問題に対し、aad_object_id → agentic_user_id → frm.id の順でフォールバックするようになりました。Python実装では microsoft/opentelemetry-distro-python のPR #118として2026年5月5日にマージされています。(GitHub)
Microsoft developer platform上でAgent365、A2A、複数チャネル対応のエージェント、OpenTelemetryによる監視を使っている場合は、単に「バグ修正」と見なさず、監視ダッシュボード、アラート条件、ログ分析、ユーザー識別の前提を確認する必要があります。特に、これまで user.id が None または空だったデータが、更新後は値を持つ可能性があります。
Microsoft developer platform documentation updateで何が変わったのか
今回の変更は、get_caller_pairs() が呼び出し元ユーザーの識別子をどのように取り出すかに関する修正です。
変更前は、userId baggage が主に aad_object_id だけから設定されていました。しかし、PRの説明では、aad_object_id は非TeamsチャネルやA2A呼び出しで None になることがあるとされています。そのため、Teams以外のチャネルやエージェント間連携では、テレメトリ上の userId が取得できないケースがありました。(GitHub)
変更後は、Python実装で次のような解決順序になります。
frm.aad_object_id or frm.agentic_user_id or frm.id
実際の差分では、従来の frm.aad_object_id のみを返す処理から、frm.aad_object_id or frm.agentic_user_id or frm.id を返す処理に変更されています。(GitHub)
| チャネル・呼び出し元 | 変更後の userId の主な取得元 | 実務上の意味 |
|---|---|---|
| Teams | aad_object_id | 既存のTeams中心の識別は大きく変わりにくい |
| 非Teamsチャネル | frm.id | これまで空だった userId が埋まる可能性がある |
| A2Aのユーザー呼び出し | aad_object_id | ユーザー由来の呼び出しでは従来のIDが優先される |
| A2Aのエージェント呼び出し | agentic_user_id | エージェント由来の呼び出しでも識別子を持てる |
PRのテスト計画でも、非Teamsチャネルでは frm.id へフォールバックすること、A2Aでは agentic_user_id へフォールバックすること、すべての識別子がある場合は aad_object_id が優先されることが確認対象として追加されています。(GitHub)
この変更が重要な理由
一見すると小さな修正ですが、影響するのは「ユーザーIDをどう表示するか」だけではありません。OpenTelemetryのBaggageは、サービスやプロセスをまたいでコンテキスト情報を伝播するためのキー・バリュー情報です。ユーザーIDのような情報をBaggageで扱うと、トレース、メトリクス、ログの分析に利用できます。(OpenTelemetry)
つまり今回の変更により、これまで観測データ上で「呼び出し元不明」に見えていた非TeamsチャネルやA2A呼び出しが、user.id で追跡しやすくなる可能性があります。
たとえば、次のような分析に影響します。
- 特定ユーザーまたは特定呼び出し元に紐づくエラー率の確認
- A2A呼び出しで、どのエージェントから処理が発生したかの追跡
- 非Teamsチャネル経由のリクエストで、
user.idが空になる件数の削減 - ログ、トレース、メトリクスを横断した原因調査
一方で、user.id が埋まるようになることで、既存のクエリ結果やダッシュボードの見え方が変わる可能性もあります。特に「user.id が空のイベント数」を異常検知や匿名ユーザー数の推定に使っていた場合は、更新前後で集計値が変化します。
対応が必要になりやすい開発者・運用担当者
今回のMicrosoft developer platform documentation updateで優先的に確認すべきなのは、次のような環境です。
| 対象 | 確認すべき理由 |
|---|---|
| Agent365やA365関連のPython実装を使っているチーム | Python側の get_caller_pairs() が直接変更されているため |
| Teams以外のチャネルを扱うエージェント開発者 | aad_object_id がないケースで frm.id が使われる可能性があるため |
| A2A呼び出しを使っている開発者 | agentic_user_id による識別が有効になる可能性があるため |
| OpenTelemetryでログ・トレース・メトリクスを分析している運用担当者 | user.id の欠損率や集計単位が変わる可能性があるため |
| SIEM、監査ログ、社内分析基盤に連携しているチーム | IDの種類が変わると相関分析や正規化処理に影響するため |
特に注意したいのは、userId が常にMicrosoft Entra IDのオブジェクトIDを意味するとは限らなくなる点です。Teamsでは aad_object_id が優先されますが、非Teamsチャネルでは frm.id、A2Aのエージェント呼び出しでは agentic_user_id が入る可能性があります。
そのため、user.id を「社内ユーザーの一意ID」として無条件に扱っている場合は、データ設計を見直す必要があります。より安全なのは、user.id を「そのチャネルまたは呼び出しコンテキストにおける呼び出し元ID」として扱い、必要に応じて別途正規化テーブルやIDマッピングを用意する方法です。
変更前後の動作を具体例で理解する
今回の修正を、実務でよくあるケースに置き換えると分かりやすくなります。
Teamsユーザーからの呼び出し
Teamsからの呼び出しで aad_object_id がある場合、変更後も aad_object_id が最優先で使われます。
aad_object_id = "aad-wins"
agentic_user_id = "agent-auid"
frm.id = "raw-id"
userId = "aad-wins"
PRに追加されたテストでも、すべての識別子が設定されている場合は aad_object_id が優先されることが確認されています。(GitHub)
このケースでは、既存のTeams中心の監視設計に大きな変更は出にくいと考えられます。ただし、他チャネルも同じダッシュボードに集約している場合は、user.id の値の種類が混在する点に注意が必要です。
非Teamsチャネルからの呼び出し
非Teamsチャネルでは、aad_object_id が None になることがあります。変更前は、このケースで userId が空になりやすい状態でした。
変更後は、agentic_user_id がなければ frm.id が使われます。
aad_object_id = None
agentic_user_id = None
frm.id = "slack-user-123"
userId = "slack-user-123"
PRの追加テストでも、非Teamsチャネルで aad_object_id が None の場合に frm.id へフォールバックするケースが検証されています。(GitHub)
ここで重要なのは、frm.id が必ずしも企業内の統一ユーザーIDではないことです。チャネルごとのユーザーID、会話IDに近い値、サービス固有の形式など、実装やチャネルに依存する可能性があります。監査や課金、権限判定の主キーとしてそのまま使うのではなく、まずは観測・相関分析用のIDとして扱うのが安全です。
A2Aのエージェント呼び出し
A2A呼び出しでは、aad_object_id がない場合に agentic_user_id が使われます。
aad_object_id = None
agentic_user_id = "bef730f4-d6f5-4ffb-b759-26ffa449ed7e"
frm.id = "29:1sH5NArUwkWAX"
userId = "bef730f4-d6f5-4ffb-b759-26ffa449ed7e"
PRでは、GUID形式の agentic_user_id が userId として解決されるテストも追加されています。(GitHub)
A2Aを利用している場合、user.id は必ずしも人間のユーザーを指すとは限りません。エージェントが呼び出し元になる場面では、user.id が「エージェント側の呼び出し元識別子」として記録される可能性があります。ログ分析やアラート通知文で「ユーザー」と表示している場合は、表現を「呼び出し元」や「caller」に寄せると誤解を減らせます。
移行前に確認すべきチェックリスト
今回の変更は、設定ファイルを大きく書き換えるタイプの移行ではありません。ただし、監視・分析・データ連携の前提が変わる可能性があるため、次の順で確認するのがおすすめです。
| 確認項目 | 見るべきポイント | 問題がある場合の対応 |
|---|---|---|
| 利用中のパッケージ・コミット | PR #118の変更が利用中のバージョンに含まれているか | requirements.txt、pyproject.toml、lockファイル、リリースノートを確認する |
user.id の欠損率 | 非Teams/A2Aで user.id が空だった割合が変わるか | 更新前後で同じ期間・同じ条件のクエリを比較する |
| ダッシュボード | user.id をグルーピング、フィルター、凡例に使っているか | 値の種類が混在しても読める表示名にする |
| アラート | user.id IS NULL や欠損率を条件にしていないか | 閾値を見直し、更新後の正常値を再定義する |
| データ連携 | SIEM、DWH、監査ログに user.id を流しているか | ID種別のメタ情報やチャネル情報も一緒に保存する |
| 個人情報・セキュリティ | frm.id や agentic_user_id の取り扱い方針が決まっているか | ログ保持期間、マスキング、外部送信範囲を確認する |
特に、PRがマージされたことと、利用中の配布パッケージに反映済みであることは別です。PR #118は2026年5月5日に main へマージされていますが、実際に本番環境へ反映する前に、利用しているパッケージバージョンやリリース状況を確認してください。(GitHub)
設定・実装確認の進め方
現在の依存関係を確認する
まず、対象プロジェクトが microsoft/opentelemetry-distro-python の該当実装を利用しているか確認します。Pythonプロジェクトであれば、次のようなファイルを確認します。
requirements.txt
pyproject.toml
poetry.lock
uv.lock
requirements.lock
確認すべきなのは、単にOpenTelemetryを使っているかではなく、A365/Agent365関連のホスティングスコープヘルパーを通じて get_caller_pairs() の結果を利用しているかです。PRの差分では、対象ファイルとして src/microsoft/opentelemetry/a365/hosting/scope_helpers/utils.py が変更されています。(GitHub)
ステージング環境で3パターンをテストする
本番投入前に、最低限次の3パターンを確認します。
| テストケース | 入力の例 | 期待する userId |
|---|---|---|
| Teams相当 | aad_object_id あり | aad_object_id |
| 非Teams相当 | aad_object_id なし、agentic_user_id なし、frm.id あり | frm.id |
| A2Aエージェント相当 | aad_object_id なし、agentic_user_id あり | agentic_user_id |
実装の期待値は、PRで追加されたテストと同じ考え方です。非Teamsチャネルでは frm.id、A2Aでは agentic_user_id、複数の識別子がある場合は aad_object_id が優先されます。(GitHub)
更新前後のクエリ結果を比較する
OpenTelemetryのバックエンドやログ基盤で、次のような観点を比較します。
更新前後で user.id が NULL / None / 空の件数
user.id ごとのエラー件数
チャネル別の user.id 件数
A2A呼び出しにおける user.id の分布
ここで見るべきなのは、「値が増えたか」だけではありません。aad_object_id、agentic_user_id、frm.id が同じ列に入るため、ID形式の種類が増える可能性があります。
たとえば、あるダッシュボードで user.id ごとの上位エラーを表示している場合、更新後はTeamsユーザーだけでなく、非TeamsチャネルのIDやエージェントIDも同じランキングに出るかもしれません。これは悪いことではありませんが、読み手が「これは人間のユーザーIDなのか、エージェントIDなのか」を判断できるように、チャネル名や呼び出し種別も一緒に表示した方が安全です。
監視ダッシュボードで見直すべきポイント
今回の変更後は、user.id の欠損が減る一方で、ダッシュボードの解釈が変わる可能性があります。
user.id の空欄を異常として扱っている場合
これまで非TeamsチャネルやA2A呼び出しで user.id が空になることを前提にしていた場合、更新後に空欄件数が減ります。
たとえば、次のようなアラートは見直しが必要です。
user.id が空のリクエストが一定数を超えたら通知
更新後は、同じ条件では通知されにくくなる可能性があります。欠損自体を監視したい場合は、チャネル別に条件を分けると判断しやすくなります。
Teams: aad_object_id の欠損を見る
非Teams: frm.id の欠損を見る
A2A: agentic_user_id の欠損を見る
user.id をユーザー数の集計に使っている場合
user.id の種類が増えることで、ユニークユーザー数の見え方が変わる場合があります。
たとえば、同じ人物がTeamsと別チャネルの両方からアクセスしている場合、Teamsでは aad_object_id、別チャネルでは frm.id として記録される可能性があります。この場合、単純な count distinct user.id は「実人数」ではなく「チャネル別識別子の数」に近くなります。
ユーザー数を正確に見たい場合は、user.id だけに頼らず、次のような補助情報を組み合わせます。
- チャネル名
- テナントID
- 会話ID
- エージェントID
- 自社側で正規化したユーザーキー
user.id を権限や課金の判断に使っている場合
テレメトリの user.id は、監視や相関分析に役立つ情報です。ただし、今回の変更で frm.id や agentic_user_id が入る可能性があるため、権限判定や課金対象の確定にそのまま使うのは避けた方が安全です。
権限や課金に使うIDは、認証・認可の正式なコンテキストから取得し、テレメトリ上の user.id は補助的な調査情報として扱うのが実務上の失敗を防ぎます。
セキュリティとプライバシーの注意点
OpenTelemetryのBaggageは、コンテキストとともにサービス間で伝播されます。公式ドキュメントでも、BaggageはHTTPヘッダーに含まれることがあり、ネットワーク上で見える可能性や、意図しない下流サービスへ伝播される可能性に注意が必要だと説明されています。(OpenTelemetry)
今回の変更で user.id がより多くのケースで設定されるようになるなら、次の点を確認してください。
| 注意点 | 確認内容 |
|---|---|
| 外部APIへの伝播 | Baggageが外部サービスへのHTTPリクエストに含まれないか |
| ログ保存期間 | user.id を含むログの保持期間が社内規程に合っているか |
| マスキング | 個人やエージェントを特定し得るIDをそのまま表示してよいか |
| 監査対応 | IDの種類が変わったことを監査ログの説明に反映しているか |
| 誤用防止 | user.id を認可判断の主キーとして使っていないか |
また、今回の最終的なPython PRは userId のフォールバック修正が中心です。.NET側の関連PRでは一時的に userEmail への言及がありましたが、その後の対応でemail関連ロジックは削除され、userId のフォールバックチェーンに絞られています。(GitHub)
そのため、「今回の更新でメールアドレスも自動的に取得できる」と解釈しないようにしてください。少なくとも確認できるPR上の最終的な焦点は、userId の解決順序です。
複数言語実装を使っている場合の見方
今回のPython PR #118は、.NET側の microsoft/Agent365-dotnet PR #246 の移植として説明されています。関連PRとして、Python、Node.js、JavaScript、.NET系リポジトリにも同趣旨の変更が参照されています。(GitHub)
複数言語でエージェントや周辺サービスを構成している場合は、言語ごとのフィールド名の違いに注意してください。
| 実装・表記 | 例 |
|---|---|
| Python | aad_object_id, agentic_user_id, frm.id |
| .NET | AadObjectId, AgenticUserId, From.Id |
| JavaScript/Node.js | aadObjectId, agenticUserId, from.id |
ロジックの意図は近くても、データの出力名や実装タイミング、リリースへの反映時期は言語ごとに異なる可能性があります。Pythonだけ更新し、Node.jsや.NET側が古いままだと、同じA2Aフローでもサービスによって user.id の入り方が異なることがあります。
複数言語構成では、次のように確認すると安全です。
1. 各サービスの利用言語とパッケージバージョンを一覧化する
2. user.id の解決順序が同じか確認する
3. ステージングで同じA2Aシナリオを流す
4. バックエンド上の user.id の値をサービス別に比較する
5. 差がある場合は、リリース反映状況または独自実装の有無を確認する
よくある疑問
Teamsだけを使っている場合も対応は必要?
Teamsだけを使っていて、aad_object_id が常に入っている前提の環境では、影響は比較的小さいと考えられます。ただし、将来的にA2Aや非Teamsチャネルを追加する予定がある場合は、今回の解決順序を前提に監視設計を見直しておくと後で楽になります。
userId は必ず入るようになる?
必ずではありません。Pythonの差分では、activity.from_property がない場合は処理を戻す流れが残っています。そのため、呼び出し元情報自体がないアクティビティでは、今回のフォールバックでも userId を解決できない可能性があります。(GitHub)
frm.id をユーザーの一意IDとして使ってよい?
監視やトラブルシュートの相関IDとしては有用ですが、全チャネル共通のユーザー主キーとして使うのは慎重に判断すべきです。frm.id はチャネル固有の値である可能性があり、Microsoft Entra IDのオブジェクトIDと同じ意味を持つとは限りません。
既存のログや過去データは変わる?
通常、この種の実装修正は今後生成されるテレメトリに影響します。過去に保存済みのログやトレースが自動的に再計算されるとは限りません。更新前後でデータを比較する場合は、期間を明確に分けて見る必要があります。
何から着手すればよい?
最初にやるべきことは、利用中のパッケージまたはコミットにPR #118相当の変更が含まれているかを確認することです。次に、ステージングでTeams、非Teams、A2Aの3パターンを流し、user.id の値が期待どおりに入るかを確認します。
まとめ:次に取るべき対応
今回の Microsoft developer platform documentation update「Fix get_caller_pairs: resolve userId across all channels」は、userId の欠損を減らし、非TeamsチャネルやA2A呼び出しの観測性を高めるための重要な修正です。
押さえるべきポイントは次の3つです。
userIdの解決順序はaad_object_id → agentic_user_id → frm.id- 非TeamsチャネルやA2A呼び出しで、これまで空だった
user.idが入る可能性がある - ダッシュボード、アラート、ログ連携、ID正規化の前提を更新前後で確認する
本番環境での対応は、まず依存関係の確認から始めます。そのうえで、ステージング環境で user.id の出力を比較し、監視クエリやアラート条件を調整してください。特にA2Aや複数チャネル対応のエージェントを運用している場合は、user.id を「人間のユーザーID」と固定的に扱わず、「呼び出し元を識別するためのテレメトリ上のID」として設計し直すことが、後の分析ミスを防ぐ近道です。

コメント