Implement vector search by integrating OpenSearch with OpenAI
Learn how to implement vector search by integrating OpenSearch with OpenAI.
- Estimated time: 30 minutes
- Recommended OS: macOS, Ubuntu
- Prerequisites
- Create an Advanced Managed Search cluster
- OpenSearch API access information (master user)
- Create an OpenAI API key
About this scenario
This tutorial integrates Advanced Managed Search with the OpenAI Embedding API to convert text data into vectors and implement semantic search (Vector Search).
Traditional keyword search can fail when words do not match exactly, but vector search can find similar documents based on sentence meaning. This enables AI search scenarios such as FAQ search, document recommendation, knowledge search, and RAG-based question answering.
You will cover the following:
- Vectorize text using the OpenAI Embedding API
- Integrate an external AI model through OpenSearch ML Connector
- Configure a vector index (
knn_vector) and index documents - Implement semantic similarity search (Vector Search)
Before you start
Before starting this tutorial, create an Advanced Managed Search cluster by referring to Create and manage clusters.
All OpenSearch API requests in this tutorial are called against the Advanced Managed Search cluster endpoint.
On the cluster details page, check the Endpoint and master user account information. Then prepend the cluster endpoint to the API path (/...) in each example before running the request.
Example: https://<AMS_ENDPOINT>/_plugins/_ml/connectors/_create
Getting started
Step 1. Create an OpenAI model group
Create a model group to use with the OpenSearch ML plugin.
POST /_plugins/_ml/model_groups/_register
{
"name": "openai",
"description": "OpenAI Model Group"
}
Use the MODEL_GROUP_ID included in the response in Step 3.
Step 2. Create an OpenAI Embedding Connector
Create a Connector that calls the OpenAI Embedding API.
POST /_plugins/_ml/connectors/_create
{
"name": "OpenAI Embedding Connector",
"description": "Connector for OpenAI Embedding API",
"version": 1,
"protocol": "http",
"parameters": {
"endpoint": "api.openai.com",
"model": "text-embedding-ada-002"
},
"credential": {
"OPENAI_API_KEY": "${OPENAI_API_KEY}"
},
"actions": [
{
"action_type": "predict",
"method": "POST",
"url": "https://${parameters.endpoint}/v1/embeddings",
"headers": {
"Authorization": "Bearer ${credential.OPENAI_API_KEY}",
"Content-Type": "application/json"
},
"request_body": "{ \"model\": \"${parameters.model}\", \"input\": ${parameters.input}, \"encoding_format\": \"float\" }",
"pre_process_function": "connector.pre_process.openai.embedding",
"post_process_function": "connector.post_process.openai.embedding"
}
]
}
| 환경변수 | 설명 |
|---|---|
| OPENAI_API_KEY🖌︎ | API key issued by OpenAI |
Use the CONNECTOR_ID included in the response in the next step.
Step 3. Register and deploy the model
POST /_plugins/_ml/models/_register?deploy=true
{
"name": "OpenAI Embedding Model",
"function_name": "remote",
"model_group_id": "${MODEL_GROUP_ID}",
"description": "OpenAI embedding model",
"connector_id": "${CONNECTOR_ID}"
}
| 환경변수 | 설명 |
|---|---|
| MODEL_GROUP_ID🖌︎ | Model Group ID returned in Step 1 |
| CONNECTOR_ID🖌︎ | Connector ID returned in Step 2 |
Use the MODEL_ID included in the response in the next step.
Step 4. Test embedding
POST /_plugins/_ml/models/${MODEL_ID}/_predict
{
"parameters": {
"input": ["Ian is not cool"]
}
}
| 환경변수 | 설명 |
|---|---|
| MODEL_ID🖌︎ | Model ID returned in Step 3 |
Step 5. Create an embedding ingest pipeline
PUT _ingest/pipeline/embedding_pipeline
{
"description": "Convert text to embedding using OpenAI",
"processors": [
{
"text_embedding": {
"field_map": {
"text": "embedding"
},
"model_id": "${MODEL_ID}"
}
}
]
}
| 환경변수 | 설명 |
|---|---|
| MODEL_ID🖌︎ | Model ID returned in Step 3 |
Step 6. Create a vector index
PUT my-index
{
"settings": {
"default_pipeline": "embedding_pipeline",
"index.knn": true
},
"mappings": {
"properties": {
"text": { "type": "text" },
"embedding": {
"type": "knn_vector",
"dimension": 1536
}
}
}
}
Step 7. Index documents
POST my-index/_doc
{ "text": "Ian is cool!" }
POST my-index/_doc
{ "text": "Ian is super cool!" }
POST my-index/_doc
{ "text": "Ian is not cool!" }
Step 8. Run vector search
GET my-index/_search
{
"_source": { "excludes": ["embedding"] },
"query": {
"neural": {
"embedding": {
"query_text": "Ian is cool?",
"model_id": "${MODEL_ID}",
"k": 2
}
}
}
}
| 환경변수 | 설명 |
|---|---|
| MODEL_ID🖌︎ | Model ID returned in Step 3 |
Example result
{
"hits": {
"hits": [
{ "_source": { "text": "Ian is cool!" } },
{ "_source": { "text": "Ian is super cool!" } }
]
}
}
1. Semantic search: In the result above, the documents closest in meaning to the query (Ian is cool?) are returned as the top results. "Ian is not cool!" has a similar word composition, but its meaning is opposite, so it receives a lower similarity score.
2. Role of the K value: Because the query sets k to 2, only the top two documents with the highest similarity are included in the result. Adjust the k value if you want to see more results.