# LANDVEX — AI Intelligence Pipeline **Beslutad:** 2026-06-21, Erik Svensson **Princip:** Lokal first, Claude last. Lägsta möjliga token-kostnad. --- ## Arkitektur ``` quiXzoom bild (JPEG) │ ▼ [STEG 1 — LOKAL, GRATIS] YOLOv8n (5MB modell) → Object detection → Tags: power_pole, cable, graffiti, signage, person, vehicle, building → Körtid: ~80ms/bild på CPU │ ▼ [STEG 2 — LOKAL, GRATIS] MobileNetV3 / CLIP-lite → Condition score 1-10 → Vacancy: open/closed/uncertain → Körtid: ~50ms/bild │ ▼ [STEG 3 — REGEL-BASERAT, GRATIS] Python rule engine → Beräknar Infrastructure Risk Index → Beräknar Contradiction potential → Jämför mot officiell data (cache) → Producerar structured JSON → Körtid: ~5ms │ ├─► 95% av bilder → direkt till databas (ingen Claude) │ ▼ [STEG 4 — CLAUDE, BARA VID BEHOV] Triggas ENDAST om: - Contradiction potential > 0.7 - Okänd objektkategori (confidence < 0.4) - Första bild från ny koordinat/stad Claude-prompt: ultra-kort, strukturerad output → ~150 tokens in, ~100 tokens ut per bild → Kostnad: ~$0.0004 per triggad bild ``` --- ## Structured Observation Schema ```json { "observation_id": "qx-bkk-20260621-001", "lat": 13.7420, "lng": 100.5571, "city": "bangkok", "district": "sukhumvit", "timestamp": "2026-06-21T12:18:00Z", "zoomer_level": "L2", "image_hash": "sha256:...", "detected_objects": [ {"class": "power_pole", "confidence": 0.94, "bbox": [...]}, {"class": "cable_bundle", "confidence": 0.87, "bbox": [...]}, {"class": "graffiti", "confidence": 0.71, "bbox": [...]}, {"class": "commercial_sign", "confidence": 0.89, "bbox": [...]} ], "computed_scores": { "infrastructure_risk": 8.2, "condition_score": 3.1, "vacancy_status": "occupied", "graffiti_density": "low", "cable_disorder_severity": "critical" }, "contradiction": { "potential": 0.84, "official_classification": "infrastructure_approved", "observed_deviation": "critical_cable_disorder", "claude_triggered": true, "narrative": "Official data: approved. Observed: critical cable bundling, fire risk." }, "tags": ["electrical_hazard", "cable_disorder", "graffiti", "commercial_active"], "source_first": { "type": "observation", "verified_by": "ai_v1.2", "confidence": 0.87 } } ``` --- ## Claude-prompt (minimalt) Bara triggas vid contradiction_potential > 0.7: ``` SYSTEM: You are a urban intelligence classifier. Output JSON only. USER: Location: Bangkok Sukhumvit. Objects: power_pole, cable_bundle(critical), graffiti(low). Official status: infrastructure_approved. Output: {"contradiction_score":0-1, "risk_tags":[], "narrative":"<20 words"} ``` Kostnad per prompt: ~$0.0003. Med 5% trigger-rate på 1000 bilder/dag = $0.15/dag. --- ## Implementation — server-side script Fil: /opt/amos/api/landvex-vision/process_image.py Kräver: ultralytics (YOLOv8), Pillow, numpy Installeras en gång: pip install ultralytics pillow numpy anthropic --- ## Träningsstrategi ### Fas 1 — Bootstrap (nu) - Labla 500 bilder manuellt (Erik + Johan, 2h) - Kategorier: infrastructure_risk, vacancy, condition, graffiti - Verktyg: Label Studio (gratis, self-hosted) ### Fas 2 — Active learning (vecka 2-4) - Modellen flaggar bilder med låg confidence → manuell labeling - Varje ny stad bootstrappas med 50-100 bilder ### Fas 3 — Temporal learning (månad 2+) - Samma koordinat fotograferas igen 30 dagar senare - Change detector: delta mellan t0 och t1 - Automatisk träningsdata utan manuellt arbete ### Fas 4 — Contradiction fine-tuning - Alla bilder där Claude ändrade klassificeringen → träningsdata - Målet: Claude-triggern sjunker från 5% → 1% → 0.1%