Phase 2 bulk replace produced a few factually wrong attributions where real publicly known sector documents/datasets/personas were incorrectly re-attributed to the fictional generic entity. Genericize those references instead. - ros-sector-checklists.md: V440 håndbok citation -> "sektorvise faglige håndbøker"; tilsynsmyndighet list -> generic phrasing - master-data-management-ai.md: NVDB row -> generic "sektor-/fagregistre" - ai-center-of-excellence-setup.md: NVDB integration line -> generic "sektorvise nasjonale registre" - multimodal-prompt-engineering.md: system_message persona -> generic "fagingeniør i norsk offentleg sektor" Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
16 KiB
Multi-Modal Prompt Engineering Techniques
Last updated: 2026-02 Status: GA Category: Multi-Modal AI
Introduksjon
Multimodal prompt engineering er kunsten å skrive effektive instruksjonar som kombinerer tekst og bilete for å utnytte kapabilitetane til vision-enabled modellar som GPT-4o, GPT-4o mini og GPT-4 Turbo with Vision. Desse modellane aksepterer både tekst og bilete som input, og kan utføre oppgåver som bildeanalyse, visuelt resonnement, dokumentforståing og diagramtolking.
Microsoft sin offisielle rettleiing for image prompt engineering identifiserer seks grunnprinsipp: kontekstuell spesifisitet, oppgåveorienterte prompts, handtering av nekting (refusals), eksempelbruk, oppdeling av komplekse oppgåver, og definering av output-format. Desse prinsippa er like relevante for norsk offentleg sektor, der multimodale modellar kan nyttast til alt frå byggesaksanalyse til kvalitetssikring av veginfrastruktur.
Azure AI Foundry Playground tilbyr eit interaktivt miljø for å eksperimentere med multimodale prompts, og GPT-4o sin image tokenization-mekanisme påverkar både kostnader og ytelse. Forståing av korleis bilete vert konvertert til tokens er kritisk for kostnadsoptimalisering i produksjonssystem.
Kjernekomponentar
| Komponent | Formål | Teknologi |
|---|---|---|
| GPT-4o / GPT-4o mini | Multimodal chat med tekst + bilete | Azure OpenAI Service |
| Image Tokenization | Konvertering av bilete til tokens | Intern GPT-4o-mekanisme |
| System Messages | Kontekstsetting for visuelle oppgåver | Chat Completions API |
| Structured Output | JSON/schema-basert output frå visuell analyse | Response format |
| Vision Fine-tuning | Tilpassing av visuell forståing | GPT-4o (2024-08-06) |
| Content Filtering | Sikkerheitsfilter for bilete-input/output | Azure AI Content Safety |
Visual Grounding og Spatial Reasoning i Prompts
Grunnleggjande image prompt-prinsipp
- Kontekstuell spesifisitet — Gi modellen kontekst om kva biletet representerer
- Oppgåveorientering — Fokuser på ei spesifikk oppgåve
- Handle refusals — Reformuler ved nekting
- Bruk eksempel — Vis ønska output-type
- Del opp komplekse oppgåver — Steg-for-steg
- Definer output-format — JSON, Markdown, tabell osv.
Spatial reasoning-prompts
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_key=os.environ["AZURE_OPENAI_API_KEY"],
api_version="2024-10-21"
)
# Spatial reasoning: Posisjon og relasjonar i biletet
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": """Du er ein vegingeniør-assistent. Analyser
biletet av vegkrysset og beskriv:
1. Kva som er i NORD (øvst i biletet)
2. Kva som er i SØR (nedst)
3. Kva som er i ØST (høgre)
4. Kva som er i VEST (venstre)
5. Eventuelle trafikkproblem du observerer
Returner som strukturert JSON."""
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "Analyser dette vegkrysset for trafikkplanlegging:"
},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/intersection.jpg",
"detail": "high"
}
}
]
}
],
max_tokens=1000,
response_format={"type": "json_object"}
)
Visual grounding med bounding box-referansar
# Be modellen referere til spesifikke regionar
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": """Når du analyserer bilete, referer til
posisjonar med relative koordinatar:
- Øvste venstre = (0,0)
- Nedste høgre = (1,1)
Bruk format: [objekt] ved ca. (x, y)"""
},
{
"role": "user",
"content": [
{"type": "text", "text": "Identifiser alle trafikkskilt "
"og deira posisjon i biletet."},
{"type": "image_url", "image_url": {"url": image_url}}
]
}
]
)
Few-shot Examples with Images
Mønster: Klassifisering med bilete-eksempel
def classify_with_examples(target_image_url: str,
examples: list[dict]) -> str:
"""
Klassifiser med few-shot bilete-eksempel.
examples = [
{"url": "...", "label": "HULLROT", "forklaring": "..."},
{"url": "...", "label": "SPREKK", "forklaring": "..."},
]
"""
messages = [
{
"role": "system",
"content": "Du er ein vegskade-klassifiseringsekspert. "
"Bruk dei gitte eksempla som referanse."
}
]
# Legg til eksempel-bilete som user/assistant-par
for ex in examples:
messages.append({
"role": "user",
"content": [
{"type": "text", "text": "Klassifiser denne vegskaden:"},
{"type": "image_url",
"image_url": {"url": ex["url"], "detail": "low"}}
]
})
messages.append({
"role": "assistant",
"content": f"Klassifisering: {ex['label']}\n"
f"Forklaring: {ex['forklaring']}"
})
# Legg til målbiletet
messages.append({
"role": "user",
"content": [
{"type": "text", "text": "Klassifiser denne vegskaden:"},
{"type": "image_url",
"image_url": {"url": target_image_url, "detail": "high"}}
]
})
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
max_tokens=500
)
return response.choices[0].message.content
Token-budsjett for few-shot med bilete
| Detalj-nivå | Tokens per bilete | Kostnadsimplikasjon |
|---|---|---|
low |
85 tokens (GPT-4o) | Optimal for eksempel-bilete |
high (1024x1024) |
~765 tokens (GPT-4o) | Bruk for mål-biletet |
high (2048x2048) |
~2805 tokens | Reduser til 1024 om mogleg |
auto |
Varierer | Standard — modellen vel |
Best practice for few-shot:
- Bruk
"detail": "low"for eksempel-bilete (85 tokens kvar) - Bruk
"detail": "high"for mål-biletet (full analyse) - Avgrens til 3-5 eksempel for å spare tokens
- Plasser biletet før tekst for single-image prompts
Chain-of-Thought Reasoning with Visuals
Visuell CoT-teknikk
# Steg-for-steg visuelt resonnement
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": """Du er ein byggesak-ekspert for norsk
offentleg sektor. Analyser biletet steg for steg:
STEG 1: Beskriv kva du ser i biletet i detalj
STEG 2: Identifiser relevante byggtekniske element
STEG 3: Vurder samsvar med gjeldande forskrifter
STEG 4: Gi din konklusjon med grunngjeving
Vis resonneringskjeda tydeleg."""
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "Vurder om dette byggeprosjektet "
"ser ut til å følgje TEK17 krav "
"til universell utforming:"
},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/building-entrance.jpg",
"detail": "high"
}
}
]
}
],
max_tokens=2000
)
Multi-image CoT-samanlikning
# Samanlikn to bilete med resonnement
messages = [
{
"role": "system",
"content": """Samanlikn dei to bileta steg for steg:
1. Beskriv bilete A
2. Beskriv bilete B
3. Identifiser forskjellar
4. Gi vurdering basert på forskjellane"""
},
{
"role": "user",
"content": [
{"type": "text",
"text": "Bilete A (før tiltak):"},
{"type": "image_url",
"image_url": {"url": before_url, "detail": "high"}},
{"type": "text",
"text": "Bilete B (etter tiltak):"},
{"type": "image_url",
"image_url": {"url": after_url, "detail": "high"}},
{"type": "text",
"text": "Vurder om vedlikehaldstiltaket er utført korrekt."}
]
}
]
"Describe first"-teknikken
Når modellen nektar å utføre ei oppgåve, be den først beskrive biletet:
# Steg 1: Be modellen beskrive biletet detaljert
describe_response = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": [
{"type": "text",
"text": "Beskriv dette biletet i detalj, inkludert "
"alle synlege element, tekst, tal og merking."},
{"type": "image_url",
"image_url": {"url": image_url, "detail": "high"}}
]
}]
)
description = describe_response.choices[0].message.content
# Steg 2: Utfør analyse basert på skildringa
analysis = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system",
"content": "Analyser følgjande bildeskilding for "
"reguleringsplan-samsvar."},
{"role": "user",
"content": f"Bildeskilding:\n{description}\n\n"
"Vurder om det skildra bygget er i samsvar "
"med reguleringsplanen."}
]
)
System Messages for Multi-Modal Tasks
Template-struktur for visuelle system messages
VISUAL_SYSTEM_TEMPLATE = """
ROLLE: {rolle}
KONTEKST: {kontekst}
OPPGÅVE: {oppgåve}
ANALYSEINSTRUKSJONAR:
{steg_for_steg_instruksjonar}
OUTPUT-FORMAT:
{format_spesifikasjon}
AVGRENSINGAR:
- {avgrensing_1}
- {avgrensing_2}
- Om du er usikker, sei eksplisitt kva du er usikker på
- Ikkje gjett — be om tilleggsinformasjon om nødvendig
"""
# Eksempel: Vegskade-vurdering
system_message = VISUAL_SYSTEM_TEMPLATE.format(
rolle="Fagingeniør med 20 års erfaring frå norsk offentleg sektor",
kontekst="Årlege fagvise inspeksjonar i Noreg",
oppgåve="Vurder vegskade og anbefal vedlikehaldstiltak",
steg_for_steg_instruksjonar="""
1. Identifiser skadetypen (sprekk, hullrot, setning, kantskade)
2. Vurder alvorlegheit på skala 1-5
3. Estimer utbreiing i m2
4. Anbefal tiltak (lappearbeid, fresing, full omlegging)
5. Prioriter (akutt, innan 3 mnd, neste sesong)""",
format_spesifikasjon="""JSON med felt:
{
"skadetype": "string",
"alvorlegheit": 1-5,
"utbreiing_m2": number,
"tiltak": "string",
"prioritet": "akutt|3mnd|neste_sesong",
"grunngjeving": "string"
}""",
avgrensing_1="Ikkje anslå kostnad utan prisgrunnlag",
avgrensing_2="Merk alle vurderingar der confidence er låg"
)
Rollebaserte system messages
| Rolle | System message-fokus | Typisk output |
|---|---|---|
| Byggesak-konsulent | TEK17-samsvar, reguleringsplan | Avviksliste med referanse |
| Vegingeniør | Skadeklassifisering, NVDB-kategori | Vedlikehaldsprioritering |
| Kulturminne-rådgjevar | Tilstandsvurdering, freding | Tilstandsrapport |
| Miljørådgjevar | Artsidentifisering, habitatvurdering | Konsekvensutgreiing |
Image Tokenization og Kostnadsoptimalisering
Token-forbruk per bilete
GPT-4o token-kalkulering (high detail):
- Skaler biletet slik at lengste side er maks 2048px
- Skaler så kortaste side er maks 768px
- Del biletet i 512x512-tiles
- Kvar tile = 170 tokens
- Legg til 85 base tokens
import math
def estimate_image_tokens(width: int, height: int,
detail: str = "high",
model: str = "gpt-4o") -> int:
"""Estimer token-forbruk for eit bilete."""
if detail == "low":
return 85 if model == "gpt-4o" else 2833
# High detail: Skaler ned
max_long = 2048
max_short = 768
# Steg 1: Skaler lengste side til 2048
ratio = min(max_long / max(width, height), 1.0)
w, h = int(width * ratio), int(height * ratio)
# Steg 2: Skaler kortaste side til 768
ratio2 = min(max_short / min(w, h), 1.0)
w, h = int(w * ratio2), int(h * ratio2)
# Steg 3: Tell tiles
tiles_x = math.ceil(w / 512)
tiles_y = math.ceil(h / 512)
total_tiles = tiles_x * tiles_y
# Steg 4: Kalkuler tokens
return 85 + (170 * total_tiles)
# Eksempel
tokens = estimate_image_tokens(4096, 3072, "high")
print(f"Estimerte tokens: {tokens}") # 85 + (170 * 6) = 1105
Kostnadsoptimaliseringsstrategiar
| Strategi | Besparingsestimat | Avveging |
|---|---|---|
Bruk detail: low for eksempel-bilete |
80-95% per bilete | Lågare oppløysing |
| Resize til 1024x1024 før sending | 40-60% | Tap av findetaljar |
| Crop til relevant region | 60-80% | Krev forhandskjennskap |
| Cache analyseresultat | 100% på gjenbruk | Stale data-risiko |
| Batch liknande bilete | Redusert overhead | Meir kompleks logikk |
Norsk offentleg sektor
Bruksområde for multimodal prompt engineering
- Byggesak: Visuell vurdering av samsvar med reguleringsplanar
- Vegforvaltning: Automatisk skadeklassifisering frå dronefoto
- Kulturarv: Tilstandsvurdering av kulturminne frå bilete
- Plan og kart: Analyse av reguleringsplanar og kartutsnitt
- Miljø: Artsidentifisering og habitatvurdering
Prompt-design for norsk kontekst
- Skriv system messages på norsk for domene-spesifikk terminologi
- Referer til norske standardar (TEK17, NVDB, NS-EN-standardar)
- Inkluder norske einskapar (NOK, m2, km/t)
- Bruk norske stadnamn og referansar
Personvern i multimodale prompts
- Bilete av personar: Aldri be modellen identifisere personar
- Nummerplatar: Sladd før analyse om ikkje nødvendig
- Brev/dokument: Fjern personnummer frå bilete-input
- Azure OpenAI content filtering aktiv som standard
Beslutningsrammeverk
| Scenario | Anbefaling | Grunngjeving |
|---|---|---|
| Enkel bildeklassifisering | Zero-shot med god system message | Raskast, lågast kostnad |
| Konsistent klassifisering | Few-shot med 3-5 eksempel-bilete | Betre konsistens, høgare kostnad |
| Kompleks vurdering | Chain-of-thought med steg-instruksjonar | Transparent resonnement |
| Kostnadsoptimalisering | detail: low + resize + caching |
Drastisk token-reduksjon |
| Nekting/refusal-problem | "Describe first"-teknikk | Omgå overivrig filtering |
| Multi-bilete-samanlikning | Sekvensielle bilete med tydelege labels | Unngå forvirring |
| Produksjonssystem | Structured output (JSON) + validering | Påliteleg parsing |
For Cosmo
- Seks grunnprinsipp for image prompts: Kontekstuell spesifisitet, oppgåveorientering, refusal-handtering, eksempelbruk, oppgåvedeling og output-formatering — følg Microsoft sin offisielle rettleiing for GPT-4o vision.
- Few-shot med bilete brukar
detail: low(85 tokens) for eksempel ogdetail: highfor mål-biletet — dette gir konsistent klassifisering utan å sprengje token-budsjettet. - Chain-of-thought med visuelt resonnement gir transparente vurderingar — kritisk for offentleg sektor der avgjerder må grunngjevast, be modellen vise resonneringskjeda steg for steg.
- Image tokenization avgjer kostnad: Eit 4096x3072 bilete i
high detailkostar ~1105 tokens med GPT-4o — resize til 1024x1024 reduserer til ~765 tokens, oglow detailer flat 85 tokens. - System messages på norsk med domene-terminologi gir betre resultat enn engelske generelle prompts — referer til norske standardar, einskapar og kontekst for presise fagvurderingar.