- ① CloudFormation でのインデックス設定
- ② Hierarchical Chunking との組み合わせ(「非推奨」の条件を正確に理解する)
- ③ メタデータフィルタリングの実機検証
- まとめ
こんにちは。XI2部の山科です。
Amazon Bedrock Knowledge Base のベクトルストアとして S3 Vectors を使う構成を CloudFormation で構築・検証しました。
S3 Vectors の基本的な仕様については
でも紹介されていますが、本記事では実際に構築する中で気になった以下の3点に絞ってまとめます。
- CloudFormation でのインデックス設定
- Hierarchical Chunking との組み合わせ(「非推奨」の条件を正確に理解する)
- メタデータフィルタリングの実機検証
① CloudFormation でのインデックス設定
コンソールのクイック作成との差分
KB をコンソールのクイック作成で構築すると、S3 Vectors インデックスは以下の設定で自動生成されます。
$ aws s3vectors get-index \
--vector-bucket-name <自動生成バケット名> \
--index-name <自動生成インデックス名> \
--region ap-northeast-1
{ "index": { "dataType": "float32", "dimension": 1024, "distanceMetric": "euclidean", "metadataConfiguration": { "nonFilterableMetadataKeys": [ "AMAZON_BEDROCK_TEXT", "AMAZON_BEDROCK_METADATA" ] } } }
注目点は2つです。
距離メトリクスは euclidean 固定
クイック作成では距離メトリクスを選択する UI がなく、euclidean で作成されます。CFN では明示的に選択できます。
なお Amazon Titan Text Embeddings V2 はデフォルトで正規化済みベクトルを返すため、cosine と euclidean で検索結果の順位は変わりません(数学的に単調変換の関係)。どちらを選んでも実用上の差はありません。
AMAZON_BEDROCK_TEXT / AMAZON_BEDROCK_METADATA は Non-filterable に設定済み
KB がチャンクテキスト本文を保存する AMAZON_BEDROCK_TEXT は数百〜数千文字になるため、Filterable(2KB 上限)に設定するとサイズ超過になります。クイック作成では自動で Non-filterable に設定されています。
CFN での設定例
CFN でインデックスを作成する場合は以下のように明示的に指定します。
VectorsIndex: Type: AWS::S3Vectors::Index Properties: VectorBucketName: !Sub '${SystemName}-${Environment}-s3-vectors' IndexName: !Sub '${SystemName}-${Environment}-kb-index' DataType: float32 Dimension: 1024 DistanceMetric: euclidean MetadataConfiguration: NonFilterableMetadataKeys: - AMAZON_BEDROCK_TEXT - AMAZON_BEDROCK_METADATA
NonFilterableMetadataKeys の指定を忘れると Ingestion 時にエラーになるため注意が必要です。
② Hierarchical Chunking との組み合わせ(「非推奨」の条件を正確に理解する)
AWS ドキュメントの記述
AWS ドキュメントには以下の記述があります。
"Hierarchical chunking is not recommended when using S3 vector bucket as your vector store."
参考: https://docs.aws.amazon.com/bedrock/latest/userguide/kb-chunking.html
この記述だけ見ると「S3 Vectors では Hierarchical Chunking は使えない」と誤解しやすいですが、実際の条件はより限定的です。
非推奨になる条件
同ドキュメントの補足によると、非推奨の条件は Parent チャンクが 8,000 トークン以上 の場合にメタデータサイズ制限に抵触する可能性がある、というものです。
Hierarchical Chunking では Child チャンクでベクトル検索を行い、対応する Parent チャンクのテキストが AMAZON_BEDROCK_TEXT に格納されて返却されます。メタデータのサイズ制限に影響するのは Parent チャンクのサイズです。
通常の設定では問題なし
| 項目 | 値 |
|---|---|
| Parent Chunk | 1,024 トークン |
| Child Chunk | 300 トークン |
| 非推奨となる閾値 | Parent 8,000 トークン以上 |
Parent を 1,024 トークン程度に設定している場合は閾値(8,000 トークン)を大きく下回るため、問題ありません。
むしろ Hierarchical Chunking は以下の点で精度面で有利です。
- Child チャンク(小さい単位)で精度の高いベクトル検索
- Parent チャンク(大きい単位)で文脈を広く返却
「S3 Vectors + Hierarchical Chunking は非推奨」という情報を見て避けている場合は、Parent チャンクのサイズを確認した上で判断することをおすすめします。
③ メタデータフィルタリングの実機検証
ユーザー属性(部署やカテゴリなど)でドキュメントを絞り込みたい場合、S3 データソースに .metadata.json を配置してカスタムフィールドを追加することで実現できます。実際に動作するか検証をしました。
手順
① S3 データソースに .metadata.json を配置
ドキュメントファイルと同じ S3 パスに <ファイル名>.metadata.json を配置します。
// document.txt.metadata.json { "metadataAttributes": { "group": "faq" } }
② KB を再同期
メタデータファイルを配置後、KB のデータ同期を実行します。再同期後にカスタムフィールドが反映されます。
③ Retrieve API でフィルタリング
response = client.retrieve(
knowledgeBaseId='<KB_ID>',
retrievalQuery={'text': '検索クエリ'},
retrievalConfiguration={
'vectorSearchConfiguration': {
'filter': {
'equals': {
'key': 'group',
'value': 'faq'
}
}
}
}
)
検証結果
以下のようにカテゴリ別にドキュメントを分類して検証しました。
| ファイル | group |
|---|---|
| faq 系ドキュメント(複数) | faq |
| 仕様書系ドキュメント(複数) | spec |
| フィルタ条件 | 返ってきたドキュメント |
|---|---|
group = "faq" |
FAQ 系ドキュメントのみ ✅ |
group = "spec" |
仕様書系ドキュメントのみ ✅ |
.metadata.json を配置して KB を再同期するだけで意図通りの絞り込みができることを確認しました。
注意点
カスタムフィールドはデフォルトで Filterable として扱われるため、インデックス側の設定変更は不要です。
一方、AMAZON_BEDROCK_TEXT / AMAZON_BEDROCK_METADATA は Non-filterable のため、これらをフィルタリング条件に使うことはできません(ValidationException: Invalid use of non-filterable metadata in filter が返ります)。フィルタリング用途には必ずカスタムフィールドを追加してください。
まとめ
| ポイント | 内容 |
|---|---|
| CFN でのインデックス設定 | NonFilterableMetadataKeys に AMAZON_BEDROCK_TEXT / AMAZON_BEDROCK_METADATA を明示的に指定する |
| Hierarchical Chunking | 「非推奨」は Parent 8,000 トークン以上の場合。通常の設定(1,024 tokens 程度)では問題なし |
| メタデータフィルタリング | .metadata.json を S3 に配置して KB を再同期するだけで実現可能。カスタムフィールドは自動で Filterable になる |
S3 Vectors を使った Bedrock KB の構築・設計の参考になれば幸いです。