Amazon DynamoDBのネイティブベクトル検索で実現するセマンティック検索の構築ガイド

益子 竜与志
益子 竜与志
XThreads
最終更新日:2026年08月09日公開日:2026年08月09日

Amazon DynamoDB にネイティブなベクトル検索が加わり、運用データとベクトル埋め込みを同じテーブルで扱えるようになりました。本記事では、DynamoDB を運用するサーバーレス開発リーダー向けに、仕組みと従来設計との違い、実装手順、そして実運用で押さえるべき制約とコストの考え方を、AWS 公式ブログの一次情報に基づいて整理します。

DynamoDBネイティブベクトルサポートとは何か

Amazon DynamoDBは、ベクトル検索をネイティブに扱う機能を一般提供として利用できるようになりました。これまで多くのアプリケーションでは、運用データを格納する主データストアとは別に、ベクトル埋め込みを保持して近似最近傍検索を行うための専用基盤を用意し、両者を同期させる設計が一般的でした。ネイティブベクトルサポートでは、ベクトル埋め込みをDynamoDBアイテムのひとつの属性としてそのまま保存し、同じテーブルの中で近似最近傍検索を実行できます。つまり単一のテーブルが、業務データを扱う運用データストアと、意味的な類似検索を担うベクトルストアの両方を兼ねられるようになったということです。

この統合がもたらす価値は運用のシンプルさにあります。データの二重管理や同期処理、整合性のずれといった課題を持ち込むことなく、既存のDynamoDBワークロードの延長線上でセマンティック検索を追加できます。サーバーレスでスケールするという特性はそのまま活かせるため、フルマネージドの利点を保ったまま、検索体験を意味ベースへと拡張できる点が大きな魅力です。

セマンティック検索とは、キーワードの完全一致ではなく、文章や問い合わせの意味的な近さで関連するデータを探し出す手法です。テキストや画像などを埋め込みモデルで数値ベクトルに変換し、そのベクトル同士の距離が近いものを類似と見なします。DynamoDBはこの検索の土台を、追加のインフラを持たずに提供します。既にDynamoDBを運用しているチームにとって、慣れた基盤の上で意味検索を実現できることは、学習コストと運用コストの両面で現実的な選択肢になります。

単一のDynamoDBテーブルが運用データとベクトル埋め込みを同居させる構成イメージ

ベクトル検索を支える仕組みを理解する

ベクトル検索を使うには、テーブルにベクトルインデックスを定義します。インデックスはcreate_tableのVectorIndexesパラメータで指定し、すでに存在するテーブルに対してはUpdateTableで追加できます。VectorIndexesの各要素は、インデックス名を表すIndexName、埋め込みを保持する属性を指すVectorAttributeのAttributeName、ベクトルの次元数を表すDimensions、距離メトリクスを指定するDistanceFunction、そして検索結果に含める属性を制御するProjectionで構成されます。

次元数は最大で4096まで指定できます。ここで重要なのは、Dimensionsに指定する値を埋め込みモデルの出力次元と必ず一致させることです。モデルが生成するベクトルの長さとインデックスの定義がずれていると正しく検索できません。AWSのサンプルでは1024次元が用いられています。

距離メトリクスはCOSINE、DOT_PRODUCT、EUCLIDEANの3種類から選べます。スコアの解釈はメトリクスによって異なります。DOT_PRODUCTはスコアが高いほど類似度が高くなります。一方でCOSINEとEUCLIDEANはスコアが低いほど類似度が高くなります。どのメトリクスを選ぶかは、利用する埋め込みモデルの推奨や、ベクトルを正規化するかどうかによって判断していきます。

もうひとつ理解しておきたいのが整合性です。ベクトルインデックスは非同期に更新される仕組みのため、ベクトル検索の結果は結果整合性となります。アイテムを書き込んだ直後に検索へ即座に反映されるとは限らない点を、アプリケーションの設計時に織り込んでおく必要があります。書き込みから検索反映までにわずかな遅延が生じうるという前提を、業務フローの設計に組み込んでおくと安心です。

セマンティック検索を実装する手順

実装の全体像は、埋め込みを生成し、ベクトルインデックス付きのテーブルを用意し、データを投入し、search_vectorsで検索するという流れになります。前提として、Python 3.12以降、Boto3 1.43.64以降、AWSアカウント、そしてDynamoDBとBedrockを操作する権限が必要です。サンプルデータにはHugging Faceのarxiv-abstracts-2021が使われています。

埋め込みの生成にはAmazon BedrockのTitan Text Embeddings V2を利用します。modelIdはamazon.titan-embed-text-v2:0です。invoke_modelには、対象テキストを表すinputText、出力次元を指定するdimensions、正規化の有無を制御するnormalizeを渡します。ここで指定するdimensionsが、後述するインデックスのDimensionsと一致している必要があります。

body = json.dumps({
    "inputText": "検索対象のテキスト",
    "dimensions": 1024,
    "normalize": True
})
resp = client.invoke_model(
    modelId="amazon.titan-embed-text-v2:0",
    body=body
)

次に、ベクトルインデックスを備えたテーブルを作成します。VectorIndexesにインデックス名、埋め込み属性、次元数、距離メトリクス、射影を指定します。ベクトルインデックスはオンデマンドの容量モードでのみ対応するため、BillingModeにはPAY_PER_REQUESTを指定します。

client.create_table(
    TableName="Documents",
    BillingMode="PAY_PER_REQUEST",
    VectorIndexes=[{
        "IndexName": "VectorIndex",
        "VectorAttribute": {"AttributeName": "embedding"},
        "Dimensions": 1024,
        "DistanceFunction": "DOT_PRODUCT"
    }]
)

テーブルが用意できたら、各アイテムに埋め込み属性を付与してデータを投入します。投入後は、検索したいテキストからも同じモデルで埋め込みを生成し、search_vectorsに渡して近似最近傍検索を行います。主なパラメータは、対象テーブルを表すTableName、利用するインデックスを表すIndexName、問い合わせベクトルを表すSearchVector、取得件数を表すTopK、消費キャパシティの取得を制御するReturnConsumedCapacityです。

result = client.search_vectors(
    TableName="Documents",
    IndexName="VectorIndex",
    SearchVector=[{"N": str(v)} for v in query_vector],
    TopK=5
)

結果はSearchResultsとして返り、各要素は射影された属性を含むItemと、類似度スコアを表すScoreを持ちます。埋め込み属性そのものは既定では結果に含まれないため、必要であれば射影を通じて取得するように構成します。この一連の流れをつかめば、既存のアプリケーションへ意味検索を段階的に組み込んでいけます。

埋め込み生成からVectorIndexes作成、search_vectorsでの検索までの実装フロー

実運用を見据えた設計ポイントと制約

本番運用に向けては、いくつかの制約を前提として設計に反映しておくことが欠かせません。まず容量モードについてです。ベクトルインデックスはオンデマンド、すなわちPAY_PER_REQUESTのテーブルでのみ利用できます。プロビジョンドキャパシティで運用している既存テーブルにベクトル検索を組み込みたい場合は、容量モードの方針を含めて検討する必要があります。

インデックス数にも上限があります。1つのテーブルあたり、デフォルトで最大5つのベクトルインデックスを持てます。用途ごとに複数の埋め込みモデルや距離メトリクスを使い分けたい場合は、この上限を意識してインデックス設計を組み立てます。

結果整合性への対応も重要な設計ポイントです。インデックスは非同期に更新されるため、書き込み直後に必ず検索結果へ反映されるわけではありません。リアルタイムでの反映が前提となる要件では、この特性が許容できるかを事前に見極め、必要に応じて業務フロー側で吸収する工夫を検討します。

次元と射影の設計を丁寧に決める

次元数は埋め込みモデルの出力に合わせて固定する必要があるため、あとから安易に変えられません。将来のモデル変更まで見据えて、どの次元で運用するかを最初に決めておくと安定します。射影については、検索結果にどの属性を含めるかを設計する部分であり、埋め込み属性は既定で含まれないという点を踏まえ、アプリケーションが必要とする属性だけを返すように整理しておくと運用が明快になります。過不足のない射影は、返却データ量を抑えることにもつながります。

コストとパフォーマンスの考え方

料金は3つの課金軸で構成されます。ベクトルの書き込みリクエスト、ベクトル検索、そしてストレージのGB-月です。いずれの軸でも最小の課金単位は1KBとされています。具体的なUSD単価は元記事に記載がないため断定はしませんが、この3軸と最小1KBという単位を理解しておくと、コストの当たりを付けやすくなります。

実務では、次元数と射影がコストに影響することを意識すると効果的です。次元数が大きいほど1件あたりのベクトルは大きくなり、ストレージや書き込みのコストへ効いてきます。求める検索精度と、次元を増やすことによるコスト増のバランスを取ることが設計の勘所です。射影についても、検索結果に含める属性を必要最小限にとどめることで、返却されるデータ量を抑えられます。最小課金単位が1KBである点も、小さなアイテムを大量に扱う場合には効いてくるため、実データで試算しておくとよいでしょう。

パフォーマンスの観点では、DynamoDBのベクトル検索は一貫した低レイテンシーを備え、数兆規模のベクトルを保存して検索できると表現されています。具体的なレイテンシーの数値やベンチマークをここで断定することはしませんが、大規模なデータ量でも運用データストアと同じ基盤で意味検索を扱える点は、スケールを見据えるうえで心強い特性です。まずは小さなデータセットで挙動と精度を確かめ、そこから段階的に規模を広げていくアプローチが、コストとリスクの両面で無理がありません。

導入判断のためのチェックポイント

最後に、導入を検討する際の観点を整理します。第一に、既存DynamoDBワークロードとの親和性です。すでにDynamoDBを運用データストアとして使っているのであれば、別のベクトル基盤を追加して同期させる代わりに、同じテーブルへ検索機能を寄せられるため、構成をシンプルに保てます。運用の統合効果が大きいほど、導入の価値は高まります。

第二に、要件適合の確認です。ベクトルインデックスがオンデマンド容量モード前提であること、検索結果が結果整合性であること、1テーブルあたりのインデックス数に上限があること、次元数を埋め込みモデルと一致させる必要があることを、自分たちのユースケースに照らして許容できるかを見極めます。リアルタイム反映が絶対条件の検索や、プロビジョンド前提の運用では、追加の検討が必要になります。

第三に、段階的な検証です。まずTitan Text Embeddings V2などで埋め込みを生成し、小規模なデータセットでVectorIndexes付きのテーブルを作成し、search_vectorsの結果とスコアの挙動を確かめるところから始めます。距離メトリクスの選択や次元数、射影の設定が検索精度とコストへどう影響するかを実データで観察しながら、徐々に本番規模へ広げていくと、判断の精度が上がります。運用データとベクトルストアを一体化できるという強みを、自分たちの要件と照らし合わせて評価することが、堅実な導入への近道です。

AI-NATIVE WORKSPACE

Openclaw AX

いつもの業務がAIとの共同作業に変わる革新的AI製品

詳しく見る →
Openclaw AX

IT/DXプロジェクト推進するPMO・コンサル人材を提供しています

AI利活用×高生産性のリソースで、あらゆるIT/DXプロジェクトを一気通貫支援します

詳しく見る →
AI駆動型ITコンサルティング
Careerバナーconsultingバナー