From ee5eb32e0953273c9db715cfc9dbccadba34224f Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 18 Aug 2026 20:16:37 +0000 Subject: [PATCH] chore(modell): rikta ALLT mot gemini-3.1-flash-lite + fixa kostnadsberakning Koden/docs pastod overallt gemini-3.5-flash-lite fast .env kor 3.1. Nu enhetligt 3.1 i .env.example, config.ts-default, gemini.ts-default, tester, eval och docs (09 + 10). Dessutom en RIKTIG bugg: estimateCostUsd rakna pa 3.5-priser ($0,30/$2,50) medan vi kor 3.1 -> overskattade spend och troffade budgetlarmet for tidigt. Nu 3.1-priser ($0,25/$1,50). docs/10 helt omraknad pa 3.1 (per uppgift, per anvandare, skala, 100k-trial-scenariot). Referenslinje kvar som visar 3.5-priset for att motivera valet. --- .env.example | 2 +- apps/api/src/config.ts | 2 +- apps/api/test/scans.test.ts | 2 +- apps/worker/src/eval/capture-eval.ts | 2 +- apps/worker/test/training-export.test.ts | 2 +- docs/09-aamos-integration.md | 8 +- docs/10-ai-kostnad.md | 100 ++++++++++++---------- packages/ai-contracts/src/gemini.ts | 7 +- packages/ai-contracts/test/gemini.test.ts | 4 +- 9 files changed, 69 insertions(+), 60 deletions(-) diff --git a/.env.example b/.env.example index 0016a3b..5901fa5 100644 --- a/.env.example +++ b/.env.example @@ -47,7 +47,7 @@ AAMOS_TIMEOUT_MS=60000 # GEMINI_API_KEY lämnas tom lokalt – hämtas från AWS SSM (/cibello/prod/gemini-api-key) i prod, # inte inskriven för hand. Skriv aldrig over en .env som redan har riktiga varden. GEMINI_API_KEY= -GEMINI_MODEL=gemini-3.5-flash-lite +GEMINI_MODEL=gemini-3.1-flash-lite GEMINI_TIMEOUT_MS=60000 GEMINI_DAILY_BUDGET_USD=25 diff --git a/apps/api/src/config.ts b/apps/api/src/config.ts index 6de2268..eb6dafe 100644 --- a/apps/api/src/config.ts +++ b/apps/api/src/config.ts @@ -48,7 +48,7 @@ const configSchema = z.object({ AAMOS_TIMEOUT_MS: z.coerce.number().int().default(60_000), GEMINI_API_KEY: z.string().optional(), - GEMINI_MODEL: z.string().default("gemini-3.5-flash-lite"), + GEMINI_MODEL: z.string().default("gemini-3.1-flash-lite"), GEMINI_TIMEOUT_MS: z.coerce.number().int().default(60_000), GEMINI_DAILY_BUDGET_USD: z.coerce.number().default(0), diff --git a/apps/api/test/scans.test.ts b/apps/api/test/scans.test.ts index e171aa6..ec31c3f 100644 --- a/apps/api/test/scans.test.ts +++ b/apps/api/test/scans.test.ts @@ -109,7 +109,7 @@ describe("scan confirmation → ai_corrections", () => { }, ], }, - modelVersion: "gemini-3.5-flash-lite", + modelVersion: "gemini-3.1-flash-lite", promptVersion: "gemini-fridge-v1", }) .returning(); diff --git a/apps/worker/src/eval/capture-eval.ts b/apps/worker/src/eval/capture-eval.ts index 89bcaed..15ac4fe 100644 --- a/apps/worker/src/eval/capture-eval.ts +++ b/apps/worker/src/eval/capture-eval.ts @@ -36,7 +36,7 @@ async function main() { ], imageQualityIssues: [], }, - modelVersion: "gemini-3.5-flash-lite", + modelVersion: "gemini-3.1-flash-lite", promptVersion: "gemini-fridge-v1", latencyMs: 1234, costUsd: 0.0001, diff --git a/apps/worker/test/training-export.test.ts b/apps/worker/test/training-export.test.ts index f0755e2..3bea876 100644 --- a/apps/worker/test/training-export.test.ts +++ b/apps/worker/test/training-export.test.ts @@ -71,7 +71,7 @@ describe("BUILD_TRAINING_SAMPLE banks locally", () => { corrected: { displayName: "Mellanmjölk", quantity: 1, unit: "LITER" }, }, imageS3Key: "fridge-scans/train.jpg", - modelVersion: "gemini-3.5-flash-lite", + modelVersion: "gemini-3.1-flash-lite", promptVersion: "gemini-fridge-v1", consentSnapshot: { anonymized_improvement: "granted", image_training: "granted" }, }) diff --git a/docs/09-aamos-integration.md b/docs/09-aamos-integration.md index 070ccef..0ccf3f1 100644 --- a/docs/09-aamos-integration.md +++ b/docs/09-aamos-integration.md @@ -2,7 +2,7 @@ > 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 3.5 Flash Lite** som +> ansiktsdetektering). Tills vidare används **Gemini 3.1 Flash Lite** som > lärar-tier för kylskåpsskanning, bakom samma `AamosClient`-gränssnitt. > AAMOS/prod rörs inte. @@ -24,7 +24,7 @@ bytas fritt bakom kontraktet ("Food API ska få stabila kontrakt oavsett modell" ┌──────────────────┬──────────┴──────────┐ │ AAMOS_MODE=http │ AAMOS_MODE=gemini │ │ HttpAamosClient │ GeminiAamosClient │ - │ → AAMOS Core v1 │ → Gemini 3.5 Flash │ + │ → AAMOS Core v1 │ → Gemini 3.1 Flash │ └──────────────────┴─────────────────────┘ ``` @@ -103,7 +103,7 @@ Gemini; API:et når aldrig nyckeln. 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 3.5 Flash Lite för allt i Skiva 1. +dyr modell. Fram till dess: Gemini 3.1 Flash Lite för allt i Skiva 1. ## Feedback → träning (Skiva 3) @@ -126,4 +126,4 @@ separat `image_training`-samtycke. Personligt minne är aldrig träningsdata (§ | ------------ | --------------------------------------------------------------- | | `mock` | dev/test utan nätverk. Produkten vägrar starta i mock. | | `http` | Riktig AAMOS Core när matmodell finns. | -| `gemini` | Gemini 3.5 Flash Lite som lärar-tier för kylskåpsskanning (Skiva 1). | +| `gemini` | Gemini 3.1 Flash Lite som lärar-tier för kylskåpsskanning (Skiva 1). | diff --git a/docs/10-ai-kostnad.md b/docs/10-ai-kostnad.md index d3f4fe1..0a96b08 100644 --- a/docs/10-ai-kostnad.md +++ b/docs/10-ai-kostnad.md @@ -1,20 +1,23 @@ # Del 10 – AI-modeller och kostnad Priser verifierade 2026-08-02 (BenchLM, uppdaterad 2026-08-01, samt korsläst mot -publika prislistor). **Kontrollera mot Anthropics officiella prissida innan avtal.** +publika prislistor). **Kontrollera mot Google/Anthropics officiella prissida innan avtal.** -> **Faktisk modell (kontrollerad mot koden):** All bildanalys, OCR och receptgenerering körs på -> **Gemini 3.5 Flash Lite** (`GEMINI_MODEL`-default i `apps/api/src/config.ts` + -> `packages/ai-contracts/src/gemini.ts`). Priserna nedan är verifierade mot Google (2026) och -> speglar `estimateCostUsd` i koden. +> **Faktisk modell (kontrollerad mot koden 2026-08):** All bildanalys, OCR och receptgenerering körs på +> **Gemini 3.1 Flash Lite** – samma värde i `.env.example`, i `GEMINI_MODEL`-defaulten i +> `apps/api/src/config.ts` och i `packages/ai-contracts/src/gemini.ts`. Priserna nedan speglar +> `estimateCostUsd` i koden. (Vi kör medvetet 3.1 och inte 3.5 – 3.1 är billigare per token, +> särskilt på output; 2.5-serien fasas ut och är inget alternativ.) ## Aktuella modeller och listpriser (USD per miljon tokens, in/ut) -| Modell | Input | Output | Roll i appen | -| ------------------------------------- | ----- | ------ | -------------------------------------------------------------- | -| Gemini 3.5 Flash Lite (standard) | $0,30 | $2,50 | Arbetshäst: all bildanalys, OCR, receptstrukturering (Skiva 1) | -| Gemini 3.5 Flash Lite (batch) | $0,15 | $1,25 | Asynkrona nattjobb: minnesuppdatering, batch-generering | -| Premium-eskalering (Skiva 2, framtid) | – | – | Större modell vid låg confidence (spec §33) – ej i volym ännu | +| Modell | Input | Output | Roll i appen | +| ------------------------------------- | ------ | ------ | -------------------------------------------------------------- | +| Gemini 3.1 Flash Lite (standard) | $0,25 | $1,50 | Arbetshäst: all bildanalys, OCR, receptstrukturering (Skiva 1) | +| Gemini 3.1 Flash Lite (batch, −50 %) | $0,125 | $0,75 | Asynkrona nattjobb: minnesuppdatering, batch-generering | +| Premium-eskalering (Skiva 2, framtid) | – | – | Större modell vid låg confidence (spec §33) – ej i volym ännu | + +Referens: Gemini 3.5 Flash Lite ligger på $0,30/$2,50 – dyrare på både in och ut, därför kör vi 3.1. Hävstänger: batch-tier −50 %; context caching sänker upprepad input; AAMOS-specialistmodeller ersätter över tid externa anrop för de vanligaste bilduppgifterna (spec §33) → kostnaden nedan @@ -24,29 +27,29 @@ ersätter över tid externa anrop för de vanligaste bilduppgifterna (spec §33) Antaget: bild ≈ 1 000 tokens (Gemini-tiling, A1), systemprompt+kontext ≈ 500–1 000 in, strukturerad JSON-output 400–1 200 ut (A2), växelkurs 10,50 SEK/USD (A4). All bildanalys på -Gemini 3.5 Flash Lite standard-tier – ingen modell-eskalering i Skiva 1. +Gemini 3.1 Flash Lite standard-tier – ingen modell-eskalering i Skiva 1. -| Uppgift | Tokens (in/ut) | Kostnad (Gemini 3.5 Flash Lite) | +| Uppgift | Tokens (in/ut) | Kostnad (Gemini 3.1 Flash Lite) | | ------------------------------- | -------------- | ------------------------------- | -| Kyl-/skafferibild (2 bilder) | 4 000 / 800 | **$0,003 ≈ 0,03 kr** | -| Kvitto | 3 000 / 1 000 | $0,003 | -| Tallriksfoto | 2 500 / 500 | $0,002 | -| Näringsetikett/datum | 2 000 / 400 | $0,002 | -| Receptstrukturering (text) | 2 500 / 1 200 | $0,004 | -| Veckoplan | 3 000 / 800 | $0,003 | -| Minnesuppdatering (batch, natt) | 4 000 / 600 | $0,0014 (batch-tier) | +| Kyl-/skafferibild (2 bilder) | 4 000 / 800 | **$0,0022 ≈ 0,023 kr** | +| Kvitto | 3 000 / 1 000 | $0,0023 | +| Tallriksfoto | 2 500 / 500 | $0,0014 | +| Näringsetikett/datum | 2 000 / 400 | $0,0011 | +| Receptstrukturering (text) | 2 500 / 1 200 | $0,0024 | +| Veckoplan | 3 000 / 800 | $0,0020 | +| Minnesuppdatering (batch, natt) | 4 000 / 600 | $0,00095 (batch-tier) | -**Tumregel: ≈ $0,003 ≈ 0,03 kr per AI-skanning.** Deterministiska flöden (rekommendationer, +**Tumregel: ≈ $0,002 ≈ 0,02 kr per AI-skanning.** Deterministiska flöden (rekommendationer, nutrition, streckkod, FEFO) kostar $0. ## Kostnad per användartyp och månad | Profil | Antagande om användning | AI-kostnad/mån | | --------------------------- | ----------------------------------------- | ----------------------------------------------- | -| Gratis | 5 skanningar (kvottak) | $0,015 ≈ 0,16 kr | -| Household (aktivt) | 60 skanningar + 4 planer + nattligt minne | $0,21 ≈ 2,2 kr | -| Family (aktivt) | 100 skanningar + 4 planer + minne | $0,33 ≈ 3,5 kr | -| Family (maxar fair use 200) | värsta fallet | $0,60 ≈ 6,3 kr — fortfarande under 129 kr-priset | +| Gratis | 5 skanningar (kvottak) | $0,011 ≈ 0,12 kr | +| Household (aktivt) | 60 skanningar + 4 planer + nattligt minne | $0,14 ≈ 1,5 kr | +| Family (aktivt) | 100 skanningar + 4 planer + minne | $0,22 ≈ 2,3 kr | +| Family (maxar fair use 200) | värsta fallet | $0,41 ≈ 4,3 kr — fortfarande långt under priset | Fair use-taken (100/200/400, gratis 5) gör att ingen enskild användare kan bli förlustaffär ens i värsta fallet. @@ -57,48 +60,53 @@ Antaget (A5): 60 % av registrerade är månadsaktiva; mix 80 % gratis / 20 % bet betalande mix 60/30/10 (Household/Family/Large); aktiva gratisanvändare gör 5 skanningar, betalande enligt tabellen ovan. -| Registrerade | Aktiva | AI-kostnad/mån (USD) | ≈ SEK/mån | Intäkt/mån (SEK) | AI-andel av intäkt | -| ------------ | ------ | -------------------- | ---------- | ---------------- | ------------------ | -| 1 000 | 600 | ≈ $140 | 1 500 kr | ≈ 11 900 kr | 12 % | -| 10 000 | 6 000 | ≈ $1 400 | 15 000 kr | ≈ 119 000 kr | 12 % | -| 100 000 | 60 000 | ≈ $14 000 | 147 000 kr | ≈ 1 190 000 kr | 12 % | +Baslinjetabellen nedan är en pessimistisk referens (en dyrare modell); raden under +visar den faktiska kostnaden med Gemini 3.1 Flash Lite. + +| Registrerade | Aktiva | Baslinje AI-kostnad/mån (USD) | ≈ SEK/mån | Intäkt/mån (SEK) | AI-andel (baslinje) | +| ------------ | ------ | ----------------------------- | ---------- | ---------------- | ------------------- | +| 1 000 | 600 | ≈ $140 | 1 500 kr | ≈ 11 900 kr | 12 % | +| 10 000 | 6 000 | ≈ $1 400 | 15 000 kr | ≈ 119 000 kr | 12 % | +| 100 000 | 60 000 | ≈ $14 000 | 147 000 kr | ≈ 1 190 000 kr | 12 % | Intäktsantagande (A6): 20 % betalande × viktat pris ≈ 99 kr. Skalan är linjär tills -specialistmodeller (spec §33) sänker styckkostnaden – rimligt mål är att halvera -bildkostnaden vid >10 000 användare genom AAMOS-specialister + cachade prompts + batch. +specialistmodeller (spec §33) sänker styckkostnaden ytterligare. -**Med Gemini 3.5 Flash Lite (~$0,003/skanning) blir AI-kostnaden ~3,3× lägre än tabellen ovan:** -≈ $42 / 440 kr (1k reg), ≈ $420 / 4 400 kr (10k), ≈ $4 200 / 44 000 kr (100k). AI-andelen av -intäkt sjunker från ~12 % till ~4 %. Firebase Auth tillkommer först vid 60 000 aktiva: +**Med Gemini 3.1 Flash Lite (~$0,0022/skanning) blir den faktiska AI-kostnaden ~4,9× lägre än baslinjen ovan:** +≈ $29 / 300 kr (1k reg), ≈ $285 / 3 000 kr (10k), ≈ $2 850 / 30 000 kr (100k). AI-andelen av +intäkt sjunker från ~12 % till ~2,5 %. Firebase Auth tillkommer först vid 60 000 aktiva: 10 000 × $0,0055 = $55/mån ≈ 580 kr. ## Känslighet Dubbla bildstorleken (A1) → +~30 % (fler bild-tokens). Fler upptäckta varor per bild → mer, -eftersom output ($2,50/1M) dominerar över input ($0,30/1M). Bevaka därför: tokens/bild och +eftersom output ($1,50/1M) dominerar över input ($0,25/1M). Bevaka därför: tokens/bild och output-tokens i verklig trafik, kostnad per uppgiftstyp (usageMetadata → ai_usage_counters / scan_jobs.cost_usd → adminpanelen) med larm på dagsbudget (§58). ## Scenario: 100 000 trial-användare dag 1 (onboarding-toppen) Antagande: 100 000 registrerar sig dag 1, alla kör 14-dagars trial (25 skanningar) och använder -upp alla 25 på bilder i **medelkvalitet** via **Gemini 3.5 Flash Lite** (~$0,003/skanning: -~1 500 input-tokens à $0,30/1M + ~700 output-tokens à $2,50/1M). +upp alla 25 på 2-bilders kylskanningar i **medelkvalitet** via **Gemini 3.1 Flash Lite** +(~$0,0022/skanning: ~4 000 input-tokens à $0,25/1M + ~800 output-tokens à $1,50/1M). | Post | Beräkning | Kostnad | | ----------------------------- | -------------------------- | ---------------------------------- | -| AI – trial-skanningar | 100 000 × 25 × $0,003 | **$7 500 ≈ 79 000 kr** (på 14 dgr) | +| AI – trial-skanningar | 100 000 × 25 × $0,0022 | **$5 500 ≈ 58 000 kr** (på 14 dgr) | | Firebase Auth (100k MAU) | 50k gratis + 50k × $0,0055 | $275/mån ≈ 2 900 kr/mån | -| **Totalt onboarding-månaden** | | **≈ $7 775 ≈ 82 000 kr** | +| **Totalt onboarding-månaden** | | **≈ $5 775 ≈ 61 000 kr** | -AI står för ~97 %, men hela toppen är nu ~3,3× lägre än den tidigare felräkningen -(263 000 kr → 79 000 kr) eftersom Flash Lite är långt billigare per token. +AI står för ~95 %, men hela toppen är nu ~4,5× lägre än den tidigare felräkningen +(263 000 kr → 58 000 kr) eftersom vi kör Gemini 3.1 Flash Lite (billigare än 3.5, långt +billigare än den ursprungliga felräkningens modell). Kör trial-skanningar som enkla +medelkvalitetsbilder (~1 500/700 tokens) landar toppen på ~37 000 kr – 58 000 kr är alltså +ett tak. -Efter trial – om alla faller till gratis (5 skanningar/mån): 100 000 × 5 × $0,003 + Firebase -≈ **19 000 kr/mån** utan intäkt. Break-even på den bördan: ~190 betalande (0,19 %), och -trial-toppen (79 000 kr) tjänas in långt inom första månaden om ~2 % konverterar. +Efter trial – om alla faller till gratis (5 skanningar/mån): 100 000 × 5 × $0,0022 + Firebase +≈ **14 000 kr/mån** utan intäkt. Break-even på den bördan: ~145 betalande (0,15 %), och +trial-toppen (58 000 kr) tjänas in långt inom första månaden om ~2 % konverterar. -Slutsats: med rätt modell är onboarding-toppen ~79 000 kr på 14 dagar vid 100k dag-1 – en -hanterbar post och strukturellt ofarlig. Batch-tier (Flash Lite $0,15/$1,25) halverar dessutom +Slutsats: med rätt modell är onboarding-toppen ~58 000 kr på 14 dagar vid 100k dag-1 – en +hanterbar post och strukturellt ofarlig. Batch-tier (Flash Lite $0,125/$0,75) halverar dessutom nattliga minnesjobb. Bevaka faktisk token-förbrukning per skanning (usageMetadata → ai_usage_counters) och konvertering – inte Firebase. diff --git a/packages/ai-contracts/src/gemini.ts b/packages/ai-contracts/src/gemini.ts index 70c19fb..e8a3d2a 100644 --- a/packages/ai-contracts/src/gemini.ts +++ b/packages/ai-contracts/src/gemini.ts @@ -313,7 +313,7 @@ export class GeminiAamosClient implements AamosClient { constructor(config: GeminiAamosClientConfig) { this.cfg = { apiKey: config.apiKey, - model: config.model ?? "gemini-3.5-flash-lite", + model: config.model ?? "gemini-3.1-flash-lite", timeoutMs: config.timeoutMs ?? 60_000, dailyBudgetUsd: config.dailyBudgetUsd ?? 0, promptVersion: config.promptVersion ?? "gemini-fridge-v4", @@ -1069,8 +1069,9 @@ Språk: ${lang}.`; } private estimateCostUsd(inputTokens: number, outputTokens: number): number { - // Gemini 3.5 Flash Lite standard-tier pricing (2026): $0.30/1M input, $2.50/1M output. - return inputTokens * 0.3e-6 + outputTokens * 2.5e-6; + // Gemini 3.1 Flash Lite standard-tier pricing (2026): $0.25/1M input, $1.50/1M output. + // (Matcha GEMINI_MODEL i .env / config.ts – kör vi 3.1, ska kostnaden räknas på 3.1.) + return inputTokens * 0.25e-6 + outputTokens * 1.5e-6; } private async isOverBudget(estimateUsd: number): Promise { diff --git a/packages/ai-contracts/test/gemini.test.ts b/packages/ai-contracts/test/gemini.test.ts index b6ffe77..3a1bf3e 100644 --- a/packages/ai-contracts/test/gemini.test.ts +++ b/packages/ai-contracts/test/gemini.test.ts @@ -67,7 +67,7 @@ describe("GeminiAamosClient", () => { const budget = new MemoryBudgetStore(); const client = new GeminiAamosClient({ apiKey: "test-key", - model: "gemini-3.5-flash-lite", + model: "gemini-3.1-flash-lite", fetchImpl: makeFetch(JPEG_BYTES), budgetStore: budget, dailyBudgetUsd: 10, @@ -82,7 +82,7 @@ describe("GeminiAamosClient", () => { expect(result.status).toBe("ok"); expect(result.output).not.toBeNull(); - expect(result.modelVersion).toBe("gemini-3.5-flash-lite"); + expect(result.modelVersion).toBe("gemini-3.1-flash-lite"); expect(result.costUsd).toBeGreaterThan(0); expect(result.inputTokens).toBe(392); expect(result.outputTokens).toBe(121);