Steg 9 (R4): unified migrate-corpus.mjs --write over engineering/governance/ infrastructure/security. 327 filer mutert, verified=null, prosa byte-identisk (fra første ## seksjon), advisor urørt (0 endringer). To applier-fixes oppdaget under kjøring (TDD, RED→GREEN): - insertHeaderFields: anker faller nå tilbake når en meta-linje selv passerer 500B (2 filer pakket et avsnitt i **Status:** → Type/Source landet utenfor scan-vinduet, applierens post-write-assertion fanget + restaurerte). - normalizeStaleVerified: fjerner nå ALLE stale non-date **Verified:** i 500B-vinduet, inkl. stray body-dup rett under --- (9 mlops-genaiops-filer var ellers falskt "verified"/fresh, droppet fra worklist). Operatør-godkjent utvidelse av carve-out; kun stray metadata-linjer, aldri prosa. test-transform-criterion: precondition oppdatert til post-migrasjons-sannhet (fila bærer nå Source). Suite 728/728 grønn.
263 lines
No EOL
11 KiB
Markdown
263 lines
No EOL
11 KiB
Markdown
# Hybrid Search - Full-Text and Vector Combined
|
||
|
||
**Last updated:** 2026-06-19 | Verified: MCP 2026-06-19
|
||
**Status:** GA
|
||
**Category:** RAG Architecture & Semantic Search
|
||
**Type:** reference
|
||
**Source:** https://learn.microsoft.com/azure/search/hybrid-search-overview
|
||
|
||
---
|
||
|
||
## Innhold
|
||
|
||
- [Introduksjon](#introduksjon)
|
||
- [Kjernekomponenter](#kjernekomponenter)
|
||
- [Arkitekturmønstre](#arkitekturmønstre)
|
||
- [Beslutningsveiledning](#beslutningsveiledning)
|
||
- [Integrasjon med Microsoft-stakken](#integrasjon-med-microsoft-stakken)
|
||
- [Offentlig sektor (Norge)](#offentlig-sektor-norge)
|
||
- [Kostnad og lisensiering](#kostnad-og-lisensiering)
|
||
- [For arkitekten (Cosmo)](#for-arkitekten-cosmo)
|
||
- [Kilder og verifisering](#kilder-og-verifisering)
|
||
|
||
## Introduksjon
|
||
|
||
Hybrid search i Azure AI Search kombinerer full-text (BM25) søk med vektorsøk i en enkelt spørring. De to søkemetodene kjøres parallelt, og resultatene fusjoneres via **Reciprocal Rank Fusion (RRF)**-algoritmen. Dette gir bedre relevans enn enten keyword- eller vektorsøk alene, fordi BM25 fanger eksakte termer mens vektorsøk fanger semantisk mening.
|
||
|
||
RRF-algoritmen beregner en samlet score basert på formelen `1/(rank + k)`, der `rank` er dokumentets posisjon i hver resultatliste og `k` er en konstant (typisk 60). Dokumenter som rangerer høyt på tvers av begge metoder prioriteres. Dette gjør hybrid search robust for varierte spørringstyper — fra eksakte nøkkelord-søk til vage, konseptuelle spørsmål.
|
||
|
||
Hybrid search er tilgjengelig fra Basic-tier og oppover i Azure AI Search, og krever ingen ekstra kostnad utover standard spørringsoperasjoner. Funksjonen er GA siden 2023, med kontinuerlige forbedringer i scoring og ytelse.
|
||
|
||
## Kjernekomponenter
|
||
|
||
### Scoring-modeller
|
||
|
||
| Søkemetode | Score-property | Algoritme | Område |
|
||
|------------|----------------|-----------|--------|
|
||
| Full-text | `@search.score` | BM25 | 0 til ubegrenset |
|
||
| Vector | `@search.score` | HNSW/KNN | 0.333–1.00 (Cosine) |
|
||
| Hybrid | `@search.score` | RRF | 0 til ~1/k per query |
|
||
| Semantic ranking | `@search.rerankerScore` | ML comprehension | 0.00–4.00 |
|
||
|
||
### Vektervekting
|
||
|
||
Vector queries støtter `weight`-parameter for å justere relativ viktighet:
|
||
|
||
- **Default:** 1.0
|
||
- **Redusere:** 0.5 (halverer vektorens bidrag til RRF-scoren)
|
||
- **Øke:** 2.0 (dobler vektorens bidrag)
|
||
|
||
```python
|
||
from azure.search.documents.models import VectorizedQuery
|
||
|
||
vector_query = VectorizedQuery(
|
||
vector=query_vector,
|
||
k_nearest_neighbors=10,
|
||
fields="DescriptionVector",
|
||
weight=2.0 # Prioriter semantisk likhet
|
||
)
|
||
```
|
||
|
||
### maxTextRecallSize
|
||
|
||
Kontrollerer hvor mange BM25-resultater som mates inn i RRF:
|
||
|
||
- **Default:** 1000
|
||
- **Justérbar:** Høyere verdi = mer tekst-recall, men økt latency
|
||
- **Anbefaling:** Default er tilstrekkelig for de fleste scenarioer
|
||
|
||
## Arkitekturmønstre
|
||
|
||
### Mønster 1: Hybrid Search uten semantic ranking
|
||
|
||
**Flyt:** Brukerquery → BM25 + Vector (parallelt) → RRF-fusjon → Topp-N resultater
|
||
|
||
**Fordeler:**
|
||
- Lavere latency (ingen L2-reranking)
|
||
- Fungerer på alle tier (Basic+)
|
||
- Ingen ekstra kostnad for semantic ranking
|
||
|
||
**Ulemper:**
|
||
- RRF er en generell ranking-algoritme, ikke domene-optimert
|
||
- Lavere relevans for komplekse, naturnlige spørsmål
|
||
|
||
**Beste for:** Høy-volum søk der latency er kritisk, eller der BM25+vector gir tilstrekkelig relevans.
|
||
|
||
### Mønster 2: Hybrid Search med Semantic Ranking (anbefalt)
|
||
|
||
**Flyt:** Brukerquery → BM25 + Vector (parallelt) → RRF-fusjon → Semantic Ranker (topp 50) → Topp-N resultater
|
||
|
||
**Fordeler:**
|
||
- Best mulig relevans (dokumentert i benchmarks)
|
||
- Semantiske captions og answers inkludert
|
||
- Scoring profile kan legges på etter semantic ranking
|
||
|
||
**Ulemper:**
|
||
- Krever S1-tier eller høyere
|
||
- Ekstra kostnad per query (etter 1000 gratis/måned)
|
||
- Noe høyere latency (~50–200ms ekstra)
|
||
|
||
**Beste for:** Enterprise RAG, kunnskapsportaler, dokumentsøk i offentlig sektor.
|
||
|
||
### Mønster 3: Hybrid Search med filtrering og facettering
|
||
|
||
**Flyt:** Brukerquery + filter/facet → Prefilter/Postfilter → BM25 + Vector → RRF → Resultater med facets
|
||
|
||
```python
|
||
results = client.search(
|
||
search_text="luxury hotel",
|
||
vector_queries=[vector_query],
|
||
filter="Rating gt 4 and ParkingIncluded eq true",
|
||
vector_filter_mode="postFilter",
|
||
facets=["Category", "Address/StateProvince"],
|
||
select=["HotelName", "Description", "Rating"],
|
||
top=10
|
||
)
|
||
```
|
||
|
||
**Fordeler:**
|
||
- Kombinerer semantisk søk med strukturert filtrering
|
||
- Støtter faceted navigation for brukergrensesnitt
|
||
|
||
**Ulemper:**
|
||
- `preFilter` kan redusere vektorkandidater for mye
|
||
- `postFilter` kan returnere færre resultater enn forventet
|
||
|
||
**Beste for:** E-commerce-liknende søk, sakssystemer med metadata-filtre.
|
||
|
||
## Beslutningsveiledning
|
||
|
||
### Når bruke hybrid search vs. alternativer
|
||
|
||
| Scenario | Anbefaling | Begrunnelse |
|
||
|----------|------------|-------------|
|
||
| Generell enterprise-søk | Hybrid + semantic | Best relevans dokumentert |
|
||
| Eksakt ID/kode-søk | Kun BM25 | Vektor tilfører ingen verdi for eksakte treff |
|
||
| Konseptuelle spørsmål | Hybrid + semantic | BM25 fanger nøkkelord, vektor fanger mening |
|
||
| Multilingual søk | Hybrid med fokus på vektor | Vektor bypasser språk-analysatorer |
|
||
| Strukturert data | BM25 + filtre | Vektor er designet for ustrukturert tekst |
|
||
| Høy-volum, lav-latency | Hybrid uten semantic | Semantic ranking legger til latency |
|
||
|
||
### Vanlige feil
|
||
|
||
1. **Ikke sette k=50 for vektor-queries med semantic ranking** — Semantic ranker jobber med topp 50, så `k` bør være minst 50
|
||
2. **Bruke `preFilter` med semantic ranking** — Kan eliminere relevante resultater før ranking
|
||
3. **Sammenligne scores på tvers av indekser** — BM25-scores er relative til dokumentfrekvens i indeksen
|
||
4. **Ignorere vekter** — Default-vekter (1.0/1.0) passer ikke alltid domenet
|
||
|
||
### Røde flagg
|
||
|
||
- Lav relevans med hybrid search → Sjekk om embedding-modellen er trent for domenet
|
||
- Høy latency → Vurder om semantic ranking er nødvendig for dette use caset
|
||
- Uventede resultater med filtre → Sjekk `preFilter` vs. `postFilter` modus
|
||
|
||
## Integrasjon med Microsoft-stakken
|
||
|
||
| Tjeneste | Integrasjon |
|
||
|----------|-------------|
|
||
| **Azure OpenAI** | Embedding-modeller (text-embedding-3-large) for vektordelen |
|
||
| **Microsoft Foundry** | Integrert vektorisering via skills i indekserings-pipeline |
|
||
| **Copilot Studio** | Azure AI Search som grounding-kilde for Copilot-agenter |
|
||
| **Semantic Kernel** | `AzureAISearchVectorStore` connector for hybrid queries |
|
||
| **Power Platform** | AI Builder kan bruke Azure AI Search via custom connectors |
|
||
|
||
## Offentlig sektor (Norge)
|
||
|
||
### Datasuverenitet
|
||
- Azure AI Search er tilgjengelig i **Norway East** og **Norway West**
|
||
- All indeksdata forblir i valgt region
|
||
- Fullt GDPR-kompatibelt via Azures rammeverk
|
||
- Microsofts EU Data Boundary gjelder for norske deployments
|
||
|
||
### Sikkerhetsfunksjoner
|
||
- **Azure Private Link:** Isoler search service fra offentlig internett
|
||
- **Managed Identity:** Sikker autentisering via Entra ID (ingen API-nøkler)
|
||
- **Customer-managed keys:** Krypter data med egne nøkler i Azure Key Vault
|
||
- **Dokumentnivå-sikkerhet:** Filtrer resultater basert på brukeridentitet
|
||
- **RBAC:** Rollebasert tilgangskontroll for indeks- og spørringsoperasjoner
|
||
|
||
### Relevante use cases
|
||
- **Regelverk og retningslinjer:** Kombinér eksakt match (§-referanser) med semantisk søk
|
||
- **Sakssystemer:** Hybrid search med metadata-filtrering per sakstype
|
||
- **Publikumstjenester:** Multilingual search der vektor bypasser språkbarrierer
|
||
- **Arkivsøk:** Historisk dokumentasjon med varierende terminologi
|
||
|
||
## Kostnad og lisensiering
|
||
|
||
### Tier-krav
|
||
| Funksjon | Minimumstier |
|
||
|----------|-------------|
|
||
| Hybrid search (BM25 + vektor) | Basic |
|
||
| Scoring profiles | Alle tier |
|
||
| Semantic ranking | S1+ (1000 gratis/mnd) |
|
||
| Integrert vektorisering | Basic+ |
|
||
|
||
### Kostnadsoptimering
|
||
- **Scalar/binary quantization** reduserer vektorlagring med opptil 50% (preview)
|
||
- **`stored: false`** på vektorfelt sparer lagring hvis du ikke trenger å hente embeddings
|
||
- **Narrower data types** for vektorfelt der presisjon tillater det
|
||
- **Tune `k`-parameter** — færre naboer = lavere kostnad
|
||
- Hybrid queries teller som **én spørringsoperasjon** (ingen prisøkning vs. enkelt søk)
|
||
|
||
## For arkitekten (Cosmo)
|
||
|
||
### Spørsmål å stille kunden
|
||
1. Hvilke typer søk gjør brukerne deres — eksakte nøkkelord, naturlige spørsmål, eller begge deler?
|
||
2. Hvor viktig er latency vs. relevans for dette use caset?
|
||
3. Har dere strukturerte metadata (kategorier, datoer, avdelinger) som bør filtreres?
|
||
4. Hvilket tier bruker dere i dag, og er semantic ranking et alternativ?
|
||
5. Trengs multilingual support?
|
||
6. Hvor store er dokumentene, og hvordan chunkes de?
|
||
|
||
### Fallgruver
|
||
- Å starte med ren vektor-search og legge til BM25 etterpå er vanskeligere enn å starte med hybrid
|
||
- Scoring profiles og semantic ranking interagerer på ikke-åpenbare måter — test grundig
|
||
- Vektervekting krever eksperimentering; det finnes ingen universell "riktig" vekt
|
||
|
||
### Anbefalinger per modenhetsnivå
|
||
| Nivå | Anbefaling |
|
||
|------|------------|
|
||
| **Starter** | Hybrid search med default-vekter, uten semantic ranking |
|
||
| **Intermediær** | Legg til semantic ranking, tune vekter basert på evaluering |
|
||
| **Avansert** | Scoring profiles, A/B-testing med debug-modus, custom reranking |
|
||
|
||
### Debug-tips
|
||
Bruk `debug: "vector"` eller `debug: "semantic"` i API-kallet for å pakke ut subscores og forstå ranking-bidrag fra hver komponent.
|
||
|
||
## Kilder og verifisering
|
||
|
||
### Verified (MCP-research)
|
||
- [Hybrid Search Overview](https://learn.microsoft.com/en-us/azure/search/hybrid-search-overview)
|
||
- [RRF Ranking Algorithm](https://learn.microsoft.com/en-us/azure/search/hybrid-search-ranking)
|
||
- [Hybrid Query How-To](https://learn.microsoft.com/en-us/azure/search/hybrid-search-how-to-query)
|
||
- [Relevance Overview](https://learn.microsoft.com/en-us/azure/search/search-relevance-overview)
|
||
- [BM25 Scoring Details](https://learn.microsoft.com/en-us/azure/search/index-similarity-and-scoring)
|
||
- [Vector Search Overview](https://learn.microsoft.com/en-us/azure/search/vector-search-overview)
|
||
|
||
### Baseline (modellkunnskap)
|
||
- Kostnadsoptimerings-tips basert på generell Azure-erfaring
|
||
- Offentlig sektor-anbefalinger basert på norsk kontekst
|
||
|
||
|
||
### Hybrid Search — Konfigurasjon og Tuning (oppdatert 2026-04)
|
||
|
||
**Anbefalt startpunkt:** Balanced hybrid med `k=30-50`, `top=10-20`, semantic ranking etter relevans-test.
|
||
|
||
**maxTextRecallSize (preview):** Kontrollerer BM25-bidrag til RRF
|
||
- Default: 1000, Max: 10000
|
||
- Reduser hvis vector dominerer; øk for store indekser der default ikke gir nok dekning
|
||
- `countAndFacetMode: "countRetrievableResults"` scope-r teller til maxTextRecallSize-vinduet
|
||
|
||
**Ytelsesmønstre:**
|
||
- Recall-first: øk `maxTextRecallSize` gradvis
|
||
- Precision-first: lav `k` og `top`, unngå unødvendig semantic ranker
|
||
|
||
**Filter-moduser i hybrid:**
|
||
- `preFilter` (default) — filtrerer FØR query, reduserer søkerom for begge subqueries
|
||
- `postFilter` — filtrerer ETTER, men kan gi <50 docs til semantic ranker
|
||
- `strictPostFilter` (preview) — strengeste modus, ikke anbefalt med semantic ranker
|
||
- `filterOverride` (preview) — per-vectorQuery filter, overstyrer globalt filter
|
||
|
||
**SDK-støtte:** Python (`azure-search-documents`), C# (`Azure.Search.Documents`), Java, JavaScript.
|
||
|
||
**API-versjoner:** `2026-04-01` (stable), `2026-05-01-preview` (maxTextRecallSize, filterOverride, strictPostFilter, etc.) |