alami-vision-api / docs /SCENE_BLOCK_CONTRACT.md
alami-ci
Deploy from alami-eco/alami-trash-ai@aee69796b70947e95efdb9c7483fa52f8d3b4520
76838d6
|
Raw
History Blame Contribute Delete
6.36 kB
# `scene`-Block — Kontrakt für Produkt & Monorepo-Team
> **Für wen:** Product Owner + das Team am Monorepo (`alami-platform`).
> **Was:** Die Vision-API bekommt ein neues, **optionales** Antwortfeld `scene`
> mit einer Einschätzung „Ist auf diesem Foto überhaupt Müll?".
> **Status:** Kontrakt festgezurrt (Typen im Code), **noch nicht aktiv**
> heute liefert keine Antwort das Feld. Erst nach eurem Go.
> **Gegenstück:** `alami-platform/docs/VISION-API-BOUNDARY.md`.
---
## 1. Das Problem, das es löst (in einem Satz)
Unser Detektor feuert auf **39 % zufälliger Nicht-Müll-Bilder** einen False
Positive — jedes davon ist potenziell eine Auszahlung für ein Foto ohne Müll.
Der `scene`-Block liefert ein zweites, unabhängiges Signal: ein Weltmodell schaut
sich die Szene an („Katze", „Rasen", „Plastikflasche") und sagt, wie plausibel
Müll ist.
## 2. Was es messbar kann (Stand 2026-07-26)
Gemessen auf 620 Bildern (339 mit Müll, 281 ohne), fair out-of-fold validiert:
| Wenn wir … | … dann bleiben von echtem Müll erhalten |
|---|---|
| **80 % der Falsch-Fälle wegfiltern** | **88 %** |
| 90 % der Falsch-Fälle wegfiltern | 70 % |
Zum Vergleich: die naive Vorversion schaffte bei 80 % Filterwirkung nur 50 %.
Details + Methodik: `docs/PHASE_A_SCENE_GATE.md` §8i.
**Ehrliche Grenzen — bitte mitlesen:**
- Gemessen auf **TACO-Datensatz-Fotos**, nicht auf echten App-Uploads. Die Zahl
ist eine belastbare Richtgröße, **keine Produktionsgarantie**.
- Es ist **kein 100-%-Detektor.** Bei 80 % Filterwirkung gehen 12 % echter
Müll-Fotos fälschlich in die Prüfung. Deshalb Punkt 3.
## 3. Die wichtigste Regel: **advisory, nicht Auszahlung**
`waste_likelihood` ist ein **Hinweis**, kein Urteil.
-**Erlaubt:** Einreichung zur **manuellen Prüfung** markieren, im Admin
sortieren/priorisieren, Betrugsmuster sichtbar machen, dem Nutzer einen Hinweis
zeigen („Wir konnten keinen Müll erkennen — trotzdem einreichen?").
-**Nicht erlaubt:** Trash Coins automatisch verweigern, Einreichung
ablehnen, Nutzer sperren — **allein** aufgrund dieses Werts.
Grund: ein Nutzer, der echten Müll gesammelt hat und wegen eines Modellfehlers
leer ausgeht, ist ein schwerer Vertrauensschaden. Der bestehende
Review-Pfad (`needs_review` → Admin gibt frei) fängt das sauber ab.
Falls wir später **automatisch** verweigern wollen, braucht es eine andere
Qualitätsstufe (≥99 % erhaltener Müll) — die ist heute **nicht** erreicht, und
der Weg dahin steht in Punkt 6.
## 4. Was sich technisch ändert — **nichts**, bis ihr es nutzt
`scene` ist ein **optionales** Feld auf `AnalyzeResponse`. Es fehlt heute in
jeder Antwort. Kein Feld wird umbenannt, entfernt oder in der Bedeutung geändert.
**Bestehende Clients brauchen keine Zeile Code.**
```jsonc
{
"prediction_id": "…", "model_version": "…", "objects": [ … ], "summary": { … },
// NEU, optional, fehlt wenn nicht aktiviert:
"scene": {
"scene_gate_version": "yolo-worldv2-…",
"waste_likelihood": 0.87, // 0..1 — ADVISORY (siehe §3)
"score_method": "learned", // "learned" | "max_conf" (Transparenz)
"waste_objects": [
{ "label": "plastic bottle", "label_de": "Plastikflasche",
"confidence": 0.81, "bbox_norm": [0.12, 0.4, 0.2, 0.3],
"material_hint": "plastic" }
],
"non_waste_objects": [
{ "label": "cat", "label_de": "Katze",
"confidence": 0.88, "bbox_norm": [0.5, 0.1, 0.3, 0.4] }
],
"counts": { "waste": 1, "non_waste": 1 },
"inventory_text": "Plastikflasche · Katze" // fertig zum Anzeigen
}
}
```
Feldbedeutungen:
| Feld | Bedeutung |
|---|---|
| `waste_likelihood` | 0..1, wie plausibel Müll im Bild ist. **Advisory.** |
| `score_method` | `learned` = gelerntes Modell, `max_conf` = einfache Rückfallebene. Immer mitloggen — sonst sind Metriken über verschiedene Stände nicht vergleichbar. |
| `waste_objects` / `non_waste_objects` | erkannte Dinge mit deutschem Label + Box (0..1, wie `objects[]`) |
| `inventory_text` | fertiger Anzeigestring, keine eigene Formatierung nötig |
| `counts` | Schnellzugriff ohne Listen zu zählen |
`bbox_norm` ist identisch normiert wie in `objects[]` — dieselbe Overlay-Logik
funktioniert.
## 5. Was wir vom Produkt brauchen (Entscheidungen für den PO)
1. **Schwelle:** Ab welchem `waste_likelihood` soll eine Einreichung in die
Prüfung wandern? *Empfehlung: konservativ starten* (nur sehr niedrige Werte
markieren), Wirkung beobachten, dann nachziehen. Die Schwelle gehört **auf
eure Seite** — so ändert ihr sie ohne Vision-Deployment.
2. **Sichtbarkeit:** Sieht der Nutzer etwas (z. B. „kein Müll erkannt") oder
zunächst nur der Admin? *Empfehlung: erst nur Admin*, bis wir Feldzahlen haben.
3. **Rollout:** Erst mitlaufen lassen und **nur loggen** (keine Wirkung), damit
wir echte Verteilungen sehen — dann entscheiden. *Empfehlung: ja.*
## 6. Wie es besser wird (und warum euer Feedback der Motor ist)
Das Modell lernt aus Korrekturen. Über den bereits gebauten Feedback-v2-Pfad
(`added_items`, `reasons`, `action` — siehe `docs/api.md`) kommen genau die
Fälle zurück, in denen die KI danebenlag. Damit trainieren wir den Score auf
**echten App-Fotos** statt auf Datensatz-Bildern nach.
Der Weg zum harten Auto-Gate führt **nur** hierüber. Je mehr Feedback fließt,
desto eher ist es realistisch.
## 7. Offene Punkte auf unserer Seite (Vision)
- **Serving:** Das Weltmodell läuft heute nur in der Auswertung, nicht im
Live-Space (anderer Runtime-Stack, Latenz-Budget zu prüfen). Das ist der
nächste Arbeitsblock — Aufwand entsteht **bevor** ihr etwas tun müsst.
- **Latenz:** Zusätzliche Inferenz kostet Zeit. Vor Aktivierung messen wir und
melden die Zahl; notfalls läuft es asynchron statt im Antwortpfad.
## 8. Zeitliche Reihenfolge (Vorschlag)
1. **Jetzt:** Ihr lest den Kontrakt, sagt ob die Feldform passt. *(kein Code)*
2. Wir bauen Serving + messen Latenz.
3. **Schattenbetrieb:** Feld wird geliefert, nur geloggt, keine Wirkung.
4. Nach echten Zahlen: PO entscheidet Schwelle + Sichtbarkeit.
5. Später, datenabhängig: Auto-Gate — nur bei ≥99 % erhaltenem Müll.
**Vertragsänderungen** (Felder, Bedeutungen, Auth) stimmen wir vorher ab —
wie Schema-Migrationen, gemäß `VISION-API-BOUNDARY.md`.