KB-currency refresh (medium priority, 2026-06-19) via /architect:kb-update. 74 medium-prioritets filer re-verifisert mot Microsoft Learn (MCP) — delegert til 15 parallelle Opus-subagenter (3 bølger) gruppert etter delt kilde, med disjunkte fil-sett. Verifisert i hovedkontekst (scope-sjekk + diff-review av de faktatunge gruppene + tester). Hovedendringer (faktuelle korreksjoner + currency): - Azure AI Search semantic ranker: TILGJENGELIG PÅ ALLE TIERS (også Free/Basic m/ gratis månedlig kvote) — gammel KB sa feilaktig "kun S1+". Korrigert i tier-tabell, anti-patterns og beslutningstabell (azure-ai-search-setup). - APIM score-threshold = DISTANSE (lavere = strengere): tuning-tabellen i rag-caching-optimization hadde retningen baklengs — invertert til korrekt. - Agentic retrieval GA/preview-nyanse presisert (hovedkontekst-korreksjon mot agentic-retrieval-how-to-migrate): GA via REST 2026-04-01 returnerer EKSTRAKTIV grounding (references + activity), IKKE syntetiserte svar. Answer synthesis, ikke-minimal reasoning effort (LLM query planning) og multi-turn messages forblir preview (2026-05-01-preview). Subagent hadde overforenklet til "hele kjernepipelinen GA"; rettet i agentic-rag-patterns + citation-tracking. - Copilot Studio modell-tabeller (platforms/copilot-studio): fjernet Claude Opus 4.5 + GPT-5.2 (borte fra kilde), lagt til Claude Sonnet 4.6/Opus 4.6 (GA), Opus 4.7 + Mistral Medium 3.5 (experimental); GPT-5 Reasoning/Auto = preview; A2A GA (apr 2026). - Computer Use (CUA): Copilot Studio GA 2026-05-07; 4 modeller m/ tier/status (OpenAI CUA + Sonnet 4.5 GA, Sonnet 4.6 + Opus 4.6 experimental); 5 credits/ steg standard, 15 premium; US-only region-krav FJERNET i GA-dok; Cloud PC pool + Hosted browser + bring-your-own-machine. - Azure AI Search REST API-versjoner bumpet: 2025-09-01 -> 2026-04-01 (stabil), 2025-11-01-preview -> 2026-05-01-preview (hybrid-search, rag-security-rbac, chunking). - Power Automate-integrasjon: trigger "Run a flow from Copilot" -> "When an agent calls the flow"; App Service innebygd MCP (preview) lagt til. - M365 Copilot-manifest v1.26 -> v1.28 (GA, mai) / v1.29 dokumentert (juni); "Tenant graph grounding" -> "Work IQ". - Speech fast transcription 2t/300MB -> 5t/500MB; multilingual 14 -> 15 locales (+ pt-BR). Content Understanding reasoning preview -> GA (v1.0, 2025-11-01). - Security Copilot E5 -> E5+E7. Død Databricks-URL ci-cd/best-practices -> ci-cd/flows. Prompt Flow retirement (2027-04-20 -> MAF) notert der den presenteres som go-forward. Gateway-topologi-tabell-feil rettet. - Alle 74 Last updated -> 2026-06-19. Discovery ikke kjørt (historisk kun Databricks-støy) -> 389-telling uendret, ingen resync. validate 239 PASS, kb-integrity 115/115 (262 orphan-warnings uendret), gitleaks clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01REiKFhP4w6xGXXqWKpPCJJ
330 lines
14 KiB
Markdown
330 lines
14 KiB
Markdown
# Multi-Index Federation and Cross-Search
|
|
|
|
**Last updated:** 2026-06-19 | Verified: MCP 2026-06-19
|
|
**Status:** GA (single-index), Not supported (native cross-index)
|
|
**Category:** RAG Architecture & Semantic Search
|
|
|
|
---
|
|
|
|
## Introduksjon
|
|
|
|
Et av de vanligste spørsmålene fra enterprise-arkitekter er: "Kan vi søke på tvers av flere Azure AI Search-indekser i en enkelt spørring?" Svaret er **nei** — Azure AI Search støtter ikke native multi-index federation. Hvert søk er alltid avgrenset til én enkelt indeks.
|
|
|
|
Dette er en bevisst designbeslutning, ikke en begrensning. Enkelt-indeks-søk gir konsistente scorer, unified ranking, og forutsigbar ytelse. Cross-index-søk ville kreve score-normalisering, resultat-merging, og distribuert ranking — noe som introduserer betydelig kompleksitet og uforutsigbarhet.
|
|
|
|
For scenarioer der data logisk tilhører separate indekser (ulike skjemaer, compliance-krav, eller ulike formål), må applikasjonslaget implementere orkestrering. Denne filen beskriver arkitekturmønstre, routing-strategier og best practices for slike scenarioer.
|
|
|
|
**Viktig funn:** Microsofts offisielle FAQ sier eksplisitt: *"Can I search across multiple indexes? No. A query is always scoped to a single index."*
|
|
|
|
**Multi-region støtte:** Azure AI Search er en single-region service, men du kan oppnå høyere reliability ved å deploye identiske search services i flere regioner. Data synkroniseres via push eller pull (indexer) APIer. Load balancing håndteres av Azure Front Door, Traffic Manager, eller Application Gateway. Data residency: innhold lagres i regionen du velger, uten kryssregional dataflyt uten eksplisitt autorisasjon.
|
|
|
|
**Multi-vector fields (Preview):** Azure AI Search støtter nå multiple vektorer i ett dokumentfelt via `Collection(Edm.ComplexType)` — opp til 100 vektorer per dokument. Nyttig for multimodal data og lange dokumenter. `perDocumentVectorLimit`-parameteren kontrollerer antall matchende vektorer per dokument i query-resultater.
|
|
|
|
## Kjernekomponenter
|
|
|
|
### Hvorfor Azure AI Search ikke støtter cross-index queries
|
|
|
|
| Utfordring | Forklaring |
|
|
|-----------|------------|
|
|
| **Scoring-isolasjon** | BM25-scores er relative til dokumentfrekvens *innenfor* indeksen — scorer fra ulike indekser kan ikke sammenlignes direkte |
|
|
| **Skjema-forskjeller** | Ulike indekser kan ha helt ulike felt, datatyper og analysatorer |
|
|
| **Ingen unified ranking** | Ingen innebygd mekanisme for å re-ranke resultater på tvers av indekser |
|
|
| **Ingen distribuerte transaksjoner** | Oppdateringer til flere indekser er ikke atomiske |
|
|
|
|
### Enkelt-indeks vs. multi-indeks
|
|
|
|
| Aspekt | Enkelt indeks | Multiple indekser |
|
|
|--------|--------------|-------------------|
|
|
| Query-logikk | Enkel, unified | Kompleks, krever orkestrering |
|
|
| Scoring | Konsistent | Inkonsistent mellom indekser |
|
|
| Vedlikehold | Enklere | Mer komplekst |
|
|
| Filtrering | Native, effektiv | Per-indeks, applikasjons-merging |
|
|
| Sikkerhet | Dokumentnivå-filtrering | Indeks-nivå isolasjon |
|
|
| Skalerbarhet | Vertikal (større tier) | Horisontal (flere services) |
|
|
|
|
### Nyere relevante features (2025)
|
|
|
|
| Feature | Status | Relevans |
|
|
|---------|--------|----------|
|
|
| Multi-vector field support | GA (2025) | Lagre multiple vektorer per dokument i én indeks |
|
|
| Agentic Retrieval | Preview | LLM-assistert query planning, men fremdeles single-index |
|
|
| Targeted vector filters | Preview | Filtre spesifikt for vektor-subqueries |
|
|
|
|
## Arkitekturmønstre
|
|
|
|
### Mønster 1: Enkelt indeks med filtrering (anbefalt)
|
|
|
|
**Flyt:** Data fra multiple kilder → Felles indeks med type/kilde-felt → Filtrering ved søk
|
|
|
|
```python
|
|
# Alle dokumenttyper i én indeks med type-felt
|
|
results = client.search(
|
|
search_text="anskaffelsesregler",
|
|
filter="doc_type eq 'regelverk' and department eq 'HR'",
|
|
select=["title", "content", "doc_type", "department"],
|
|
top=10
|
|
)
|
|
```
|
|
|
|
**Fordeler:**
|
|
- Enklest implementering
|
|
- Unified scoring og ranking
|
|
- Native filtrering, facettering
|
|
- Ingen orkestreringskode nødvendig
|
|
|
|
**Ulemper:**
|
|
- Skjemaet må være tilstrekkelig fleksibelt for alle dokumenttyper
|
|
- Indeksen kan bli stor (skalering vertikalt)
|
|
- Alle dokumenter deler analysatorer og innstillinger
|
|
|
|
**Beste for:** De fleste enterprise-scenarioer der data har lignende struktur.
|
|
|
|
### Mønster 2: Parallell query med applikasjons-merging
|
|
|
|
**Flyt:** Query → Fork til N indekser (parallelt) → Samle resultater → Score-normalisering → Merged resultat
|
|
|
|
```python
|
|
from azure.search.documents import SearchClient
|
|
from azure.identity import DefaultAzureCredential
|
|
import asyncio
|
|
|
|
async def query_multiple_indexes(query_text, indexes):
|
|
credential = DefaultAzureCredential()
|
|
|
|
async def query_index(index_name):
|
|
client = SearchClient(
|
|
endpoint=endpoint,
|
|
index_name=index_name,
|
|
credential=credential
|
|
)
|
|
results = []
|
|
async for result in client.search(search_text=query_text, top=10):
|
|
results.append({
|
|
"source_index": index_name,
|
|
"score": result["@search.score"],
|
|
**result
|
|
})
|
|
return results
|
|
|
|
# Parallelle queries
|
|
tasks = [query_index(idx) for idx in indexes]
|
|
all_results = await asyncio.gather(*tasks)
|
|
|
|
# Flatten og normaliser
|
|
merged = []
|
|
for results in all_results:
|
|
merged.extend(results)
|
|
|
|
# MERK: Score-normalisering nødvendig her
|
|
merged = normalize_scores(merged)
|
|
merged.sort(key=lambda x: x["normalized_score"], reverse=True)
|
|
|
|
return merged[:10]
|
|
|
|
def normalize_scores(results):
|
|
"""Min-max normalisering per indeks."""
|
|
by_index = {}
|
|
for r in results:
|
|
idx = r["source_index"]
|
|
if idx not in by_index:
|
|
by_index[idx] = []
|
|
by_index[idx].append(r)
|
|
|
|
for idx, items in by_index.items():
|
|
scores = [i["score"] for i in items]
|
|
min_s, max_s = min(scores), max(scores)
|
|
range_s = max_s - min_s if max_s != min_s else 1
|
|
for item in items:
|
|
item["normalized_score"] = (item["score"] - min_s) / range_s
|
|
|
|
return results
|
|
```
|
|
|
|
**Fordeler:**
|
|
- Støtter fundamentalt ulike skjemaer
|
|
- Compliance-isolasjon mellom indekser
|
|
- Horisontal skalering
|
|
|
|
**Ulemper:**
|
|
- Score-normalisering er heuristisk, ikke eksakt
|
|
- Økt latency (selv med parallellisering)
|
|
- Kompleks kode å vedlikeholde
|
|
- Resultater kan "konkurrere" unfairly mellom indekser
|
|
|
|
**Beste for:** Scenarioer med fundamentalt ulike datatyper (HR-håndbok vs. produktkatalog).
|
|
|
|
### Mønster 3: Query routing basert på intent
|
|
|
|
**Flyt:** Query → Intent-analyse (LLM/classifier) → Route til riktig indeks → Enkelt-indeks søk → Resultat
|
|
|
|
```python
|
|
def route_query(query_text):
|
|
"""Bestem hvilken indeks som er mest relevant."""
|
|
# Enkel keyword-basert routing
|
|
if any(word in query_text.lower() for word in ["anskaffelse", "kontrakt", "anbud"]):
|
|
return "regelverk-index"
|
|
elif any(word in query_text.lower() for word in ["personal", "ferie", "lønn"]):
|
|
return "hr-index"
|
|
else:
|
|
return "general-index"
|
|
|
|
# Eller med LLM-basert intent-klassifisering
|
|
def route_query_llm(query_text):
|
|
response = openai_client.chat.completions.create(
|
|
model="gpt-4o-mini",
|
|
messages=[{
|
|
"role": "system",
|
|
"content": "Classify the query into one of: regelverk, hr, general"
|
|
}, {
|
|
"role": "user",
|
|
"content": query_text
|
|
}]
|
|
)
|
|
intent = response.choices[0].message.content.strip()
|
|
return f"{intent}-index"
|
|
```
|
|
|
|
**Fordeler:**
|
|
- Kun én indeks queries per request (lavest latency)
|
|
- Tydelig domene-separasjon
|
|
- Skalerbar routing-logikk
|
|
|
|
**Ulemper:**
|
|
- Routing-feil betyr at brukeren ikke finner det de leter etter
|
|
- LLM-basert routing legger til latency og kostnad
|
|
- Krever vedlikehold av routing-logikk
|
|
|
|
**Beste for:** Klart adskilte domener med liten overlapp.
|
|
|
|
### Mønster 4: Multi-region search services
|
|
|
|
**Flyt:** Query → Nearest region service (via Traffic Manager) → Lokalt søk → Resultat
|
|
|
|
For geo-distribuerte brukere der latency er kritisk:
|
|
|
|
- Identiske indekser i flere regioner
|
|
- Synkronisering via push/pull API
|
|
- Azure Traffic Manager, Front Door, eller Application Gateway for routing
|
|
|
|
**Beste for:** Globale applikasjoner med latency-krav.
|
|
|
|
## Beslutningsveiledning
|
|
|
|
### Valg av indeks-topologi
|
|
|
|
```
|
|
Trenger du ulike skjemaer per datakilde?
|
|
├── Nei → Enkelt indeks med filtrering (Mønster 1)
|
|
└── Ja → Er datakildene compliance-adskilt?
|
|
├── Ja → Multi-indeks med routing (Mønster 3)
|
|
└── Nei → Kan skjemaene generaliseres?
|
|
├── Ja → Enkelt indeks med complex types
|
|
└── Nei → Multi-indeks med parallell query (Mønster 2)
|
|
```
|
|
|
|
### Vanlige feil
|
|
|
|
1. **Opprette separate indekser for hvert datasett** — Start med filtrering i én indeks
|
|
2. **Sammenligne BM25-scores direkte mellom indekser** — Scores er relative, ikke absolutte
|
|
3. **Sekvensiell querying av multiple indekser** — Bruk alltid parallell utførelse
|
|
4. **Implementere cross-index joins** — Azure AI Search støtter ikke dette
|
|
5. **Ignorere skjema-denormalisering** — Dupliser data hvis nødvendig for søkbarhet
|
|
|
|
### Røde flagg
|
|
|
|
- Behov for mer enn 3-4 indekser → Vurder om indeksdesignet er suboptimalt
|
|
- Brukere klager over manglende resultater → Mulig routing-feil i multi-indeks-oppsett
|
|
- Inkonsistente scorer mellom søk → Score-normalisering trenger kalibrering
|
|
|
|
## Integrasjon med Microsoft-stakken
|
|
|
|
| Tjeneste | Rolle |
|
|
|----------|-------|
|
|
| **Azure Traffic Manager** | Geo-basert routing mellom search services |
|
|
| **Azure Front Door** | Lastbalansering og CDN for multi-region |
|
|
| **Azure Application Gateway** | L7 load balancing for search requests |
|
|
| **Azure API Management** | API-gateway med routing-logikk for multi-indeks |
|
|
| **Semantic Kernel** | Orchestration-framework for multi-indeks RAG |
|
|
|
|
## Offentlig sektor (Norge)
|
|
|
|
### Data-klassifisering og indeks-separasjon
|
|
- **Ugradert data:** Kan samles i én indeks med filtrering
|
|
- **Fortrolig/begrenset:** Bør ha egen indeks med strengere tilgangskontroll
|
|
- **Sikkerhetsgradert:** Kan kreve egen search service i isolert nettverk
|
|
|
|
### Compliance-krav
|
|
- **Arkivloven:** Dokumenter fra ulike arkivserier kan kreve logisk separasjon
|
|
- **Forvaltningsloven:** Tilgangskontroll per sak/avdeling
|
|
- **GDPR:** Persondata kan kreve egen indeks for enklere sletting (right to be forgotten)
|
|
|
|
### Anbefalt tilnærming
|
|
For de fleste offentlige virksomheter:
|
|
1. **Primærindeks:** All ugradert dokumentasjon i én indeks med avdelings-/kategori-filtrering
|
|
2. **Sekundærindeks:** Persondata eller begrenset informasjon med RBAC
|
|
3. **Routing:** Intent-basert routing for å bestemme hvilken indeks som søkes
|
|
|
|
## Kostnad og lisensiering
|
|
|
|
### Kostnadsimplikasjoner av multi-indeks
|
|
|
|
| Topologi | Kostnadsfaktorer |
|
|
|----------|-----------------|
|
|
| Enkelt indeks | Én search service, standard lagring og query-kostnad |
|
|
| Multiple indekser (én service) | Delte ressurser, men økt lagring |
|
|
| Multiple search services | Separate kostnader per service, duplikert lagring |
|
|
| Multi-region | Multiplisert lagring + synkroniseringskostnad |
|
|
|
|
### Kostnadsoptimering
|
|
- **Start med enkelt indeks** — Unngå unødvendig kompleksitet og kostnad
|
|
- **Bruk replika-fordeling** fremfor separate services der mulig
|
|
- **Vurder search service tier** basert på samlet indeksstørrelse og query-volum
|
|
- **Synkroniser incrementally** i multi-region — ikke full re-indeksering
|
|
|
|
## For arkitekten (Cosmo)
|
|
|
|
### Spørsmål å stille kunden
|
|
1. Hvor mange datakikylder har dere, og har de lignende eller ulik struktur?
|
|
2. Er det compliance-krav som krever fysisk separasjon av data?
|
|
3. Trenger brukerne å søke på tvers av alle datakilder, eller er domenene adskilte?
|
|
4. Hva er latency-kravene — kan parallell multi-indeks query aksepteres?
|
|
5. Har dere geo-distribuerte brukere som trenger multi-region?
|
|
6. Hva er budsjett — én stor service vs. flere mindre?
|
|
|
|
### Fallgruver
|
|
- Å designe for cross-index fra start uten å vurdere filtrering i enkelt indeks
|
|
- Å underestimere kompleksiteten i score-normalisering og resultat-merging
|
|
- Å anta at fremtidige Azure-oppdateringer vil løse cross-index — dette er et bevisst designvalg
|
|
- Å bruke LLM for query routing uten fallback til bredere søk
|
|
|
|
### Anbefalinger per modenhetsnivå
|
|
| Nivå | Anbefaling |
|
|
|------|------------|
|
|
| **Starter** | Enkelt indeks med filtrering — alltid start her |
|
|
| **Intermediær** | Legg til separate indekser kun ved compliance-krav, med intent-routing |
|
|
| **Avansert** | Multi-region med synkronisering, custom orkestrering, semantic reranking av merged resultater |
|
|
|
|
### Viktig designprinsipp
|
|
|
|
> **Default til enkelt indeks med filtrering.** Opprett separate indekser kun når du har en konkret, dokumentert grunn — ikke "for sikkerhets skyld."
|
|
|
|
Grunner som rettferdiggjør separate indekser:
|
|
- Fundamentalt ulikt skjema (tekst vs. strukturert data)
|
|
- Compliance-krav til fysisk separasjon
|
|
- Ulik livsyklus (hyppig vs. sjelden oppdatering)
|
|
- Ulike tilgangsmodeller (intern vs. ekstern)
|
|
|
|
## Kilder og verifisering
|
|
|
|
### Verified (MCP-research)
|
|
- [Azure AI Search FAQ — Cross-index queries](https://learn.microsoft.com/en-us/azure/search/search-faq-frequently-asked-questions)
|
|
- [Multi-region deployments](https://learn.microsoft.com/en-us/azure/search/search-multi-region)
|
|
- [Grounding data design — Index topology](https://learn.microsoft.com/en-us/azure/well-architected/ai/grounding-data-design)
|
|
- [Multi-vector field support](https://learn.microsoft.com/en-us/azure/search/vector-search-multi-vector-fields)
|
|
- [Tutorial: Index from multiple data sources](https://learn.microsoft.com/en-us/azure/search/tutorial-multiple-data-sources)
|
|
- [GitHub: Multiple search services (.NET)](https://github.com/Azure-Samples/azure-search-dotnet-scale/tree/main/multiple-search-services)
|
|
|
|
### Baseline (modellkunnskap)
|
|
- Score-normaliserings-kode
|
|
- Routing-eksempler
|
|
- Offentlig sektor-anbefalinger
|