ms-ai-architect/skills/ms-ai-engineering/references/multi-modal/dalle-image-generation.md
Kjell Tore Guttormsen 3a73eeafdc refactor(ms-ai-architect): R13 del 1 — nøytraliser Cosmo-personaen i ref-korpusets headinger, etter å ha rettet en gate som var målt usann to ganger
Ordre 20260912T193441Z-7358817909. Steg 1 var ikke transformen, men å rette
roadmapens R13-gate og få den ratifisert. Gaten `grep -rl "Cosmo"
skills/*/references -> 0` var usann på to uavhengige måter:

1. Ordren fanget den første: 451 av forekomstene er Azure Cosmos DB, ekte
   produktinnhold. Diskriminatoren er ikke bokstaven «s» — `Cosmos <norsk
   substantiv>` er genitiv av personaen (`### Cosmos tonalitet`), mens
   `Cosmos DB`/`CosmosClient`/`cosmos_ru` er produkt.
2. Denne økten fant den andre: 132 persona-forekomster ligger i prosa,
   tabeller, dialog-replikker og proveniens-linjer. Heading-nøytralisering
   kan ikke nå dem, så «0 persona» er uoppnåelig også under den ratifiserte
   formen. Operatøren ratifiserte alternativ A: gaten speiler formen, og de
   132 bokføres til R13b/R14.

Tre korreksjoner av premisser som sto i ordren og STATE:
  «ca 320 produkt»   -> 451 (case-sensitivt nett manglet 327 lowercase
                        TOC-ankre + 99 identifikatorer; sann nevner 1 638)
  «169 headinger»    -> 401. 169 var `^## For Cosmo`-prefikset (168) og var
                        internt inkonsistent med sin egen topp-variant (204)
  «417 matcher ingen
   populasjon»       -> 417 er cosmo-headinger utenfor kodefences; briefens
                        nevner var reell hele tiden

Fence-bevissthet er målt skadelig, ikke nødvendig: begge toggle-regler er
gale på dette korpuset (naiv toggle skjuler en ekte heading i
chain-of-thought-prompting.md, CommonMark-regelen ubalanserer
service-level-documentation-dr.md). Fence-agnostisk deteksjon finner 401
heading-linjer i nøyaktig de samme 40 variantene som fence-bevisst finner
400 i — ingen kodeblokk-linje er byte-identisk til en persona-heading. Derfor
nøkles transformen på 40 enumererte heading-tekster og ignorerer fences. En
ukjent variant kaster; en slug-kollisjon kaster. Ingenting auto-fikses.

TOC-en regenereres ikke, den rettes kirurgisk: alle 327 persona-lenker hadde
lenketekst lik én av de 40 heading-tekstene og anker lik slugify av den
(327/327, 0 avvik), så heading og TOC-entry skrives i samme operasjon og
ingen mellomtilstand etterlater en død lenke.

Ratifisert målform: `For Cosmo`, `For Cosmo Skyberg` og `For arkitekten
(Cosmo)` konvergerer på `For arkitekten`. To filer kolliderte og er adjudisert
ved å lese dem, ikke ved regel.

Verifisering (alle 7 kriterier fra ordren):
  G1 persona på heading-linjer   401 -> 0
  G2 døde fragmentlenker         1 -> 1 (pre-eksisterende, unntatt)
  G3 produkt-forekomster         451 -> 451; `Cosmos DB|Azure Cosmos` 308 = 308
  de 3 kun-produkt-filene        byte-identiske
  nettet validert begge veier    injisert persona feller G1; genitiv feller G1;
                                 produkt-heading og de 3 filene passerer
  hele diffen                    802 heading-linjer + 654 TOC-linjer, ANNET = 0
  linjeantall                    728 lagt til = 728 slettet
  suite                          1120/1120 (1097 + 23 nye)
  validate-plugin                250 PASS / 0 FAIL
  stikkprøve                     10 filer, alle 5 skills, inkl. de 3 mest
                                 produkt-tunge (26/20/19) — kun heading+TOC

Utenfor scope, urørt: de 4 SKILL.md, de 23 commands, CLAUDE.md, README.md,
NOTICE.md, docs/ (alt R14).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 22:12:28 +02:00

536 lines
19 KiB
Markdown

# DALL-E Image Generation for Public Sector
**Last updated:** 2026-02
**Status:** GA (DALL-E 3) / Limited Access Preview (GPT-image-1)
**Category:** Multi-Modal AI
**Type:** reference
---
## Innhold
- [Introduksjon](#introduksjon)
- [DALL-E Capabilities og Limitations](#dall-e-capabilities-og-limitations)
- [Content Filtering og Safety](#content-filtering-og-safety)
- [Batch Image Generation](#batch-image-generation)
- [Integration with Document Pipelines](#integration-with-document-pipelines)
- [Tilgjengelegheit (Accessibility) Considerations](#tilgjengelegheit-accessibility-considerations)
- [Merking og transparens](#merking-og-transparens)
- [For arkitekten](#for-arkitekten)
## Introduksjon
DALL-E og GPT-image-1 er Azure OpenAI sine bildegenerering-modellar som skapar bilete frå tekstbeskrivelsar. For norsk offentleg sektor opnar desse modellane moglegheiter innanfor visualisering av offentlege planforslag, illustrasjon av informasjonsmateriell, prototyping av brukargrensesnitt, og generering av tilgjengelege bilete for universell utforming.
Azure OpenAI sin bildegenereringsteneste kjem med innebygde Responsible AI-beskyttingar, inkludert innhaldsfiltrering, prompt-transformasjon for redusert bias, og Content Credentials som merkjer bilete som AI-generert. Dette er særleg viktig for offentleg sektor der tillit og truverde er fundamentalt.
Det er viktig å forstå at bildegenereringsmodellar har vesentlege avgrensingar: dei kan produsere faktisk feilaktige bilete, dei har bias frå treningsdata, og dei krev aktiv styring av innhaldskvalitet og etisk bruk. Norsk offentleg sektor må utvise særleg aktsemd knytt til bruk av AI-genererte bilete i offisiell kommunikasjon.
---
## DALL-E Capabilities og Limitations
### Modelloversikt
| Eigenskap | GPT-image-1.5 | GPT-image-1 | GPT-image-1-mini | DALL-E 3 |
|-----------|---------------|-------------|------------------|----------|
| **Status** | Limited Access | Limited Access | Limited Access | GA |
| **Bilete per request** | 1-10 | 1-10 | 1-10 | 1 |
| **Maks prompt-lengde** | 32 000 teikn | 32 000 teikn | 32 000 teikn | 4 000 teikn |
| **Størleikar** | Fleksibel | Fleksibel | Fleksibel | 1024x1024, 1792x1024, 1024x1792 |
| **Kvalitetsval** | auto, high, medium, low | auto, high, medium, low | auto, high, medium, low | hd, standard |
| **Stilval** | Tilpassa | Tilpassa | Tilpassa | vivid, natural |
| **Inpainting/editing** | Ja | Ja | Ja | Ja |
| **Ansiktsbevaring** | Ja (avansert) | Ja (avansert) | Nei | Nei |
| **Streaming** | Ja | Ja | Ja | Nei |
| **Output-format** | PNG, JPEG, WEBP | PNG, JPEG, WEBP | PNG, JPEG, WEBP | URL (24t gyldig) |
| **Transparent bakgrunn** | Ja (PNG) | Ja (PNG) | Ja (PNG) | Nei |
### Regionstilgjengelegheit
| Modell | Regionar |
|--------|---------|
| **DALL-E 3** | East US, Australia East, Sweden Central |
| **GPT-image-1** | West US 3, UAE North, Poland Central (Global Standard) |
| **GPT-image-1-mini** | Sjekk Azure-portalen for oppdatert liste |
| **GPT-image-1.5** | Sjekk Azure-portalen for oppdatert liste |
> **For norsk offentleg sektor:** DALL-E 3 er tilgjengeleg i Sweden Central, som er den næraste EU/EØS-regionen. GPT-image-1 krev Global Standard deployment.
### Kjende avgrensingar
| Avgrensing | Detaljar | Workaround |
|-----------|---------|-----------|
| **Tekst i bilete** | Variabel kvalitet, spesielt for norsk | Legg til tekst i post-prosessering |
| **Nøyaktigheit** | Kan generere faktisk feilaktige bilete | Alltid manuell gjennomgang |
| **Konsistens** | Vanskeleg å oppretthalde stil over bilete | Bruk detaljerte stilprompts |
| **Personar** | Fotorealistiske bilete av mindreårige blokkert | By design |
| **Opphavsrett** | Kan generere innhald som liknar verna materiale | Bruk innhaldsfiltrering |
| **Norske kulturelle referansar** | Avgrensa forståing av norsk kontekst | Detaljerte beskrivelsar |
---
## Content Filtering og Safety
### Innebygde Responsible AI-beskyttingar
Azure OpenAI bildegenereringsmodellar har fleire lag med tryggleiksbeskyttingar:
**Lag 1: Prompt-transformasjon (DALL-E 3)**
- Automatisk omskriving av prompts for betre kvalitet og mangfald
- Reduserer bias i genererte bilete
- Kan ikkje deaktiverast
**Lag 2: Innhaldsfiltrering (Input)**
- Analyserer prompt for skadeleg innhald
- Blokkerer prompts som bryt brukspolicyen
- Konfigurerbare alvorlegheitsgrader
**Lag 3: Innhaldsfiltrering (Output)**
- Analyserer generert bilete etter opprettelse
- Blokkerer bilete som bryt tryggleiksreglane
- Returnerer feilmelding `contentFilter`
**Lag 4: Content Credentials**
- Alle DALL-E-bilete inkluderer digital legitimasjon (C2PA)
- Markerer innhald som AI-generert
- Kan verifiserast med Content Authenticity Initiative SDK
### Innhaldsfilterkategoriar
| Kategori | Standardinnstilling | Kan konfiguerast |
|----------|-------------------|-----------------|
| **Hate** | Medium filtrering | Ja (låg, medium, høg) |
| **Violence** | Medium filtrering | Ja (låg, medium, høg) |
| **Sexual** | Medium filtrering | Ja (låg, medium, høg) |
| **Self-harm** | Medium filtrering | Ja (låg, medium, høg) |
| **Jailbreak risk** | Av (valfri) | Ja |
| **Protected material** | Av (valfri) | Ja |
| **Custom blocklists** | Ingen | Ja |
| **Microsoft profanity** | Tilgjengeleg | Ja |
### Feilhandtering for innhaldsfilteret
```python
from openai import AzureOpenAI
client = AzureOpenAI(
api_version="2024-06-01",
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"]
)
def generate_image_safe(prompt: str, model: str = "dall-e-3") -> dict:
"""Generer bilete med robust feilhandtering."""
try:
response = client.images.generate(
model=model,
prompt=prompt,
size="1024x1024",
quality="hd",
style="natural",
n=1
)
return {
"status": "success",
"url": response.data[0].url,
"revised_prompt": response.data[0].revised_prompt
}
except Exception as e:
error_body = getattr(e, 'body', {}) or {}
error_code = error_body.get('code', 'unknown')
if error_code == 'contentFilter':
return {
"status": "filtered",
"reason": "Prompt eller generert bilete blei blokkert av innhaldsfilteret",
"recommendation": "Reformuler prompten med meir nøytralt språk"
}
elif error_code == 'rate_limit_exceeded':
return {
"status": "rate_limited",
"reason": "Kvotegrense nådd",
"recommendation": "Vent og prøv igjen, eller be om høgare kvote"
}
else:
return {
"status": "error",
"reason": str(e),
"recommendation": "Sjekk feilmelding og prøv igjen"
}
```
### Spesielle omsyn for mindreårige
Fotorealistiske bilete av mindreårige er blokkert som standard. Enterprise-kundar får automatisk godkjenning for denne kapabiliteten, men for offentleg sektor tilrår vi å behalde denne begrensinga aktiv.
---
## Batch Image Generation
### Rate Limits og kvotering
| Modell | Standard kvote | Format |
|--------|---------------|--------|
| **DALL-E 2** | 2 samtidige requests | Concurrent |
| **DALL-E 3** | 6 requests per minutt | RPM |
| **GPT-image-1** | 9 requests per minutt | RPM |
| **GPT-image-1-mini** | 12 requests per minutt | RPM |
| **GPT-image-1.5** | 9 requests per minutt | RPM |
### Batch-prosesseringspattern
```python
import asyncio
from typing import List
from dataclasses import dataclass
@dataclass
class ImageRequest:
prompt: str
filename: str
size: str = "1024x1024"
quality: str = "hd"
style: str = "natural"
class BatchImageGenerator:
"""Batch-generering av bilete med rate limiting."""
def __init__(self, client: AzureOpenAI, model: str = "dall-e-3",
max_concurrent: int = 2, requests_per_minute: int = 6):
self.client = client
self.model = model
self.semaphore = asyncio.Semaphore(max_concurrent)
self.min_interval = 60.0 / requests_per_minute
self.last_request_time = 0
async def generate_batch(self, requests: List[ImageRequest]) -> List[dict]:
"""Generer ei batch med bilete med respekt for rate limits."""
results = []
for i, request in enumerate(requests):
async with self.semaphore:
# Rate limiting
elapsed = asyncio.get_event_loop().time() - self.last_request_time
if elapsed < self.min_interval:
await asyncio.sleep(self.min_interval - elapsed)
print(f"Genererer bilete {i+1}/{len(requests)}: {request.filename}")
result = await self._generate_single(request)
results.append(result)
self.last_request_time = asyncio.get_event_loop().time()
return results
async def _generate_single(self, request: ImageRequest) -> dict:
"""Generer eit enkelt bilete med retry."""
for attempt in range(3):
try:
response = self.client.images.generate(
model=self.model,
prompt=request.prompt,
size=request.size,
quality=request.quality,
style=request.style,
n=1
)
return {
"filename": request.filename,
"status": "success",
"url": response.data[0].url,
"revised_prompt": response.data[0].revised_prompt
}
except Exception as e:
if "rate_limit" in str(e).lower() and attempt < 2:
await asyncio.sleep(10 * (attempt + 1))
continue
return {
"filename": request.filename,
"status": "error",
"error": str(e)
}
```
### GPT-image-1 batch med streaming
GPT-image-1 støttar fleire bilete per request (`n`-parameter) og streaming:
```python
# GPT-image-1: Generer fleire bilete i eitt kall
response = client.images.generate(
model="gpt-image-1",
prompt="Illustrasjon av norsk fjordlandskap med moderne infrastruktur",
n=4, # Opptil 10 bilete per request
quality="high",
output_format="png",
output_compression=90
)
# Streaming for raskare visuell feedback
response = client.images.generate(
model="gpt-image-1",
prompt="Arkitekturdiagram for smart bynett",
n=1,
stream=True,
partial_images=3 # 1-3 delbilete under generering
)
```
---
## Integration with Document Pipelines
### Automatisert illustrasjon av offentlege dokument
```
Dokument (tekst) → GPT-4o: Identifiser illustrasjonsbehov
Generer prompt per seksjon
DALL-E 3 / GPT-image-1
Kvalitetskontroll (manuell)
Sett inn i dokument
+ Content Credentials metadata
Publiser med AI-generert-markering
```
### Prompt engineering for offentleg sektor
```python
# Mal for offentleg sektorillustrasjon
def create_public_sector_prompt(context: str, style: str = "informativ") -> str:
base_prompts = {
"informativ": (
"Profesjonell, klar illustrasjon i flat design-stil. "
"Nøytrale fargar (blå, grå, kvit). "
"Ingen tekst i biletet. "
"Eigna for offentleg informasjonsmateriell. "
),
"arkitektur": (
"Teknisk arkitekturdiagram i isometrisk stil. "
"Azure-blåtonar og -ikoner. "
"Tydelege boksar og pilar. "
"Profesjonell og ryddig layout. "
),
"infografikk": (
"Informasjonsgrafikk-stil med ikon-basert design. "
"Høgkontrastfargar for tilgjengelegheit. "
"Tydelege visuelle hierarki. "
"Universell utforming-venleg. "
)
}
return f"{base_prompts.get(style, base_prompts['informativ'])}{context}"
# Eksempel: Generer illustrasjon for vegsikkerheit
prompt = create_public_sector_prompt(
"Illustrer konseptet med nullvisjon for trafikksikkerheit. "
"Vis ein trygg veg med fotgjengarfelt, sykkelsti og bil "
"i ein moderne norsk bysamanheng med fjell i bakgrunnen.",
style="informativ"
)
```
### Integrasjon med Power Automate
```json
{
"trigger": {
"type": "manual",
"inputs": {
"schema": {
"properties": {
"document_url": {"type": "string"},
"illustration_count": {"type": "integer", "default": 3}
}
}
}
},
"actions": {
"Analyze_document": {
"type": "OpenAI",
"inputs": {
"model": "gpt-4o",
"prompt": "Les dette dokumentet og foreslå 3 illustrasjonar som vil forbetre forståinga. For kvar illustrasjon, skriv ein DALL-E-prompt."
}
},
"Generate_images": {
"type": "ForEach",
"foreach": "@body('Analyze_document').illustrations",
"actions": {
"Generate_image": {
"type": "OpenAI_Image",
"inputs": {
"model": "dall-e-3",
"prompt": "@items('Generate_images').prompt",
"size": "1024x1024",
"quality": "hd"
}
}
}
}
}
}
```
---
## Tilgjengelegheit (Accessibility) Considerations
### WCAG 2.1-krav for AI-genererte bilete
| Krav | Nivå | Implementering |
|------|------|---------------|
| **1.1.1 Non-text Content** | A | Alt-tekst for alle genererte bilete |
| **1.4.1 Use of Color** | A | Ikkje stol berre på farge for å formidle informasjon |
| **1.4.3 Contrast** | AA | Minimum 4.5:1 kontrastforhold |
| **1.4.11 Non-text Contrast** | AA | Minimum 3:1 for grafiske element |
### Automatisk alt-tekst-generering
```python
def generate_accessible_image(prompt: str, context: str) -> dict:
"""Generer bilete med tilgjengelegheitsinformasjon."""
# Steg 1: Generer biletet
image_result = generate_image_safe(prompt)
if image_result["status"] != "success":
return image_result
# Steg 2: Generer alt-tekst med GPT-4o
alt_text_response = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
"Du genererer alt-tekst for bilete i offentlege norske dokument. "
"Alt-teksten skal vere kortfatta (maks 125 teikn), beskrivande, "
"og formidla det vesentlege innhaldet i biletet. "
"Skriv på norsk bokmål."
)
},
{
"role": "user",
"content": [
{"type": "text", "text": f"Kontekst: {context}\nBeskriv biletet for alt-tekst:"},
{"type": "image_url", "image_url": {"url": image_result["url"], "detail": "low"}}
]
}
],
max_tokens=200
)
# Steg 3: Generer lang beskriving for complexe bilete
long_desc = client.chat.completions.create(
model="gpt-4o",
messages=[
{
"role": "system",
"content": (
"Skriv ei detaljert beskriving av dette biletet for bruk med "
"aria-describedby i HTML. Beskriv layout, fargar, objekt og "
"relasjonar mellom element. Norsk bokmål."
)
},
{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": image_result["url"], "detail": "high"}}
]
}
],
max_tokens=500
)
return {
**image_result,
"alt_text": alt_text_response.choices[0].message.content,
"long_description": long_desc.choices[0].message.content,
"ai_generated": True,
"content_credentials": True
}
```
### Kontrastsjekk for genererte bilete
```python
from PIL import Image
import numpy as np
def check_image_contrast(image_path: str) -> dict:
"""Sjekk kontrastforhold i eit generert bilete."""
img = Image.open(image_path).convert('RGB')
pixels = np.array(img)
# Berekn gjennomsnittleg luminans
luminance = 0.2126 * pixels[:,:,0] + 0.7152 * pixels[:,:,1] + 0.0722 * pixels[:,:,2]
# Finn lys og mørk region
bright = np.percentile(luminance, 90)
dark = np.percentile(luminance, 10)
# Berekn kontrastforhold (WCAG-formel)
l1 = (bright / 255 + 0.05)
l2 = (dark / 255 + 0.05)
contrast_ratio = l1 / l2 if l1 > l2 else l2 / l1
return {
"contrast_ratio": round(contrast_ratio, 1),
"meets_aa": contrast_ratio >= 4.5,
"meets_aaa": contrast_ratio >= 7.0,
"recommendation": (
"OK for WCAG AA" if contrast_ratio >= 4.5
else "For låg kontrast — vurder å regenerere med høgare kontrast"
)
}
```
---
## Merking og transparens
### Content Credentials (C2PA)
Alle DALL-E-bilete inkluderer digitale legitimasjonar som dokumenterer at biletet er AI-generert:
```javascript
// Verifiser Content Credentials med C2PA SDK
import { createC2pa } from '@contentauth/c2pa-node';
const c2pa = await createC2pa();
const result = await c2pa.read('generated-image.png');
if (result.manifests) {
console.log('AI-generert bilete bekrefta');
console.log('Generert av:', result.manifests[0].claimGenerator);
}
```
### Tilrådde merkingspraksis for offentleg sektor
| Kontekst | Merking | Plassering |
|----------|---------|-----------|
| **Informasjonsmateriell** | "Illustrasjon: AI-generert" | Under biletet |
| **Presentasjonar** | "AI-generert illustrasjon" | I bildetekst |
| **Nettside** | Alt-tekst + metadata | HTML + C2PA |
| **Rapport/utgreiing** | Fotnote om AI-genererte element | Metodeseksjon |
---
## For arkitekten
- **DALL-E 3 er GA i Sweden Central**, noko som gjer det til det tryggaste valet for norsk offentleg sektor akkurat no. GPT-image-1 gir betre kvalitet og fleksibilitet, men krev Global Standard deployment og limited access-godkjenning.
- **Innhaldsfilteret blokkerer automatisk skadeleg innhald** på både input og output. For offentleg sektor tilrår vi å behalde standardinnstillingane og ikkje søke om unntak utan sterke grunnar.
- **Alle AI-genererte bilete MÅ merkast** tydeleg som AI-genererte i offentleg kommunikasjon. Bruk Content Credentials og synleg merking i bildtekst.
- **Batch-generering krev aktiv rate limiting** — DALL-E 3 har berre 6 RPM som standard. Design pipelines med kø og retry for å unngå throttling.
- **Tilgjengelegheit er ikkje valfritt** i offentleg sektor. Kombiner DALL-E med GPT-4o for automatisk generering av alt-tekst, og utfør kontrastsjekk på genererte bilete for WCAG AA-etterleving.