View a markdown version of this page

教學課程:您的第一個向量搜尋 - Amazon DynamoDB

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

教學課程:您的第一個向量搜尋

試想一個產品目錄,其中消費者用自己的話描述他們想要什麼,而不是匹配確切的關鍵字。您可以在 DynamoDB 中存放每個產品描述的向量內嵌,然後查詢向量索引以尋找最接近的相符項目。

本教學課程會建立具有向量索引的資料表、使用 Amazon Bedrock Titan Text Embeddings V2 產生 1024 維度內嵌、載入 50 個產品,以及執行傳回 5 個最接近相符項目的相似性搜尋。每個命令都可以直接貼入終端機。如需內嵌如何使用 DynamoDB 的背景,請參閱 產生向量內嵌

關於擴展和召回

生產向量索引可容納數百萬到數十億個向量。向量索引使用近似最接近的鄰搜尋,而且該方法的取回特性只有在更大的規模下才能觀察到。將這裡的 50 個項目目錄視為示範機制。如需調整大小和調校的指引,請參閱 向量索引的最佳實務

先決條件

開始前,請確定您具有下列項目:

  • AWS CLI 2.36.16 版或更新版本。向量索引支援已新增至 2026 年 8 月 4 日發行的服務模型更新中的 AWS CLI 和 AWS SDKs。舊版無法辨識 --vector-indexes 參數或 search-vectors命令。使用 檢查您的版本aws --version,並視需要升級。如果您使用 AWS SDK 而非 AWS CLI,則需要 botocore 1.43.64 或更新版本,或同等版本的語言 SDK。

  • 具有 DynamoDB 動作 CreateTableDescribeTableDeleteTable、、、 PutItem BatchWriteItem Scan SearchVectors UpdateTable和 以及 Amazon Bedrock 動作 許可的登入資料InvokeModeldynamodb:SearchVectors 是新的動作,因此授予 DynamoDB 讀取存取權的現有政策不包含在內。

  • 存取您的帳戶和區域在 Amazon Bedrock 中啟用的 Titan Text Embeddings V2 模型。每個帳戶和每個區域都會授予 Amazon Bedrock 模型存取權,因此您必須先啟用模型,才能呼叫模型。

  • jq 安裝 以將模型輸出重塑為 DynamoDB 格式。

  • 可使用 DynamoDB 向量索引和 Amazon Bedrock Titan Text Embeddings V2 的區域。Amazon Bedrock 模型可用性因區域而異,通常比 DynamoDB 區域涵蓋範圍更窄,因此請在選擇區域之前確認兩者。如需 Amazon Bedrock 模型可用性,請參閱《Amazon Bedrock 使用者指南》中的依 AWS 區域提供的模型支援

費用

本教學課程會產生 Amazon Bedrock 模型調用和 DynamoDB 儲存體的費用。它會對簡短的單一句子輸入進行 51 個內嵌呼叫,每個呼叫都以 Amazon Bedrock 推論請求計費。只要資料表和向量索引存在,就會收取 DynamoDB 儲存費用。

確認您正在使用的 區域

本教學課程中的每個命令都必須在相同的 區域中執行。在開始之前,請確認 AWS CLI 實際使用的 區域,因為 AWS_REGION 優先於 AWS_DEFAULT_REGION,而兩者都優先於 AWS CLI 組態檔案中region的設定。殼層中的偏離AWS_REGION值會在您預期區域以外的位置建立資料表,而 Amazon Bedrock 模型可能不會在該處啟用。若要移除所有疑義,請在每個命令上--region region明確傳遞 。

SearchVectors 使用單獨的端點

SearchVectors 會解析為專用搜尋端點,而不是標準 DynamoDB 端點。在商業區域中,請求會移至 search-dynamodb.region.amazonaws.com,而本教學課程中的所有其他操作則會移至 dynamodb.region.amazonaws.com。FIPS 和雙堆疊變體遵循相同的模式。這有兩個後果:

  • 如果您的網路限制透過 VPC 端點、代理或輸出允許清單的傳出流量,您也必須允許搜尋主機名稱。否則CreateTable,寫入操作會成功且只會SearchVectors失敗,通常是連線錯誤未指出原因。

  • 請勿使用 --endpoint-url 覆寫這些命令的 DynamoDB 端點。單一覆寫無法同時提供兩個主機名稱,且會中斷搜尋路由。

  1. 建立具有向量索引的資料表。這會在 DescriptionVector 屬性DescriptionIndex上建立具有名為 之向量索引的Products資料表。索引使用具有 1024 個維度COSINE的距離函數,以符合 Titan Text Embeddings V2 輸出。由於未定義向量索引分割區索引鍵,您不需要SearchConditionExpression搜尋 。

    aws dynamodb create-table \ --table-name Products \ --attribute-definitions AttributeName=ProductId,AttributeType=S \ --key-schema AttributeName=ProductId,KeyType=HASH \ --billing-mode PAY_PER_REQUEST \ --vector-indexes \ "[ { \"IndexName\": \"DescriptionIndex\", \"VectorAttribute\": {\"AttributeName\": \"DescriptionVector\"}, \"Projection\": {\"ProjectionType\": \"ALL\"}, \"Dimensions\": 1024, \"DistanceFunction\": \"COSINE\" } ]"

    此範例使用 ProjectionTypeALL以便每個屬性可供搜尋結果使用。如果您INCLUDE改用 ,請注意已共用投影的非金鑰屬性預算:向量屬性計為一個屬性,而每個INLINE_FILTER搜尋結構描述元素計為一個。HASH搜尋結構描述元素不會計為限制。

  2. 等待索引變成作用中。IndexStatus為 之前執行此動作ACTIVE

    aws dynamodb describe-table \ --table-name Products \ --query 'Table.VectorIndexes[0].[IndexName,IndexStatus,Backfilling]'

    對於作為 一部分建立的索引CreateTable,如本教學中所示, Backfilling 不會報告,且 命令會null傳回該索引。在這種情況下,請IndexStatus單獨使用 做為您的訊號。

    Backfilling 會報告您新增至具有 之現有資料表的向量索引UpdateTable。在這種情況下,請等到 IndexStatusACTIVEBackfillingfalse,再依賴完整的搜尋結果。

    等待索引,而不只是資料表

    請勿使用 aws dynamodb wait table-exists將搜尋設為閘道。該等待程式符合 上的 Table.TableStatus,這會變成 ,ACTIVE而向量索引仍然可以是 CREATING。沒有向量索引整備的等待程式,因此您必須輪詢DescribeTable,如下所示。搜尋尚未ACTIVE失敗的索引,以及在回填期間搜尋可能會傳回不完整的結果。

    基於相同原因,您無法刪除資料表,直到每個向量索引完成建立為止。 ResourceInUseExceptionDeleteTable傳回「建立、更新或刪除索引時無法刪除資料表」的訊息。

  3. 建立產品目錄。將下列 50 個產品儲存至名為 的標籤分隔檔案products.tsv。每一行都包含產品 ID、名稱和單聲道描述。目錄包含 10 個群組的 5 個相關產品,這使得最後一個步驟中的搜尋結果更容易解譯。

    p01 Insulated Travel Mug A vacuum insulated stainless steel mug that keeps hot drinks warm for up to twelve hours. p02 Stovetop Espresso Maker A compact aluminum pot that brews strong espresso style coffee directly on a gas or electric burner. p03 Manual Burr Coffee Grinder A hand cranked grinder with adjustable ceramic burrs for consistent coffee grounds. p04 Pour Over Coffee Dripper A ceramic cone that sits on a mug and brews a single cup of filter coffee. p05 Electric Milk Frother A handheld battery powered whisk that creates dense foam for lattes and cappuccinos. p06 Lightweight Running Shoe A breathable mesh road shoe with cushioned foam midsole for daily training runs. p07 Trail Running Shoe An aggressive lugged outsole shoe built for grip on loose gravel and muddy trails. p08 Moisture Wicking Running Socks Ankle height socks knitted from synthetic yarn that pulls sweat away from the skin. p09 Reflective Running Vest A lightweight vest with high visibility strips for running safely after dark. p10 Hydration Waist Belt An elastic belt that holds two small water flasks and a phone during long runs. p11 Ergonomic Mesh Office Chair An adjustable desk chair with breathable mesh back and lumbar support for long work sessions. p12 Sit Stand Desk Converter A height adjustable platform that raises a monitor and keyboard for standing work. p13 Monitor Arm Mount A clamp mounted articulating arm that lifts a display off the desk surface. p14 Under Desk Footrest An angled cushioned platform that supports the feet and improves seated posture. p15 Wireless Split Keyboard A two piece keyboard that separates for a natural shoulder width typing position. p16 Noise Cancelling Headphones Over ear wireless headphones that actively silence engine noise on long flights. p17 Wireless Earbuds Compact in ear buds with a charging case and multi hour battery for commuting. p18 Portable Bluetooth Speaker A water resistant rechargeable speaker sized to fit in a backpack side pocket. p19 Studio Monitor Headphones Wired closed back headphones with flat frequency response for audio mixing. p20 Wired Lapel Microphone A small clip on microphone for recording clear speech during interviews. p21 Four Season Backpacking Tent A double wall tent with an aluminum pole set rated for wind and heavy rain. p22 Down Sleeping Bag A mummy shaped bag filled with compressible down insulation for cold weather camping. p23 Inflatable Sleeping Pad A lightweight pad that inflates in a few breaths and packs down to bottle size. p24 Canister Camping Stove A screw on burner that boils water quickly using a compact fuel canister. p25 Rechargeable Camp Lantern A collapsible lantern with adjustable brightness and a built in battery. p26 Cast Iron Skillet A preseasoned heavy pan that holds heat evenly for searing and oven baking. p27 Nonstick Frying Pan A coated aluminum pan that releases eggs and fish without added oil. p28 Stainless Steel Stock Pot A tall wide pot for boiling pasta and simmering large batches of soup. p29 Enameled Dutch Oven A heavy lidded pot that moves from stovetop to oven for slow braising. p30 Bamboo Cutting Board A large reversible board with a juice groove around the edge. p31 Padded Laptop Backpack A water resistant pack with a suspended sleeve that protects a fifteen inch laptop. p32 Slim Laptop Sleeve A close fitting neoprene case that shields a notebook inside a larger bag. p33 Rolling Carry On Suitcase A hard shell four wheel case sized to fit most overhead cabin bins. p34 Packing Cube Set Zippered fabric cubes that compress clothing and organize a suitcase. p35 Leather Messenger Bag A single strap shoulder bag with a padded compartment and interior pockets. p36 Daily Facial Moisturizer A light lotion with humectants that hydrates skin without leaving residue. p37 Mineral Sunscreen Lotion A broad spectrum zinc based sunscreen formulated for sensitive facial skin. p38 Gentle Foaming Cleanser A low pH face wash that removes oil and sunscreen without stripping the skin. p39 Vitamin C Serum A brightening serum applied before moisturizer to even skin tone over time. p40 Overnight Repair Cream A rich night cream with ceramides that restores the skin barrier while sleeping. p41 Stainless Steel Dog Bowl A weighted nonslip bowl that resists tipping during enthusiastic feeding. p42 Padded Dog Harness An adjustable chest harness that distributes pull away from the neck on walks. p43 Retractable Dog Leash A spring loaded leash that extends and locks at several walking lengths. p44 Interactive Cat Puzzle Feeder A slow feed tray that makes a cat work for dry food and eat more slowly. p45 Self Cleaning Litter Box An enclosed box with a raking mechanism that sifts waste after each use. p46 Bypass Pruning Shears Sharp hardened blades that make clean cuts on green stems and small branches. p47 Long Handled Garden Spade A steel bladed spade with a wooden shaft for turning soil and digging beds. p48 Adjustable Hose Spray Nozzle A metal nozzle that shifts from a fine mist to a strong jet stream. p49 Raised Garden Bed Kit Interlocking cedar panels that assemble into an elevated planting box. p50 Drip Irrigation Starter Kit Tubing and emitters that deliver water slowly to the base of each plant.

    三個欄位之間的分隔符號必須是文字標籤字元。如果您從瀏覽器複製目錄,請在繼續之前驗證標籤是否存活。

  4. 為一個產品產生內嵌。請先執行單一內嵌呼叫,以確認您的 Amazon Bedrock 模型存取是否有效。inputText 欄位包含要嵌入的文字、dimensions設定輸出大小 (有效值為 256、512 或 1024),並normalize產生單位長度向量,建議用於餘弦相似性搜尋。

    mkdir -p emb aws bedrock-runtime invoke-model \ --model-id amazon.titan-embed-text-v2:0 \ --body '{"inputText":"A vacuum insulated stainless steel mug that keeps hot drinks warm for up to twelve hours.","dimensions":1024,"normalize":true}' \ --cli-binary-format raw-in-base64-out \ --content-type application/json \ --accept application/json \ emb/p01.json

    需要 --cli-binary-format raw-in-base64-out旗標。 AWS CLI v2 預設為二進位參數的 base64 編碼,因此如果沒有此旗標,原始 JSON 內文無法正確傳送。回應會寫入 ,emb/p01.json並包含 1024 個浮點數的embedding陣列。確認維度計數。

    jq '.embedding | length' emb/p01.json

    輸出是 1024

  5. 撰寫第一個產品。將內嵌轉換為 DynamoDB 項目格式並寫入。存放的向量屬性使用 DynamoDB L(清單) 類型來包裝 N類型中的每個數字。

    jq '{"ProductId":{"S":"p01"},"Title":{"S":"Insulated Travel Mug"},"DescriptionVector":{"L":[.embedding[]|{"N":(.|tostring)}]}}' emb/p01.json > item-p01.json aws dynamodb put-item --table-name Products --item file://item-p01.json
    向量大小和項目限制

    1024 維度向量會將大約 32 KB 新增至請求承載,並將大約 5 KB 新增至預存項目,這遠低於 400 KB DynamoDB 項目大小限制。當您存放內嵌時,維度計數是項目大小的主要驅動因素。

  6. 內嵌其餘產品。此迴圈會為每個剩餘的產品產生內嵌。它會略過任何已存在的檔案,因此您可以在呼叫失敗時安全地重新執行它。

    while IFS=$'\t' read -r id title description; do [ -s "emb/$id.json" ] && continue body=$(jq -n --arg t "$description" '{inputText:$t,dimensions:1024,normalize:true}') aws bedrock-runtime invoke-model \ --model-id amazon.titan-embed-text-v2:0 \ --body "$body" \ --cli-binary-format raw-in-base64-out \ --content-type application/json \ --accept application/json \ "emb/$id.json" >/dev/null || echo "FAILED $id" done < products.tsv ls emb/*.json | wc -l

    計數必須是 50,才能繼續。如果任何呼叫已列印 FAILED,請再次執行迴圈;它只會重試缺少的檔案。

    InvokeModel 速率配額

    Amazon Bedrock 會將請求率配額套用至 InvokeModel。如果您修改此迴圈以平行發出呼叫, 預期某些呼叫會有調節例外狀況,並一律驗證最終檔案計數,而不是假設每次呼叫都成功。部分內嵌的目錄載入時不會發生錯誤,並產生搜尋結果,以無提示方式省略缺少的產品。

  7. 載入剩餘的產品。建置每個 25 個項目的請求承載,這是 BatchWriteItem 接受的最大值。

    batch=0 count=0 echo -n '{"Products":[' > batch-0.json while IFS=$'\t' read -r id title description; do if [ "$count" -eq 25 ]; then echo ']}' >> "batch-$batch.json" batch=$((batch+1)); count=0 echo -n '{"Products":[' > "batch-$batch.json" fi [ "$count" -gt 0 ] && echo -n ',' >> "batch-$batch.json" jq -c --arg id "$id" --arg title "$title" \ '{PutRequest:{Item:{ProductId:{S:$id},Title:{S:$title}, DescriptionVector:{L:[.embedding[]|{"N":(.|tostring)}]}}}}' \ "emb/$id.json" >> "batch-$batch.json" count=$((count+1)) done < <(tail -n +2 products.tsv) echo ']}' >> "batch-$batch.json"

    迴圈從重新導向而非管道讀取,因為管道while迴圈在某些 shell 中以子殼執行,這會捨棄 batchcount值,並產生格式不正確的批次檔案。

    提交每個批次。 BatchWriteItem可以部分成功,因此請重新提交它在 中傳回的任何內容UnprocessedItems

    for f in batch-*.json; do cp "$f" pending.json for attempt in 1 2 3 4 5; do aws dynamodb batch-write-item \ --request-items file://pending.json \ --output json > resp.json left=$(jq '(.UnprocessedItems.Products // []) | length' resp.json) echo "$f attempt $attempt: unprocessed=$left" [ "$left" -eq 0 ] && break jq '.UnprocessedItems' resp.json > pending.json sleep 2 done done

    確認所有 50 個項目都存在。

    aws dynamodb scan --table-name Products --select COUNT --query 'Count'
    ItemCount 更新延遲

    向量索引DescribeTable報告的 ItemCountIndexSizeBytes值大約每六小時更新一次,因此0即使寫入了每個項目,它們在載入後立即仍然可以讀取。使用 Scan搭配 來驗證負載--select COUNT,如下所示。請勿將零ItemCount視為失敗的載入。

  8. 產生查詢內嵌和搜尋。使用您用於存放項目的相同模型和維度計數嵌入搜尋片語。

    aws bedrock-runtime invoke-model \ --model-id amazon.titan-embed-text-v2:0 \ --body '{"inputText":"How can I make my desk more comfortable to work at","dimensions":1024,"normalize":true}' \ --cli-binary-format raw-in-base64-out \ --content-type application/json \ --accept application/json \ embedding-query.json
    SearchVector 格式與預存向量格式不同

    當您將向量存放在項目屬性中時,您可以將其包裝為 L(清單) 類型:{"L":[{"N":"0.123"},...]}。當您將查詢向量傳遞至 時SearchVectors,您會使用不含L包裝函式的純N值陣列:[{"N":"0.123"},...]。基於此原因,下列jq轉換與您用於存放項目的轉換不同。如需詳細資訊,請參閱基本搜尋

    jq '[.embedding[]|{"N":(.|tostring)}]' embedding-query.json > query-vector.json aws dynamodb search-vectors \ --table-name Products \ --index-name DescriptionIndex \ --search-vector file://query-vector.json \ --top-k 5 \ --projection-expression "ProductId, Title" \ --return-consumed-capacity TOTAL

    查詢向量和預存向量必須來自相同的內嵌模型,且必須具有相同數量的維度。使用不同的模型或維度計數會產生無意義的結果或驗證錯誤。

  9. 讀取結果。DynamoDB 會傳回依相似性排序的結果,最相似的項目優先。每個結果都包含投影屬性ItemScore

    { "SearchResults": [ { "Item": { "ProductId": { "S": "p11" }, "Title": { "S": "Ergonomic Mesh Office Chair" } }, "Score": 0.6130197048187256 }, { "Item": { "ProductId": { "S": "p12" }, "Title": { "S": "Sit Stand Desk Converter" } }, "Score": 0.781868577003479 }, { "Item": { "ProductId": { "S": "p14" }, "Title": { "S": "Under Desk Footrest" } }, "Score": 0.816369354724884 }, { "Item": { "ProductId": { "S": "p13" }, "Title": { "S": "Monitor Arm Mount" } }, "Score": 0.8283305168151855 }, { "Item": { "ProductId": { "S": "p15" }, "Title": { "S": "Wireless Split Keyboard" } }, "Score": 0.8469693064689636 } ], "ConsumedCapacity": { "VectorSearchRequestBytes": 31449.0 } }

    分數取決於內嵌模型和確切的輸入文字,因此您的值會略有不同。重要的是已選取哪些項目,以及依何種順序選取。查詢不包含單字組、監視器或鍵盤,但搜尋會在目錄中的其他 45 個項目前面傳回所有五個桌面和辦公室產品。不會顯示來自咖啡、營地或寵物群組的任何內容。

    嘗試其他查詢,以查看不同群組的相同行為。使用 重複上一個步驟,"Something to brew fresh coffee at home"而最上方的結果是濃縮咖啡製作器、傾倒在滴水器上,以及鮮奶。使用 重複此動作"Keeping my dog safe on walks",而繫結和固定帶會先出現,接著是僅鬆散相關的項目,因為目錄只包含兩個緊密相符的產品。最後一個案例值得注意:搜尋一律會傳回您請求的項目數量,即使目錄不包含這麼多的良好相符項目。使用 Score值,而不是結果計數來判斷相符品質。

    如何讀取分數取決於索引使用的距離函數:

    • COSINE 和 會EUCLIDEAN傳回分數最低的項目,因此較低的 比較相似。餘弦分數的範圍從相同方向的 0 到相反方向的 2。

    • DOT_PRODUCT 會傳回分數最高的項目,因此較高的值更相似。

    此索引使用 COSINE,因此第一個結果的分數最低。使用與預存描述相同的文字搜尋,會先傳回分數為零或接近零的項目。

清除

若要避免持續收費,請刪除您在本教學課程中建立的資源。只要索引存在,無論您是否對其執行搜尋,向量索引儲存都會計費。

若要刪除向量索引,但保留Products資料表及其項目,請使用 UpdateTable。這些項目會保留在資料表中,而且只會移除索引。

aws dynamodb update-table \ --table-name Products \ --vector-index-updates \ "[ {\"Delete\": {\"IndexName\": \"DescriptionIndex\"}} ]"

若要同時刪除資料表及其向量索引,請刪除資料表。

aws dynamodb delete-table --table-name Products

確認資料表已移除。下列命令會在ResourceNotFoundException刪除完成後傳回 。

aws dynamodb describe-table --table-name Products

如需從您要保留的資料表中移除向量索引的詳細資訊,請參閱 刪除向量索引

後續步驟

完成此基本向量搜尋後,請探索這些相關主題。