# Hierarchical RAG Patterns — Multi-nivå retrieval

**Last updated:** 2026-02
**Status:** GA (index projections), Preview (agentic retrieval)
**Category:** RAG Architecture & Semantic Search

---

## Introduksjon

Hierarchical RAG organiserer kunnskap i multi-nivå strukturer i stedet for flat chunk-indeksering. Ved å etablere relasjoner mellom parent-dokumenter, seksjoner og chunks muliggjøres en «zoom inn/ut»-mekanisme der søk starter bredt (dokumentnivå) og driller ned til relevante segmenter.

Azure AI Search implementerer hierarkisk RAG gjennom **index projections** som håndterer one-to-many relasjoner mellom kildedokumenter og chunks. Document Intelligence Layout skill bevarer dokumentstruktur (headings, avsnitt) som muliggjør hierarkisk navigasjon.

Forskning (2025-2026) viser at hierarkisk retrieval gir 47% høyere Hit@1 og opptil 250x reduksjon i token-kostnad sammenlignet med flat retrieval, fordi søkeområdet reduseres gjennom coarse-to-fine filtrering.

---

## Kjernekomponenter

### Parent-child relasjoner i Azure AI Search

Azure AI Search tilbyr tre arkitekturmønstre for parent-child indeksering:

| Mønster | Beskrivelse | Brukstilfelle |
|---------|-------------|---------------|
| **Single index, repeating parent fields** | Parent-metadata repeteres per chunk | Standard RAG, enkel query-logikk (anbefalt) |
| **Single index, mixed document shapes** | Parents og chunks co-eksisterer | Fulldokument-søk + chunk-søk i én indeks |
| **Separate parent-child indexes** | Dedikert parent-index + child-index | Enterprise med strikt separasjon, compliance |

### Index projection-konfigurasjon

```json
{
  "indexProjections": {
    "selectors": [
      {
        "targetIndexName": "my_consolidated_index",
        "parentKeyFieldName": "parent_id",
        "sourceContext": "/document/pages/*",
        "mappings": [
          { "name": "chunk", "source": "/document/pages/*" },
          { "name": "chunk_vector", "source": "/document/pages/*/chunk_vector" },
          { "name": "title", "source": "/document/title" }
        ]
      }
    ],
    "parameters": {
      "projectionMode": "skipIndexingParentDocuments"
    }
  }
}
```

**Nøkkelparametere:**

| Parameter | Verdier | Beskrivelse |
|-----------|---------|-------------|
| `projectionMode` | `skipIndexingParentDocuments` / `includeIndexingParentDocuments` | Kun chunks eller begge |
| `parentKeyFieldName` | `parent_id`, `text_parent_id` | Felt som kobler chunk → parent |
| `sourceContext` | `/document/pages/*` | Enrichment path for granularitet |

### Automatisk chunk-ID generering

Azure AI Search genererer chunk-IDer basert på parent-ID:
- Parent: `aa1b22c33`
- Chunk 1: `aa1b22c33_pages_0`
- Chunk 2: `aa1b22c33_pages_1`

Hash-komponenten endres ved parent-oppdatering → sikrer change tracking.

---

## Arkitekturmønstre

### Mønster 1: Single index med parent-metadata (anbefalt)

**Arkitektur:** Data source → Indexer → Document Layout → Text Split → Embedding → Index projections (parent fields repeteres per chunk)

**Index-schema:**
```json
{
  "fields": [
    { "name": "chunk_id", "type": "Edm.String", "key": true },
    { "name": "parent_id", "type": "Edm.String", "filterable": true },
    { "name": "chunk", "type": "Edm.String", "searchable": true },
    { "name": "chunk_vector", "type": "Collection(Edm.Single)" },
    { "name": "title", "type": "Edm.String", "filterable": true },
    { "name": "section_heading", "type": "Edm.String", "filterable": true },
    { "name": "page_number", "type": "Edm.Int32", "filterable": true }
  ]
}
```

**Fordeler:**
- Enklest å implementere og vedlikeholde
- Én query gir chunks med full parent-kontekst
- Metadata-filtrering (tittel, seksjon) for hierarkisk drill-down

**Anbefalt for:** 80% av RAG-løsninger, spesielt ved enkel dokumentstruktur.

### Mønster 2: Multi-resolution retrieval med lookup-queries

**Arkitektur:** Child index (chunks) + Parent index (summaries/metadata) → Vector search på child → Lookup til parent

**Implementering:**
```python
# Steg 1: Hent relevante chunks
child_results = child_client.search(
    vector_queries=[VectorQuery(vector=query_embedding, k=5)],
    select=["chunk_id", "parent_id", "chunk"]
)

# Steg 2: Lookup parent-dokumenter
parent_ids = {r["parent_id"] for r in child_results}
parent_docs = parent_client.search(
    filter=f"parent_id in ({','.join(parent_ids)})",
    select=["parent_id", "title", "summary"]
)

# Steg 3: Assembler kontekst
context = []
for chunk in child_results:
    parent = next(p for p in parent_docs if p["parent_id"] == chunk["parent_id"])
    context.append({
        "chunk": chunk["chunk"],
        "source": parent["title"],
        "summary": parent["summary"]
    })
```

**Fordeler:**
- «Zoom ut» fra chunk til fullt dokument
- Parent-summary gir LLM bedre kontekstuell forståelse
- Sporbarhet for citation og audit

**Anbefalt for:** Enterprise RAG med krav til kildehenvisning og compliance.

### Mønster 3: Retrieval cascade (Summary → Section → Chunk)

**Arkitektur:** Tre indeksnivåer med progressiv filtrering:

```
Nivå 1: Document summaries → Velg relevante dokumenter (top-10)
Nivå 2: Section headings → Velg relevante seksjoner (top-20)
Nivå 3: Chunks → Hent detaljerte segmenter (top-5)
```

**Fordeler:**
- Drastisk reduksjon av søkerom (10-100x)
- Minimerer «lost in the middle»-problemet
- Opptil 250x reduksjon i token-kostnad

**Ulemper:**
- Tre separate søkeoperasjoner (økt latency)
- Kompleks indeksstruktur
- Krever generering av summaries per dokument/seksjon

**Anbefalt for:** Store dokumentsamlinger (>100K docs) der flat søk gir dårlig precision.

---

## Beslutningsveiledning

### Beslutningstabell

| Scenario | Volum | Anbefalt mønster |
|----------|-------|------------------|
| Standard RAG | <50K docs | Mønster 1 (single index, parent fields) |
| Krav til citation/sporbarhet | Alle | Mønster 2 (lookup queries) |
| Stort volum, lav precision | >100K docs | Mønster 3 (retrieval cascade) |
| Compliance/audit | Alle | Mønster 2 med `dataDeletionDetectionPolicy` |

### Vanlige feil

| Feil | Konsekvens | Løsning |
|------|------------|---------|
| Ingen parent-child mapping | Kan ikke spore chunk → kildedokument | Bruk index projections med `parentKeyFieldName` |
| Ignorerer `dataDeletionDetectionPolicy` | GDPR right to erasure brytes | Konfigurer cascade deletion på data source |
| Flat index for >100K docs | Dårlig precision, høy token-kostnad | Vurder retrieval cascade |
| Manglende metadata (section, page) | Ingen mulighet for hierarkisk filtrering | Legg til `section_heading` og `page_number` |

---

## Integrasjon med Microsoft-stakken

| Tjeneste | Integrasjonspunkt |
|----------|-------------------|
| **Azure AI Search** | Index projections, parent-child mapping, lookup queries |
| **Azure AI Document Intelligence** | Document Layout skill med `markdownHeaderDepth: "h3"` |
| **Azure Content Understanding** | Semantisk chunking med kryssende sider |
| **Azure OpenAI** | Summary-generering for retrieval cascade |
| **Semantic Kernel** | TextSearchProvider med namespace-filtrering |
| **Azure Cosmos DB** | Alternativ parent-child storage med hierarkisk query |

### Document Layout skill for hierarkisk chunking

```json
{
  "@odata.type": "#Microsoft.Skills.Util.DocumentIntelligenceLayoutSkill",
  "context": "/document",
  "outputMode": "oneToMany",
  "markdownHeaderDepth": "h3",
  "inputs": [{"name": "file_data", "source": "/document/file_data"}],
  "outputs": [{"name": "markdown_document", "targetName": "markdownDocument"}]
}
```

Output: Markdown med `# H1`, `## H2`, `### H3` som bevarer hierarkisk dokumentstruktur.

---

## Offentlig sektor (Norge)

### Dataplassering

- **Azure AI Search:** Norway East — hierarkisk indeks forblir i Norge
- **Document Intelligence:** West Europe — dokument-parsing i EU

### Relevante vurderinger

| Krav | Implikasjon |
|------|-------------|
| **Forvaltningsloven** | Chunks må spores til kildedokument — krev parent-child mapping |
| **GDPR Art. 17** | Sletting av kildedokument MÅ kaskadere til alle chunks |
| **AI Act** | Hierarkisk sporbarhet støtter forklarbarhetskrav |
| **Arkivloven** | Parent-index bevarer dokumentkontekst for arkivformål |

---

## Kostnad og lisensiering

### Kostnadskomponenter

| Komponent | Kostnad | Notat |
|-----------|---------|-------|
| Index projections | Inkludert i AI Search | Ingen ekstra kostnad |
| Document Layout skill | ~$0.01-0.05/side | Document Intelligence-prising |
| Summary-generering (cascade) | GPT-4o per dokument | ~$0.01-0.05/dokument |
| Ekstra indekslagring (parent-felter) | Per GB | ~20-30% økning ved repeterte felter |

### Optimaliseringstips

1. **Bruk `projectionMode: skipIndexingParentDocuments`** for å unngå dobbelt lagring
2. **Generer summaries off-peak** for å minimere compute-kostnad
3. **Sett `stored: false` på vektorfelt** for å spare lagringsplassn

---

## For arkitekten (Cosmo)

### Spørsmål å stille kunden

1. **"Trenger brukerne å se hvilke dokumenter et svar kommer fra?"** — Hvis ja, krev parent-child mapping
2. **"Hvor mange dokumenter er i samlingen?"** — >100K → vurder cascade
3. **"Er det compliance-krav til sletting (GDPR)?"** — Krev cascade deletion
4. **"Har dokumentene tydelig struktur (headings, kapitler)?"** — Bruk Document Layout skill
5. **"Hva er akseptabel query-latency?"** — Cascade = 2-3x latency

### Fallgruver

- **Over-engineering for småskala:** Single index med parent fields er nok for <50K docs
- **Glemmer deletion policy:** GDPR-brudd hvis chunks overlever parent-sletting
- **Cascade uten summaries:** Første nivå i cascade trenger AI-genererte summaries for å fungere

### Anbefalinger per modenhetsnivå

| Modenhet | Anbefaling |
|----------|------------|
| **Prototyp** | Single index med `parent_id` felt. Ingen cascade. |
| **Pilot** | Index projections med parent fields + Document Layout. |
| **Produksjon** | Mønster 2 (lookup queries) + cascade deletion policy. |
| **Enterprise** | Retrieval cascade + AI-summaries + automated quality evaluation. |

---

## Kilder og verifisering

| Kilde | Konfidens | URL |
|-------|-----------|-----|
| Define index projections (Azure AI Search) | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/search/search-how-to-define-index-projections) |
| Chunk and vectorize by document layout | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/search/search-how-to-semantic-chunking) |
| RAG and generative AI (Azure AI Search) | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/search/retrieval-augmented-generation-overview) |
| Model complex data types | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/search/search-howto-complex-data-types) |
| Hierarchical RAG research | **Baseline** | [emergentmind.com](https://www.emergentmind.com/topics/hierarchical-rag) |
