Перакладзіце дэманстрацыі вектарных дадзеных Redis у спяшчаны індэкс Azure AI Search.
Перакладзіце пошук на адрэсах вектараў LangGraph з дэманстрацый Redis у спяльны індэкс Azure AI Search: заявіце схему, фільтруйце па сесіях, выдаліце па запытках, адзінавочыце іншых корыстнікаў.
Чаму Redis не быў канечным выборам
Локальны пошук на адной вектарнай базе дадзеных Redis ідэальна для дэманстрацый на ноутбуках. Аднак спяльныя сераўры, пошук падтрымваны угодамі SLA і аўтэнтыфікацыя, прызначаная для Azure, спрабоўваюць пераканаць команды выбраць Azure AI Search. У такім пераходзе застаёцца пайплайн LangGraph, але змінюецца вектарны бэкенд.
Традыцыйны пошук з AI протыў гэтага падходу
Класычны пошук за ключоўкамі ранжуе дакладнастка лексычнага перакрыцця. У мігрантным падходзе эмбеддынгі зберагаюцца разам з тэкстам, а пошук ведзецца за дапамогою сэмантычнай супадальнасці — за жылезным выборам можна ўжоўважыць фільтры. Azure AI Search стае кераваным рашэнням для такіх вектарных дадзеных.
Едынны рашэнні, якое павінна было змяніцца: спяльны індэкс протыў індэкса на кожную сесію
У дэманстрацыях Redis частаўка за раз выклікае новы індэкс на кожную сесію. Azure AI Search прагтае спяльны індэкс з полем фільтрацыі сесіі (או тэнанта). Адменшэнне цэлага індэксу, каб «зачыстыць сесію», — глыткі спосаб; правы спосаб — выдаленне па фільтрацыі.
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>...
Шаг за шагам: што змянілася ў кодзе
get_vector_store() — больш не ў межах сесіі
Вертае кліента, прыўязанага да назвы спяльнага індэксу. Ізоляція сесій пераходзіць у фільтры метаданых, а не ў окрэмыя індэксы.
Схема поля — прызначаецца явна
Загадзя задаюцца вектарныя выміры, поля зместу і ID сесій, якія можна фільтруваць. Тых паслявыборных значэнняў, якія працавалі ў Redis, больш не будзе ў спосабе полей Azure AI Search.
retrieve_node — фільтр у віглядзе строкі, а не об’екта фільтра
Запісайце session_id eq '…' (або адэкватны фільтр OData), ўбачымач, каб часткі аднаго карыстальніка не прасочыліся ў рэзультаты іншага.
clear_session() — выдаленне праз запыт, а не знішчэнне індэкса
Выконайце фільтрованае выдаленне для ключа сэсіі. Перзаснавленне індэксаў па кожной сэсіі спрачынае перападзеныя лімітаванняў сервіса і спаможвае затрымкі пад час запуску.
Спіс пераканалення
- Падаброўце вымір эмбедынгу да поля вектара індэкса
- Перэмбедджуйце толькі калі змяніўся модэль эмбедынгу; іншыя разы проста апдэйтуйце існуючыя часткі
- Перад пераканаленням працавайце адночасна з Redis і Azure AI Search над прыкладнымі запытамі
- Як толькі можна, перайміце секрэты ў Key Vault / managed identity
- Апдэйтуйце інструкцыі: больш няма прыпускаў на канец “docker restart redis clears state”
Рэзультаты і компромісы
Azure AI Search дае можлівасць керавання масштабам, інструменты портала і сістэму RBAC. Ён таксама прыносіць адзінакавасць у часе падготовкі рэсурсаў і абмежэнняя, яеявляюцься ў дызайне спільных індэксаў. Для графа запытаў і адпаведзей у фармаце PDF граф вузлаў застаўся стабільным; змяніліся толькі адаптар хранення дадзенаў і цыкл жыцця сесій.
Заключанне
Расследзіце Redis як дапаможны прыстрой для навучэння, а Azure AI Search — як основны прыстрой для апрацоўкі дадзенаў. Зберагаюце ізоляцыю сесій у фільтрах, чытка задаеце схему і выкалываеце дадзеныя праз запыт. Сістэма керавання LangGraph практычна не будзе заўважаць змяны — калі ж і будзе, значы абстракцыя была занадта непразрачная.
Параўнанне пасля перайшоў: заставіце Redis у рэжыме толькі для чытання прыблізна на тыдзень, пакуль Azure AI Search апрацоўвае рэальны трафік, і параблікуйце найбольшыя 3 перакрыцці ў золатым наборэ запытаў. Калі перакрыцці зменшыцца, абследаваце клазусы фільтраў і назвы полей, перш чым карайце мадэль укладання дадзенаў. Большасць рэгрэсій пад час міграцыі ў такім фармаце ёсць багамі фільтраў, а не багамі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у «золатай» сэткі запытаў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычынуя гэта не модэлю эмбедынгу. Большасць рэгрэсій падчас міграцыі ў такім фармаце ёсць багамі фільтраў, а не багамі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у «золатай» сэткі запытаў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычынуя гэта не модэлю эмбедынгу. Большасць рэгрэсій падчас міграцыі ў такім фармаце ёсць багамі фільтраў, а не багамі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у «золатай» сэткі запытаў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычынуя гэта не модэлю эмбедынгу. Большасць рэгрэсій падчас міграцыі ў такім фармаце ёсць багамі фільтраў, а не багамі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у «золатай» сэткі запытаў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычынуя гэта не модэлю эмбедынгу. Большасць рэгрэсій падчас міграцыі ў такім фармаце ёсць багамі фільтраў, а не багамі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у стандартным наборы запытанняў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычынуя гэта не модэлю эмбедынгу. Большасць проблем падчас міграцыі ў такім фармаце ёсць багі фільтраў, а не багі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у стандартным наборы запытанняў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычынуя гэта не модэлю эмбедынгу. Большасць проблем падчас міграцыі ў такім фармаце ёсць багі фільтраў, а не багі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у стандартным наборы запытанняў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычымуя гэта не модэлю эмбедынгу. Большасць проблем падчас міграцыі ў такім фармаце ёсць багі фільтраў, а не багі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у стандартным наборы запытанняў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычымуя гэта не модэлю эмбедынгу. Большасць проблем падчас міграцыі ў такім фармаце ёсць багі фільтраў, а не багі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у стандартным наборы запытанняў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычымуя гэта не модэлю эмбедынгу. Большасць проблем падчас міграцыі ў такім фармаце ёсць багі фільтраў, а не багі вектарнай матэматыкі.
Парадакт перайходу: заставіце Redis працаваць толькі у рэжыме чытання прыблызна на тыдзень, пакуль Azure AI Search обслугоўвае трафік у працэйнай суперактуальнасці, і пораўняйце ступень перакрыцча топ-3 адпаведзей у стандартным наборы запытанняў. Калі ступень перакрыцча знізіцца, абавязкова перагляньце клазулі фільтраў і назвы полей, прычымуя гэта не модэлю эмбедынгу. Большасць проблем падчас міграцыі ў такім фармаце ёсць багі фільтраў, а не багі вектарнай матэматыкі.
Складна дысцыпліна мае значэнне два разы: аднойчы пад час стварэння індэксу Azure AI Search, і зноў пад час апградацыі модэлю embedding. Несувярэннасці ў вымерах вызываюць явныя проблемы; несувярэннасці ў полях, якія можна фільтраваць, выражаюцыся толькі пустымі набрамі рэзультатаў. Дадаць асерцыю пад час запуску, якая чытае вакліканне індэкса і паруравнае вымеры вектораў і назвы поль сэсіі з дакументамі настройкі, якія выконваюцца.