Files
Cibello-app/docs/09-aamos-integration.md
T
Sven (AAMOS AI) 050c958285 feat(gemini): Skiva 1 – Gemini 2.5 Flash som lärar-tier för kylskåpsskanning
- Gemini-adapter bakom AamosClient-interface (AAMOS_MODE=gemini)
- Serversida/worker: hämtar bild, anropar Gemini, mappar mot canonical_ingredients
- Kostnad/tokens bokförs i ai_usage_counters; global dagsbudget via BudgetStore
- Redis-backed budget i worker, in-memory i tester
- Migration 0019: ai_cost_usd_microcents
- Hermetiska tester med inspelad fixture; separat pnpm eval:scan
- docs/09 uppdaterad ärligt: AAMOS-status, Gemini-flöde, säkerhet/kostnad
- REQUIRE_REAL=1 stödjer AAMOS_MODE=gemini; deploy-grind uppdaterad
2026-08-08 03:30:59 +07:00

6.2 KiB
Raw Blame History

Del 9 AI-integration (AAMOS + Gemini-lärar-tier)

Uppdaterad 2026-08-08 efter scouting: AAMOS Core v1 är autentiseringsmässigt nåbar men saknar konfigurerad matmodell (/v1/detect faller tillbaka på YuNet ansiktsdetektering). Tills vidare används Gemini 2.5 Flash som lärar-tier för kylskåpsskanning, bakom samma AamosClient-gränssnitt. AAMOS/prod rörs inte.

Appen når AI uteslutande via backend (beslut 2026-08-02). Mobilappen har aldrig direktkontakt och innehåller inga AI-hemligheter (spec §31, §61.13).

Kontraktet (packages/ai-contracts)

Appen definierar ett versionerat, Zod-validerat kontrakt per uppgiftstyp. Input valideras FÖRE nätverksanropet, output valideras EFTER ett svar som bryter kontraktet behandlas som fel och når aldrig användardata. Modeller, prompts och leverantörer kan bytas fritt bakom kontraktet ("Food API ska få stabila kontrakt oavsett modell").

┌─────────┐   signed image URL   ┌──────────┐   AamosClient   ┌─────────────────┐
│   App   │ ───────────────────→ │ Food API │ ───────────────→│ Worker adapter  │
└─────────┘                      └──────────┘                 └─────────────────┘
                                                                    │
                                     ┌──────────────────┬──────────┴──────────┐
                                     │ AAMOS_MODE=http  │ AAMOS_MODE=gemini   │
                                     │ HttpAamosClient  │ GeminiAamosClient   │
                                     │ → AAMOS Core v1  │ → Gemini 2.5 Flash  │
                                     └──────────────────┴─────────────────────┘

createAamosClient() väljer adapter utifrån AAMOS_MODE. Inga anropare behöver ändras. App→Food API→leverantörsgränsen är oförändrad.

AAMOS Core v1-status

Reella endpoints (ingen /v1/tasks fiktion):

POST /v1/detect      POST /v1/verify      POST /v1/compare
POST /v1/segment     POST /v1/classify    POST /v1/authenticate
POST /v1/score       POST /v1/explain     POST /v1/extract
POST /v1/track       GET  /v1/health

Scouting 2026-08-08 visade:

  • amos-core.service på server-2 anropar http://localhost:3207.
  • Värdport 3207 ägs av aamos-identity-rust, inte AI-inferens.
  • AI-inferenscontainern amos-ai-inference:latest exponerar värdport 3209.
  • Port mismatch gör att AAMOS Core aldrig når inferens.
  • Även efter hypotetisk port-fix saknas FOOD/GROCERY/VISION_MODEL konfiguration i .env.amos-core; /v1/detect defaultar till yunet.

Beslut: rör inte AAMOS-prod. AAMOS kan återaktiveras i framtiden när en matmodell finns konfigurerad, via HttpAamosClient.

Gemini-lärar-tier (Skiva 1)

Aktiveras med AAMOS_MODE=gemini + GEMINI_API_KEY. Endast workern anropar Gemini; API:et når aldrig nyckeln.

Hanterade uppgiftstyper

  • ANALYZE_FRIDGE_IMAGE
  • ANALYZE_PANTRY_IMAGE

Övriga task types (READ_RECEIPT, READ_NUTRITION_LABEL, etc.) svarar failed i Skiva 1 och faller tillbaka på appens befintliga flöden.

Flöde

  1. App laddar upp bild → Food API skapar scan_job (status queued).
  2. Workern plockar jobbet, hämtar bilden från lagring (S3/mock).
  3. GeminiAamosClient skickar bilden + svensk livsmedelsprompt till generativelanguage.googleapis.com/v1beta/models/{GEMINI_MODEL}:generateContent.
  4. Gemini svarar med JSON: produkt, varumärke, kvantitet, enhet, kategori, bäst-före/sista-förbruk (om läsbart), konfidens, imageQualityIssues.
  5. Workern mappar detekterade namn mot canonical_ingredients (mjuk matchning).
  6. Resultatet sparas i scan_jobs som awaiting_confirmation.
  7. Användaren granskar och bekräftar i appen. Aldrig auto-commit.
  8. AI är aldrig facit för allergener/näring — mjölkprincipen orörd.

Kostnadskontroll

  • scan_jobs.costUsd lagrar verklig kostnad per anrop.
  • ai_usage_counters.ai_cost_usd_microcents ackumulerar månadskostnad per användare (utan PII).
  • Hushållskvoten aiScans respekteras (befintlig entitlements-logik).
  • Global dagsbudget GEMINI_DAILY_BUDGET_USD via BudgetStore. Workern använder Redis-backed budget; tester använder in-memory budget. När budgeten är förbrukad nekar adaptern nya anrop.
  • Loggning: status, latens, tokens, kostnad, taskType. Ingen bild, inget fritext, inga PII-fält.

Säkerhet

  • Nyckeln finns i .env på workerservrar (SSM i produktion) och checkas aldrig in.
  • App/API validerar att AAMOS_MODE=gemini kräver GEMINI_API_KEY i produktion.
  • REQUIRE_REAL=1 i deploy-grinden gör att start failar om nyckel saknas.

Routing & specialister (framtida)

Skiva 2 kommer lägga premium-eskaleringsstier (Gemini Pro / GPT-4o / Claude) internt i adaptern vid låg konfidens, med eval/guldset som beslutar billig vs dyr modell. Fram till dess: Gemini 2.5 Flash för allt i Skiva 1.

Feedback → träning (Skiva 3)

Varje användarkorrigering i granska-flödet sparas som ai_corrections (AI-utdata + korrigering + modell/promptversion + samtyckessnapshot). Veckojobbet BUILD_TRAINING_SAMPLE exporterar endast rader där anonymized_improvement = granted vid korrigeringstillfället; bilder kräver separat image_training-samtycke. Personligt minne är aldrig träningsdata (§32).

Evals (spec §34)

  • pnpm test: hermetiska tester med inspelad Gemini-fixture, når aldrig nätet.
  • pnpm --filter @app/worker eval:scan: live-eval mot litet guldset. Rapporterar precision, recall, kostnad, latens. Kräver AAMOS_MODE=gemini + nyckel.
  • Regel: ingen modell-/promptändring tas i produktion utan grön eval.

Lägen

AAMOS_MODE Användning
mock dev/test utan nätverk. Produkten vägrar starta i mock.
http Riktig AAMOS Core när matmodell finns.
gemini Gemini 2.5 Flash som lärar-tier för kylskåpsskanning (Skiva 1).