Azure AI Search - Vector Store
Azure AI Search - Vector Store (Passthrough API)
Azure AI Search API를 네이티브 형식 그대로 사용해 개발자가 벡터 스토어를 생성하고 검색할 수 있게 하되, Azure AI 자격 증명은 노출하지 않게 해요. 이 기능은 Proxy 전용이에요.
출처: 문서
본문
관리자 흐름 (Admin Flow)
1. LiteLLM에 벡터 스토어 추가
LiteLLM에 벡터 스토어 자격 증명을 추가해요.
model_list:
- model_name: embedding-model
litellm_params:
model: openai/text-embedding-3-large
vector_store_registry:
- vector_store_name: "azure-ai-search"
litellm_params:
vector_store_id: "can-be-anything" # vector store id can be anything for the purpose of passthrough api
custom_llm_provider: "azure_ai"
api_key: os.environ/AZURE_SEARCH_API_KEY
api_base: https://azure-kb-search.search.windows.net
litellm_embedding_model: "azure/text-embedding-3-large"
litellm_embedding_config:
api_base: https://krris-mh44uf7y-eastus2.cognitiveservices.azure.com/
api_key: os.environ/AZURE_API_KEY
api_version: "2025-09-01"
general_settings:
database_url: "postgresql://user:***@host:port/database"
master_key: "sk-<your-litellm-master-key>"
2. Proxy 시작
litellm --config /path/to/config.yaml
# RUNNING on http://0.0.0.0:4000
3. 가상 인덱스 생성
이는 개발자가 벡터 스토어를 생성하고 검색할 때 사용하는 가상 인덱스예요.
curl -L -X POST 'http://0.0.0.0:4000/v1/indexes' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ***" \
-d '{
"index_name": "dall-e-4",
"litellm_params": {
"vector_store_index": "real-index-name-2",
"vector_store_name": "azure-ai-search"
}
}'
4. 벡터 스토어 권한으로 키 생성
키에 가상 인덱스와 임베딩 모델에 대한 접근 권한을 부여해요.
curl -L -X POST 'http://0.0.0.0:4000/key/generate' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer ***" \
-d '{
"allowed_vector_store_indexes": [{"index_name": "dall-e-4", "index_permissions": ["write", "read"]}],
"models": ["embedding-model"]
}'
{ "key": "sk-…" }
개발자 흐름 (Developer Flow)
1. 문서 몇 개로 벡터 스토어 생성
참고: passthrough API에 Azure의
azure_ai공급자를 사용하려면/azure_ai엔드포인트를 사용해요.
import requests
import json
# ----------------------------
# 🔐 CONFIGURATION
# ----------------------------
# Azure OpenAI (for embeddings)
AZURE_OPENAI_ENDPOINT = "http://0.0.0.0:4000"
AZURE_OPENAI_KEY = "sk-…"
EMBEDDING_DEPLOYMENT_NAME = "embedding-model"
# Azure AI Search
AZURE_AI_SEARCH_ENDPOINT = "http://0.0.0.0:4000/azure_ai" # IMPORTANT: Use the '/azure_ai' endpoint for the passthrough api to Azure
SEARCH_API_KEY = "sk-…"
INDEX_NAME = "dall-e-4"
# Vector dimensions (text-embedding-3-large uses 3072 dimensions)
VECTOR_DIMENSIONS = 3072
# Example docs (replace with your own)
documents = [
{"id": "1", "content": "Refunds must be requested within 30 days."},
{"id": "2", "content": "We offer 24/7 support for all enterprise customers."},
]
def delete_index_if_exists():
"""Delete the index if it exists"""
index_url = f"{AZURE_AI_SEARCH_ENDPOINT}/indexes/{INDEX_NAME}?api-version=2024-07-01"
headers = {"api-key": SEARCH_API_KEY}
response = requests.delete(index_url, headers=headers)
if response.status_code == 204:
print(f"Deleted existing index '{INDEX_NAME}'")
return True
elif response.status_code == 404:
print(f"Index '{INDEX_NAME}' does not exist yet")
return False
else:
print(f"Delete response: {response.status_code}")
return False
def create_index():
"""Create the Azure AI Search index with proper schema"""
index_url = f"{AZURE_AI_SEARCH_ENDPOINT}/indexes/{INDEX_NAME}?api-version=2024-07-01"
headers = {"Content-Type": "application/json", "api-key": SEARCH_API_KEY}
index_schema = {
"name": INDEX_NAME,
"fields": [
{"name": "id", "type": "Edm.String", "key": True, "filterable": True},
{"name": "content", "type": "Edm.String", "searchable": True, "filterable": False},
{
"name": "contentVector",
"type": "Collection(Edm.Single)",
"searchable": True,
"dimensions": VECTOR_DIMENSIONS,
"vectorSearchProfile": "my-vector-profile",
},
],
"vectorSearch": {
"algorithms": [{"name": "my-vector-profile", "kind": "hnsw", "hnswParameters": {}}],
},
}
response = requests.put(index_url, headers=headers, json=index_schema)
...
2. 쿼리 임베딩 생성 및 벡터 검색
import requests
import json
# ----------------------------
# 🔐 CONFIGURATION
# ----------------------------
AZURE_OPENAI_ENDPOINT = "http://0.0.0.0:4000"
AZURE_OPENAI_KEY = "sk-…"
EMBEDDING_DEPLOYMENT_NAME = "embedding-model"
AZURE_AI_SEARCH_ENDPOINT = "http://0.0.0.0:4000/azure_ai"
SEARCH_API_KEY = "sk-…"
INDEX_NAME = "dall-e-4"
def get_embedding(text: str):
"""Generate embedding for the query text"""
url = f"{AZURE_OPENAI_ENDPOINT}/openai/deployments/{EMBEDDING_DEPLOYMENT_NAME}/embeddings?api-version=2024-10-21"
headers = {"Content-Type": "application/json", "api-key": AZURE_OPENAI_KEY}
payload = {"input": text}
response = requests.post(url, headers=headers, json=payload)
if response.status_code != 200:
raise Exception(f"Embedding failed: {response.status_code}\n{response.text}")
return response.json()["data"][0]["embedding"]
def search_knowledge_base(query: str, top_k: int = 3):
"""Search the knowledge base using vector similarity.
Args:
query: The search query string
top_k: Number of top results to return (default: 3)
Returns:
List of search results with content and scores
"""
print(f"Searching for: '{query}'")
# Step 1: Generate embedding for the query
query_vector = get_embedding(query)
# Step 2: Perform vector search
search_url = f"{AZURE_AI_SEARCH_ENDPOINT}/indexes/{INDEX_NAME}/docs/search?api-version=2024-07-01"
headers = {"Content-Type": "application/json", "api-key": SEARCH_API_KEY}
search_payload = {
"search": "*", # Get all documents
"vectorQueries": [
{
"vector": query_vector,
"fields": "contentVector",
"kind": "vector",
"k": top_k, # Number of nearest neighbors to return
}
],
"select": "id,content", # Fields to return
"top": top_k,
}
...