構建向量與原始檔案的映射關係
OSS Vectors 的檢索結果返回的是向量 Key 和 Metadata,而非原始檔案本身。要將檢索結果關聯回原始檔案(如圖片、文檔、視頻),需要在寫入向量時構建映射關係。
根據業務情境不同,可以選擇兩種映射策略:
-
一對一映射:一個檔案對應一個向量,將檔案路徑直接作為 Vector Key。
-
一對多映射:一個檔案產生多個向量(如長文檔切片、OCR 多模態),通過 Metadata 記錄來源。
檢索流程
典型的向量語義檢索流程如下:
-
調用
QueryVectors介面進行向量檢索,返回最相似的 TopK 向量及其 Metadata。 -
從返回結果中擷取 Vector Key 或 Metadata 中的來源欄位(如
source_file)。 -
通過
GetObject從 OSS 通用 Bucket 下載對應的原始檔案,返回給使用者。
使用者搜尋請求 (QueryVectors)
↓
向量檢索 → 返回 TopK 向量 (Key + Metadata)
↓
從 Metadata 擷取來源資訊 (source_file)
↓
從 OSS 通用 Bucket 下載原始檔案 (GetObject)
↓
返回原始檔案給使用者
選擇映射策略
|
映射策略 |
適用情境 |
實現方式 |
|
一對一映射 |
一個檔案對應一個向量(如一張圖片提取一個特徵向量) |
將原始檔案的 Object Key 直接作為 Vector Key |
|
一對多映射 |
一個檔案產生多個向量(如長文檔切片、OCR 多模態處理) |
在 Metadata 中記錄 |
使用 OSS Vectors Embed CLI工具寫入向量時,會自動在 Metadata 中添加 OSSVECTORS-EMBED-SRC-LOCATION 欄位記錄原始檔案路徑,無需手動維護。
情境樣本:OCR 處理流
以下樣本展示了一個原始檔案 invoice_001.jpg 產生兩條向量(映像特徵 + OCR 文本)的一對多映射情境:
|
原始檔案 Key |
衍生資料內容 |
向量類型 |
映射策略 (Metadata) |
|
|
映像特徵 |
Image Vector |
|
|
|
OCR 識別文本 |
Text Vector |
|
通過 CLI 構建映射
oss-vectors-embed CLI 工具在寫入向量時會自動在 Metadata 中記錄原始檔案路徑。安裝方式請參見使用 OSS Vectors Embed CLI 工具寫入和檢索向量資料。
開始前,請確保滿足以下條件:
-
已配置環境變數
OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET和DASHSCOPE_API_KEY。 -
已建立向量 Bucket 和向量索引,且索引維度與所用 Embedding 模型輸出維度一致。
將以下樣本中的預留位置替換為實際值:
|
預留位置 |
說明 |
|
|
阿里雲帳號 ID |
|
|
向量 Bucket 名稱 |
|
|
向量索引名稱 |
一對一映射:使用檔案名稱作為 Vector Key
通過 --filename-as-key 參數,將原始檔案名直接作為 Vector Key。檢索時通過返回的 Vector Key 即可定位原始檔案。
oss-vectors-embed \
--account-id "<your-account-id>" \
--vectors-region cn-hangzhou \
put \
--vector-bucket-name "<your-vector-bucket>" \
--index-name "<your-index>" \
--model-id text-embedding-v4 \
--text /path/to/document.txt \
--filename-as-key
命令返回樣本:
{
"key": "document.txt",
"bucket": "<your-vector-bucket>",
"index": "<your-index>",
"model": "text-embedding-v4",
"contentType": "text",
"embeddingDimensions": 1024,
"metadata": {
"OSSVECTORS-EMBED-SRC-LOCATION": "document.txt",
"OSSVECTORS-EMBED-SRC-CONTENT-TYPE": "TEXT",
"OSSVECTORS-EMBED-SRC-CONTENT": "檔案內容..."
}
}
CLI 自動在 Metadata 中添加 OSSVECTORS-EMBED-SRC-LOCATION 欄位記錄原始檔案路徑,無需手動維護映射。
一對多映射:通過自訂 Metadata 關聯
當一個原始檔案產生多個向量時(如長文檔切片),通過 --metadata 參數附加來源資訊,將多個向量關聯回同一原始檔案。
oss-vectors-embed \
--account-id "<your-account-id>" \
--vectors-region cn-hangzhou \
put \
--vector-bucket-name "<your-vector-bucket>" \
--index-name "<your-index>" \
--model-id text-embedding-v4 \
--text /path/to/chunk_3.txt \
--filename-as-key \
--metadata '{"source_file": "manuals/guide.pdf", "chunk_id": "3"}'
命令返回樣本:
{
"key": "chunk_3.txt",
"bucket": "<your-vector-bucket>",
"index": "<your-index>",
"model": "text-embedding-v4",
"contentType": "text",
"embeddingDimensions": 1024,
"metadata": {
"source_file": "manuals/guide.pdf",
"chunk_id": "3",
"OSSVECTORS-EMBED-SRC-LOCATION": "chunk_3.txt",
"OSSVECTORS-EMBED-SRC-CONTENT-TYPE": "TEXT",
"OSSVECTORS-EMBED-SRC-CONTENT": "檔案內容..."
}
}
檢索時通過返回的 Metadata 中的 source_file 欄位定位原始檔案。
通過 SDK 構建映射
調用 PutVectors 介面寫入向量時,在每條向量的 metadata 欄位中注入原始檔案的映射資訊。
SDK 方式需要傳入已產生的向量(如 float32 數組),而非原始文本。從文本出發檢索的情境,建議先通過 Embedding 模型產生向量,或直接使用 CLI 方式。
Python SDK
開始前請安裝 alibabacloud-oss-v2 SDK:
pip install alibabacloud-oss-v2
確保已配置環境變數 OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET。
一對一映射
將原始檔案的 Object Key 直接作為向量 Key,檢索時通過 Vector Key 即可定位原始檔案。
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.vectors as oss_vectors
ACCOUNT_ID = "<your-account-id>"
REGION = "cn-hangzhou"
BUCKET = "<your-vector-bucket>"
INDEX = "<your-index>"
def create_vector_client():
"""建立向量檢索用戶端"""
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
cfg = oss.config.load_default()
cfg.credentials_provider = credentials_provider
cfg.region = REGION
cfg.account_id = ACCOUNT_ID
cfg.use_internal_endpoint = True # 如需通過公網訪問,請將此處設定為False或刪除此行
return oss_vectors.Client(cfg)
client = create_vector_client()
# 將原始檔案路徑直接作為向量 Key,實現 1:1 映射
result = client.put_vectors(oss_vectors.models.PutVectorsRequest(
bucket=BUCKET,
index_name=INDEX,
vectors=[
{
"key": "marketing/poster_01.png", # 直接使用原始檔案路徑
"data": {"float32": [0.12] * 128}, # 向量維度需與索引一致
"metadata": {
"category": "promotion",
}
}
]
))
print(f"寫入結果: status_code={result.status_code}")
運行後輸出:
寫入結果: status_code=200
一對多映射
同一原始檔案產生多條向量(如 OCR 情境),在 Metadata 中記錄來源檔案路徑,檢索時通過 Metadata 反查原始檔案。
import alibabacloud_oss_v2 as oss
import alibabacloud_oss_v2.vectors as oss_vectors
ACCOUNT_ID = "<your-account-id>"
REGION = "cn-hangzhou"
BUCKET = "<your-vector-bucket>"
INDEX = "<your-index>"
def create_vector_client():
"""建立向量檢索用戶端"""
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
cfg = oss.config.load_default()
cfg.credentials_provider = credentials_provider
cfg.region = REGION
cfg.account_id = ACCOUNT_ID
cfg.use_internal_endpoint = True # 如需通過公網訪問,請將此處設定為False或刪除此行
return oss_vectors.Client(cfg)
client = create_vector_client()
# 同一原始檔案 invoice_001.jpg 產生兩條向量(映像特徵 + OCR 文本)
result = client.put_vectors(oss_vectors.models.PutVectorsRequest(
bucket=BUCKET,
index_name=INDEX,
vectors=[
{
"key": "vec_ocr_text_001",
"data": {"float32": [0.05] * 128}, # 向量維度需與索引一致
"metadata": {
"source_file": "invoice_001.jpg",
"ocr_text_file": "invoice_001.txt",
"type": "text",
}
},
{
"key": "vec_ocr_image_001",
"data": {"float32": [0.08] * 128}, # 向量維度需與索引一致
"metadata": {
"source_file": "invoice_001.jpg",
"type": "image",
}
}
]
))
print(f"寫入結果: status_code={result.status_code}")
# 檢索並通過 Metadata 反查原始檔案
query_result = client.query_vectors(oss_vectors.models.QueryVectorsRequest(
bucket=BUCKET,
index_name=INDEX,
query_vector={"float32": [0.05] * 128}, # 向量維度需與索引一致
return_metadata=True,
return_distance=True,
top_k=5,
))
print(f"查詢結果: status_code={query_result.status_code}")
if query_result.vectors:
for v in query_result.vectors:
key = v.get("key")
metadata = v.get("metadata", {})
source = metadata.get("source_file", key) # 優先從 metadata 擷取來源
print(f" 向量 Key: {key}, 來源檔案: {source}, 類型: {metadata.get('type', 'unknown')}")
運行後輸出:
寫入結果: status_code=200
查詢結果: status_code=200
向量 Key: vec_ocr_text_001, 來源檔案: invoice_001.jpg, 類型: text
向量 Key: vec_ocr_image_001, 來源檔案: invoice_001.jpg, 類型: image
...
Go SDK
開始前請安裝 alibabacloud-oss-go-sdk-v2 SDK:
go get github.com/aliyun/alibabacloud-oss-go-sdk-v2
確保已配置環境變數 OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET。
package main
import (
"context"
"fmt"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/vectors"
)
const (
region = "cn-hangzhou"
bucketName = "<your-vector-bucket>"
accountId = "<your-account-id>"
indexName = "<your-index>"
)
func main() {
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region).
WithAccountId(accountId).
// 如需通過公網訪問,請將此處設定為false或刪除此行
WithUseInternalEndpoint(true)
client := vectors.NewVectorsClient(cfg)
// 寫入向量,通過 metadata 關聯原始檔案
result, err := client.PutVectors(context.TODO(), &vectors.PutVectorsRequest{
Bucket: oss.Ptr(bucketName),
IndexName: oss.Ptr(indexName),
Vectors: []map[string]any{
{
"key": "marketing/poster_01.png",
"data": map[string]any{"float32": []float32{0.12, 0.05, 0.88}}, // 向量維度需與索引一致
"metadata": map[string]any{
"source_file": "marketing/poster_01.png",
"category": "promotion",
},
},
},
})
if err != nil {
log.Fatalf("寫入失敗: %v", err)
}
fmt.Printf("寫入結果: status_code=%d\n", result.StatusCode)
// 查詢並通過 metadata 擷取來源檔案
queryResult, err := client.QueryVectors(context.TODO(), &vectors.QueryVectorsRequest{
Bucket: oss.Ptr(bucketName),
IndexName: oss.Ptr(indexName),
QueryVector: map[string]any{"float32": []float32{0.12, 0.05, 0.88}}, // 向量維度需與索引一致
ReturnMetadata: oss.Ptr(true),
ReturnDistance: oss.Ptr(true),
TopK: oss.Ptr(5),
})
if err != nil {
log.Fatalf("查詢失敗: %v", err)
}
fmt.Printf("查詢結果: status_code=%d\n", queryResult.StatusCode)
for _, v := range queryResult.Vectors {
fmt.Printf(" 向量 Key: %v, metadata: %v\n", v["key"], v["metadata"])
}
}
運行後輸出:
寫入結果: status_code=200
查詢結果: status_code=200
向量 Key: marketing/poster_01.png, metadata: map[category:promotion source_file:marketing/poster_01.png]
...
最佳實務
-
Vector Key 設計:若原始檔案和向量為 1:1,首選將原始檔案的 Object Key 作為 Vector Key。若為 1:N(如長文檔切片),建議使用
{ObjectKey}#{ChunkID}格式,既能標識來源又能區分各切片。 -
Metadata 設計:在 Metadata 中至少保留
source_file欄位,方便從檢索結果反查原始檔案。 -
效能考量:避免在 Metadata 中儲存過大的原始文本,僅儲存 Key 或摘要。具體內容通過
GetObject回 OSS 查詢。 -
CLI 自動對應:使用
oss-vectors-embedCLI 寫入時,會自動添加OSSVECTORS-EMBED-SRC-LOCATION欄位記錄來源,無需手動維護。 -
Key 首碼管理:使用 CLI 的
--key-prefix參數為向量 Key 添加統一首碼,便於按業務維度批量管理和清理。