Ansvar och människa i loopen
Kunna designa var en människa fattar beslut och hur det dokumenteras.
Förkunskaper
- EEU:s AI-förordningkrävs
Intuition
«Människa i loopen» är inte ett tillstånd utan en skala, och den skillnaden är avgörande:
| Grad | Betyder | Människan är ansvarig? |
|---|---|---|
| Human-in-the-loop | människan fattar beslutet, AI:n föreslår | ja |
| Human-on-the-loop | AI:n beslutar, människan övervakar och kan avbryta | delvis |
| Human-in-command | människan sätter ramarna, granskar i efterhand | på systemnivå |
| Full automation | ingen människa i beslutet | organisationen, inte en individ |
Att skriva «en människa granskar» i en policy räcker inte. Granskningen måste vara meningsfull, och det ställer fyra krav:
- Granskaren har tid att faktiskt granska.
- Granskaren har information nog att kunna avvika.
- Granskaren har befogenhet att säga nej.
- Att säga nej är inte dyrare för granskaren än att säga ja.
Brister någon av de fyra är granskningen en formalitet, och ansvaret har i praktiken flyttat till modellen.
Formellt
Rubber-stamping är det vanligaste misslyckandet: granskaren godkänner nästan allt, eftersom AI:n har rätt oftast och tiden är knapp. Då finns människan där juridiskt men inte praktiskt.
Motmedel som faktiskt fungerar:
| Motmedel | Effekt |
|---|---|
| Mät avvikelsefrekvensen | ligger den under någon procent granskas det inte på riktigt |
| Kräv motivering vid godkännande, inte bara vid avslag | tvingar fram ett övervägande |
| Visa modellens osäkerhet och underlaget | ger något att granska |
| Rotera och stickprovskontrollera granskare | upptäcker driften |
| Plantera testfall med kända fel | mäter om granskningen fångar dem |
Den sista är den mest avslöjande och används i säkerhetskritiska branscher: skicka med jämna mellanrum in ett fall där AI:n har uppenbart fel och mät hur ofta det fångas.
Automatiseringsbias är den underliggande mekanismen: människor litar systematiskt mer på ett automatiserat förslag än på sin egen bedömning, särskilt under tidspress och när systemet brukar ha rätt. Den är väldokumenterad inom flyg och medicin, och den försvinner inte för att man är medveten om den.
Var människan ska placeras beror på konsekvensen:
| Konsekvens | Placering |
|---|---|
| Irreversibel och stor (avslag, uppsägning, medicinsk) | in-the-loop — människan beslutar |
| Reversibel men betydande | on-the-loop med möjlighet att ångra |
| Liten och reversibel | in-command — stickprov i efterhand |
Dokumentation. För varje beslut som påverkar någon ska följande gå att rekonstruera:
| Fält | Varför |
|---|---|
| Modellversion och konfiguration | vad som faktiskt körde |
| Indata (eller dess hash) | vad beslutet byggde på |
| Modellens utdata och konfidens | vad som föreslogs |
| Vem som beslutade, och när | ansvaret |
| Om och varför människan avvek | den mest värdefulla datan i hela loggen |
| Utfall, när det blir känt | för att kunna mäta om systemet fungerar |
Den näst sista raden är guld värd: avvikelserna är exakt de fall där modellen och en kunnig människa är oense, och de är den bästa källan till förbättring som finns.
Kod
import hashlib, json, time
from dataclasses import dataclass, asdict
from enum import Enum
class Grad(Enum):
IN_THE_LOOP = "människan beslutar"
ON_THE_LOOP = "AI beslutar, människan kan avbryta"
IN_COMMAND = "stickprov i efterhand"
def valj_grad(irreversibel: bool, betydande: bool) -> Grad:
if irreversibel and betydande:
return Grad.IN_THE_LOOP
if betydande:
return Grad.ON_THE_LOOP
return Grad.IN_COMMAND
@dataclass
class Beslut:
arende_id: str
modellversion: str
indata_hash: str
modellens_forslag: str
modellens_konfidens: float
beslut: str
beslutad_av: str
avvek: bool
motivering: str # KRÄVS även vid godkännande
tidpunkt: float
utfall: str | None = None
def registrera(arende, forslag, konfidens, beslut, granskare, motivering, modellversion):
if not motivering or len(motivering) < 15:
raise ValueError("motivering krävs även när förslaget godkänns")
return Beslut(
arende_id=arende["id"],
modellversion=modellversion,
indata_hash=hashlib.sha256(
json.dumps(arende, sort_keys=True).encode()).hexdigest()[:16],
modellens_forslag=forslag, modellens_konfidens=konfidens,
beslut=beslut, beslutad_av=granskare,
avvek=(beslut != forslag), motivering=motivering, tidpunkt=time.time())
def granskningskvalitet(beslut: list[Beslut]) -> dict:
n = len(beslut)
avvek = sum(b.avvek for b in beslut)
per_granskare = {}
for b in beslut:
d = per_granskare.setdefault(b.beslutad_av, {"n": 0, "avvek": 0})
d["n"] += 1; d["avvek"] += int(b.avvek)
return {
"avvikelsefrekvens": round(avvek / max(n, 1), 4),
"varning": "under 1 % — granskas troligen inte på riktigt" if avvek / max(n, 1) < 0.01 else "ok",
"per_granskare": {k: round(v["avvek"] / v["n"], 3) for k, v in per_granskare.items()},
}
# Planterade testfall: mät om granskningen faktiskt fångar fel
def plantera_testfall(ko, testfall, andel=0.02):
"""Blanda in fall där modellens förslag är känt felaktigt."""
import random
ut = list(ko)
for t in testfall:
if random.random() < andel:
ut.insert(random.randrange(len(ut) + 1), t | {"_test": True})
return ut
def fangstgrad(beslut, testfall_id):
t = [b for b in beslut if b.arende_id in testfall_id]
return round(sum(b.avvek for b in t) / max(len(t), 1), 3)
# < 0.8 betyder att granskningen missar fel som den borde fånga
Behärskning innebär
- Skiljer mellan graderna av mänsklig inblandning
- Placerar människan där den gör nytta
- Dokumenterar beslut spårbart
Logga in för att göra övningarna och bygga upp din behärskning.
Källor
- EU:s AI-förordning (2024/1689) — EU-rättsakt
- Google — People + AI Guidebook — fri läsning
- GDPR — förordning (EU) 2016/679 — EU-rättsakt