# 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

---

## 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 Statens vegvesen 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.