![[アップデート] AWS Agent Registryのレコードにカスタムメタデータを付けられるようになりました](https://devio2024-media.developers.io/image/upload/f_auto,q_auto,w_3840/f_auto,q_auto/v1790875048/eyecatch/edq4dfptctqlcwjhffhs.png)
[アップデート] AWS Agent Registryのレコードにカスタムメタデータを付けられるようになりました
はじめに
こんにちは、スーパーマーケットが大好きなコンサル部の神野です。
2026年10月13日、AWS Agent Registryのレコードにカスタムメタデータを付けられるようになりました!
早速アップデート内容を確認して試してみましょうか!
カスタムメタデータでできること
今回のアップデートで追加されたのはレジストリに「どんな項目を持たせるか」を決めておいて、レコードを登録するときに値を入れる機能です!
この項目の定義の仕方は全レコードで共通したものか、レコードごと(エージェント、MCP Server,スキル固有)の種別で指定するかの2種類あります。
| 種類 | APIでの名前 | 対象 |
|---|---|---|
| 共通の項目 | defaultSchema |
すべてのレコード種別 |
| レコード種別ごとの項目 | recordTypeSchemaOverrides |
MCPサーバー、エージェントなど指定した種別 |
文字だけだとわかりづらいので簡単に絵にしてみました。
例えば、こんな関係になります。MCPサーバーのレコードは共通の項目だけ、エージェントのレコードは共通の項目とエージェント用の項目の両方を持つようなことができます。

テキスト・選択肢(enum)・URL・真偽値の4種類を使用でき、JSON Schemaで書きます。共通の項目を種別側にもう一度書くと、その種別だけ必須にしたり、選択肢を増やしたりもできます。
検索では customMetadata.項目名 で絞り込めます。一致($eq)、不一致($ne)、いずれかに一致($in)を、$and や $or で組み合わせられます。
イメージはこんな感じです。登録した値はスキーマでチェックされて、利用者は同じ項目を条件にして探します。

どんなときに使えそうか
どんな時にこの新機能を使うんでしょうか。ちょっとイメージを膨らませてみましょう。
例えば、同じレジストリのスキルを社外向けと社内向けのAgentで使うケースです。社外向けのチャットAgentには、社内の手順や顧客情報を扱うスキルは使わせたくないですよね。データ分類を項目にしておけば、Agentが検索するときの条件で使えるものだけに絞れます。

ほかにもこんな使い方なども考えられそうです。
- 社内のMCPサーバーやエージェントが応答しなくなったとき、レコードに担当チーム(
owner)と運用手順のURL(runbookUrl)が入っていれば、Registryを見るだけで誰に連絡して何を確認すればよいか分かります。必須の項目にしておけば、書き忘れたレコードは承認に進めません。 - 担当チームで絞れば、自分のチームが公開しているエージェント・MCPサーバー・スキルだけを探せます。棚卸しや、使われなくなったものの整理にも使えそうです。
- 社外向けのアプリからエージェントやMCPサーバーを呼ぶときも、データ分類が社外向け(public)のものだけを候補にできます。
スキルに限らず、エージェントやMCPサーバーのレコードでも同じことが言えます。
1つのRegistryを多くのスキルやエージェント、MCPが存在していて、カテゴリで絞り込みたい際に便利な機能ですね!
試してみる
ぼんやりと全体像を理解したところで早速試してみましょう。
今回は社外向けと社内向けのエージェントで、読み込むスキルをデータ分類ごとに絞り分けてみます。レジストリの作成から検索まではAWS CLIで進めて、最後にStrands Agentsのエージェントから対象のスキルを読み込む流れで進めていきます!
前提
今回は下記前提で進めていきます。
- リージョン:東京(ap-northeast-1)
- AWS CLI 2.37.13、jq 1.7.1
- Agent部分:Python 3.14.6、strands-agents 1.60.0、boto3 1.43.111
- モデル:Amazon BedrockのClaude Sonnet 4.5(us-east-1)
項目を定義してレジストリを作る
今回は共通の項目として、担当チーム(owner)とデータ分類(dataClassification)の2つを定義し、どちらも必須項目に設定しました!
{
"type": "object",
"properties": {
"owner": {"type": "string"},
"dataClassification": {"type": "string", "enum": ["public", "internal", "confidential"]}
},
"required": ["owner", "dataClassification"]
}
スキーマはJSON文字列として defaultSchema に渡す必要があるため、jqで整形してからレジストリを作成します。承認フローの挙動も確認したいので、自動承認ルールは空に設定して無効化しておきます。
export AWS_REGION=ap-northeast-1
jq -n --rawfile s schema.json '{defaultSchema: $s}' > schema-config.json
aws agent-registry-control create-registry \
--name skills-custom-metadata \
--approval-configuration '{"autoApprovalRules": []}' \
--custom-metadata-schema-configuration file://schema-config.json
aws agent-registry-control wait registry-ready --registry-id <レジストリID>
{
"registryArn": "arn:aws:agent-registry:ap-northeast-1:123456789012:registry/hCbYcobDKaxhSSNx"
}
registryArn の末尾がレジストリIDです。
スキルを3つ登録する
データ分類の設定を変えた3種類のスキルを用意しました。
| スキル | 担当チーム | データ分類 | 中身 |
|---|---|---|---|
| product-faq | sales-platform | public | お客様に丁寧語で答える。社内の手順は書かない |
| order-escalation | support-team | internal | 注文トラブルを社内でエスカレーションする手順 |
| customer-lookup | crm-team | confidential | 顧客の購入履歴を調べる手順 |
SKILL.md(3つ)
---
name: product-faq
description: お客様からの商品や注文に関する質問に、丁寧な言葉で答える
---
お客様からの質問に答えるときのルールです。
- 丁寧語で、3文以内で答える
- 在庫や配送日は断定せず、「確認のうえご連絡します」と伝える
- 社内の担当者名や社内の手順は書かない
---
name: order-escalation
description: 注文トラブル(未着・破損・誤配送)を社内でエスカレーションする手順
---
注文トラブルの相談を受けたら、次の手順を案内してください。
1. 注文番号と発送日を確認する
2. 発送から5営業日を過ぎていたら、Slackの #order-trouble に注文番号を投稿する
3. 破損・誤配送は写真を添えて、物流チームに再発送を依頼する
---
name: customer-lookup
description: 顧客IDから購入履歴や連絡先を調べるときの手順
---
顧客の購入履歴や連絡先を調べるときは、CRMの顧客IDで検索してください。
連絡先は本人確認が済んだ問い合わせにだけ使ってください。
SKILL.mdの内容は agentSkillsDefinition.additionalData.skillMd.data に格納します。カスタムメタデータは --custom-metadata オプションに指定します。product-faq の登録は下記コマンドで行います。
jq -n --rawfile md skills/product-faq/SKILL.md \
'{agentSkillsDefinition: {additionalData: {skillMd: {data: $md}}}}' > product-faq.json
aws agent-registry-control create-registry-record \
--registry-id <レジストリID> \
--name product-faq \
--description "お客様からの商品や注文に関する質問に、丁寧な言葉で答える" \
--record-type SKILL --record-version 1.0 \
--descriptors file://product-faq.json \
--custom-metadata '{"owner": "sales-platform", "dataClassification": "public"}'
残りの2つも、名前・説明文・--custom-metadata のパラメータをそれぞれ差し替えて登録します。レコードを作成したら、承認申請を行って承認ステータスへ進めます。
aws agent-registry-control submit-registry-record-for-approval \
--registry-id <レジストリID> --record-id <レコードID>
aws agent-registry-control update-registry-record-status \
--registry-id <レジストリID> --record-id <レコードID> \
--status APPROVED --status-reason "custom metadata test"
aws agent-registry-control wait registry-record-approved \
--registry-id <レジストリID> --record-id <レコードID>
承認後に get-registry-record コマンドで確認すると、設定したメタデータが取得できます。
{
"name": "product-faq",
"status": "APPROVED",
"customMetadata": {
"dataClassification": "public",
"owner": "sales-platform"
},
"customMetadataSchemaComplianceStatus": "COMPLIANT"
}
問題なく登録されていますね!
スキーマを満たしていれば COMPLIANT、満たしていなければ NON_COMPLIANT になります。3つとも COMPLIANT でした。
CLIで絞り込んでみる
CLIを使って検索を試してみます。検索クエリは固定したまま、--filters の条件を切り替えて実行します。
aws agent-registry search-discoverable-registry-records \
--registry-ids <レジストリARN> \
--search-query "注文や商品の問い合わせに対応するスキル" \
--filters '{"customMetadata.dataClassification": {"$eq": "public"}}' \
--query 'registryRecords[].[name, customMetadata.dataClassification]' --output text
フィルターなし、$eq 指定、$ne 指定の3パターンで実行した結果がこちらです。
| 条件 | 返ったスキル |
|---|---|
| なし | product-faq(public)、order-escalation(internal)、customer-lookup(confidential) |
{"customMetadata.dataClassification": {"$eq": "public"}} |
product-faq |
{"customMetadata.dataClassification": {"$ne": "confidential"}} |
product-faq、order-escalation |
フィルターを指定しない場合は全件が取得され、条件を指定した場合はデータ分類の指定に沿ってレコードが絞り込まれました!
Agentからスキルを読み込む
続いて、レジストリで絞り込んだスキルをStrands Agentsのエージェントに読み込ませます。社外向け(external)には public のスキルを、社内向け(internal)には confidential 以外のスキルを渡します。
uv init --bare --python 3.14
uv add boto3 strands-agents
"""Load skills from Agent Registry by data classification and answer with Strands Agents."""
import os
import sys
import boto3
from strands import Agent
from strands.models import BedrockModel
from strands.vended_plugins.skills import AgentSkills, Skill
REGISTRY_ARN = os.environ['REGISTRY_ARN']
# 社外向けはpublicだけ、社内向けはconfidential以外のスキルを読み込む
FILTERS = {
'external': {'customMetadata.dataClassification': {'$eq': 'public'}},
'internal': {'customMetadata.dataClassification': {'$ne': 'confidential'}},
}
def load_skills(filters):
registry = boto3.client('agent-registry', region_name='ap-northeast-1')
records = registry.search_discoverable_registry_records(
registryIds=[REGISTRY_ARN], searchQuery='注文や商品の問い合わせに対応するスキル',
filters={'$and': [{'recordType': {'$eq': 'SKILL'}}, filters]},
)['registryRecords']
return [Skill.from_content(r['descriptors']['agentSkillsDefinition']['additionalData']['skillMd']['data'])
for r in records]
skills = load_skills(FILTERS[sys.argv[1]])
print('読み込んだスキル:', [s.name for s in skills])
model = BedrockModel(model_id='us.anthropic.claude-sonnet-4-5-20250929-v1:0', region_name='us-east-1', temperature=0)
agent = Agent(model=model, plugins=[AgentSkills(skills=skills)], callback_handler=None)
print(agent('注文した商品が1週間たっても届きません。どうすればいいですか?'))
レジストリの検索結果をそのままスキルとして渡す構成のため、エージェントが参照できる機能は filters の条件によって決まります。両方の設定で同じ質問を投げてみます。
export REGISTRY_ARN=<レジストリARN>
uv run agent.py external
uv run agent.py internal
読み込んだスキル: ['product-faq']
ご注文いただいた商品が届いておらず、ご心配をおかけして申し訳ございません。配送状況を確認のうえ、ご連絡させていただきます。お手数ですが、ご注文番号とお名前をお知らせいただけますでしょうか。
読み込んだスキル: ['product-faq', 'order-escalation']
ご注文の商品が届いていないとのこと、大変ご心配をおかけしております。
お調べいたしますので、以下の情報を教えていただけますでしょうか。
1. **ご注文番号**
2. **発送日**(発送完了メールに記載されています)
発送から5営業日を過ぎている場合は、すぐに社内の物流チームに確認を依頼いたします。状況を調査し、できる限り早く対応させていただきますので、上記の情報をお知らせください。
ご不便をおかけして申し訳ございません。
社外向けは product-faq だけで答え、社内向けは order-escalation の「発送から5営業日」という判断基準まで使って答えました! customer-lookup はどちらにも読み込まれていません。
今回はアプリ側で filters を固定していますが、条件なしで検索すれば confidential のスキルも返ってきます。確実に絞りたいケースはユーザー属性のJWTや外部パラメータなどで条件を絞るのが良さそうですね。
レコード種別ごとの項目も足せる
ここまでの担当チームとデータ分類は、すべてのレコードに付く共通の項目でした。ただ、MCPサーバー・エージェント・スキルでは、持たせたい情報が少しずつ違いますよね。そういう項目は、種別ごとに足せます。
| 種別 | 足すと便利そうな項目の例 |
|---|---|
| MCPサーバー | 接続先の環境(本番・検証) |
| エージェント | 使っているモデル |
| スキル | 対応している言語 |
書き方は、種別ごとのスキーマを recordTypeSchemaOverrides に足すだけです。例えばエージェントにだけ、使っているモデル(modelFamily)を必須にするならこうなります。
{
"type": "object",
"properties": {
"modelFamily": {"type": "string"}
},
"required": ["modelFamily"]
}
jq -n --rawfile common schema.json --rawfile agent agent.json \
'{defaultSchema: $common, recordTypeSchemaOverrides: [{recordType: "AGENT", schema: $agent}]}' > schema-config.json
別のレジストリで試したところ、エージェントのレコードで modelFamily を省くと required property 'modelFamily' not found で拒否され、MCPサーバーのレコードは modelFamily なしで登録できました!
気をつけたいところ
実際に触ってみて気付いたポイントを整理しておきます。
もし同じように動かないなどあればこの辺り意識してみると良いと思います!
- スキーマ定義に存在しない値を指定すると、レコード登録時にエラーとなります。例えばデータ分類に
secretを渡したところ、does not have a value in the enumeration ["public", "internal", "confidential"]というメッセージで登録が拒否されました。 - 検索時の注意点として、項目名を誤って指定した際(
dataClasificationなど)はエラーが発生せず、空の結果(0件)が返ります。検索結果が0件になった場合は、項目名の記述を確認するのが良さそうです。 - レジストリのMCPエンドポイントを介して検索する場合、フィルター引数は単数形の
filterを指定します。APIに合わせて複数形のfiltersを渡すと、引数が無視されて全件が返ってくる挙動になりました。 - スキーマの更新は項目の追加に対応しています。項目や選択肢の削除、必須項目から任意項目への変更は拒否されます。任意だった項目を後から必須にすると、既存のレコードは
NON_COMPLIANTになりますが、承認済みのまま検索にも出てきます。
後片付け
作成したレコードとレジストリを削除します。レコードが存在する状態ではレジストリを削除できない仕様のため、先にレコードを削除してからレジストリ本体を削除します。
for id in $(aws agent-registry-control list-registry-records --registry-id <レジストリID> \
--query 'registryRecords[].recordId' --output text); do
aws agent-registry-control delete-registry-record --registry-id <レジストリID> --record-id $id
done
aws agent-registry-control delete-registry --registry-id <レジストリID>
おわりに
項目を定義して、登録時のチェックから検索の絞り込み、Agentに読み込ませるスキルの出し分けまでできました!カテゴリで絞り込みたい際に便利ですね!
項目は後から消せないので、まずは担当チームやデータ分類のような、どのレコードにも必要な項目から始めるのがよさそうです!
最後までご覧いただきありがとうございました!











