feat(ms-ai-architect): add plugin to open marketplace (v1.5.0 baseline)

Initial addition of ms-ai-architect plugin to the open-source marketplace.
Private content excluded: orchestrator/ (Linear tooling), docs/utredning/
(client investigation), generated test reports and PDF export script.
skill-gen tooling moved from orchestrator/ to scripts/skill-gen/.

Security scan: WARNING (risk 20/100) — no secrets, no injection found.
False positive fixed: added gitleaks:allow to Python variable reference
in output-validation-grounding-verification.md line 109.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-04-07 17:17:17 +02:00
commit 6a7632146e
490 changed files with 213249 additions and 2 deletions

View file

@ -0,0 +1,329 @@
# Document Chunking — Strategies and Implementation
**Last updated:** 2026-02
**Status:** GA (core features), Preview (token chunking)
**Category:** RAG Architecture & Semantic Search
---
## Introduksjon
Chunking er prosessen med å dele opp dokumenter i mindre segmenter som kan indekseres og hentes uavhengig i en RAG-pipeline. Kvaliteten på chunking har direkte innvirkning på retrieval-kvalitet, svar-nøyaktighet og kostnader — og er ofte den viktigste faktoren for om en RAG-løsning oppleves som nyttig eller frustrerende.
Azure AI Search tilbyr fem innebygde chunking-strategier gjennom integrated vectorization: fixed-size (Text Split skill), variable-size (sentence mode), document layout-basert (Document Intelligence), semantisk (Azure Content Understanding), og document parsing (native formatstøtte). I tillegg støttes custom skills for egendefinert logikk via Azure Functions eller eksterne biblioteker som LangChain og Semantic Kernel.
Valg av chunking-strategi avhenger av dokumenttype, bruksmønster, kvalitetskrav og kostnadsrammer. Det finnes ingen universell "beste" strategi — men det finnes gode utgangspunkt og kjente fallgruver.
## Kjernekomponenter
### Chunking-strategier i Azure AI Search
| Strategi | Skill / Metode | Status | Kostnad | Best for |
|----------|---------------|--------|---------|----------|
| Fixed-size | Text Split skill (`pages` mode) | GA | Inkludert i AI Search | Generell RAG, rask oppsett |
| Sentence-basert | Text Split skill (`sentences` mode) | GA | Inkludert | Finkornet søk (bruk forsiktig) |
| Document Layout | Document Intelligence Layout skill | GA | Per side (DI-prising) | Strukturerte dokumenter (PDF, DOCX) |
| Semantisk | Azure Content Understanding skill | GA | Per dokument (CU-prising) | Komplekse dokumenter, kryssende sider |
| Document parsing | Indexer parsing modes (Markdown, JSON) | GA | Inkludert | Pre-strukturert innhold |
| Custom | Custom Web API skill | GA | Egen infrastruktur | Domenespesifikk logikk |
### Konfigurasjonsparametere (Text Split skill)
| Parameter | Default | Anbefalt start | Beskrivelse |
|-----------|---------|----------------|-------------|
| `textSplitMode` | `pages` | `pages` | `pages` = multi-sentence chunks, `sentences` = enkeltsetninger |
| `maximumPageLength` | 2000 | 2000 (tegn) | Maks tegn per chunk (~512 tokens) |
| `pageOverlapLength` | 0 | 500 (25%) | Overlapp mellom chunks |
| `defaultLanguageCode` | `en` | `no` (for norsk) | Språkspesifikk setningsdeteksjon |
| `maximumPagesToTake` | 0 | 0 | Begrens antall chunks (0 = alle) |
### Skillset-definisjon (Text Split)
```json
{
"@odata.type": "#Microsoft.Skills.Text.SplitSkill",
"textSplitMode": "pages",
"maximumPageLength": 2000,
"pageOverlapLength": 500,
"defaultLanguageCode": "no",
"context": "/document/content",
"inputs": [{"name": "text", "source": "/document/content"}],
"outputs": [{"name": "textItems", "targetName": "pages"}]
}
```
### Document Layout skill (strukturert 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"}]
}
```
## Arkitekturmønstre
### Mønster 1: Standard fixed-size chunking
**Arkitektur:** Data source → Indexer → Text Split skill → Embedding skill → Index
**Fordeler:**
- Enklest å sette opp og forstå
- Forutsigbar chunk-størrelse og kostnad
- Ingen ekstra API-kostnader (inkludert i AI Search)
- God nok for de fleste generelle brukstilfeller
**Ulemper:**
- Kan bryte semantisk sammenheng midt i avsnitt
- Ingen bevissthet om dokumentstruktur
- Overlap er eneste mekanisme for kontekstbevaring
**Anbefalt for:** Rask prototyping, generell RAG, homogent tekstinnhold.
### Mønster 2: Strukturbasert chunking med Document Intelligence
**Arkitektur:** Data source → Indexer → Document Layout skill → Text Split skill (om nødvendig) → Embedding skill → Index
**Fordeler:**
- Bevarer overskrifter, avsnitt og dokumentstruktur
- Markdown-output med hierarkiske headings
- Metadata om posisjon (sidenummer, bounding boxes)
- Kan kombineres med Text Split for størrelsesbegrensning
**Ulemper:**
- Ekstra kostnad per side (Document Intelligence-prising)
- Begrenset portalstøtte (East US, West Europe, North Central US)
- Krever filbasert datakilde (PDF, DOCX, PPTX, etc.)
**Anbefalt for:** Offentlig sektor (policy-dokumenter, regelverk), strukturerte rapporter, juridiske tekster.
### Mønster 3: Parent-child med index projections
**Arkitektur:** Data source → Indexer → Chunking skill → Index projections → Parent index + Child index
**Fordeler:**
- Sporbarhet: chunk → kildedokument via `text_parent_id`
- Muliggjør "zoom ut" fra chunk til fullt dokument
- Automatisk felt-mapping uten `outputFieldMappings`
- Viktig for citation tracking og audit
**Ulemper:**
- Mer kompleks indeksstruktur
- Krever forståelse av index projections
- Noe mer lagringskostnad
**Anbefalt for:** Enterprise RAG med krav til kildehenvisning, compliance-systemer, revisjonsklare løsninger.
### Mønster 4: Semantisk/kontekst-bevisst chunking
**Arkitektur:** Data source → Indexer → Azure Content Understanding skill → Semantiske enheter → Embedding skill → Index
**Konsept:** I stedet for å dele dokumenter etter fast størrelse eller setningsgrenser, identifiserer semantisk chunking meningsfulle tematiske enheter som kan spenne over sider. Azure Content Understanding (GA nov 2025) analyserer dokumentstruktur og semantikk for å produsere chunks som bevarer sammenhengende konsepter.
**Fordeler:**
- Chunks bryter ikke midt i et konsept eller argument
- Støtter kryss-side-enheter (tabeller, avsnitt som fortsetter)
- Markdown-output med LaTeX, HTML-tabeller og headings
- Bedre retrieval-kvalitet for komplekse dokumenter
**Ulemper:**
- Høyere kostnad enn Text Split (Content Understanding-prising)
- Regional tilgjengelighet begrenset
- Mindre forutsigbar chunk-størrelse
**Sammenligning med andre strategier:**
| Aspekt | Fixed-size | Document Layout | Semantisk (CU) |
|--------|-----------|-----------------|-----------------|
| Chunk-grenser | Tegntelling | Headings/avsnitt | Semantiske enheter |
| Kryss-side | Nei | Nei | Ja |
| Tabellhåndtering | Brytes | Delvis | Full støtte |
| Kostnad | Gratis | Per side (DI) | Per dokument (CU) |
| Forutsigbarhet | Høy | Middels | Lav |
**Custom semantic chunking via Azure Functions:**
For domenespesifikke krav kan du implementere egen semantisk chunking via custom skill:
```python
# Custom skill: Semantisk chunking med embedding-likhet
from sentence_transformers import SentenceTransformer
import numpy as np
model = SentenceTransformer("all-MiniLM-L6-v2")
def semantic_split(text, threshold=0.5):
sentences = text.split(". ")
embeddings = model.encode(sentences)
chunks, current = [], [sentences[0]]
for i in range(1, len(sentences)):
sim = np.dot(embeddings[i], embeddings[i-1]) / (
np.linalg.norm(embeddings[i]) * np.linalg.norm(embeddings[i-1]))
if sim < threshold:
chunks.append(". ".join(current))
current = [sentences[i]]
else:
current.append(sentences[i])
chunks.append(". ".join(current))
return chunks
```
**Anbefalt for:** Komplekse dokumenter med tabeller, kryssende seksjoner, og semantisk rike avsnitt.
## Beslutningsveiledning
### Beslutningstabell
| Dokumenttype | Volumkrav | Budsjett | → Anbefalt strategi |
|-------------|-----------|----------|---------------------|
| Ren tekst (artikler, e-post) | Alle | Lavt | Text Split (fixed-size) |
| Strukturerte PDF-er (rapporter) | Alle | Moderat | Document Layout skill |
| Komplekse dokumenter (tabeller over sider) | Lavt-moderat | Høyere | Content Understanding |
| Pre-strukturert (Markdown, JSON) | Alle | Lavt | Document parsing modes |
| Domenespesifikke krav | Alle | Varierer | Custom skill |
| Blanding av formater | Høyt | Moderat | Document Layout + fallback til Text Split |
### Vanlige feil
| Feil | Konsekvens | Løsning |
|------|------------|---------|
| `sentences` mode i produksjon | 200-siders PDF → 13 000+ chunks, enorm kostnad | Bruk `pages` mode |
| Overlap > 50% av chunk size | Gir faktisk ingen overlapp (Azure-begrensning) | Hold overlap ≤ 25-30% |
| Ignorerer token-grenser | Embedding-modellen trunkerer, kvalitetstap | Sjekk med tiktoken, hold under 8191 tokens |
| Ingen parent-child tracking | Kan ikke spore tilbake til kildedokument | Bruk index projections |
| Hardkodet chunk-størrelse | Suboptimal for ulike dokumenttyper | Test og iterer basert på kvalitetsmetrikker |
| Glemmer språkparameter | Feil setningsoppdeling for norsk tekst | Sett `defaultLanguageCode: "no"` |
### Røde flagg
- Chunk-størrelse valgt uten testing med faktiske spørringer
- Ingen overlapp i chunks med narrativt innhold
- Bruker `sentences` mode for annet enn analyse/forskning
- Ingen evaluering av retrieval-kvalitet etter chunking-endring
- Blander chunking-strategi og embedding-modell uten å re-evaluere
## Integrasjon med Microsoft-stakken
| Tjeneste | Integrasjonspunkt |
|----------|-------------------|
| **Azure AI Search** | Integrated vectorization pipeline (indexer → skillset → index) |
| **Azure OpenAI** | Embedding-generering (text-embedding-3-small/large) |
| **Document Intelligence** | Document Layout skill for strukturbasert chunking |
| **Azure Content Understanding** | Semantisk chunking med kryssende sider |
| **Azure Functions** | Custom chunking skills via Web API |
| **Microsoft Fabric / Databricks** | Pre-processing pipeline for stor-skala dokumentbehandling |
| **Semantic Kernel** | TextChunker-klasse for kode-basert chunking |
| **LangChain** | RecursiveCharacterTextSplitter for fleksibel chunking |
### Integrated vectorization pipeline
```
Blob Storage → Indexer → Skillset:
1. Document Layout / Text Split (chunking)
2. AzureOpenAIEmbedding (vektorisering)
→ Index (med index projections for parent-child)
→ Query (med semantic ranker + vectorizer)
```
## Offentlig sektor (Norge)
### Dataplassering og suverenitet
- **Azure AI Search:** Tilgjengelig i Norway East — data forblir i Norge
- **Document Intelligence:** Tilgjengelig i West Europe — data i EU, men ikke Norge spesifikt
- **Content Understanding:** Sjekk regional tilgjengelighet (endres hyppig)
- **GDPR:** Chunking-prosessen behandler potensielt personopplysninger — databehandleravtale påkrevd
### Relevante vurderinger
| Krav | Implikasjon for chunking |
|------|-------------------------|
| **Forvaltningsloven** | Chunks må kunne spores tilbake til kildedokument (bruk parent-child) |
| **GDPR Art. 17** | Sletting av kildedokument må kaskadere til chunks (index projections) |
| **AI Act** | Dokumentasjon av chunking-strategi som del av AI-systemdokumentasjon |
| **Schrems II** | Unngå tjenester som sender data utenfor EU/EØS under chunking |
| **Sikkerhetsloven** | Gradert informasjon krever on-premises chunking (custom skill) |
### Norsk språkstøtte
- Text Split skill: `defaultLanguageCode: "no"` for korrekt norsk setningsoppdeling
- Document Intelligence Layout: Støtter norsk tekst i OCR og strukturgjenkjenning
- Embedding-modeller (text-embedding-3): Støtter norsk, men tren/evaluer med norske testdata
## Kostnad og lisensiering
### Kostnadskomponenter
| Komponent | Prismodell | Estimat (liten skala) |
|-----------|------------|----------------------|
| Text Split skill | Inkludert i AI Search | $0 ekstra |
| Document Layout skill | DI Standard per side | ~$0.01-0.05/side |
| Content Understanding | Per dokument/side | Varierer |
| Embedding (text-embedding-3-small) | Per 1M tokens | ~$0.02/1M tokens |
| Vektorlagring | Per GB i indeksen | Avhenger av tier |
| Custom skill | Azure Functions compute | ~$0.20/million invocations |
### Optimaliseringstips
1. **Start med Text Split:** $0 ekstra kostnad, god nok for 70% av brukstilfeller
2. **Bruk Document Layout selektivt:** Kun for dokumenter som har viktig struktur
3. **Optimaliser chunk-størrelse:** Færre, større chunks = lavere embedding- og lagringskostnad
4. **Sett `stored: false` på vektorfelt:** Sparer lagring hvis du ikke trenger rå-vektorer i søkeresultater
5. **Batch-indeksering:** Kjør under off-peak for lavere compute-kostnad
6. **Monitor med Azure Cost Management:** Tag AI Search-ressurser for sporbarhet
### Kostnadseffekt av overlapp
Overlapp øker antall chunks proporsjonalt:
- 0% overlapp: N chunks
- 25% overlapp: ~1.33N chunks (+33% lagring og embedding-kostnad)
- 50% overlapp: ~2N chunks (+100% kostnad)
## For arkitekten (Cosmo)
### Spørsmål å stille kunden
1. **"Hva slags dokumenter skal indekseres?"** — Strukturerte PDF-er krever Document Layout, ren tekst klarer seg med Text Split
2. **"Hvor viktig er kildehenvisning i svarene?"** — Hvis viktig, krev parent-child med index projections
3. **"Hva er typisk spørringslengde og -type?"** — Korte, presise spørringer → mindre chunks. Brede tematiske → større chunks
4. **"Finnes det gradert eller sensitiv informasjon?"** — Kan kreve on-premises chunking med custom skill
5. **"Hva er akseptabel latency?"** — Flere chunks = mer søketid, men potensielt bedre kvalitet
6. **"Har dere norskspråklige dokumenter?"** — Sett `defaultLanguageCode: "no"`, test embedding-kvalitet
7. **"Hva er volumet?"** — Høyt volum + Document Intelligence = betydelig kostnad per side
8. **"Hvordan håndterer dere dokumentoppdateringer?"** — Inkrementell oppdatering vs. full re-indeksering påvirker arkitekturen
### Fallgruver
- **Over-engineering fra dag 1:** Start med Text Split, mål kvaliteten, iterer. Ikke begynn med Content Understanding før du har bevist at det trengs.
- **Chunk-størrelse som dogme:** "512 tokens" er et utgangspunkt, ikke et fasitsvar. Evaluer med faktiske spørringer og dokumenter.
- **Glemmer overlapp:** Uten overlapp mistes kontekst ved chunk-grenser. 25% er en god start.
- **Sentences-fellen:** `textSplitMode: sentences` ser logisk ut men genererer tusenvis av chunks per dokument. Bruk `pages`.
### Anbefalinger per modenhetsnivå
| Modenhet | Anbefaling |
|----------|------------|
| **Prototyp** | Text Split, 2000 tegn, 25% overlapp. Evaluer med 5-10 testspørringer. |
| **Pilot** | Legg til Document Layout for strukturerte dokumenter. Implementer parent-child med index projections. |
| **Produksjon** | Differensiert strategi per dokumenttype. Automatisert kvalitetsevaluering. Kostnadsmonitorering. |
| **Enterprise** | Custom skills for domenespesifikke krav. Token chunking (preview). A/B-testing av chunk-strategier. |
## Kilder og verifisering
| Kilde | Konfidens | URL |
|-------|-----------|-----|
| Chunk large documents for RAG (Azure AI Search) | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/search/vector-search-how-to-chunk-documents) |
| Chunk and vectorize by document layout | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/search/search-how-to-semantic-chunking) |
| Integrated vectorization overview | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/search/vector-search-integrated-vectorization) |
| Set up integrated vectorization (REST) | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/search/search-how-to-integrated-vectorization) |
| RAG chunking phase (Architecture Guide) | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/architecture/ai-ml/guide/rag/rag-chunking-phase) |
| RAG with Document Intelligence | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/ai-services/document-intelligence/concept/retrieval-augmented-generation) |
| Azure Search Vector Samples (GitHub) | **Verified** | [github.com/Azure](https://github.com/Azure/azure-search-vector-samples) |
| Token chunking (preview) | **Baseline** | Annonsert i 2025-11-01-preview API |
| Prisinformasjon | **Baseline** | Basert på offentlige prislister, sjekk Azure-kalkulator for oppdaterte priser |