# 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://.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.