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.
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 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.
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.
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.
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.
Mønsteret dukker opp overalt der fysiske objekter, kontrakter eller kunder har en livshistorie spredt over flere systemer.
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.
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.
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.
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)
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.
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.
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.
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.
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.
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.
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.
# 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)
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.
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.
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.