OpenAI
埋め込みモデルを選択し、テキスト埋め込み関数を持つ collection を作成することで、Zilliz Cloud で OpenAI の埋め込みモデルを使用します。
Model choices
Zilliz Cloud は OpenAI が提供するすべての埋め込みモデルをサポートしています。以下は、すぐに参照できるように利用可能な OpenAI 埋め込みモデルをまとめたものです。
| Model Name | Dimensions | Max Tokens | Description |
|---|---|---|---|
| text-embedding-3-small | デフォルト: 1,536(1,536 未満の次元サイズに短縮可能) | 8,191 | コスト重視かつスケーラブルなセマンティック検索に最適。より低価格で高い性能を提供します。 |
| text-embedding-3-large | デフォルト: 3,072(3,072 未満の次元サイズに短縮可能) | 8,191 | より高い検索精度と豊かなセマンティック表現が求められるアプリケーションに最適です。 |
| text-embedding-ada-002 | 固定: 1,536(短縮不可) | 8,191 | 旧世代のモデルで、レガシーパイプラインや後方互換性が必要なシナリオに適しています。 |
第3世代の埋め込みモデル(text-embedding-3)は、dim パラメータによって埋め込みサイズを小さくすることをサポートしています。一般に、埋め込みが大きいほど、計算、メモリ、ストレージの観点でコストが高くなります。次元数を調整できることで、全体的なコストと性能をより細かく制御できます。各モデルの詳細については、Embedding models および OpenAI announcement blog post を参照してください。
Before you start
テキスト埋め込み関数を使用する前に、次の前提条件を満たしていることを確認してください。
-
埋め込みモデルを選択する
使用する埋め込みモデルを決定してください。この選択により、埋め込みの動作と出力形式が決まります。詳細は Choose an embedding model を参照してください。
-
OpenAI と統合し、integration ID を取得する
OpenAI で提供される埋め込みモデルを使用する前に、OpenAI との model provider integration を作成し、integration ID を取得する必要があります。詳細は Integrate with Model Providers を参照してください。
-
互換性のある collection schema を設計する
collection schema には次の項目を含めるよう計画してください。
-
生の入力テキスト用のテキストフィールド(
VARCHAR) -
選択した埋め込みモデルに一致するデータ型と次元を持つ dense vector field
-
-
挿入時および検索時に生テキストを扱う準備をする
テキスト埋め込み関数を有効にすると、生テキストを直接挿入およびクエリできます。埋め込みはシステムによって自動的に生成されます。
Step 1: Create a collection with a text embedding function
Define schema fields
埋め込み関数を使用するには、特定の schema を持つ collection を作成します。この schema には、少なくとも次の 3 つの必須フィールドを含める必要があります。
-
collection 内の各 entity を一意に識別する primary field。
-
埋め込み対象となる生データを格納する
VARCHARfield。 -
テキスト埋め込み関数が
VARCHARfield に対して生成する dense vector embedding を格納するために予約された vector field。
次の例では、テキストデータを保存するための VARCHAR field "document" と、テキスト埋め込み関数によって生成される dense embedding を保存するための vector field "dense" を持つ schema を定義しています。vector dimension(dim)は、選択した埋め込みモデルの出力に合わせて設定してください。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
from pymilvus import MilvusClient, DataType, Function, FunctionType
# Initialize Milvus client
client = MilvusClient(
uri="YOUR_CLUSTER_ENDPOINT",
token="YOUR_CLUSTER_TOKEN"
)
# Create a new schema for the collection
schema = client.create_schema()
# Add primary field "id"
schema.add_field("id", DataType.INT64, is_primary=True, auto_id=False)
# Add scalar field "document" for storing textual data
schema.add_field("document", DataType.VARCHAR, max_length=9000)
# Add vector field "dense" for storing embeddings.
# IMPORTANT: Set dim to match the exact output dimension of the embedding model.
# For instance, OpenAI's text-embedding-3-small model outputs 1536-dimensional vectors.
# For dense vector, data type can be FLOAT_VECTOR or INT8_VECTOR
schema.add_field("dense", DataType.FLOAT_VECTOR, dim=1536)
import io.milvus.v2.common.DataType;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
String CLUSTER_ENDPOINT = "YOUR_CLUSTER_ENDPOINT";
String TOKEN = "YOUR_CLUSTER_TOKEN";
ConnectConfig connectConfig = ConnectConfig.builder()
.uri(CLUSTER_ENDPOINT)
.token(TOKEN)
.build();
MilvusClientV2 client = new MilvusClientV2(connectConfig);
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.autoID(false)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("document")
.dataType(DataType.VarChar)
.maxLength(9000)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("dense")
.dataType(DataType.FloatVector)
.dimension(1536)
.build());
// nodejs
// go
# restful
#include "milvus/MilvusClientV2.h"
auto client = milvus::MilvusClientV2::Create();
milvus::ConnectParam connect_param{"YOUR_CLUSTER_ENDPOINT", "YOUR_CLUSTER_TOKEN"};
auto status = client->Connect(connect_param);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
milvus::CollectionSchemaPtr schema = std::make_shared<milvus::CollectionSchema>();
schema->AddField({"id", milvus::DataType::INT64, "", true, false});
schema->AddField(milvus::FieldSchema("document", milvus::DataType::VARCHAR).WithMaxLength(9000));
schema->AddField(milvus::FieldSchema("dense", milvus::DataType::FLOAT_VECTOR).WithDimension(1536));
Define the text embedding function
テキスト埋め込み関数は、VARCHAR field に保存された生データを自動的に embedding に変換し、明示的に定義された vector field に格納します。
以下の例では、scalar field "document" を embedding に変換し、結果の vector を先ほど定義した "dense" vector field に格納する Function module(openai_embedding)を追加しています。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
# Define embedding function (example: OpenAI provider)
text_embedding_function = Function(
name="openai_embedding", # Unique identifier for this embedding function
function_type=FunctionType.TEXTEMBEDDING, # Type of embedding function
input_field_names=["document"], # Scalar field to embed
output_field_names=["dense"], # Vector field to store embeddings
params={ # Provider-specific configuration (highest priority)
"provider": "openai", # Embedding model provider
"model_name": "text-embedding-3-small", # Embedding model
"integration_id": "YOUR_INTEGRATION_ID", # Integration ID generated in the Zilliz Cloud console for the selected model provider
# "dim": "1536", # Optional: shorten the vector dimension
# "user": "user123" # Optional: identifier for API tracking
}
)
# Add the embedding function to your schema
schema.add_function(text_embedding_function)
import io.milvus.v2.service.collection.request.CreateCollectionReq.Function;
Function function = Function.builder()
.functionType(FunctionType.TEXTEMBEDDING)
.name("openai_embedding")
.inputFieldNames(Collections.singletonList("document"))
.outputFieldNames(Collections.singletonList("dense"))
.param("provider", "openai")
.param("model_name", "text-embedding-3-small")
.param("integration_id", "YOUR_INTEGRATION_ID")
.build();
schema.addFunction(function);
// nodejs
// go
# restful
milvus::FunctionPtr function = std::make_shared<milvus::Function>("openai_embedding", milvus::FunctionType::TEXTEMBEDDING);
function->AddInputFieldName("document");
function->AddOutputFieldName("dense");
function->AddParam("provider", "openai");
function->AddParam("model_name", "text-embedding-3-small");
function->AddParam("integration_id", "YOUR_INTEGRATION_ID");
collection_schema->AddFunction(function);
Configure the index
必要なフィールドと組み込み関数を含む schema を定義した後、collection の index を設定します。このプロセスを簡単にするために、index_type として AUTOINDEX を使用してください。これは、データ構造に基づいて Zilliz Cloud が最適な index type を選択し、設定してくれるオプションです。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
# Prepare index parameters
index_params = client.prepare_index_params()
# Add AUTOINDEX to automatically select optimal indexing method
index_params.add_index(
field_name="dense",
index_type="AUTOINDEX",
metric_type="COSINE"
)
import io.milvus.v2.common.IndexParam;
List<IndexParam> indexes = new ArrayList<>();
indexes.add(IndexParam.builder()
.fieldName("dense")
.indexType(IndexParam.IndexType.AUTOINDEX)
.metricType(IndexParam.MetricType.COSINE)
.build());
// nodejs
// go
# restful
std::vector<milvus::IndexDesc> indexes = {
milvus::IndexDesc("dense", "", milvus::IndexType::AUTOINDEX, milvus::MetricType::COSINE)
}
Create the collection
ここで、定義した schema と index parameters を使用して collection を作成します。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
# Create collection named "demo"
client.create_collection(
collection_name='demo',
schema=schema,
index_params=index_params
)
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("demo")
.collectionSchema(schema)
.indexParams(indexes)
.build();
client.createCollection(requestCreate);
// nodejs
// go
# restful
auto status = client->CreateCollection(milvus::CreateCollectionRequest()
.WithCollectionName("demo")
.WithIndexes(std::move(indexes))
.WithCollectionSchema(schema));
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
Step 2: Insert data
collection と index の設定が完了したら、生データを挿入する準備が整います。このプロセスでは、生テキストだけを提供すれば十分です。先ほど定義した Function module が、各テキストエントリに対応する sparse vector を自動的に生成します。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
# Insert sample documents
client.insert('demo', [
{'id': 1, 'document': 'Milvus simplifies semantic search through embeddings.'},
{'id': 2, 'document': 'Vector embeddings convert text into searchable numeric data.'},
{'id': 3, 'document': 'Semantic search helps users find relevant information quickly.'},
])
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.milvus.v2.service.vector.request.InsertReq;
Gson gson = new Gson();
List<JsonObject> rows = Arrays.asList(
gson.fromJson("{\"id\": 0, \"document\": \"Milvus simplifies semantic search through embeddings.\"}", JsonObject.class),
gson.fromJson("{\"id\": 1, \"document\": \"Vector embeddings convert text into searchable numeric data.\"}", JsonObject.class),
gson.fromJson("{\"id\": 2, \"document\": \"Semantic search helps users find relevant information quickly.\"}", JsonObject.class),
);
client.insert(InsertReq.builder()
.collectionName("demo")
.data(rows)
.build());
// nodejs
// go
# restful
milvus::EntityRows data = {
{{"id", 1}, {"document", "Milvus simplifies semantic search through embeddings."}},
{{"id", 2}, {"document", "Vector embeddings convert text into searchable numeric data."}},
{{"id", 3}, {"document", "Semantic search helps users find relevant information quickly."}}
};
milvus::InsertResponse response;
auto status = client->Insert(milvus::InsertRequest()
.WithCollectionName("demo")
.WithRowsData(std::move(data))
, response);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
Step 3: Search with text
データの挿入後、生のクエリテキストを使用してセマンティック検索を実行します。Milvus はクエリを自動的に embedding vector に変換し、類似度に基づいて関連ドキュメントを取得し、最も一致する結果を返します。
- Python
- Java
- NodeJS
- Go
- cURL
- C++
# Perform semantic search
results = client.search(
collection_name='demo',
data=['How does Milvus handle semantic search?'], # Use text query rather than query vector
anns_field='dense', # Use the vector field that stores embeddings
limit=1,
output_fields=['document'],
)
print(results)
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
import io.milvus.v2.service.vector.response.SearchResp;
SearchResp searchResp = client.search(SearchReq.builder()
.collectionName("demo")
.data(Collections.singletonList(new EmbeddedText("How does Milvus handle semantic search?")))
.limit(1)
.outputFields(Collections.singletonList("document"))
.build());
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
for (SearchResp.SearchResult result : results) {
System.out.println(result);
}
}
// nodejs
// go
# restful
auto request = milvus::SearchRequest()
.WithCollectionName("demo")
.AddEmbeddedText("How does Milvus handle semantic search?")
.WithLimit(1)
.WithAnnsField("dense")
.AddOutputField("document");
milvus::SearchResponse response;
auto status = client->Search(request, response);
if (!status.IsOk()) {
std::cout << status.Message() << std::endl;
}
検索操作およびクエリ操作の詳細については、Basic Vector Search および Query を参照してください。