Migre las demostraciones de vectores de Redis a un índice compartido de Azure AI Search
Mueva la búsqueda vectorial de LangGraph de las demostraciones de Redis a un índice compartido de Azure AI Search: declare el esquema, filtre por sesión, elimine mediante consulta y mantenga a los demás usuarios.
Por qué Redis no fue la opción final
La búsqueda vectorial local de Redis es perfecta para demostraciones en portátiles. Los entornos compartidos, la búsqueda respaldada por SLA y la autenticación nativa de Azure llevan a los equipos hacia Azure AI Search. Esta migración mantiene el pipeline de LangGraph y sustituye el backend vectorial.
Búsqueda de IA tradicional vs este patrón
La búsqueda por palabras clave clásica clasifica según la superposición léxica. La ruta migrada almacena embeddings junto con el texto y realiza búsquedas por similitud semántica, opcionalmente combinada con filtros. Azure AI Search se convierte en el hogar gestionado para esos vectores.
La única decisión que tuvo que cambiar: índice compartido vs índice por sesión
Las demostraciones de Redis suelen crear un índice desechable por sesión. Azure AI Search prefiere un índice compartido con un campo de filtro de sesión (o inquilino). Eliminar todo el índice para “limpiar una sesión” es la herramienta incorrecta; usar la eliminación por filtro es la opción adecuada.
uv add langgraph langchain-core langchain-openai langchain-text-splitters \
azure-ai-documentintelligence azure-core \
langchain-redis redisvl \
python-dotenv
def get_vector_store() -> AzureSearch:
global _vector_store
if _vector_store is None:
_vector_store = AzureSearch(
azure_search_endpoint=config.AZURE_SEARCH_ENDPOINT,
azure_search_key=config.AZURE_SEARCH_API_KEY,
index_name=config.AZURE_SEARCH_INDEX_NAME,
embedding_function=embeddings,
fields=_FIELDS,
vector_search_dimensions=config.EMBEDDING_DIMENSIONS,
)
return _vector_store
_FIELDS = [
SimpleField(name="id", type=SearchFieldDataType.String, key=True, filterable=True),
SearchableField(name="content", type=SearchFieldDataType.String),
SearchField(
name="content_vector",
type="Collection(Edm.Single)",
searchable=True,
vector_search_dimensions=config.EMBEDDING_DIMENSIONS,
vector_search_profile_name="myHnswProfile",
),
SearchableField(name="metadata", type=SearchFieldDataType.String),
SimpleField(name="session_id", type=SearchFieldDataType.String, filterable=True),
SimpleField(name="file_name", type=SearchFieldDataType.String, filterable=True),
SimpleField(name="chunk_index", type=SearchFieldDataType.Int32, filterable=True, sortable=True),
]
state["retrieved"] = vs.similarity_search(
state["query"],
k=config.TOP_K,
filters=f"session_id eq '{state['session_id']}'",
)
def clear_session(session_id: str) -> None:
vs = get_vector_store()
results = vs.client.search(
search_text="*",
filter=f"session_id eq '{session_id}'",
select=["id"],
)
ids = [r["id"] for r in results]
if ids:
vs.delete(ids=ids)
az search service create \
--name "$SEARCH_SERVICE_NAME" \
--resource-group "$RESOURCE_GROUP" \
--location "$LOCATION" \
--sku basic \
--partition-count 1 \
--replica-count 1
SEARCH_ADMIN_KEY=$(az search admin-key show \
--resource-group "$RESOURCE_GROUP" \
--service-name "$SEARCH_SERVICE_NAME" \
--query primaryKey -o tsv)
AZURE_OPENAI_ENDPOINT=https://aif-cus-aisearchegs-dev-01.cognitiveservices.azure.com/
AZURE_OPENAI_API_KEY=<<redacted>>
# AZURE_OPENAI_API_VERSION = os.environ.get("AZURE_OPENAI_API_VERSION", "2024-10-21")
AZURE_OPENAI_EMBEDDING_DEPLOYMENT=text-embedding-3-small
AZURE_OPENAI_CHAT_DEPLOYMENT="gpt-5-mini"
# --- Azure Document Intelligence (used for all file text extraction) ---
DOCUMENTINTELLIGENCE_ENDPOINT=https://adi-cus-aisearchegs-dev-01.cognitiveservices.azure.com/
DOCUMENTINTELLIGENCE_KEY=<<redacted>>
AZURE_SEARCH_ENDPOINT=https://ais-cus-aisearchegs-dev-01.search.windows.net
AZURE_SEARCH_API_KEY=<<redacted>>
AZURE_SEARCH_INDEX_NAME=chat-file-search-index
azure.core.exceptions.HttpResponseError: The vector field 'content_vector'
must have the properties 'dimensions' and 'vectorSearchConfiguration' set.
TypeError: Object of type float32 is not JSON serializable
from azure.search.documents._utils.model_base import SdkJSONEncoder
_original_default = SdkJSONEncoder.default
def _numpy_safe_default(self, o):
if isinstance(o, np.floating):
return float(o)
if isinstance(o, np.integer):
return int(o)
return _original_default(self, o)
SdkJSONEncoder.default = _numpy_safe_default
uv run python -m aisearchmanualvectorization.main \
--session demo1 \
--files ./source/sample_bank_statement.pdf ./source/sample_loan_agreement.pdf
uv run python -m aisearchmanualvectorization.main \
--session demo1 \
--query "What's the overdraft protection fee?"
A: The overdraft protection transfer fee is $10.00 per occurrence.
Sources:
- sample_bank_statement.pdf (chunk 7): Overdraft Protection...
- sample_bank_statement.pdf (chunk 8): Interest Rate & Annual Percentage Yield...
- sample_bank_statement.pdf (chunk 9): Monthly Maintenance Fee...
- sample_bank_statement.pdf (chunk 3): <td>-$10.44</td> <td>$8,096.52</td>...
Paso a paso: qué cambió en el código
get_vector_store() — ya no está limitado a la sesión
Devuelve un cliente vinculado al nombre de un índice compartido. La aislamiento de sesiones se realiza mediante filtros de metadatos, no mediante índices separados.
El esquema de campos: declarado explícitamente
Se definen por adelantado las dimensiones vectoriales, los campos de contenido y los IDs de sesión filtrables. Los valores por defecto que funcionaban en Redis no coincidirán con los tipos de campos de Azure AI Search.
retrieve_node — un filtro de cadena en lugar de un objeto de filtro
Especifique session_id eq '…' (o el filtro OData equivalente) para que los fragmentos de un usuario no se filtren en los resultados de otro.
clear_session() — eliminar mediante consulta, no borrar el índice
Ejecute una eliminación filtrada para la clave de sesión. Recrear índices por sesión superará los límites del servicio y ralentizará los arranques iniciales.
Lista de verificación para la migración
- Alinear la dimensión de incrustación con el campo vectorial del índice
- Volver a incrustar solo si cambió el modelo de incrustación; de lo contrario, volver a insertar los fragmentos existentes
- Ejecutar simultáneamente Redis y Azure AI Search con preguntas de referencia antes del cambio
- Mover los secretos a Key Vault o identidades gestionadas cuando sea posible
- Actualizar los manuales de operaciones: dejar de asumir que “reiniciar docker redis borra el estado”
Resultados y compensaciones
Azure AI Search añade escalabilidad gestionada, herramientas en el portal y control de acceso basado en roles. También introduce un tiempo de preparación adicional y la restricción del diseño de índices compartidos. En el gráfico de Preguntas y Respuestas en PDF, el grafo de nodos se mantuvo estable; solo cambiaron el adaptador de almacenamiento y el ciclo de vida de las sesiones.
Cierre
Considere a Redis como las ruedas de apoyo y a Azure AI Search como los neumáticos principales. Mantenga la isolación de sesiones mediante filtros, declare explícitamente el esquema y elimine los datos mediante consultas. La orquestación de LangGraph debería apenas notar cambios; si lo hace, significa que la abstracción era demasiado permeable.
Consejo para el cambio: mantenga a Redis en modo solo lectura durante una semana mientras Azure AI Search maneja el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de los filtros y los nombres de los campos antes de culpar al modelo de embedding. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas matemáticos relacionados con vectores.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
Consejo para la migración: mantenga Redis en modo solo lectura durante una semana mientras Azure AI Search atiende el tráfico de producción, comparando la superposición de los 3 resultados más relevantes en el conjunto de preguntas de referencia. Si la superposición disminuye, revise las cláusulas de filtro y los nombres de campos antes de culpar al modelo de incrustación. La mayoría de las regresiones en este tipo de migraciones se deben a errores en los filtros, no a problemas en las matemáticas vectoriales.
La disciplina del esquema es importante en dos momentos: una vez al crear el índice de Azure AI Search, y nuevamente cuando se actualiza el modelo de embedding. Las incoherencias en las dimensiones generan errores evidentes; las discrepancias en los campos filtrables se manifiestan de forma silenciosa como conjuntos de resultados vacíos. Añada una afirmación al inicio del proceso que lea la definición del índice y compare las dimensiones vectoriales y los nombres de los campos de sesión con la configuración en ejecución.