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>
431 lines
16 KiB
Markdown
431 lines
16 KiB
Markdown
# Accessibility in Multi-Modal AI Systems
|
|
|
|
**Last updated:** 2026-02
|
|
**Status:** GA
|
|
**Category:** Multi-Modal AI
|
|
**Type:** reference
|
|
|
|
---
|
|
|
|
## Innhold
|
|
|
|
- [Introduksjon](#introduksjon)
|
|
- [Kjernekomponentar](#kjernekomponentar)
|
|
- [Alt-tekst generering og WCAG Compliance](#alt-tekst-generering-og-wcag-compliance)
|
|
- [Lydbeskrivingar for visuelt innhald](#lydbeskrivingar-for-visuelt-innhald)
|
|
- [Undertekstar og transkripsjongenerering](#undertekstar-og-transkripsjongenerering)
|
|
- [Brukarpreferansar og hjelpemiddelintegrasjon](#brukarpreferansar-og-hjelpemiddelintegrasjon)
|
|
- [Implementeringsmønstre](#implementeringsmønstre)
|
|
- [Norsk offentleg sektor](#norsk-offentleg-sektor)
|
|
- [Beslutningsrammeverk](#beslutningsrammeverk)
|
|
- [For arkitekten](#for-arkitekten)
|
|
|
|
## Introduksjon
|
|
|
|
Tilgjengeleg AI-design er ikkje berre ein moralsk forplikting — det er eit lovkrav i Noreg og EU. Likestillings- og diskrimineringslova, saman med EUs Web Accessibility Directive og den kommande European Accessibility Act (EAA), stiller konkrete krav til at digitale tenester skal vere tilgjengelege for alle brukarar. Multi-modal AI-system som kombinerer tekst, bilete, tale og video introduserer unike tilgjengelegheitsutfordringar — og moglegheiter.
|
|
|
|
Azure AI-plattforma tilbyr fleire tenester som direkte støttar tilgjengeleg design: Azure AI Vision sin Image Analysis for automatisk generering av alt-tekst, Azure AI Speech for sanntids teksting og transkribering, Azure OpenAI for kontekstuell beskriving av visuelt innhald, og Azure Video Indexer for automatiske undertekstar og lydbeskrivingar. Desse tenestene kan integrerast i eksisterande system for å drastisk forbetre tilgjengelegheita.
|
|
|
|
For norsk offentleg sektor er dette særleg relevant fordi Forskrift om universell utforming av IKT (basert på WCAG 2.1 AA) krev at alle nye nettløysingar og appar skal vere universelt utforma. AI-basert tilgjengelegheit kan automatisere mykje av dette arbeidet og sikre konsistent kvalitet på tvers av store mengder innhald.
|
|
|
|
---
|
|
|
|
## Kjernekomponentar
|
|
|
|
| Komponent | Formål | Teknologi |
|
|
|-----------|--------|-----------|
|
|
| **Alt-tekst generering** | Automatiske biletbeskrivingar for skjermlesarar | Azure AI Vision Image Analysis 4.0 |
|
|
| **Undertekstar og transkripsjon** | Tale-til-tekst for video og lydfiler | Azure AI Speech / Whisper |
|
|
| **Lydbeskrivingar** | Beskrivingar av visuelt innhald i lyd | Azure OpenAI GPT-4o |
|
|
| **Talesyntetisering** | Tekst-til-tale for visuelt innhald | Azure AI Speech TTS |
|
|
| **Innhaldstilpassing** | Tilpassing av kompleksitet og format | Azure OpenAI |
|
|
| **Teiknspråktolking** | Gjenkjenning og generering | Azure AI Vision Custom Models |
|
|
|
|
---
|
|
|
|
## Alt-tekst generering og WCAG Compliance
|
|
|
|
### Azure AI Vision Image Captioning
|
|
|
|
Azure AI Vision sin Image Analysis gir automatisk generering av biletbeskrivingar som kan brukast som alt-tekst. Microsoft sine eigne produkt som PowerPoint, Word og Edge nettlesar brukar denne teknologien.
|
|
|
|
```python
|
|
from azure.ai.vision.imageanalysis import ImageAnalysisClient
|
|
from azure.core.credentials import AzureKeyCredential
|
|
|
|
client = ImageAnalysisClient(
|
|
endpoint="https://<resource>.cognitiveservices.azure.com/",
|
|
credential=AzureKeyCredential("<api-key>")
|
|
)
|
|
|
|
# Generer bilettekst
|
|
result = client.analyze(
|
|
image_url="https://example.com/bilde.jpg",
|
|
visual_features=["Caption", "DenseCaptions", "Tags"],
|
|
language="en" # Norsk ikkje støtta for captions enno
|
|
)
|
|
|
|
# Hovud-caption
|
|
print(f"Alt-tekst: {result.caption.text}")
|
|
print(f"Confidence: {result.caption.confidence}")
|
|
|
|
# Dense captions for meir detaljert beskriving
|
|
for caption in result.dense_captions.list:
|
|
print(f" Region: {caption.bounding_box}, Tekst: {caption.text}")
|
|
```
|
|
|
|
### WCAG 2.1 Krav for bilete
|
|
|
|
| WCAG-krav | Nivå | Korleis AI hjelper |
|
|
|-----------|------|-------------------|
|
|
| **1.1.1 Non-text Content** | A | Automatisk alt-tekst generering |
|
|
| **1.2.1 Audio-only and Video-only** | A | Automatisk transkripsjon |
|
|
| **1.2.2 Captions (Prerecorded)** | A | AI-genererte undertekstar |
|
|
| **1.2.3 Audio Description** | A | GPT-4o-basert lydbeskrivelse |
|
|
| **1.2.5 Audio Description (Extended)** | AA | Detaljert scene-beskriving |
|
|
| **1.4.3 Contrast (Minimum)** | AA | Automatisk kontrastsjekk |
|
|
| **1.4.5 Images of Text** | AA | OCR + alternativ tekst |
|
|
|
|
### Kvalitetssikring av alt-tekst
|
|
|
|
```python
|
|
def validate_alt_text(caption_result, min_confidence=0.4):
|
|
"""Kvalitetssikring av AI-generert alt-tekst for WCAG compliance."""
|
|
|
|
issues = []
|
|
|
|
# Confidence-sjekk
|
|
if caption_result.confidence < min_confidence:
|
|
issues.append({
|
|
"type": "low_confidence",
|
|
"message": f"Confidence {caption_result.confidence:.2f} under terskel {min_confidence}",
|
|
"action": "manuell_gjennomgang"
|
|
})
|
|
|
|
# Lengde-sjekk (alt-tekst bør vere 10-150 teikn)
|
|
text_len = len(caption_result.text)
|
|
if text_len < 10:
|
|
issues.append({
|
|
"type": "for_kort",
|
|
"message": "Alt-tekst er for kort til å vere beskrivande",
|
|
"action": "utvid_manuelt"
|
|
})
|
|
elif text_len > 150:
|
|
issues.append({
|
|
"type": "for_lang",
|
|
"message": "Alt-tekst er for lang — vurder å forkorte",
|
|
"action": "forkort_eller_bruk_longdesc"
|
|
})
|
|
|
|
# Sjekk for generiske beskrivingar
|
|
generic_terms = ["an image of", "a picture of", "a photo of"]
|
|
if any(term in caption_result.text.lower() for term in generic_terms):
|
|
issues.append({
|
|
"type": "generisk",
|
|
"message": "Alt-tekst startar med generisk frase",
|
|
"action": "reformuler"
|
|
})
|
|
|
|
return {
|
|
"alt_text": caption_result.text,
|
|
"confidence": caption_result.confidence,
|
|
"wcag_compliant": len(issues) == 0,
|
|
"issues": issues
|
|
}
|
|
```
|
|
|
|
### GPT-4o for kontekstuell alt-tekst
|
|
|
|
For meir detaljerte beskrivingar, spesielt for komplekse bilete:
|
|
|
|
```python
|
|
from openai import AzureOpenAI
|
|
|
|
client = AzureOpenAI(
|
|
azure_endpoint="https://<resource>.openai.azure.com/",
|
|
api_key="<api-key>",
|
|
api_version="2024-08-01-preview"
|
|
)
|
|
|
|
response = client.chat.completions.create(
|
|
model="gpt-4o",
|
|
messages=[
|
|
{
|
|
"role": "system",
|
|
"content": """Du er ein tilgjengelegheitsekspert som skriv alt-tekst
|
|
for bilete på offentlege norske nettsider. Følg desse reglane:
|
|
1. Beskriv innhaldet, ikkje utsjånaden
|
|
2. Maks 150 teikn for dekorative bilete
|
|
3. For informative bilete: beskriv all relevant informasjon
|
|
4. Unngå 'bilete av' eller 'foto av'
|
|
5. Inkluder tekst som finst i biletet"""
|
|
},
|
|
{
|
|
"role": "user",
|
|
"content": [
|
|
{"type": "text", "text": "Skriv WCAG-kompatibel alt-tekst for dette biletet."},
|
|
{"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}}
|
|
]
|
|
}
|
|
],
|
|
max_tokens=200
|
|
)
|
|
|
|
alt_text = response.choices[0].message.content
|
|
```
|
|
|
|
---
|
|
|
|
## Lydbeskrivingar for visuelt innhald
|
|
|
|
### Audio Description Pipeline
|
|
|
|
Lydbeskrivingar (audio descriptions) gjer visuelt innhald tilgjengeleg for blinde og svaksynte brukarar. Pipelinen kombinerer scene-analyse med talesyntetisering:
|
|
|
|
```python
|
|
from azure.ai.vision.imageanalysis import ImageAnalysisClient
|
|
from azure.cognitiveservices.speech import SpeechConfig, SpeechSynthesizer
|
|
|
|
def generate_audio_description(image_url, output_file):
|
|
"""Generer lydbeskrivelse frå eit bilete."""
|
|
|
|
# Steg 1: Analyser biletet med GPT-4o for rik beskriving
|
|
vision_response = openai_client.chat.completions.create(
|
|
model="gpt-4o",
|
|
messages=[
|
|
{
|
|
"role": "system",
|
|
"content": "Beskriv biletet for ein person som ikkje kan sjå det. "
|
|
"Ver presis, inkluder romleg plassering av element."
|
|
},
|
|
{
|
|
"role": "user",
|
|
"content": [
|
|
{"type": "image_url", "image_url": {"url": image_url}}
|
|
]
|
|
}
|
|
]
|
|
)
|
|
|
|
description = vision_response.choices[0].message.content
|
|
|
|
# Steg 2: Konverter til tale med Azure Speech
|
|
speech_config = SpeechConfig(
|
|
subscription="<speech-key>",
|
|
region="norwayeast"
|
|
)
|
|
speech_config.speech_synthesis_voice_name = "nb-NO-FinnNeural"
|
|
|
|
synthesizer = SpeechSynthesizer(
|
|
speech_config=speech_config,
|
|
audio_config=AudioOutputConfig(filename=output_file)
|
|
)
|
|
|
|
result = synthesizer.speak_text_async(description).get()
|
|
return description, result
|
|
```
|
|
|
|
### Video Audio Description
|
|
|
|
For video brukar ein Video Indexer sin scene-deteksjon kombinert med GPT-4o:
|
|
|
|
1. **Video Indexer** identifiserer scener, shots og keyframes
|
|
2. **GPT-4o** analyserer keyframes og genererer beskrivingar
|
|
3. **Azure Speech TTS** syntetiserer lydbeskrivingar
|
|
4. **Timing-synkronisering** plasserer beskrivingar i naturlege pausar
|
|
|
|
---
|
|
|
|
## Undertekstar og transkripsjongenerering
|
|
|
|
### Automatisk underteksting med Azure AI Speech
|
|
|
|
```python
|
|
import azure.cognitiveservices.speech as speechsdk
|
|
|
|
speech_config = speechsdk.SpeechConfig(
|
|
subscription="<speech-key>",
|
|
region="norwayeast"
|
|
)
|
|
|
|
# Norsk bokmål
|
|
speech_config.speech_recognition_language = "nb-NO"
|
|
|
|
# Kontinuerleg gjenkjenning for undertekstar
|
|
audio_config = speechsdk.AudioConfig(filename="video_audio.wav")
|
|
recognizer = speechsdk.SpeechRecognizer(
|
|
speech_config=speech_config,
|
|
audio_config=audio_config
|
|
)
|
|
|
|
captions = []
|
|
|
|
def recognized_handler(evt):
|
|
"""Handterer ferdig gjenkjende segment."""
|
|
captions.append({
|
|
"text": evt.result.text,
|
|
"offset": evt.result.offset,
|
|
"duration": evt.result.duration
|
|
})
|
|
|
|
recognizer.recognized.connect(recognized_handler)
|
|
recognizer.start_continuous_recognition()
|
|
|
|
# Eksporter til SRT-format
|
|
def export_to_srt(captions, output_file):
|
|
with open(output_file, "w", encoding="utf-8") as f:
|
|
for i, cap in enumerate(captions, 1):
|
|
start = format_timestamp(cap["offset"])
|
|
end = format_timestamp(cap["offset"] + cap["duration"])
|
|
f.write(f"{i}\n{start} --> {end}\n{cap['text']}\n\n")
|
|
```
|
|
|
|
### WebVTT for Webvideo
|
|
|
|
```python
|
|
def export_to_webvtt(captions, output_file):
|
|
"""Eksporter undertekstar i WebVTT-format for HTML5 video."""
|
|
with open(output_file, "w", encoding="utf-8") as f:
|
|
f.write("WEBVTT\n\n")
|
|
for i, cap in enumerate(captions, 1):
|
|
start = format_vtt_timestamp(cap["offset"])
|
|
end = format_vtt_timestamp(cap["offset"] + cap["duration"])
|
|
f.write(f"{start} --> {end}\n{cap['text']}\n\n")
|
|
```
|
|
|
|
---
|
|
|
|
## Brukarpreferansar og hjelpemiddelintegrasjon
|
|
|
|
### Adaptive Content Delivery
|
|
|
|
```python
|
|
class AccessibleContentManager:
|
|
"""Tilpassar innhald basert på brukarpreferansar."""
|
|
|
|
def __init__(self, user_preferences):
|
|
self.preferences = user_preferences
|
|
|
|
def deliver_image_content(self, image_url, context):
|
|
"""Lever bildeinnhald tilpassa brukarens behov."""
|
|
|
|
content = {}
|
|
|
|
# Alt-tekst for alle brukarar
|
|
content["alt_text"] = self.generate_alt_text(image_url)
|
|
|
|
# Utvida beskriving for skjermlesarbrukarar
|
|
if self.preferences.get("screen_reader"):
|
|
content["long_description"] = self.generate_detailed_description(
|
|
image_url, context
|
|
)
|
|
|
|
# Lydbeskriving for blinde brukarar
|
|
if self.preferences.get("audio_description"):
|
|
content["audio"] = self.generate_audio_description(
|
|
image_url,
|
|
voice=self.preferences.get("preferred_voice", "nb-NO-FinnNeural"),
|
|
speed=self.preferences.get("speech_rate", 1.0)
|
|
)
|
|
|
|
# Forenkla beskriving for kognitive utfordringar
|
|
if self.preferences.get("simplified"):
|
|
content["simplified"] = self.simplify_description(
|
|
content["alt_text"],
|
|
complexity_level=self.preferences.get("complexity", "easy")
|
|
)
|
|
|
|
# Høgkontrastversjon
|
|
if self.preferences.get("high_contrast"):
|
|
content["high_contrast_url"] = self.generate_high_contrast(image_url)
|
|
|
|
return content
|
|
```
|
|
|
|
### ARIA Integration
|
|
|
|
```html
|
|
<!-- Eksempel på WCAG-kompatibel bildevisning med AI-generert innhald -->
|
|
<figure role="figure" aria-labelledby="fig-caption-1">
|
|
<img
|
|
src="arkitekturdiagram.png"
|
|
alt="Arkitekturdiagram som viser tre Azure-tenester kopla saman"
|
|
aria-describedby="fig-desc-1"
|
|
loading="lazy"
|
|
/>
|
|
<figcaption id="fig-caption-1">
|
|
Figur 1: Systemarkitektur for dokumentbehandling
|
|
</figcaption>
|
|
<div id="fig-desc-1" class="sr-only">
|
|
<!-- AI-generert detaljert beskriving for skjermlesarar -->
|
|
Diagrammet viser ein dataflyt frå venstre til høgre.
|
|
Dokument kjem inn via Azure Blob Storage, blir prosessert
|
|
av Document Intelligence, og resultata blir lagra i
|
|
Azure Cosmos DB. Piler viser dataflyten mellom komponentane.
|
|
</div>
|
|
</figure>
|
|
```
|
|
|
|
---
|
|
|
|
## Implementeringsmønstre
|
|
|
|
### Mønster 1: Proaktiv tilgjengelegheit
|
|
|
|
Integrer tilgjengelegheits-AI i innhaldsproduksjon, ikkje som ettertanke:
|
|
|
|
1. **Opplasting** — Brukar lastar opp bilete/video
|
|
2. **Automatisk analyse** — AI genererer alt-tekst, undertekstar, beskrivingar
|
|
3. **Kvalitetskontroll** — Confidence scoring + manuell gjennomgang ved låg score
|
|
4. **Publisering** — Innhald med fullstendig tilgjengelegheitsmetadata
|
|
|
|
### Mønster 2: Retrospektiv tilgjengelegheit
|
|
|
|
For eksisterande innhald utan tilgjengelegheitsdata:
|
|
|
|
1. **Crawl** — Identifiser bilete utan alt-tekst, videoar utan undertekstar
|
|
2. **Batch-generering** — Kjør AI-analyse over alt manglande innhald
|
|
3. **Prioritering** — Start med mest besøkte sider
|
|
4. **Gradvis utrulling** — Deploy i fasar med kvalitetskontroll
|
|
|
|
---
|
|
|
|
## Norsk offentleg sektor
|
|
|
|
### Lovkrav
|
|
|
|
- **Forskrift om universell utforming av IKT** — Krev WCAG 2.1 AA for alle nye nettløysingar
|
|
- **Likestillings- og diskrimineringslova § 17** — Plikt til universell utforming
|
|
- **EUs Web Accessibility Directive** — Krav til offentlege nettsider
|
|
- **European Accessibility Act (EAA)** — Bredare krav frå 2025
|
|
|
|
### Digitaliseringsdirektoratet sine retningslinjer
|
|
|
|
Digdir tilrår at offentlege verksemder brukar automatiserte verktøy for tilgjengelegheitstesting, men presiserer at automatiserte verktøy berre kan fange ca. 30-40% av WCAG-feil. AI-basert tilgjengelegheit kan auke denne dekninga vesentleg.
|
|
|
|
### Tilsynet for universell utforming av IKT
|
|
|
|
Tilsynet kan gi pålegg og dagbøter for manglande tilgjengelegheit. AI-basert automatisk generering av alt-tekst og undertekstar reduserer risikoen for lovbrot vesentleg.
|
|
|
|
---
|
|
|
|
## Beslutningsrammeverk
|
|
|
|
| Scenario | Anbefaling | Begrunnelse |
|
|
|----------|------------|-------------|
|
|
| Alt-tekst for enkle bilete | Azure AI Vision Image Captioning | Rask, billeg, god nok kvalitet |
|
|
| Alt-tekst for komplekse diagram | GPT-4o med kontekst-prompt | Treng semantisk forståing |
|
|
| Videoundertekstar (norsk) | Azure AI Speech nb-NO | Best norsk STT-kvalitet |
|
|
| Lydbeskrivingar for video | GPT-4o + Azure Speech TTS | Multimodal pipeline |
|
|
| Stor-skala retrospektiv tilgjengelegheit | Batch API + prioritering etter trafikk | Kostnadseffektiv |
|
|
| Sensitive dokument (helse) | On-premises med CMK | Datakontroll |
|
|
|
|
---
|
|
|
|
## For arkitekten
|
|
|
|
- **WCAG 2.1 AA er lovpålagt** for alle nye offentlege norske nettløysingar — AI-basert tilgjengelegheit er ikkje valfritt, det er ein compliance-forplikting
|
|
- **Azure AI Vision Image Analysis 4.0** genererer alt-tekst som Microsoft sjølv brukar i PowerPoint, Word og Edge — confidence threshold på 0.0 for v4.0 API (0.4 for v3.2)
|
|
- **GPT-4o overtreff Image Analysis** for komplekse bilete som kart, diagram og infografikkar — bruk kontekstuell system prompt for å styre format og lengde
|
|
- **Audio description pipeline** (GPT-4o + Azure Speech TTS nb-NO-FinnNeural) gjer visuelt innhald tilgjengeleg for blinde — kritisk for offentlege tenester med visuelle grensesnitt
|
|
- **Automatisering dekker 60-70% av tilgjengelegheitsarbeidet** — kombiner med manuell gjennomgang for dei resterande 30-40% som krev menneskelig vurdering
|