Tech AI · 7 min lesing

Når du vet nøyaktig
hva du leter etter

RAG er svaret når du ikke vet hvor svaret er. Men hva om du vet det? Da er et vanlig søk feil verktøy — og vectordatabaser helt unødvendig. Context injection er det enklere, presise alternativet.

01 — Grunnforskjellen

RAG leter. Context injection slår opp.

RAG løser et finneproblemet: du har en stor haug med tekst, du vet ikke nøyaktig hva som er relevant, og du ber en embedding-modell finne de nærmeste naboene til spørsmålet ditt. Det er smart — men det er søk under usikkerhet.

Context injection er noe annet. Du har en nøkkel — et serienummer, et kundenummer, et IMO-nummer, en ordre-ID — og du vet nøyaktig hvilke systemer som har data om den nøkkelen. Oppgaven er ikke å finne riktig dokument. Oppgaven er å hente, sammenstille og tolke.

🔍 RAG — søk under usikkerhet
Spørsmålet er ustrukturert: "fortell meg om X"
Ikke kjent på forhånd hvilke dokumenter som er relevante
Semantisk nærhet avgjør hva som hentes
Passer for store tekstkorpus: manualer, e-post, rapporter
Krever vectordatabase og embedding-modell
🔑 Context injection — presisjonsoppslag
Nøkkelen er kjent: serienummer, IMO, kunde-ID
Systemene som har data er kjent på forhånd
Eksakt oppslag — ingen usikkerhet i retrieval
Passer for strukturerte systemer: ERP, CRM, CMMS, IoT
Krever kun API-kall og en god systemprompt

RAG spør: "Hva er relevant?" Context injection spør: "Hva vet vi om dette objektet — og hva betyr det?"

Det er ingenting i veien for å kombinere de to. Presis context injection for strukturerte data, RAG for tekstlig dokumentasjon. Mange av de mest nyttige systemene gjør akkurat det.

02 — Mekanikken

Slik fungerer det

Flyten er enkel. En nøkkel trigger et sett med parallelle oppslag mot ulike systemer. Svarene sammenstilles til en strukturert context. Den contexten sendes til språkmodellen sammen med brukerens spørsmål.

Context injection — flyt
🔑
Nøkkel inn
IMO-nr, serienr, kunde-ID
Parallelle oppslag
API-kall til N systemer
🧩
Sammenstill
Bygg strukturert context
🤖
Modellen tolker
Spørsmål + context → svar
Parallelle oppslag reduserer ventetid — hent fra alle systemer samtidig, ikke sekvensielt

Fan-out: én nøkkel, mange systemer

Det karakteristiske mønsteret er fan-out: én inngangsnøkkel ekspanderer til oppslag mot mange systemer. Hvert system bidrar med sin del av bildet — ingen av dem har hele historien alene.

🔧
Vedlikeholdssystem
Servicehistorikk, åpne arbeidsordrer
📦
Parts-database
Komponenter, serienummer, BOM
🚨
Alarm-historikk
Feil siste 90 dager, trender
📋
Teknisk dokumentasjon
Manualer for denne modellen
📡
Sensordata / IoT
Temperatur, trykk, driftstimer
🔑
Én nøkkel
f.eks. serienummer
📄
Kontekst
Sammenstilt til AI

Legg merke til at dokumentasjon godt kan hentes via RAG her — du vet hvilken modell det gjelder, og kan bruke det som nøkkel inn i et semantisk søk mot manualer og servicenotater. Strukturert data (alarms, sensorer, historikk) hentes via API. Begge lander i samme contextobjekt.

03 — Use cases

Hvem trenger presisjonsoppslag?

Mønsteret dukker opp overalt der fysiske objekter, kontrakter eller kunder har en livshistorie spredt over flere systemer.

⚙️
Industrielt vedlikehold
Maritim / Industri
Tekniker skanner QR-kode på en pumpe. Systemet henter servicehistorikk, active alarms, siste målinger og relevant del av servicemanualen. AI gir anbefalt tiltak.
Serienummer Utstyrs-ID Plassering
🚢
Skip og fartøy
Maritim
IMO-nummer trigger oppslag mot klassedatabase, equipmentsregister, vedlikeholdsplan og alarmsystem. AI sammenstiller status og kan flagge flag fra klassekrav.
IMO-nummer MMSI Call sign
🏥
Medisinsk equipment
Helse
Serienummer på en CT-skanner henter vedlikeholdslogg, kalibreringsstatus, tilbakekallingsnotater fra produsent og active feilkoder. Gir biomed-ingeniøren et samlet bilde.
Serienummer UDI Avdeling
🚗
Kjøretøy og flåte
Transport / Forsikring
Registreringsnummer eller VIN henter EU-kontrollhistorikk, forsikringsavtaler, leasingbetingelser, servicelogg og active feilkoder fra OBD. Passer for flåteoperatører og forsikringsselskaper.
VIN Regnr Chassis-ID
🏢
Kundeservice / CRM
Alle bransjer
Kundenummer henter ordrehistorikk, åpne saker, abonnementsavtaler, betalingsstatus og tidligere interaksjoner. Agent eller AI-bot kan svare i full context fra første message.
Kundenummer Ordrenummer Epost
🏗️
Bygg og anlegg
Eiendom / FM
Bygnings-ID eller matrikkel-ID henter BIM-modell, driftsavtaler, energidata, tilstandsrapporter og åpne flag. Driftsansvarlig kan spørre: "hva trenger ettersyn denne måneden?"
Bygnings-ID Matrikkel Etasje/rom
Energi og kraftnett
Energi / Utilities
Anleggs-ID på en transformator eller vindturbin henter driftsdata, flagsmessageer, inspeksjonshistorikk og produksjonsstatistikk. AI kan vurdere om planlagt vedlikehold bør fremskyndes.
Anleggs-ID NVE-nr Koordinater
💊
Legemidler og batch
Pharma / Matproduksjon
Batchnummer eller lot-nummer trigger sporbarhetskjeden: råvarer, produksjonslogg, QC-resultater, distribusjon og mottakere. Kritisk ved tilbakekall — AI kan raskt identifisere omfang.
Batchnummer Lot-ID GLN
04 — Kontekstkvalitet

Hva du putter inn avgjør alt

Siden vi ikke er avhengig av semantisk søk for å finne riktige data, flyttes ansvaret for kvalitet helt over til hva vi velger å inkludere og hvordan vi strukturerer det. Modellen er god — gi den godt råstoff.

Vær selektiv, ikke uttømmende

Det er fristende å dumpe alt du har om et objekt inn i contexten. Det er feil strategi. Lange, ufiltrerte datadumper gir dårligere svar enn kortfattede, strukturerte oppsummeringer. Velg ut det som er relevant for denne typen spørsmål.

Et godt utgangspunkt: lag ulike contextmaler for ulike bruksscenarier. En tekniker som feilsøker trenger annen context enn en controller som vurderer vedlikeholdsbudsjett for samme objekt.

Strukturer contexten — ikke bare dump JSON

Rå JSON er maskinlesbart, ikke modellvennlig. Oversett til klartekst med tydelige seksjoner. Inkluder enheter, tidsstempler og kildeangivelse. En modell som ser «temperatur: 87» vet ingenting — «Kjølevannstemperatur: 87 °C (normalverdi: 60–75 °C, siste avlesning: 14.03.2026 08:42)» er nyttig.

Python — bygg strukturert contexttekst fra API-svar
def format_context(equipment_id: str, data: dict) -> str:
    """Convert raw API data into a model-friendly context string."""

    equipment = data["equipment"]
    alarms = data["alarms"]
    service = data["service_history"]
    sensor  = data["sensor_readings"]

    lines = [
        f"## Utstyr: {equipment['name']} ({equipment_id})",
        f"Modell: {equipment['model']}  |  Produsert: {equipment['year']}  |  Plassering: {equipment['location']}",
        f"Driftstimer totalt: {equipment['runtime_hours']:,} t",
        "",
        "## Latest sensor readings",
    ]

    for s in sensor["latest"]:
        flag = " ⚠️ UTENFOR NORMALVERDI" if s["out_of_range"] else ""
        lines.append(
            f"  {s['name']}: {s['value']} {s['unit']}"
            f"  (normalt: {s['normal_range']}, avlest: {s['timestamp']}){flag}"
        )

    active = [a for a in alarms if a["active"]]
    lines += ["", f"## Active alarms ({len(active)})"]
    if active:
        for a in active:
            lines.append(f"  [{a['severity'].upper()}] {a['code']}: {a['description']} — siden {a['since']}")
    else:
        lines.append("  Ingen active alarms.")

    lines += ["", "## Service history (siste 3)"]
    for s in service["recent"][:3]:
        lines.append(f"  {s['date']}  {s['type']}  — {s['summary']}")

    return "\n".join(lines)
💡
Inkluder normalverdier og historikk. En verdi isolert gir lite — en verdi i context av hva som er normalt, og hvordan den har endret seg, gir modellen mulighet til å resonnere om trender og flag.
05 — Best practice

Hva som faktisk avgjør kvaliteten

01

Hent parallelt — ikke sekvensielt

Fem API-kall sekvensielt tar 5× så lang tid som parallelt. Bruk asyncio.gather() i Python eller Promise.all() i JavaScript. Brukeropplevelsen avhenger av det tregeste systemet — ikke summen av alle.

02

Håndter manglende data eksplisitt

Ikke alle systemer returnerer data for alle nøkler. Om vedlikeholdssystemet ikke finner serienummeret skal contexten si «ingen data fra vedlikeholdssystem» — ikke utelate seksjonen stille. Modellen bør vite hva som mangler, ikke bare hva som finnes.

03

Fortell modellen hva det skal gjøre med contexten

En god systemprompt spesifiserer rollen («du er teknisk støtteassistent for kompressorer»), hva contexten inneholder, og hva slags svar som er forventet. Ikke la modellen gjette formålet.

04

Cache det som ikke endrer seg

Tekniske spesifikasjoner for en modell endres sjelden. Sensor-avlesninger endres hvert minutt. Cache statisk data aggressivt — det reduserer latens og API-kostnader, og gjør systemet mer robust mot tredjepartstjenester som er nede.

05

Kombiner med RAG der det gir mening

Strukturerte data (alarms, historikk, sensorer) hentes via eksakt oppslag. Ustrukturert dokumentasjon (servicenotater, manualer, bulletiner) hentes via RAG med modell og kategori som nøkkel. Begge lander i samme contextobjekt — det er ikke enten/eller.

06

Logg hva som ble hentet

Når modellen gir et svar basert på injisert context er det avgjørende å kunne spore tilbake: hvilke systemer ble spurt, hva returnerte de, og hva ble faktisk sendt til modellen. Logger på contextnivå er langt mer nyttig enn kun å logge brukerens spørsmål og svar.

06 — Kodeeksempel

En komplett injection-pipeline

Her er et fullt eksempel som henter data fra tre systemer parallelt, sammenstiller contexten og sender til Claude. Systemene er stubbet som enkle Python-funksjoner — i praksis er dette API-kall, databasespørringer eller SDK-er.

Python — parallel context injection med asyncio + Claude
# pip install anthropic

import asyncio, anthropic
from datetime import datetime

# ── Replace these stubs with your actual API calls ─────────────────

async def fetch_equipment(equipment_id: str) -> dict:
    # Bytt ut med ditt CMMS / ERP / SQL-spørring
    return {
        "name": "Kjølevannspumpe #3",
        "model": "Grundfos CM5-7",
        "location": "Maskinrom B, spant 42",
        "runtime_hours": 14820,
        "installed": "2019-04-12",
    }

async def fetch_alarms(equipment_id: str) -> list:
    # Bytt ut med ditt alarm-system
    return [
        {"code": "HH-TI-301", "description": "Høy kjølevannstemperatur",
         "severity": "high", "active": True,  "since": "2026-03-13 06:14"},
        {"code": "L-PI-204",  "description": "Lavt oljetrykk",
         "severity": "medium", "active": False, "since": "2026-02-28 22:05"},
    ]

async def fetch_service(equipment_id: str) -> list:
    # Bytt ut med ditt vedlikeholdssystem
    return [
        {"date": "2026-01-15", "type": "Periodisk service",
         "summary": "Tetningsring byttet, pumpe OK"},
        {"date": "2025-07-03", "type": "Uplanlagt stopp",
         "summary": "Vibrasjon, impeller rengjort"},
    ]

# ── Fetch everything in parallel ───────────────────────────────────

async def build_context(equipment_id: str) -> str:
    equipment, alarms, service = await asyncio.gather(
        fetch_equipment(equipment_id),
        fetch_alarms(equipment_id),
        fetch_service(equipment_id),
    )

    active = [a for a in alarms if a["active"]]
    alarm_text = "\n".join(
        f"  [{a['severity'].upper()}] {a['code']}: {a['description']} siden {a['since']}"
        for a in active
    ) or "  Ingen active alarms."

    service_text = "\n".join(
        f"  {s['date']}  {s['type']} — {s['summary']}"
        for s in service[:3]
    )

    return f"""## Utstyr: {equipment['name']} ({equipment_id})
Model: {equipment['model']}  |  Location: {equipment['location']}
Runtime: {equipment['runtime_hours']:,} h  |  Installed: {equipment['installed']}

## Active alarms ({len(active)})
{alarm_text}

## Service history
{service_text}

(Data fetched: {datetime.now().strftime('%Y-%m-%d %H:%M')})"""

# ── Query Claude with the context ──────────────────────────────────

async def ask(equipment_id: str, question: str) -> str:
    context = await hent_context(equipment_id)

    client = anthropic.Anthropic()
    svar = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1024,
        system="""Du er teknisk støtteassistent for skipsequipment.
Du mottar strukturert context om et spesifikt equipment.
Svar basert på contexten. Fremhev flag og risiko tydelig.
Referer alltid til konkrete verdier, koder og datoer fra contexten.""",
        messages=[{
            "role": "user",
            "content": f"Utstyrscontext:\n{context}\n\nSpørsmål: {question}"
        }]
    )
    return svar.content[0].text

# Run
result = asyncio.run(ask("EQ-4421", "What is the current status and what should I do now?"))
print(result)
🚀
Poenget med parallell henting: asyncio.gather() kjører alle tre API-kallene samtidig. Om hvert kall tar 300 ms tar hele operasjonen ~300 ms — ikke 900 ms. For systemer med mange datakilder er dette avgjørende for responsivitet.

Hva modellen faktisk får

Det er verdt å stoppe opp og se på hva som sendes til Claude. Konteksten er ikke rå JSON — den er strukturert prosa med klare seksjoner, konkrete verdier og eksplisitt markering av flag. Modellen kan dermed resonnere: aktiv høy-alarm på kjølevannstemperatur, kombinert med en historikk som inkluderer en vibrasjonsstopp siste år, er en annen situasjon enn de samme alarmene uten den historikken.

Det er tolkningen som er verdiskapingen — ikke oppslagene i seg selv. Oppslagene kunne en dataingeniør gjort for tjue år siden. Det nye er at du kan stille contexten et åpent spørsmål og få et gjennomtenkt svar tilbake.

📄
Relatert artikkel
Hva er RAG?
Når du ikke vet nøyaktig hva du leter etter — vectorsøk, embeddings og semantisk retrieval.
Avslutning

Ikke alt er et søkeproblem

Det er lett å gå inn i AI-prosjekter med hammeren «semantisk søk» og se alle problemer som spiker. Men mange av de mest verdifulle brukstilfellene er ikke søkeproblemer i det hele tatt — de er aggregeringsproblemer. Dataen finnes. Systemene finnes. Det som mangler er sammenstillingen og tolkningen.

Context injection er teknisk sett enklere enn RAG. Ingen vectordatabase, ingen embedding-modell, ingen indeksering. Men den arkitektoniske utfordringen er større: du må kjenne systemlandskapet godt nok til å vite hva som bør hentes, i hvilken form, og med hvilken prioritet.

Den vanskelige jobben er ikke å koble til systemene. Det er å bestemme hva som er relevant å fortelle modellen — og hva som bare er støy.