快速入门

最近更新时间:2026-04-01 15:41:32

我的收藏

相关资源

对象存储的 Go SDK 源码下载地址:Go SDK
演示示例 Demo 可以在源码的 example/vector 中找到,下载地址:Go SDK Demo
SDK 更新日志请参见 ChangeLog

环境配置与准备

COS Vector Bucket 向量桶服务和原 COS 服务共用 Go SDK,Go SDK 的环境配置和安装方式见 Go SDK 快速入门。推荐使用 Go 1.14 及以上版本。

初始化向量桶服务

下面为您介绍如何使用 COS Go SDK 初始化向量桶客户端后完成一个基础操作,例如创建向量存储桶、查询向量存储桶列表、创建向量桶索引、查询向量桶索引列表、写入向量、查询向量等。

初始化 COS Vectors Client

注意:
建议用户使用子账号密钥 + 环境变量的方式调用 SDK,提高 SDK 使用的安全性。为子账号授权时,请遵循 最小权限指引原则,防止泄露目标存储桶或对象之外的资源。
一般而言,建议使用临时密钥访问向量桶服务,如果您一定要使用永久密钥,建议遵循对永久密钥的权限范围进行限制。
下面介绍 Go SDK Client 的初始化方式。与普通 COS 存储桶不同,向量桶服务需要通过专用的辅助函数生成向量专属的 URL,并传递给 Client 初始化。
说明:
正常情况下,全局只需要生成一个 Cos Client 实例,然后循环进行桶、索引、向量等操作,不建议每次访问都生成新的实例,以复用底层的连接池。
COS Vectors Client 初始化(使用永久密钥)
COS Vectors Client 临时密钥初始化(建议)
说明:
目前提供了三种 URL 生成方式:
1. NewVectorURL:通过地域名生成公网 URL(例如:https://vectors.ap-guangzhou.coslake.com
2. NewVectorInternalURL:通过地域名生成内网 URL(例如:https://vectors.ap-guangzhou.internal.tencentcos.com
3. NewVectorEndpointURL:直接通过自定义的完整 Endpoint 生成 URL

package main

import (
"net/http"
"os"

cos "github.com/tencentyun/cos-go-sdk-v5"
)

func main() {
// 方式一:通过地域名生成公网 URL (推荐)
// 第二个参数控制是否使用 HTTPS,建议为 true
vectorURL, _ := cos.NewVectorURL("ap-guangzhou", true)
// 方式二:通过地域名生成内网 URL (适用于同地域云服务器内网访问)
// vectorURL, _ := cos.NewVectorInternalURL("ap-guangzhou", true)
// 方式三:直接使用自定义的 Endpoint
// vectorURL, _ := cos.NewVectorEndpointURL("https://vectors.ap-guangzhou.coslake.com")

// 用户的 SecretId 和 SecretKey,建议使用子账号密钥,授权遵循最小权限指引。
secretID := os.Getenv("COS_VECTORS_SECRET_ID")
secretKey := os.Getenv("COS_VECTORS_SECRET_KEY")

// 初始化 Client,设置 VectorURL 及鉴权
_ = cos.NewClient(&cos.BaseURL{VectorURL: vectorURL}, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: secretID,
SecretKey: secretKey,
},
})
// 后续所有向量相关的操作均通过 client.Vector 进行访问
}
说明:
关于临时密钥如何生成和使用,请参见 临时密钥生成及使用指引

package main

import (
"net/http"
"os"

cos "github.com/tencentyun/cos-go-sdk-v5"
)

func main() {
vectorURL, _ := cos.NewVectorURL("ap-guangzhou", true)
// 临时密钥生成和使用指引参见 https://cloud.tencent.com/document/product/436/14048
secretID := os.Getenv("COS_VECTORS_TMP_SECRET_ID")
secretKey := os.Getenv("COS_VECTORS_TMP_SECRET_KEY")
sessionToken := os.Getenv("COS_VECTORS_SESSION_TOKEN")

_ = cos.NewClient(&cos.BaseURL{VectorURL: vectorURL}, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: secretID,
SecretKey: secretKey,
SessionToken: sessionToken, // 必须设置 SessionToken 以使用临时凭证
},
})
// 后续所有向量相关的操作均通过 client.Vector 进行访问
}

访问向量桶服务

向量桶相关操作
向量索引相关操作
向量相关操作
向量桶策略相关操作

package main

import (
"context"
"fmt"
"net/http"
"os"
"time"

cos "github.com/tencentyun/cos-go-sdk-v5"
)

func main() {
vectorURL, _ := cos.NewVectorURL("ap-guangzhou", true)
client := cos.NewClient(&cos.BaseURL{VectorURL: vectorURL}, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_VECTORS_SECRET_ID"),
SecretKey: os.Getenv("COS_VECTORS_SECRET_KEY"),
},
})

bucketName := "examplebucket-1250000000" // 替换为您的向量桶名称

// ==================== 列出向量桶 ====================
fmt.Println("==================== 列出向量桶 ====================")
listRes, _, err := client.Vector.ListVectorBuckets(context.Background(), &cos.ListVectorBucketsOptions{})
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("向量桶总数: %d\\n", len(listRes.VectorBuckets))
if listRes.NextToken != "" {
fmt.Printf("下一页标记: %s\\n", listRes.NextToken)
}
for i, b := range listRes.VectorBuckets {
fmt.Printf(" [%d] 桶名称: %s\\n", i+1, b.VectorBucketName)
fmt.Printf(" 资源QCS: %s\\n", b.VectorBucketQcs)
fmt.Printf(" 创建时间: %s\\n", time.Unix(b.CreationTime, 0).Format("2006-01-02 15:04:05"))
}

// ==================== 创建向量桶 ====================
fmt.Println("\\n==================== 创建向量桶 ====================")
createOpt := &cos.CreateVectorBucketOptions{
VectorBucketName: bucketName,
}
createRes, _, err := client.Vector.CreateVectorBucket(context.Background(), createOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("创建成功!\\n")
fmt.Printf(" 资源QCS: %s\\n", createRes.VectorBucketQcs)

// ==================== 获取向量桶 ====================
fmt.Println("\\n==================== 获取向量桶详情 ====================")
getOpt := &cos.GetVectorBucketOptions{
VectorBucketName: bucketName,
}
getRes, _, err := client.Vector.GetVectorBucket(context.Background(), getOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
if getRes.VectorBucket != nil {
vb := getRes.VectorBucket
fmt.Printf(" 桶名称: %s\\n", vb.VectorBucketName)
fmt.Printf(" 资源QCS: %s\\n", vb.VectorBucketQcs)
fmt.Printf(" 创建时间: %s\\n", time.Unix(vb.CreationTime, 0).Format("2006-01-02 15:04:05"))
if vb.EncryptionConfiguration != nil {
fmt.Printf(" 加密类型: %s\\n", vb.EncryptionConfiguration.SseType)
}
}

// ==================== 删除向量桶 ====================
fmt.Println("\\n==================== 删除向量桶 ====================")
delOpt := &cos.DeleteVectorBucketOptions{
VectorBucketName: bucketName,
}
_, err = client.Vector.DeleteVectorBucket(context.Background(), delOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("向量桶 %s 删除成功!\\n", bucketName)
}

package main

import (
"context"
"fmt"
"net/http"
"os"
"strings"
"time"

cos "github.com/tencentyun/cos-go-sdk-v5"
)

func main() {
vectorURL, _ := cos.NewVectorURL("ap-guangzhou", true)
client := cos.NewClient(&cos.BaseURL{VectorURL: vectorURL}, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_VECTORS_SECRET_ID"),
SecretKey: os.Getenv("COS_VECTORS_SECRET_KEY"),
},
})

bucketName := "examplebucket-1250000000"
indexName := "idx-dim3"

// ==================== 列出向量索引 ====================
fmt.Println("==================== 列出向量索引 ====================")
listIdxOpt := &cos.ListIndexesOptions{
VectorBucketName: bucketName,
}
listIdxRes, _, err := client.Vector.ListIndexes(context.Background(), listIdxOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("索引总数: %d\\n", len(listIdxRes.Indexes))
if listIdxRes.NextToken != "" {
fmt.Printf("下一页标记: %s\\n", listIdxRes.NextToken)
}
for i, idx := range listIdxRes.Indexes {
fmt.Printf(" [%d] 索引名称: %s\\n", i+1, idx.IndexName)
fmt.Printf(" 所属桶: %s\\n", idx.VectorBucketName)
fmt.Printf(" 资源QCS: %s\\n", idx.IndexQcs)
fmt.Printf(" 创建时间: %s\\n", time.Unix(idx.CreationTime, 0).Format("2006-01-02 15:04:05"))
}

// ==================== 创建向量索引 ====================
fmt.Println("\\n==================== 创建向量索引 ====================")
createIdxOpt := &cos.CreateIndexOptions{
VectorBucketName: bucketName,
IndexName: indexName,
DataType: "float32",
Dimension: 3,
DistanceMetric: "euclidean",
}
createIdxRes, _, err := client.Vector.CreateIndex(context.Background(), createIdxOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("索引创建成功!\\n")
fmt.Printf(" 资源QCS: %s\\n", createIdxRes.IndexQcs)

// ==================== 获取向量索引详情 ====================
fmt.Println("\\n==================== 获取向量索引详情 ====================")
getIdxOpt := &cos.GetIndexOptions{
VectorBucketName: bucketName,
IndexName: indexName,
}
getIdxRes, _, err := client.Vector.GetIndex(context.Background(), getIdxOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
if getIdxRes.Index != nil {
idx := getIdxRes.Index
fmt.Printf(" 索引名称: %s\\n", idx.IndexName)
fmt.Printf(" 所属桶: %s\\n", idx.VectorBucketName)
fmt.Printf(" 资源QCS: %s\\n", idx.IndexQcs)
fmt.Printf(" 数据类型: %s\\n", idx.DataType)
fmt.Printf(" 向量维度: %d\\n", idx.Dimension)
fmt.Printf(" 距离度量: %s\\n", idx.DistanceMetric)
fmt.Printf(" 创建时间: %s\\n", time.Unix(idx.CreationTime, 0).Format("2006-01-02 15:04:05"))
if idx.MetadataConfiguration != nil && len(idx.MetadataConfiguration.NonFilterableMetadataKeys) > 0 {
fmt.Printf(" 不可过滤键: %s\\n", strings.Join(idx.MetadataConfiguration.NonFilterableMetadataKeys, ", "))
}
}

// ==================== 删除向量索引 ====================
fmt.Println("\\n==================== 删除向量索引 ====================")
delIdxOpt := &cos.DeleteIndexOptions{
VectorBucketName: bucketName,
IndexName: indexName,
}
_, err = client.Vector.DeleteIndex(context.Background(), delIdxOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("索引 %s 删除成功!\\n", indexName)
}
package main

import (
"context"
"fmt"
"net/http"
"os"

cos "github.com/tencentyun/cos-go-sdk-v5"
)

func main() {
vectorURL, _ := cos.NewVectorURL("ap-guangzhou", true)
client := cos.NewClient(&cos.BaseURL{VectorURL: vectorURL}, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_VECTORS_SECRET_ID"),
SecretKey: os.Getenv("COS_VECTORS_SECRET_KEY"),
},
})

bucketName := "examplebucket-1250000000"
indexName := "idx-dim3"

// 存储桶中已创建 Index 向量索引

// ==================== 插入向量 ====================
fmt.Println("==================== 插入向量 ====================")
putVecOpt := &cos.PutVectorsOptions{
VectorBucketName: bucketName,
IndexName: indexName,
}
vectors := []cos.InputVector{
{
Key: "vector1",
Data: &cos.VectorData{
Float32: []float32{0.1, 0.2, 0.3},
},
Metadata: map[string]interface{}{
"key1": "value1",
"key2": "value2",
},
},
{
Key: "vector2",
Data: &cos.VectorData{
Float32: []float32{0.4, 0.5, 0.6},
},
Metadata: map[string]interface{}{
"key1": "value1",
"key2": "value2",
},
},
}
_, err := client.Vector.PutVectors(context.Background(), putVecOpt, vectors)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("成功插入 %d 条向量数据\\n", len(vectors))

// ==================== 获取向量 ====================
fmt.Println("\\n==================== 获取向量 ====================")
getVecOpt := &cos.GetVectorsOptions{
VectorBucketName: bucketName,
IndexName: indexName,
ReturnData: cos.Bool(true),
ReturnMetadata: cos.Bool(true),
}
keys := []string{"vector1", "vector2"}
getVecRes, _, err := client.Vector.GetVectors(context.Background(), getVecOpt, keys)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("获取到 %d 条向量:\\n", len(getVecRes.Vectors))
for i, v := range getVecRes.Vectors {
fmt.Printf(" [%d] 主键: %s\\n", i+1, v.Key)
if v.Data != nil && len(v.Data.Float32) > 0 {
fmt.Printf(" 向量数据: %v\\n", v.Data.Float32)
}
if len(v.Metadata) > 0 {
fmt.Printf(" 元数据:\\n")
for mk, mv := range v.Metadata {
fmt.Printf(" %s = %v\\n", mk, mv)
}
}
}

// ==================== 相似度搜索 ====================
fmt.Println("\\n==================== 相似度搜索 ====================")
queryOpt := &cos.QueryVectorsOptions{
VectorBucketName: bucketName,
IndexName: indexName,
ReturnData: cos.Bool(true),
ReturnMetadata: cos.Bool(true),
}
queryVec := &cos.VectorData{
Float32: []float32{0.1, 0.2, 0.3},
}
topK := 10
queryRes, _, err := client.Vector.QueryVectors(context.Background(), queryOpt, queryVec, topK)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("搜索到 %d 条相似向量 (TopK=%d):\\n", len(queryRes.Vectors), topK)
for i, v := range queryRes.Vectors {
fmt.Printf(" [%d] 主键: %s, 距离: %f\\n", i+1, v.Key, v.Distance)
if v.Data != nil && len(v.Data.Float32) > 0 {
fmt.Printf(" 向量数据: %v\\n", v.Data.Float32)
}
if len(v.Metadata) > 0 {
fmt.Printf(" 元数据:\\n")
for mk, mv := range v.Metadata {
fmt.Printf(" %s = %v\\n", mk, mv)
}
}
}

// ==================== 列出向量 ====================
fmt.Println("\\n==================== 列出向量 ====================")
listVecOpt := &cos.ListVectorsOptions{
VectorBucketName: bucketName,
IndexName: indexName,
MaxResults: 10,
}
listVecRes, _, err := client.Vector.ListVectors(context.Background(), listVecOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("列出 %d 条向量:\\n", len(listVecRes.Vectors))
if listVecRes.NextToken != "" {
fmt.Printf("下一页标记: %s\\n", listVecRes.NextToken)
}
for i, v := range listVecRes.Vectors {
fmt.Printf(" [%d] 主键: %s\\n", i+1, v.Key)
}

// ==================== 删除向量 ====================
fmt.Println("\\n==================== 删除向量 ====================")
delVecOpt := &cos.DeleteVectorsOptions{
VectorBucketName: bucketName,
IndexName: indexName,
}
_, err = client.Vector.DeleteVectors(context.Background(), delVecOpt, keys)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("成功删除 %d 条向量\\n", len(keys))
}

package main

import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"os"

cos "github.com/tencentyun/cos-go-sdk-v5"
)

func main() {
vectorURL, _ := cos.NewVectorURL("ap-guangzhou", true)
client := cos.NewClient(&cos.BaseURL{VectorURL: vectorURL}, &http.Client{
Transport: &cos.AuthorizationTransport{
SecretID: os.Getenv("COS_VECTORS_SECRET_ID"),
SecretKey: os.Getenv("COS_VECTORS_SECRET_KEY"),
},
})

bucketName := "examplebucket-1250000000"

// ==================== 配置向量桶策略 ====================
fmt.Println("==================== 配置向量桶策略 ====================")
// 构造策略 JSON 字符串,各字段含义:
// - Version: 策略版本,固定为 "2.0"
// - Effect: 授权效果,"Allow" 表示允许
// - Principal: 被授权的主体,格式为 qcs::cam::uin/<主账号UIN>:uin/<子账号UIN>
// - Action: 允许的操作列表,此处授予查看向量桶和列出向量的权限
// - Resource: 授权的资源范围,格式为 qcs::cosvector:<region>:uid/<APPID>:bucket/<桶名>/*
policy := `{
"Version": "2.0",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"qcs": [
"qcs::cam::uin/700000000000:uin/700001234567"
]
},
"Action": [
"name/cos:GetVectorBucket",
"name/cos:ListVectors"
],
"Resource": [
"qcs::cosvector:ap-guangzhou:uid/1250000000:bucket/examplebucket-1250000000/*"
]
}
]
}`
putPolOpt := &cos.PutVectorBucketPolicyOptions{
VectorBucketName: bucketName,
Policy: policy,
}
_, err := client.Vector.PutVectorBucketPolicy(context.Background(), putPolOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("策略配置成功! 目标桶: %s\\n", bucketName)

// ==================== 查看向量桶策略 ====================
fmt.Println("\\n==================== 查看向量桶策略 ====================")
getPolOpt := &cos.GetVectorBucketPolicyOptions{
VectorBucketName: bucketName,
}
getPolRes, _, err := client.Vector.GetVectorBucketPolicy(context.Background(), getPolOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
// 将策略 JSON 字符串格式化输出
var prettyJSON bytes.Buffer
if err := json.Indent(&prettyJSON, []byte(getPolRes.Policy), " ", " "); err == nil {
fmt.Printf(" 当前策略:\\n %s\\n", prettyJSON.String())
} else {
fmt.Printf(" 当前策略: %s\\n", getPolRes.Policy)
}

// ==================== 删除向量桶策略 ====================
fmt.Println("\\n==================== 删除向量桶策略 ====================")
delPolOpt := &cos.DeleteVectorBucketPolicyOptions{
VectorBucketName: bucketName,
}
_, err = client.Vector.DeleteVectorBucketPolicy(context.Background(), delPolOpt)
if err != nil {
if vecErr, ok := cos.IsVectorError(err); ok {
fmt.Printf("向量服务错误 [%s]: %s (RequestID: %s)\\n", vecErr.Code, vecErr.Message, vecErr.RequestID)
} else {
fmt.Printf("请求失败: %v\\n", err)
}
return
}
fmt.Printf("桶 %s 的策略删除成功!\\n", bucketName)
}