ankuro.dev
← ブログ一覧に戻る
Bedrock Knowledge Base × S3 Vectors——仕様とハマりどころを整理する
2026-04-16#AWS#Bedrock#Knowledge Base#S3 Vectors#RAG

Bedrock Knowledge Base × S3 Vectors——仕様とハマりどころを整理する

Bedrock Knowledge Baseのベクトルストアとして、2025年12月に一般提供された Amazon S3 Vectors が選択できるようになった。

実際に構築・検証する中で、S3 Vectors特有の仕様やハマりどころがいくつかあったので整理する。

この記事でわかること:

  • S3 Vectorsのメタデータ制限(2KB問題)と回避方法
  • CFnで距離メトリクスを選択する方法とコンソール作成時の違い
  • Hierarchical Chunkingとの組み合わせで注意すべき条件
  • メタデータフィルタリングの実装手順と検証結果

S3 Vectorsとは

S3 Vectorsは、ベクトル埋め込みデータの保存・検索に特化したAWSのストレージサービス。

OpenSearch Serverlessと比較してコストが低く、大量のドキュメントを長期保存するユースケースに向いている。Bedrock Knowledge Baseのベクトルストアとして選択でき、ナレッジベース構築のコストを抑えたい場合の選択肢になる。


メタデータの仕様

S3 Vectorsのメタデータには以下の制限がある。

種別 上限
Filterableメタデータ(全フィールド合計) 2 KB
メタデータ全体(Filterable + Non-filterable合計) 40 KB
メタデータキー数(合計) 最大50キー
Non-filterableキー数 最大10キー

参考: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-vectors-limitations.html

FilterableとNon-filterableの違い

Filterable Non-filterable
値の保存・返却
フィルタリング条件に使用 ❌(400エラー)
サイズ上限 2KB(全フィールド合計) 別枠

Non-filterableフィールドをfilter条件に指定すると、以下のエラーが返る。

ValidationException: Invalid use of non-filterable metadata in filter (Status Code: 400)

参考: https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-vectors-query.html


Bedrock KBとの組み合わせで押さえるべき設計ポイント

ポイント① AMAZON_BEDROCK_TEXT / AMAZON_BEDROCK_METADATAはNon-filterableに設定する

Bedrock KBは、チャンクテキスト本文を AMAZON_BEDROCK_TEXT というメタデータフィールドに保存する。

このフィールドは数百〜数千文字になるため、Filterableに設定すると2KB上限を超える可能性がある。Non-filterable に設定する必要がある。

KBのコンソールからクイック作成した場合、自動でこれらがNon-filterableに設定されていることをCLIで確認した。

$ aws s3vectors get-index \
    --vector-bucket-name <自動生成バケット名> \
    --index-name <自動生成インデックス名> \
    --region ap-northeast-1
{
  "index": {
    "distanceMetric": "euclidean",
    "metadataConfiguration": {
      "nonFilterableMetadataKeys": [
        "AMAZON_BEDROCK_TEXT",
        "AMAZON_BEDROCK_METADATA"
      ]
    }
  }
}

CFnでインデックスを作成する場合は明示的に指定する。

VectorsIndex:
  Type: AWS::S3Vectors::Index
  Properties:
    VectorBucketName: !Sub "${SystemName}-${Environment}-s3-vectors"
    IndexName: !Sub "${SystemName}-${Environment}-kb-index"
    DataType: float32
    Dimension: 1024
    DistanceMetric: cosine
    MetadataConfiguration:
      NonFilterableMetadataKeys:
        - AMAZON_BEDROCK_TEXT
        - AMAZON_BEDROCK_METADATA

Non-filterableにしてもKBの動作に影響はない

KBの Retrieve API経由では、AMAZON_BEDROCK_TEXT の内容は content.text として整形されて返却される。Non-filterableかどうかはKBの検索結果に影響しない。

response = client.retrieve(
    knowledgeBaseId='<KB_ID>',
    retrievalQuery={'text': '検索クエリ'}
)
# → content.text にチャンクテキストが返ってくる

S3 Vectorsを直接クエリする場合は returnMetadata=True を指定することでNon-filterableフィールドも返却される。


ポイント② CFnでは距離メトリクスを選択できる

KBのコンソールからクイック作成した場合、距離メトリクスを選択するUIがなく euclidean で作成される。

一方、Titan Text Embeddings V2は normalize パラメータがデフォルト true で正規化済みベクトルを返す。

正規化済みベクトルでは、cosineとeuclideanで検索結果の順位は変わらない(単調変換の関係)。ただしcosineはドット積で計算できるため計算効率が高いという利点がある。

参考:

CFnでインデックスを作成する場合は距離メトリクスを明示的に選択できる。Titan Text Embeddings V2の正規化済みベクトルではcosineとeuclideanで検索結果の順位は変わらないため、どちらを選んでも実用上の差はない。


ポイント③ Hierarchical Chunkingとの組み合わせ

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

ただし、この非推奨の条件は Parentチャンクが8,000トークン以上 の場合にメタデータサイズ制限に抵触する可能性がある、というもの。

Hierarchical ChunkingではChildチャンクでベクトル検索し、Parentチャンクのテキストが AMAZON_BEDROCK_TEXT に格納されて返却される。メタデータサイズ制限に影響するのはParentチャンクのサイズ。

通常の用途(Parent 1,024トークン程度)であれば問題ない。むしろHierarchical Chunkingは以下の理由から精度面で有利になる。

  • Childチャンク(小さい単位)で精度の高いベクトル検索
  • Parentチャンク(大きい単位)で文脈を広く返却

メタデータフィルタリングを実装する場合

ユーザー属性(部署やロールなど)でドキュメントを絞り込みたい場合は、S3データソースに .metadata.json を配置してカスタムフィールドを追加する。

手順

① メタデータファイルを作成してS3に配置

// document.txt.metadata.json
{
  "metadataAttributes": {
    "group": "dev"
  }
}

② KBを再同期

メタデータファイルを配置後、KBのデータ同期を実行する。

③ Retrieve APIでフィルタリング

response = client.retrieve(
    knowledgeBaseId='<KB_ID>',
    retrievalQuery={'text': '検索クエリ'},
    retrievalConfiguration={
        'vectorSearchConfiguration': {
            'filter': {
                'equals': {
                    'key': 'group',
                    'value': 'dev'
                }
            }
        }
    }
)

検証結果

カスタムフィールド group を付与して検証したところ、意図通りの絞り込みができることを確認した。

フィルタ条件 返ってきたドキュメント
group = "faq" FAQ系ドキュメントのみ ✅
group = "spec" 仕様書系ドキュメントのみ ✅

.metadata.json を配置して再同期するだけで動作する。カスタムフィールドはデフォルトでFilterableとして扱われるため、インデックス側の設定変更は不要。

注意点

AMAZON_BEDROCK_TEXT / AMAZON_BEDROCK_METADATA はNon-filterableのため、これらをフィルタリング条件に使うことはできない。フィルタリング用途にはカスタムフィールドを追加する。


まとめ

設計ポイント 内容
AMAZON_BEDROCK_TEXT / AMAZON_BEDROCK_METADATA Non-filterableに設定(2KB上限回避)
距離メトリクス CFnでは明示的に選択可能(クイック作成はeuclidean固定)。正規化済みベクトルではcosine / euclideanの検索結果は同じ
Hierarchical Chunking Parent 8,000トークン未満であれば問題なし
メタデータフィルタリング .metadata.json をS3に配置して再同期するだけで実現可能

S3 VectorsはOpenSearch Serverlessより低コストでナレッジベースを構築できるが、メタデータの2KB制限やコンソール作成時の制約など、事前に把握しておくべき仕様がいくつかある。特にCFnで構築する場合はNon-filterableキーと距離メトリクスの明示的な指定を忘れないこと。