本記事の移行元および料金比較の対象は、Amazon OpenSearch Serverless Classicです。
2026年5月に一般提供されたAmazon OpenSearch Serverless NextGenは、今回の比較には含めていません。
はじめに
はじめまして。2026 Japan AWS Jr.champions の長井です。
この記事は「2026 Japan AWS Jr. Champions 真夏のQiitaリレー」の28日目の記事です。
※この内容をもとに、本の執筆を予定しています。(技術書展で発売予定)
過去の投稿は、こちらのリンク集からご覧いただけます。
背景
業務では、Knowledge Bases for Amazon Bedrockを使ったAIナレッジ検索システムを開発・運用しています。
FAQや業務マニュアルをKnowledge Baseへ登録し、利用者が自然文で必要な情報を検索できるRAGシステムです。
※インフラはAWS Cloud Development Kit(AWS CDK)で管理しています。
テナントごとにAWSアカウントと環境を分離し、それぞれにKnowledge Baseとベクトルストアを構築しました。
ベクトルストアとしてAmazon OpenSearch Serverlessを使用し、性能に不満はありませんでしたが、テナントが増えるほどベースラインコストも積み上がる構造が課題でした。
そこで、CDKで構築できるようになったAmazon S3 Vectorsへ移行しました。
私は、移行可否の技術検証から本番環境の切り替えまでを担当しました。
本記事では、顧客固有の情報やリソース名を除き、判断に必要だった検証結果と、実際に詰まったポイントを一般化して紹介します。
先に結論
セマンティック検索で要件を満たす、利用頻度の低いRAGでは、S3 Vectorsは固定的なコストを避ける有力な選択肢です。
ベクトルストアの選定では、安さだけでなく検索方式から判断する必要があります。
| 要件・状況 | 判断 |
|---|---|
| セマンティック検索で要件を満たし、テナントごとのベースラインコストを避けたい | S3 Vectorsを検討する |
| 型番やエラーコードなど、キーワードの完全一致が重要 | OpenSearch Serverlessを検討する |
本記事は、筆者の環境で行った検証と移行の結果をまとめたものです。
検索品質やレイテンシは、データ、クエリ、Embeddingモデル、チャンキング、フィルター条件によって変わります。
必ずしも本記事の構成が最適とは限らないため、実際の要件とデータで評価してください。
S3 Vectorsとは
Amazon S3 Vectorsは、ベクトルの保存と類似検索に特化したAmazon S3の機能です。
通常のS3バケットとは別に、ベクトルバケットとベクトルインデックスを作成します。Knowledge Baseのベクトルストアとして利用できます。
一言で表すと、常時稼働する検索基盤を持たず、保存量とリクエスト量に応じて利用できる従量課金制のベクトルストアです。
移行前後の構成
文書を取り込む同期経路と、利用者の質問を処理する検索経路を示します。
主な構成と変更範囲
| 項目 | 使用技術・設定 | 移行時の扱い |
|---|---|---|
| データソース | Amazon S3 | 変更なし |
| Knowledge Base | Knowledge Bases for Amazon Bedrock | 新しいリソースを作成 |
| ベクトルストア | Amazon OpenSearch Serverless Classic → Amazon S3 Vectors | 変更 |
| Embeddingモデル | Amazon Titan Text Embeddings V2 | 変更なし |
| 距離メトリクス | cosine | 変更なし |
| チャンキング | 移行前後で同じ設定 | 変更なし |
| 検索・回答生成 |
RetrieveAndGenerate API |
変更なし |
| IaC | AWS CDK(aws-cdk-lib 2.246.0、L1 Construct) |
S3 Vectors関連リソースを追加 |
メタデータ、IAM、既存フィルターは、S3 Vectorsに合わせて修正・確認しました。
なぜS3 Vectorsへ移行したのか
RAGシステムの開発開始時点では、S3 Vectorsはプレビュー直後で、CDKから管理できなかったため、OpenSearch Serverless Classicを採用していました。
その後、CDKから構築できるようになったことを受け、移行先として再評価しました。
当時利用していたOpenSearch ServerlessのClassic構成では、データ量や利用頻度が少ないテナントでも、ベースラインとなるOpenSearch Compute Unit(OCU)のコストが発生していました。
一方、S3 Vectorsは保存量や書き込み・検索リクエストに応じた課金です。テナントによって利用量にばらつきがある今回の構成に適していました。
料金表から試算すると、約7,000分の1
「安い」と言うだけでは判断材料にならないため、OpenSearch ServiceとAmazon S3の公式料金表にある米国東部(バージニア北部)の料金を使い、小規模な構成を試算しました。
- ベクトル数:10,000
- ベクトル1件あたり:平均6.17 KB(1,024次元のベクトルとメタデータを想定)
- 検索回数:月10,000回
- 全ベクトルの再登録:月1回
- OpenSearch Serverless Classic:冗長化ありの初回コレクションで、最小2 OCUを常時使用
- 比較対象:ベクトルストア部分のみ
| 構成 | 月額の概算 | 計算の概要 |
|---|---|---|
| OpenSearch Serverless Classic | 約350.40 USD+管理ストレージ料金 | 2 OCU × 0.24 USD × 730時間 |
| S3 Vectors | 約0.05 USD | 保存:約0.004 USD、PUT:約0.012 USD、検索:約0.027 USD(合計約0.043 USDを切り上げ) |
この前提では、S3 Vectorsのベクトルストア部分はOpenSearch Serverless ClassicのOCU料金だけと比べても約7,000分の1です。
実際の移行案件の請求額ではなく、あくまで料金表に基づく参考値です。
利用量の少ないテナントほど固定的なOCUコストとの差が大きくなることが分かります。
リージョン、ベクトル数、メタデータ量、更新頻度、検索回数、OCUをほかのコレクションと共有できるかによって金額は変わります。
また、Embedding・生成モデルの推論料、原本を置くS3、データ転送など、両構成で共通する費用は含めていません。
S3 VectorsのPUT料金はベクトルをまとめて登録する前提です。1回のPUTには128KBの最低課金があるため、登録方法によって実際の料金は増える可能性があります。
NextGenは、同じコレクショングループ全体で10分間リクエストがない場合、検索・インデックス作成のOCUがそれぞれ0までスケールダウンします。
現在新規に選定する場合は比較対象になりますが、復帰時の初回リクエストには10~30秒程度かかる可能性があります。詳しくは公式ドキュメントを参照してください。
移行前に確認したこと
移行判断では、検索品質とエンドツーエンドのレイテンシを確認しました。
検索品質
検証用Knowledge Baseに対象のFAQ・マニュアル群を同期し、代表的な質問に対する回答・引用とラベルフィルターを確認しました。
この範囲では、業務利用を妨げる問題は見つかりませんでした。
ただし、これは定性的な受け入れ確認です。
Recall@5 や nDCG@5 による定量評価は実施していないため、OpenSearch ServerlessとS3 Vectorsの検索精度が同じとは結論付けていません。
また、Knowledge BaseとS3 Vectorsの組み合わせはセマンティック検索のみで、ハイブリッド検索には対応していません。
製品型番、エラーコード、固有名詞などの完全一致が重要な用途では、OpenSearch Serverlessを優先すべきです。
レイテンシ
OpenSearch ServerlessとS3 Vectorsに対して、同じ5クエリとAPIオプションで RetrieveAndGenerate APIを20回ずつ実行しました。
- 固定した5クエリを各4回実行
- 連続実行によるウォーム条件
- リランキングあり、メタデータフィルターなし
- Amazon API GatewayやAWS Lambdaを経由せず直接計測
- 検索、リランキング、回答生成を含む時間
P50は中央値です。
P90とP95は、それぞれ全体の90%・95%がその時間以内に完了したことを示し、平均値だけでは見えにくい遅いリクエストを確認できます。
例えば、S3 VectorsのP95が6,593 msなら、約95%のリクエストが約6.6秒以内に完了したと読めます。
| 指標 | OpenSearch Serverless Classic | S3 Vectors | 差分 |
|---|---|---|---|
| 平均 | 5,125 ms | 5,161 ms | +0.7% |
| P50(中央値) | 5,245 ms | 4,904 ms | -6.5% |
| P90 | 5,776 ms | 6,377 ms | +10.4% |
| P95 | 6,697 ms | 6,593 ms | -1.6% |
当初設定したP95 5秒未満という基準は、両構成とも満たしませんでした。
一方、既存のOpenSearch Serverlessからレイテンシーが悪化していないことを確認できたため、移行の観点では条件付きGoと判断しました。
ただし、サンプル数は各20回と少なく、コールドスタートを含みません。
また、LLM生成とリランキングも測定時間に含まれるため、ベクトルストア単体の性能が同等であることを示す結果ではありません。
AWS CDKの主な変更点
実装、執筆時点ではS3 VectorsのL2 Constructがないため、CfnVectorBucket と CfnIndex を使いました。
Knowledge Baseの主な変更は storageConfiguration です。
storageConfiguration: {
type: "S3_VECTORS",
s3VectorsConfiguration: {
vectorBucketArn: vectorBucket.attrVectorBucketArn,
indexName: vectorIndex.indexName,
},
}
Vector Indexでは、Knowledge Baseが付与するテキストとメタデータをフィルター対象から外します。
AWS公式の設定例では AMAZON_BEDROCK_TEXT が示されていますが、本環境では取り込み後のベクトルに AMAZON_BEDROCK_TEXT_CHUNK が保存されていることを確認したため、次のように設定しました。
metadataConfiguration: {
nonFilterableMetadataKeys: [
"AMAZON_BEDROCK_TEXT_CHUNK",
"AMAZON_BEDROCK_METADATA",
],
}
これだけでなく、周辺の設定には注意が必要です。
移行で詰まった6つのポイント
| 症状 | 原因 | 対策 |
|---|---|---|
データ同期が Metadata cannot exceed 2048 bytes で失敗 |
Knowledge Baseが付与するテキストとメタデータがフィルター可能メタデータとして扱われた | 実際に保存された予約キーを確認し、nonFilterableMetadataKeys に指定 |
s3:* を許可してもアクセスできない |
S3 Vectorsは通常のS3とは別のIAMアクション |
s3vectors 名前空間の権限を対象ARNに限定して追加 |
| リソース作成順序で失敗 | L1リソース間の依存関係が不足 | VectorBucket → VectorIndex → KnowledgeBase → DataSourceの順に addDependency を設定 |
| 初回のデプロイが失敗 | 既存リソースと論理ID・物理名が衝突 | 新しいConstruct IDとKnowledge Base名で並行作成 |
| CloudFormationのスキーマ検証で失敗 |
indexName と indexArn を同時指定 |
vectorBucketArn と indexName の組み合わせに統一 |
| 回答は返るが引用が0件 | 既存の x-amz-bedrock-kb-source-uri フィルターを移植できなかった |
S3 Vectorsで利用できるカスタムメタデータのラベルへ変更 |
特に注意したいのは、最後のフィルター互換性です。ベクトルストアだけを見ていると、アプリケーションは正常に回答しているように見えます。
今回は引用件数も確認したことで、既存フィルターが原因だと分かりました。
S3 Vectors自体は、フィルター可能なメタデータが1ベクトルあたり最大2KBです。一方、Knowledge Basesと組み合わせる場合、カスタムメタデータは1ベクトルあたり最大1KB・35キーです。上限の対象が異なる点に注意してください。
詳しくはS3 Vectorsの制限とKnowledge Basesとの統合に関する制限を参照してください。
Knowledge Baseのサービスロールについて、AWS公式例で示されているデータ操作は s3vectors:PutVectors、s3vectors:GetVectors、s3vectors:DeleteVectors、s3vectors:QueryVectors、s3vectors:GetIndex の5つです。本構成ではリソース管理系を含む計10アクションを同じロールに許可していました。対象ARNを限定したうえで、実行時の権限と構築・管理時の権限を分ける余地があります。
詳しくはKnowledge BasesのIAM権限を参照してください。
本番移行は旧環境を残して進めた
既存のKnowledge Baseをその場で置換せず、旧OpenSearchリソースを RETAIN で残したまま、S3 Vectors用のKnowledge Baseを新しく作成しました。
-
cdk diffで変更内容と旧リソースのRETAINを確認 - S3 Vectors用Knowledge Baseをデプロイし、アプリケーションの参照先を更新
- データソースを同期
- フィルターなしの検索で回答と引用を確認
- ラベルフィルターを確認
| 項目 | 結果 |
|---|---|
| データソース同期 | 全ドキュメントの同期完了を確認 |
| 検索確認 | フィルターなし・ラベルフィルターの両方で回答と引用を確認 |
| ロールバック | 旧OpenSearch環境を RETAIN で保持 |
| メンテナンス作業 | 予定枠2時間に対し、確認完了まで約48分 |
旧環境を残したことで、同期や確認で問題が起きても戻せる状態を維持できました。
まとめ
今回の移行で最も重要だったのは、料金差だけで判断せず、検索方式の制約を先に確認したうえで、実際のデータと質問を使って検索品質とレイテンシを確かめることでした。
本番移行では旧OpenSearch環境を残し、新しいKnowledge Baseの同期、回答・引用、フィルターを確認しました。
問題があれば旧Knowledge Baseへ参照を戻せるようにしたことが、技術検証を本番移行につなげるポイントでした。誰かの参考になれば嬉しいです。
本記事で扱い切れなかった内容は、技術書典21で頒布予定のAWS Jr. Champions 2026 の技術書にまとめる予定です。