ms-ai-architect/skills/ms-ai-engineering/references/rag-architecture/contextual-retrieval.md
Kjell Tore Guttormsen ddce43d8b2 feat(ms-ai-architect): Spor 1 — Port-1-substrat migrert på 4 ikke-advisor-skills (243 Source + 327 Type + 325 TOC + stale-verified poison fjernet) [skip-docs]
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.
2026-07-04 10:19:11 +02:00

313 lines
No EOL
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Contextual Retrieval — Kontekstuell berikelse av chunks
**Last updated:** 2026-04 | Verified: MCP 2026-04
**Status:** GA (custom skill pattern), Preview (agentic retrieval)
**Category:** RAG Architecture & Semantic Search
**Type:** reference
**Source:** https://learn.microsoft.com/azure/search/cognitive-search-custom-skill-interface
---
## 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
Contextual Retrieval er en teknikk der hvert dokumentsegment (chunk) berikes med en LLM-generert kontekstbeskrivelse *før* embedding og indeksering. I tradisjonell RAG mister chunks kontekst når de løsrives fra kildedokumentet — pronomener, forkortelser og referanser blir tvetydige. Contextual Retrieval løser dette ved å prepende en 2-3-setningers forklaring som beskriver segmentets plass i dokumentet.
Anthropic dokumenterte teknikken i 2024 og viste at den reduserer retrieval failures med opptil 67% når den kombineres med BM25 og reranking. Microsoft Tech Community har validert tilnærmingen i Azure AI Search med 80-85% reduksjon i token-bruk per query og 31% forbedring i retrieval precision.
I Azure-stakken implementeres contextual retrieval via en **Custom Web API Skill** (Azure Functions) som genererer kontekstuell prefiks via Azure OpenAI GPT-4o, integrert i skillset-pipelinen mellom chunking og embedding.
---
## Kjernekomponenter
### Kontekstuell prefiks-generering
| Komponent | Beskrivelse |
|-----------|-------------|
| **Custom Web API Skill** | Azure Function som mottar chunk + metadata, returnerer kontekstuell prefiks |
| **LLM (GPT-4o)** | Genererer 2-3 setninger som forklarer chunkens plass i dokumentet |
| **Text Merge Skill** | Konkatenerer kontekstuell prefiks + original chunk |
| **Embedding Skill** | Embedder den berikede teksten (prefiks + chunk) |
### Eksempel
```
Original chunk: "Forskningen understreket AI"
→ Problematisk: Hvem, når, hvilken AI?
Contextual chunk: "Fra Direktoratet for digital tjenesteutvikling sin 2025-rapport om autonome
kjøretøy. Dette avsnittet diskuterer AI-teknologier for selvkjørende biler.
Forskningen understreket AI"
→ Tydelig: LLM kan nå forstå konteksten
```
### Custom Skill-konfigurasjon
```json
{
"@odata.type": "#Microsoft.Skills.Custom.WebApiSkill",
"name": "context-generation-skill",
"uri": "https://<function-app>.azurewebsites.net/api/generate-context",
"httpMethod": "POST",
"timeout": "PT90S",
"context": "/document/pages/*",
"inputs": [
{ "name": "chunk", "source": "/document/pages/*" },
{ "name": "documentTitle", "source": "/document/metadata_storage_name" },
{ "name": "documentMetadata", "source": "/document/metadata" }
],
"outputs": [
{ "name": "contextualPrefix", "targetName": "context" }
]
}
```
### Azure Function (Python)
```python
import azure.functions as func
from openai import AzureOpenAI
import json, os
client = AzureOpenAI(
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_KEY"),
api_version="2024-10-01-preview"
)
def main(req: func.HttpRequest) -> func.HttpResponse:
values = req.get_json()['values']
results = []
for record in values:
chunk = record['data']['chunk']
doc_title = record['data']['documentTitle']
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": f"""Generate a 2-3 sentence
contextual summary for this chunk.
Document: {doc_title}
Chunk: {chunk}
Include: document source/type, section/topic, temporal context."""}],
max_tokens=100,
temperature=0.3
)
context = response.choices[0].message.content
results.append({
"recordId": record['recordId'],
"data": {"contextualPrefix": context},
"errors": [], "warnings": []
})
return func.HttpResponse(
json.dumps({"values": results}),
mimetype="application/json"
)
```
---
## Arkitekturmønstre
### Mønster 1: Post-chunking context enrichment (anbefalt)
**Arkitektur:** Data source → Indexer → Document Layout/Text Split → Custom Context Skill → Text Merge → Embedding → Index
**Fordeler:**
- Enklest å integrere i eksisterende pipelines
- Bruker standard Azure AI Search skillset-mekanismer
- Kompatibel med alle chunking-strategier
**Ulemper:**
- Ekstra LLM-kall per chunk (GPT-4o kostnad)
- Økt indekseringstid (90s timeout per batch)
**Anbefalt for:** Alle RAG-systemer der retrieval-kvalitet er viktigere enn indekseringskostnad.
### Mønster 2: Pre-chunking context med document summary
**Arkitektur:** Data source → Indexer → Document Summary Skill (1 per dokument) → Text Split → Inject Summary as Context → Embedding → Index
**Fordeler:**
- Kun ett LLM-kall per dokument (ikke per chunk)
- 60-80% kostnadsreduksjon vs. per-chunk context
- Caching-vennlig
**Ulemper:**
- Mindre spesifikk kontekst per chunk
- Document summary kan miste nyanser i store dokumenter
**Anbefalt for:** Kostnadsbevisste løsninger, homogene dokumentsamlinger.
### Mønster 3: Contextual Retrieval + BM25 + Reranking
**Arkitektur:** Contextual embedding + BM25 full-text indeksering → Hybrid search (RRF) → Semantic Ranker → Top-k
**Effekt (Anthropic benchmarks):**
| Metode | Retrieval failure rate | Forbedring |
|--------|------------------------|------------|
| Standard embeddings | 5.7% | Baseline |
| Contextual Embeddings | 3.7% | -35% |
| + Contextual BM25 | 2.9% | -49% |
| + Reranking | 1.9% | -67% |
**Nøkkel:** BM25 fanger kontekst-spesifikke termer (organisasjonsnavn, datoer) som embeddings kan miste.
---
## Beslutningsveiledning
### Beslutningstabell
| Scenario | Anbefalt mønster | Begrunnelse |
|----------|------------------|-------------|
| Generell enterprise RAG | Mønster 1 (post-chunking) | Best kvalitet, akseptabel kostnad |
| Høyt dokumentvolum (>100K docs) | Mønster 2 (document summary) | Kostnadseffektiv |
| Kritisk retrieval-kvalitet | Mønster 3 (full hybrid) | Maksimal reduksjon i failures |
| Budget-begrenset PoC | Ingen contextual retrieval | Start med standard hybrid search |
### Vanlige feil
| Feil | Konsekvens | Løsning |
|------|------------|---------|
| Genererer kontekst med gpt-4o-mini | Lavere kvalitet på kontekst | Bruk gpt-4o for kontekst-generering |
| Ingen caching av document summaries | Gjentatte LLM-kall for samme dokument | Cache summary og gjenbruk per chunk |
| Ignorerer BM25-indeksering av kontekst | Mister keyword-matching fordeler | Indekser berikede chunks i searchable felt |
| Overlap > timeout (PT90S) | Skill-feil ved store batcher | Reduser batch-størrelse eller øk timeout |
---
## Integrasjon med Microsoft-stakken
| Tjeneste | Integrasjonspunkt |
|----------|-------------------|
| **Azure AI Search** | Skillset pipeline (Custom Web API Skill + Text Merge + Embedding) |
| **Azure OpenAI** | GPT-4o for kontekst-generering, text-embedding-3-large for embedding |
| **Azure Functions** | Hosting av custom skill (Python/C#), consumption plan |
| **Azure AI Document Intelligence** | Document Layout skill for strukturert chunking før context enrichment |
| **Semantic Kernel** | TextChunker + custom context injection i kode-basert pipeline |
| **Application Insights** | Monitorering av skill-latency, LLM token-bruk, feilrate |
### Fullstendig skillset-pipeline
```
Blob Storage → Indexer → Skillset:
1. Document Layout skill (struktur → Markdown)
2. Text Split skill (chunk-størrelse kontroll)
3. Custom Context Generation skill (GPT-4o)
4. Text Merge skill (context + chunk)
5. Azure OpenAI Embedding skill (text-embedding-3-large)
→ Index (med index projections for parent-child)
→ Query (hybrid search + semantic ranker)
```
---
## Offentlig sektor (Norge)
### Dataplassering
- **Azure AI Search:** Norway East — data i Norge
- **Azure Functions:** Norway East — compute i Norge
- **Azure OpenAI:** Sweden Central (nærmeste region med GPT-4o) — data i EU/EØS
- **GDPR:** Kontekst-generering behandler dokumentinnhold via LLM — databehandleravtale påkrevd
### Relevante vurderinger
| Krav | Implikasjon |
|------|-------------|
| **Forvaltningsloven** | Kontekstuell prefiks skal ikke endre dokumentets meningsinnhold |
| **GDPR Art. 17** | Sletting av kildedokument kaskaderer til berikede chunks |
| **AI Act** | Dokumenter bruk av LLM i indekseringspipeline som del av AI-systemdokumentasjon |
| **Sikkerhetsloven** | Gradert informasjon kan ikke sendes til Azure OpenAI — bruk on-premises alternativ |
---
## Kostnad og lisensiering
### Kostnadskomponenter
| Komponent | Prismodell | Estimat (1 000 dokumenter, 20 chunks/doc) |
|-----------|------------|-------------------------------------------|
| Context generation (GPT-4o) | Per token | ~60 NOK (100 tokens/chunk × 20K chunks) |
| Text embedding (text-embedding-3-large) | Per token | ~5 NOK (berikede chunks er ~30% større) |
| Azure Functions (consumption) | Per invocation | ~2 NOK |
| Økt vektorlagring | Per GB | ~5 NOK/mnd (berikede chunks = større indeks) |
| **Totalt ekstra vs. standard RAG** | — | ~72 NOK per 1 000 dokumenter |
### ROI-vurdering
Hvis contextual retrieval reduserer irrelevante LLM-kall med 30%:
- Savings per 1 000 queries: 300 × 10 NOK = 3 000 NOK
- Incremental cost per 1 000 docs: ~72 NOK
- **Break-even:** >24 queries per 1 000 dokumenter (svært lav terskel)
---
## For arkitekten (Cosmo)
### Spørsmål å stille kunden
1. **"Hvor ofte er retrieval-kvaliteten utilstrekkelig i dag?"** — Contextual retrieval lønner seg mest ved dårlig baseline
2. **"Hva er typisk dokumentlengde?"** — Lange dokumenter med mange seksjoner gir størst effekt
3. **"Er det mye tvetydig innhold (pronomen, forkortelser)?"** — Indikerer høy verdi av kontekst
4. **"Hva er akseptabel indekseringskostnad?"** — GPT-4o kall per chunk er ikke gratis
5. **"Bruker dere hybrid search (BM25 + vektor)?"** — Contextual retrieval gir størst effekt med hybrid search
### Fallgruver
- **Hopper over baseline-måling:** Uten metrics på nåværende retrieval-kvalitet kan du ikke bevise forbedring
- **Kontekst som forvrenger mening:** LLM-generert kontekst kan introdusere feil — valider med stikkprøver
- **Over-investering i kontekst for enkle use cases:** Noen dokumentsamlinger er allerede godt chunket
### Anbefalinger per modenhetsnivå
| Modenhet | Anbefaling |
|----------|------------|
| **Prototyp** | Standard chunking + hybrid search. Mål baseline retrieval metrics. |
| **Pilot** | Legg til document summary-basert kontekst (mønster 2). Test med 500 docs. |
| **Produksjon** | Per-chunk contextual retrieval (mønster 1) + BM25 + semantic ranker. |
| **Enterprise** | Full mønster 3 med reranking. A/B-testing. Automated quality evaluation. |
---
## Kilder og verifisering
| Kilde | Konfidens | URL |
|-------|-----------|-----|
| Contextual Retrieval (Anthropic) | **Verified** | [anthropic.com](https://www.anthropic.com/news/contextual-retrieval) |
| Context-Aware RAG System (MS Tech Community) | **Verified** | [techcommunity.microsoft.com](https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/context-aware-rag-system-with-azure-ai-search-to-cut-token-costs-and-boost-accur/4456810) |
| Building Contextual Retrieval System (MS Tech Community) | **Verified** | [techcommunity.microsoft.com](https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/building-a-contextual-retrieval-system-for-improving-rag-accuracy/4271924) |
| Custom skill interface (Azure AI Search) | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/search/cognitive-search-custom-skill-interface) |
| Custom skill example (Python) | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/previous-versions/azure/search/cognitive-search-custom-skill-python) |
| Retrieval failure benchmarks | **Baseline** | Anthropic research, validert av Microsoft |
### Custom Skill Interface (oppdatert 2026-04)
Custom skills integreres i Azure AI Search enrichment pipeline via `#Microsoft.Skills.Custom.WebApiSkill`.
**Interface-krav:**
- HTTPS endpoint (Azure Functions, containers, eller annen Azure-hosted tjeneste)
- Aksepterer JSON batch: `{"values": [{"recordId": "...", "data": {...}}, ...]}`
- Returnerer JSON batch: `{"values": [{"recordId": "...", "data": {...}, "errors": [], "warnings": []}]}`
- Timeout: default 30s, maks 230s (`PT230S`)
- Autentisering: API-key i URI/header, eller managed identity med `authResourceId`
**Kontekstuell berikelse via custom skill:**
Custom skills brukes for contextual retrieval der hver chunk berikes med kontekst fra omliggende tekst (f.eks. "Dette er fra kapittel 3 om sikkerhet..."). Custom skill kaller LLM med original dokument + chunk, og returnerer kontekstualisert chunk for bedre embedding-kvalitet.