Azure Machine Learning(Azure ML)のデータアセットにYAMLでproperties:を書いたのに登録後は空になる――この「なぜ?」に明確な答えと、今日から現場で実践できる回避策・設計指針・運用パターンをまとめて解説します。CLIやYAMLのサンプル、検索クエリ、CI/CDへの組み込み例まで網羅し、メタデータを“失わない”ための実践ガイドとしてご活用ください。
事象の要約
YAMLファイルに任意のメタデータをproperties:として記述し、az ml data create -f <file>.ymlでデータアセットを登録しても、az ml data showで確認するとpropertiesは空のままです。これは書式ミスやシステム予約キーの衝突ではなく、サービス仕様によってデータアセットのカスタムpropertiesが保存対象外になっているために発生します(2025年11月時点)。
症状
dataアセットのYAMLにproperties:を記述しても、登録後のaz ml data show出力では空。- 同じキーを
tagsとpropertiesに二重に書いてもエラーにはならないが、返却値のpropertiesは空。 - CLIバージョンやフォーマット、予約語の問題ではない。
再現手順(最小例)
name: demo_hr_dataset
version: 1
type: uri_file
description: "社員データ(学習用)"
path: azureml://datastores/wsdstore/paths/hr/hr-data.csv
# 保存されない(data assetでは無視される)
properties:
source_system: HR
pii_scan: passed
# 保存される
tags:
meta.source_system: HR
meta.pii_scan: passed
登録と確認:
# 登録
az ml data create -f data_asset.yml
# 確認(tagsだけが保持されていることを確認)
az ml data show -n demo_hr_dataset --version 1 --output yaml
結論(仕様と設計方針)
データアセット(data asset)では、カスタムpropertiesは現在保存されません。そのため、任意メタデータを維持・検索・自動化に活用したい場合は、以下のいずれか(または併用)で設計します。
tagsに格納する(推奨・第一候補)descriptionにJSONなどで埋め込む(軽量・補助)- 別資産やサイドカー(補助)ファイルで管理する(構造化や大型メタデータ)
実務で使える回避策
1. tagsに格納する(最有力)
もっとも扱いやすく、CLI/SDK/ポータルのいずれでも閲覧・検索・フィルタが容易です。キーにmeta.などのプレフィックスを付け、命名規約と用途を明確にします。
name: hr_train_dataset
version: 2
type: uri_file
description: "人事データのトレーニング用抽出(2025-Q3)"
path: azureml://datastores/prod/paths/hr/train/hr-data.csv
tags:
meta.resolvedDataPath: azureml://datastores/prod/paths/hr/train/hr-data.csv
meta.source_system: HR
meta.owner: [email protected]
meta.pii_scan: passed
meta.schema_version: "1.2.0"
登録・更新・閲覧の基本コマンド:
# 新規登録
az ml data create -f hr_train_dataset.yml
# 一覧(主要フィールドのみ表示)
az ml data list --query "[].{name:name,ver:version,type:type,tags:tags}" -o table
# 詳細(YAML)
az ml data show -n hr_train_dataset --version 2 -o yaml
# タグの追加・上書き(その場で)
az ml data update -n hr_train_dataset --version 2 --set tags.meta.reviewed_by=mlops@example
よく使う検索クエリ例(JMESPath):
# HRシステム由来のデータアセットだけ抽出
az ml data list --query "items[?tags.'meta.source_system'=='HR'].[name,version,tags]" -o tsv
# PIIスキャン合格の最新版だけ
az ml data list --query "items[?tags.'meta.pii_scan'=='passed'] | reverse(sort_by(@,&version)) | [].{name:name,version:version}" -o table
# オーナー単位で棚卸し
az ml data list --query "items[?contains(tags.'meta.owner','data-platform')].[name,version]" -o table
メリット
- 登録後も確実に保持・表示される。
- フィルタ・集計・自動化(スクリプト)との相性がよい。
- 小さく始めて拡張しやすい。
留意点
- キー/値はシンプルな文字列で設計する(巨大な構造体は避ける)。
- 命名規約(
meta.<領域>.<項目>など)をチームで統一する。
2. descriptionにJSON等を埋め込む(補助策)
タグでは表現しづらい階層や配列を、軽量に持たせたい場合に有効です。検索性はタグに劣るため、タグ+説明JSONの併用を推奨します。
description: |
HRデータ(トレーニング用)。抽出ルールは sidecar JSON を参照。
{
"owner": "[email protected]",
"lineage": {
"src_datastore": "prod",
"src_path": "hr/train/hr-data.csv",
"transforms": ["drop_na", "encode_job_level"]
},
"quality": {
"pii_scan": "passed",
"null_ratio": 0.3
}
}
スクリプト側でdescriptionを取得し、JSON部分を抽出して利用できます。
3. 別資産やサイドカー(補助ファイル)を使う
より厳密なスキーマや大型のメタデータ、監査証跡を扱う場合は、データストアにサイドカーJSONを置き、データアセットからタグでひも付けるのが堅実です。あるいはpropertiesをサポートする別種アセット(例: model / environment)でメタ情報を管理し、データアセットとは相互参照する設計も選択肢になります。
# サイドカー例(/paths/hr/train/hr-data.meta.json)
{
"schema_version": "1.2.0",
"dq_report_uri": "azureml://datastores/prod/paths/hr/train/reports/dq_2025Q3.html",
"pii_scan_artifact": "azureml://datastores/prod/paths/hr/train/reports/pii_scan_2025Q3.json",
"slack_channel": "#ml-data-hr",
"approvers": ["alice", "bob"]
}
データアセットのタグ:
tags:
meta.sidecar_uri: azureml://datastores/prod/paths/hr/train/hr-data.meta.json
meta.dq_report_uri: azureml://datastores/prod/paths/hr/train/reports/dq_2025Q3.html
比較表:どこに何を入れるべき?
| 保管場所 | 向いている情報 | 検索性 | 構造表現 | 規模 | 想定用途 |
|---|---|---|---|---|---|
tags | キー=値の属性(例:owner、system、schema_version、pii_scan) | ◎(CLI/ポータルで容易) | △(平坦。配列/階層は非推奨) | 小〜中 | 検索・フィルタ・自動化の主軸 |
description | 補助的な詳細、JSONスニペット、注意事項 | △(全文検索は困難) | ◯(自由記述で表現可能) | 小〜中 | 人間向けの文脈+軽量な構造の併記 |
| サイドカーJSON | 大きいメタデータ、レポートURI、配列・階層・監査証跡 | ◯(タグでURIを索引化) | ◎(完全自由) | 中〜大 | 厳密なスキーマ、監査、外部連携 |
| 別アセット(model/env) | アーティファクト単位の厳密メタ(properties活用) | ◯ | ◎ | 中 | アセスメントや承認ワークフローと連動 |
運用パターン別・設計ガイド
- クイック検索が最優先:
tags中心。meta.<領域>.<項目>で命名を統一。 - 人が読む説明も必要:タグで索引、
descriptionにJSON+説明文を併記。 - 監査・長期保存・外部連携:タグは索引に専念、本文はサイドカーJSONへ。
- 厳密なスキーマが必須:別アセットの
propertiesも活用し、データアセットから参照。
YAML/CLI 実例(そのまま使えるテンプレート)
テンプレート:データアセット定義
name: {{project}}_{{domain}}_dataset
version: {{semver}}
type: uri_folder # or uri_file / mltable
description: |
{{domain}}ドメインの学習用データセット。
{
"owner": "{{team_mail}}",
"schema_version": "{{schema_ver}}",
"lineage": {
"src_datastore": "{{datastore}}",
"src_path": "{{path}}"
}
}
path: azureml://datastores/{{datastore}}/paths/{{path}}
tags:
meta.domain: "{{domain}}"
meta.owner: "{{team_mail}}"
meta.schema_version: "{{schema_ver}}"
meta.sidecar_uri: "azureml://datastores/{{datastore}}/paths/{{path}}.meta.json"
登録・更新・検索
# 登録
az ml data create -f dataset.yml
# タグの一括付与(パッチ的に)
az ml data update -n {{project}}_{{domain}}_dataset --version {{semver}}
--set tags.meta.lifecycle=prod tags.meta.pii_scan=passed
# 最新版のみ一覧
az ml data list --name {{project}}_{{domain}}_dataset --query "max_by(items,&version)"
CI/CDへの組み込み(GitHub Actions例)
name: register-data-asset
on:
push:
paths:
- "assets/data/**.yml"
jobs:
register:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Azure ML CLI install
run: pip install azure-ai-ml azure-identity
- name: Validate YAML (naming & required tags)
run: |
python scripts/validate_tags.py assets/data
- name: Register
run: |
for f in assets/data/*.yml; do
az ml data create -f "$f"
done
ベストプラクティス
- 必須タグ(
meta.owner、meta.schema_version、meta.source_systemなど)を静的解析で検査。 - スキーマ(JSON Schema)でサイドカーJSONを検証し、PR時に失敗させる。
- 命名規約(プロジェクト・ドメイン・用途・semver)をREADMEに明文化。
トラブルシューティング
propertiesが空のまま:仕様です。tags等の代替策へ設計変更。- タグが反映されない:YAMLのインデント/引用符/エンコードを再確認。数値は文字列化(例:
"1.2.0")。 - 検索でヒットしない:JMESPathのキー名にドットがある場合、
tags.'meta.schema_version'のように引用。 - 巨大なJSONを入れたい:タグではなくサイドカーJSONに退避し、URIだけタグに保持。
監査と可観測性:クエリ集
# 直近30日で作成/更新のデータアセット
az ml data list --query "items[?to_number(substring(updatedOn,0,10)) >=`date +%s`-30*24*3600]"
# ドメイン別の最新バージョン一覧
az ml data list --query "items | sort_by(@,&[name,version]) | reverse(@) |
[].{name:name,version:version,domain:tags.'meta.domain'}" -o table
# サイドカーレポートURIが欠落している資産
az ml data list --query "items[?!tags.'meta.sidecar_uri'].[name,version]" -o table
よくある質問(FAQ)
Q. propertiesは今後サポートされますか? A. 仕様は将来変わる可能性があります。設計はタグ中心にしつつ、将来propertiesが使えるようになった場合の移行手順(タグ→プロパティの同期スクリプト)を用意しておくと安心です。
<dt>Q. タグキーの命名はどう決めればよいですか?</dt>
<dd>A. <code>meta.<領域>.<項目></code>の3階層(例:<code>meta.quality.pii_scan</code>)を推奨。英小文字・数字・アンダースコア・ハイフン・ドットに限定すると運用が安定します。</dd>
<dt>Q. 同じ情報をタグと説明の両方に書いても良い?</dt>
<dd>A. 問題ありません。検索性の高いタグを“正”とし、説明には読み物や補足JSONを載せる方針が実務上扱いやすいです。</dd>
<dt>Q. データ品質レポートなど成果物のURIはどこに?</dt>
<dd>A. タグに<code>meta.dq_report_uri</code>などのキーで保持し、実体はデータストアのHTML/JSONに置くのが管理しやすいです。</dd>
<dt>Q. 既存資産を新方針へ揃えるには?</dt>
<dd>A. 一括移行スクリプトで<code>az ml data list</code>→タグ欠落検出→<code>az ml data update</code>の反復を自動化します。移行前後で一覧を差分比較し、監査ログを保存しましょう。</dd>
チェックリスト(貼って使える)
- [必須]
meta.owner/meta.source_system/meta.schema_versionを付与したか。 - [必須]サイドカーURI(必要時)を
meta.sidecar_uriに設定したか。 - [推奨]
descriptionに簡潔な説明+最小限のJSONを併記したか。 - [推奨]CIでタグの必須性・形式・重複を検証しているか。
- [推奨]クエリ(JMESPath)をチーム標準化し、定期棚卸しを自動化しているか。
サンプル:移行・同期スクリプト(概念例)
# 目的:旧来のdescription内JSONの一部をタグに昇格させる
# 方針:descriptionからowner/schema_versionを抽出→tagsへ反映
#!/usr/bin/env python3
import json, subprocess
def list_assets():
out = subprocess.check_output(["az","ml","data","list","-o","json"])
return json.loads(out)
def show_asset(name, version):
out = subprocess.check_output(["az","ml","data","show","-n",name,"--version",str(version),"-o","json"])
return json.loads(out)
def update_tag(name, version, key, value):
subprocess.check_call(["az","ml","data","update","-n",name,"--version",str(version),"--set",f"tags.{key}={value}"])
for it in list_assets().get("items",[]):
name, ver = it["name"], it["version"]
detail = show_asset(name, ver)
desc = detail.get("description","")
try:
payload = json.loads(desc[desc.index("{"):desc.rindex("}")+1])
except Exception:
continue
owner = payload.get("owner")
schema = payload.get("schema_version")
if owner:
update_tag(name, ver, "meta.owner", owner)
if schema:
update_tag(name, ver, "meta.schema_version", schema)
ベストプラクティス(要点)
- タグ主導:検索・自動化に強い。URIや可観測性の要点をタグで索引化。
- 説明は読み物+最小JSON:ヒトが理解しやすい文脈を提供。
- サイドカーで拡張:大きい・複雑なメタは外出しし、規約で結合。
- CIで強制:レビュー任せにしない。必須タグ・スキーマ・命名規約を自動検査。
- 将来変化への余白:将来
propertiesが有効化されても移行可能な同期スクリプトを用意。
まとめ
データアセットの
propertiesは現在保存されません。任意メタデータはtagsで保持し、必要に応じてdescriptionにJSONを併記、またはサイドカーJSONで構造化・拡張しましょう。設計の肝は「索引はタグ、本文はサイドカー」。この分離により、検索・自動化・監査のすべてがシンプルになります。
付録:コピペ用スニペット
最小YAML(タグ中心)
name: gmatheus01rmlwhrmodel_train_dataset
version: 1
type: uri_file
description: "学習用HRデータ"
path: azureml://datastores/wsdstore/paths/hr-data.csv
tags:
meta.resolvedDataPath: azureml://datastores/wsdstore/paths/hr-data.csv
meta.source_system: HR
登録・確認
az ml data create -f data_asset.yml
az ml data show -n gmatheus01rmlwhrmodel_train_dataset --output yaml
棚卸しクエリ(代表例)
az ml data list --query "items[?tags.'meta.source_system']=='HR'].[name,version,tags]" -o table

コメント