Add /ultraresearch-local for structured research combining local codebase analysis with external knowledge via parallel agent swarms. Produces research briefs with triangulation, confidence ratings, and source quality assessment. New command: /ultraresearch-local with modes --quick, --local, --external, --fg. New agents: research-orchestrator (opus), docs-researcher, community-researcher, security-researcher, contrarian-researcher, gemini-bridge (all sonnet). New template: research-brief-template.md. Integration: --research flag in /ultraplan-local accepts pre-built research briefs (up to 3), enriches the interview and exploration phases. Planning orchestrator cross-references brief findings during synthesis. Design principle: Context Engineering — right information to right agent at right time. Research briefs are structured artifacts in the pipeline: ultraresearch → brief → ultraplan --research → plan → ultraexecute. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
248 lines
10 KiB
Markdown
248 lines
10 KiB
Markdown
# Late Chunking Patterns — Chunking etter embedding
|
|
|
|
**Last updated:** 2026-02
|
|
**Status:** GA (Jina Embeddings), Preview (Azure Marketplace)
|
|
**Category:** RAG Architecture & Semantic Search
|
|
|
|
---
|
|
|
|
## Introduksjon
|
|
|
|
Late chunking er en teknikk der et helt dokument embeddes gjennom en transformer-modell *før* det deles opp i chunks. I tradisjonell (naiv) chunking embeddes hver chunk isolert, og mister dermed kontekst fra resten av dokumentet — pronomener som «den», «de» og «selskapet» blir semantisk tvetydige.
|
|
|
|
Ved late chunking genererer modellen token-level embeddings med full dokumentkontekst via self-attention, og deretter beregnes chunk-embeddings via mean pooling over de relevante token-posisjonene. Resultatet er at hvert segment «vet» hva resten av dokumentet inneholder.
|
|
|
|
Jina AI introduserte teknikken i 2024 (arXiv:2409.04701) og viste konsistent forbedring på BeIR-datasett: SciFact +1.9%, NFCorpus +27.8% relativ forbedring i nDCG@10. Effekten øker med dokumentlengde.
|
|
|
|
Azure-integrasjon er mulig via Jina Embeddings v3/v4 på Azure Marketplace. Azure OpenAI sine embedding-modeller (text-embedding-3) eksponerer per i dag ikke token-level embeddings, men overlapping chunk-strategier gir en tilnærming.
|
|
|
|
---
|
|
|
|
## Kjernekomponenter
|
|
|
|
### Naiv vs. Late Chunking
|
|
|
|
| Aspekt | Naiv chunking | Late chunking |
|
|
|--------|---------------|---------------|
|
|
| **Rekkefølge** | Chunk → Embed | Embed → Chunk |
|
|
| **Kontekst-scope** | Kun innen chunk | Hele dokumentet |
|
|
| **Kryss-referanser** | Tapes | Bevares via token-embeddings |
|
|
| **Krav til modell** | Vilkårlig embedding-modell | Long-context embedding (8K+ tokens) |
|
|
| **Kostnad** | Lavere (kun chunks embeddes) | Høyere (fullt dokument embeddes) |
|
|
|
|
### Long-context embedding-modeller
|
|
|
|
| Modell | Context Length | Dimensjoner | Azure-tilgjengelighet |
|
|
|--------|----------------|-------------|----------------------|
|
|
| **text-embedding-3-large** | 8 191 tokens | 3 072 | GA via Azure OpenAI |
|
|
| **text-embedding-3-small** | 8 191 tokens | 1 536 | GA via Azure OpenAI |
|
|
| **jina-embeddings-v3** | 8 192 tokens | 1 024 | Azure Marketplace |
|
|
| **jina-embeddings-v4** | 8 192 tokens | 1 024 | Azure Marketplace |
|
|
|
|
8 000 tokens ≈ 10 standardsider — tilstrekkelig for de fleste enkeltdokumenter.
|
|
|
|
### Benchmark-resultater (BeIR)
|
|
|
|
| Datasett | Naiv chunking (nDCG@10) | Late chunking (nDCG@10) | Forbedring |
|
|
|----------|--------------------------|-------------------------|------------|
|
|
| SciFact | 64.20% | 66.10% | +1.9 pp |
|
|
| NFCorpus | 23.46% | 29.98% | +6.52 pp (+27.8%) |
|
|
|
|
Effekten er størst for lengre dokumenter med mange kryss-referanser.
|
|
|
|
---
|
|
|
|
## Arkitekturmønstre
|
|
|
|
### Mønster 1: Native late chunking med Jina Embeddings
|
|
|
|
**Arkitektur:** Data source → Indexer → Text extraction → Jina API (`late_chunking=True`) → Azure AI Search index
|
|
|
|
**Implementering:**
|
|
|
|
```python
|
|
import requests
|
|
|
|
response = requests.post(
|
|
"https://<jina-endpoint>.azurecontainer.io/v1/embeddings",
|
|
headers={"Authorization": f"Bearer {api_key}"},
|
|
json={
|
|
"input": full_document_text,
|
|
"model": "jina-embeddings-v3",
|
|
"late_chunking": True,
|
|
"chunk_size": 512
|
|
}
|
|
)
|
|
chunk_embeddings = response.json()["data"]
|
|
```
|
|
|
|
**Fordeler:**
|
|
- Ekte late chunking med full dokumentkontekst
|
|
- Native API-parameter — ingen custom logikk
|
|
- God multilingual-støtte (norsk inkludert)
|
|
|
|
**Ulemper:**
|
|
- Krever Jina-modell (ikke Azure OpenAI natively)
|
|
- Azure Marketplace deployment nødvendig
|
|
- 8K token-grense per dokument
|
|
|
|
**Anbefalt for:** Narrative dokumenter med mange kryss-referanser (juridiske tekster, forskningsrapporter).
|
|
|
|
### Mønster 2: Pseudo-late chunking med overlapping windows (Azure OpenAI)
|
|
|
|
**Arkitektur:** Data source → Indexer → Text Split (chunks med kontekst-vinduer) → Azure OpenAI Embedding → Index
|
|
|
|
**Implementering:**
|
|
|
|
```python
|
|
from openai import AzureOpenAI
|
|
|
|
client = AzureOpenAI(...)
|
|
chunks = split_document(document, chunk_size=500, overlap=150)
|
|
|
|
for i, chunk in enumerate(chunks):
|
|
# Include surrounding chunks for context
|
|
context_window = chunks[max(0,i-1):min(len(chunks),i+2)]
|
|
enriched_text = " ".join(context_window)
|
|
|
|
embedding = client.embeddings.create(
|
|
model="text-embedding-3-large",
|
|
input=enriched_text[:8000]
|
|
).data[0].embedding
|
|
```
|
|
|
|
**Fordeler:**
|
|
- Bruker Azure OpenAI (ingen tredjepartavhengighet)
|
|
- Enkelt å implementere i eksisterende pipeline
|
|
- 70-80% av late chunking-effekten til lavere kostnad
|
|
|
|
**Ulemper:**
|
|
- Ikke ekte late chunking (kun nabochunk-kontekst)
|
|
- Økt embedding-kostnad (3x chunk-størrelse)
|
|
|
|
**Anbefalt for:** Teams som vil ha bedre kontekst uten å introdusere Jina-avhengighet.
|
|
|
|
### Mønster 3: Hybrid — Late chunking for langdokumenter, naiv for korte
|
|
|
|
**Arkitektur:** Router → [Kort dokument: naiv chunking] + [Langt dokument: late chunking] → Felles index
|
|
|
|
**Beslutningsregel:**
|
|
- Dokument < 2 000 tokens → Naiv chunking (lite å vinne)
|
|
- Dokument 2 000-8 000 tokens → Late chunking via Jina
|
|
- Dokument > 8 000 tokens → Segmenter i 8K-vinduer, late chunking per segment
|
|
|
|
**Anbefalt for:** Produksjonsløsninger med heterogene dokumentsamlinger.
|
|
|
|
---
|
|
|
|
## Beslutningsveiledning
|
|
|
|
### Beslutningstabell
|
|
|
|
| Dokumenttype | Late chunking? | Begrunnelse |
|
|
|-------------|----------------|-------------|
|
|
| Lange rapporter (>2K tokens) | Ja | Mange kryss-referanser |
|
|
| Narrative tekster (artikler) | Ja | Kontekst flyter mellom seksjoner |
|
|
| Korte, selvstendige docs | Nei | Ingen kryss-avhengigheter |
|
|
| Strukturerte data (tabeller, lister) | Nei | Rader/elementer er selvstendig |
|
|
| Juridiske dokumenter med referanser | Ja | Paragrafhenvisninger krever kontekst |
|
|
|
|
### Vanlige feil
|
|
|
|
| Feil | Konsekvens | Løsning |
|
|
|------|------------|---------|
|
|
| Late chunking på korte docs (<1K tokens) | Ingen gevinst, økt kostnad | Bruk naiv chunking for korte docs |
|
|
| Ignorerer 8K token-grense | Trunkering = tap av sluttkontekst | Segmenter lange docs i 8K-vinduer |
|
|
| Blander embedding-modeller i samme indeks | Inkompatible vektorrom | Én modell per vector-felt |
|
|
| Hopper over eval etter bytte | Vet ikke om det faktisk hjalp | Mål nDCG@10, precision@5, recall@5 |
|
|
|
|
---
|
|
|
|
## Integrasjon med Microsoft-stakken
|
|
|
|
| Tjeneste | Integrasjonspunkt |
|
|
|----------|-------------------|
|
|
| **Azure AI Search** | Vector index med custom embedding via push API eller custom skill |
|
|
| **Azure OpenAI** | text-embedding-3-large for pseudo-late chunking (mønster 2) |
|
|
| **Jina Embeddings (Azure Marketplace)** | Native late chunking via Container Instance |
|
|
| **Azure Functions** | Custom skill wrapper for Jina API |
|
|
| **Azure AI Document Intelligence** | Tekst-ekstraksjon før late chunking |
|
|
| **Semantic Kernel** | Custom embedding connector for Jina |
|
|
|
|
---
|
|
|
|
## Offentlig sektor (Norge)
|
|
|
|
### Dataplassering
|
|
|
|
- **Jina Embeddings (Azure Marketplace):** Deploy i Norway East — data forblir i Norge
|
|
- **Azure OpenAI Embeddings:** Sweden Central — data i EU/EØS
|
|
- **Azure AI Search:** Norway East — indeks i Norge
|
|
|
|
### Relevante vurderinger
|
|
|
|
| Krav | Implikasjon |
|
|
|------|-------------|
|
|
| **Schrems II** | Jina AI er tysk selskap — EU-data processing |
|
|
| **GDPR** | Embedding-prosessen behandler dokumentinnhold — databehandleravtale |
|
|
| **Sikkerhetsloven** | Gradert informasjon krever on-premises embedding |
|
|
|
|
---
|
|
|
|
## Kostnad og lisensiering
|
|
|
|
### Kostnadssammenligning (1 000 dokumenter, 5 000 tokens snitt, 10 chunks/doc)
|
|
|
|
| Tilnærming | Embedding-kall | Totalt tokens | Kostnad (text-embedding-3-large) |
|
|
|------------|----------------|---------------|----------------------------------|
|
|
| Naiv chunking | 10 000 | ~500K | ~$0.26 |
|
|
| Late chunking (full doc + chunks) | 11 000 | ~5.5M | ~$2.86 |
|
|
| Pseudo-late chunking (3x window) | 10 000 | ~1.5M | ~$0.78 |
|
|
|
|
**Trade-off:** 3-10x kostnadsøkning for 5-30% bedre retrieval-kvalitet (avhengig av dokumenttype).
|
|
|
|
### Jina Embeddings på Azure
|
|
|
|
- **Deployment:** Azure Container Instance (consumption-basert)
|
|
- **Prising:** Per API-kall til Jina-endepunktet
|
|
- **Fordel:** Ingen Azure OpenAI-kvote nødvendig
|
|
|
|
---
|
|
|
|
## For arkitekten (Cosmo)
|
|
|
|
### Spørsmål å stille kunden
|
|
|
|
1. **"Hvor lange er dokumentene?"** — Late chunking gir mest verdi for docs >2 000 tokens
|
|
2. **"Er det mange kryss-referanser internt i dokumenter?"** — Pronomen, forkortelser, «se avsnitt 3.2»
|
|
3. **"Er retrieval-kvaliteten god nok i dag?"** — Mål baseline først
|
|
4. **"Aksepterer dere Jina AI som tredjepart?"** — GDPR/vendor assessment
|
|
5. **"Hva er embedding-budsjettet?"** — Late chunking er 3-10x dyrere
|
|
|
|
### Fallgruver
|
|
|
|
- **Over-investering for korte docs:** Late chunking gir tilnærmet null gevinst for docs <1K tokens
|
|
- **Vendor lock-in til Jina:** Azure OpenAI kan få native late chunking-støtte — design for utbyttbarhet
|
|
- **Manglende evaluering:** Uten nDCG/precision-metrics vet du ikke om det hjelper
|
|
|
|
### Anbefalinger per modenhetsnivå
|
|
|
|
| Modenhet | Anbefaling |
|
|
|----------|------------|
|
|
| **Prototyp** | Naiv chunking med 25% overlap. Mål baseline. |
|
|
| **Pilot** | Pseudo-late chunking (mønster 2) med 3-chunk vinduer. Sammenlign metrics. |
|
|
| **Produksjon** | Hybrid (mønster 3) — late chunking for lange docs, naiv for korte. |
|
|
| **Enterprise** | Native late chunking via Jina + A/B-testing mot baseline. |
|
|
|
|
---
|
|
|
|
## Kilder og verifisering
|
|
|
|
| Kilde | Konfidens | URL |
|
|
|-------|-----------|-----|
|
|
| Late Chunking in Long-Context Embedding Models (Jina AI) | **Verified** | [jina.ai](https://jina.ai/news/late-chunking-in-long-context-embedding-models/) |
|
|
| arXiv:2409.04701 (forskningspaper) | **Verified** | [arxiv.org](https://arxiv.org/abs/2409.04701) |
|
|
| Jina Embeddings on Azure Marketplace | **Verified** | [azuremarketplace.microsoft.com](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/jinaai.jina-embeddings-v4) |
|
|
| Jina Embeddings v3 announcement | **Verified** | [jina.ai](https://jina.ai/news/jina-embeddings-v3-a-frontier-multilingual-embedding-model/) |
|
|
| Azure OpenAI Embeddings | **Verified** | [learn.microsoft.com](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/tutorials/embeddings) |
|
|
| Late Chunking tutorial (DataCamp) | **Baseline** | [datacamp.com](https://www.datacamp.com/tutorial/late-chunking) |
|