Vi raderade vår utgiftstolk
Dimesums regelbaserade utgiftstolk höll en vecka innan fyra vanliga meningar bokförde pengar på fel person och den ersattes av en enda vägransregel.
Vi raderade en tolk vi just hade skrivit klart. Dimesums första försök till tolkning av utgifter i naturligt språk var en regelmotor, och fyra vanliga meningar avvecklade den: dinner 12-08 400 lästes som 12 kr, ravioli 600 lade en medlem vid namn Ravindra i delningen, kirana 500 debiterade en medlem vid namn Kiran, och refund -483.50 blev en debitering på 483,50 kr.
Att förstå en mening är modellens uppgift och ingen annans. Det som ersatte regelmotorn är en enda nivå som kallas amount_only: ett enda tal, som returneras bara när texten innehåller exakt en otvetydig pengakandidat, och aldrig ett påstående om personer. Två kandidater betyder inget belopp. En regel ersatte en växande hög av skydd.
Fyra meningar avslutade regeltolken
Den raderade tolken täckte hela den uppsättning entiteter som vårt AI-designdokument anger: matchning av medlemmar och smeknamn, ett exkluderingslexikon, härledning av betalare, ett kategorilexikon och finjusterade säkerhetsvärden per fält. Var och en av de fyra bristerna nedan hade en självklar lösning. Varje lösning var ett nytt skydd med sin egen blinda fläck.
| Vad användaren skrev | Vad tolken gjorde | Varför det hände |
|---|---|---|
dinner 12-08 400 | Läste beloppet som 12 kr | En läsare ser ett datum och en summa. En regex ser tre tal och tar det första. |
ravioli 600 | La en medlem vid namn Ravindra i delningen | Luddig smeknamnsmatchning poängsatte en maträtt mot en person. |
kirana 500 | Debiterade en medlem vid namn Kiran | Samma matchning, den här gången med ett butiksnamn. |
refund -483.50 | Bokförde en debitering på 483,50 kr | Siffrorna överlevde men inte tecknet, så pengarna pekade åt motsatt håll. |
Två av de fyra är samma fel i olika kläder. Luddig matchning kan inte skilja en maträtt från en person eller en butik från en person, för på teckennivå ser ravioli och Ravindra verkligen lika ut. Kräv en längre prefixmatchning så bryter du ravi, som är just det fall matchningen finns till för.
Varje skydd du lägger till väcker två nya formuleringar
En regeltolk misslyckas på ett bestämt sätt: den svarar självsäkert och fel. Ett tomt fält kostar användaren en tryckning. En felaktig delning kostar förtroendet för huvudboken, och i en app för att dela utgifter är huvudboken produkten. De fyra raderna ovan är inte nära ögat, de är pengafel.
Löpbandet är det verkliga argumentet, inte någon enskild defekt. Lägg till ett datumskydd så dyker ordernummerfallet upp. Lägg till ett ordernummerskydd så kommer lägenhetsnummer, sedan antal, sedan bordsnummer. Skyddslistan växer och konvergerar aldrig, för naturligt språk har ingen ändlig uppsättning formuleringar att räkna upp.
Inmatning i naturligt språk är en AI-funktion, och ingenting i Dimesums kodbas mönstermatchar den. Beslutet landade 2026-08-20, nedskrivet tillsammans med de fyra bristerna, så att ingen bygger om skydden av misstag.
Det som levererades är ett tal och en vägran
amount_only är den nedgraderade nivån i vårt AI-designdokument, bokstavligt implementerad. Den nivån lyder "det enkla formuläret med förifyllt beloppsregex på klientsidan", så nivån returnerar ett belopp och inget annat: ingen beskrivning, ingen kategori, inga betalare, inga deltagare, inga undantag. Den kostar ingenting och anropar ingen, vilket är varför test och CI körs på den.
Tvetydighet är en vägran, inte en utslagsröst
Hela regeln finns i en enda funktion, extract_amount_minor. En siffra kommer tillbaka bara när texten innehåller exakt en kandidat till den, så order 90210 dinner 400 och flat 402 rent 15000 returnerar tomt i stället för att välja en vinnare. En valutamärkt siffra räknas som otvetydig även bredvid nakna tal, vilket är varför dela på 3 1 200 kr ändå läses som 1 200 kr.
En negerad siffra är inget belopp alls i stället för sitt absolutvärde. -500, minus 200 och revisorns (500) kommer alla tillbaka tomma, för fältet är en debitering och att behålla siffrorna men släppa tecknet pekar pengarna åt motsatt håll mot texten. Parenteser räknas bara när de sluter kring själva siffran, så (500 each) förblir en parentes.
Valutan avgör aritmetiken
Minsta enheter är den enda representation pengar har i Dimesum, så nivån konverterar med en ISO 4217-exponenttabell i stället för en hårdkodad multiplikation med 100. Den japanska yenen har ingen underenhet alls, och ×100 blåser upp ett kvitto på ¥1,200 hundra gånger. En siffra finare än valutans minsta enhet vägras i stället för att avrundas, för att avrunda ett belopp någon skrivit är att hitta på ett.
Indiska talord är en del av att skriva en siffra, inte en del av att förstå en mening. 1.2k, 2 lakh och 500/- löses alla upp, precis som 1,200. Allt över huvudbokens högsta belopp kommer tillbaka tomt, så en felskriven siffra tömmer ett fält i stället för att spilla över ett heltal längre ner.
| Fält | Regeltolk (raderad) | amount_only (i drift) | Modellnivå (kopplad, utan nyckel) |
|---|---|---|---|
| Belopp | Gissat från flera tal | En otvetydig siffra, annars tomt | Läst i sammanhang |
| Beskrivning, kategori | Lexikonmatchning | Alltid null | Utvunnet ur meningen |
| Deltagare, undantag | Luddig namnmatchning | Alltid tomt | Upplöst till riktiga medlems-id:n |
| Betalare | Härlett ur formulering | Alltid tomt | Namngiven, med ett nullbart belopp |
| Total säkerhet | Finjusterad per fält | Fast på 0.3 | Per tolkning |
| Rapporterad prompt | Ingen fanns | Null, ingen prompt lästes | Prompt-id och version |
Nivån i drift klarar aldrig 0.6-gränsen för användbarhet
Vårt tolkningskontrakt överger en tolkning under 0.6 i total säkerhet och släpper användaren till det enkla formuläret. amount_only rapporterar 0.3 på varje svar, och konstanten är strukturell snarare än finjusterad. Ett ensamt belopp är ingen tolkning, så nivån ligger på halva gränsen oavsett vad den hittade. En konstant för varje svar är det som håller den där: ett värde per fall är ett värde som någon till slut petar uppåt.
Nivån rapporterar också ingen prompt alls. Både prompt_id och prompt_version kommer tillbaka null, för nivån läste ingen prompt. Att namnge en skulle tillskriva varje utvärderingsresultat en promptversion som nivån aldrig såg, och utvärderingsriggen är det enda instrument som får befordra en nivå till förslag med en tryckning, vid 95% precision på belopp och deltagare tillsammans.
Två ytterligare nivåer är deklarerade och ingen är i drift. Nivån cheap-fast har en Groq-adapter för openai/gpt-oss-120b och ingen nyckel; mellannivån har ingen adapter. Att välja endera misslyckas vid start snarare än vid användarens första förfrågan, för en LLM debiterar per anrop och ett debiterbart beroende måste fela stängt.
Ingenting bokförs automatiskt, så ett tomt fält kostar en tryckning
Ett tomt fält kostar så lite bara för att ingen registrering i Dimesum kan bokföra pengar. En registrering skapar ett förslag, en person bekräftar det, och bekräftelsen är det som skapar utgiften. Briefens beslut D5 anger regeln, och .go-arch-lint.yml upprätthåller den: registreringskontexten nekas varje beroende av expense eller ledger, så en registrering kan inte bokföra en journal ens av misstag. CI fäller importen, vilket vi kontrollerade genom att lägga till en.
Registreringen behåller råtexten oavsett vad tolken gör, och namnger vilka fält som är olösta. Klienten markerar de tomma fälten i stället för att visa ett påhittat utkast, vilket är skillnaden mellan en tolk som säger ingenting och en som gissar. Bekräftelsen härleder sitt utgifts-id från förslags-id:t, så en dubbel tryckning spelas upp igen i stället för att debitera två gånger.
Regeln värd att stjäla
Räkna dina skydd, inte dina buggar. En skyddslista som växer varje vecka säger dig att uppgiften är förståelse, och förståelse hör hemma hos en modell. Vårt nästa steg är att köra den gyllene uppsättningen i contracts/parse_expense/eval/ mot en riktig modellnivå, för ingenting här blir ett förslag med en tryckning utan den domen.
Vanliga frågor
Varför tog Dimesum bort sin regelbaserade utgiftstolk?
Dimesum tog bort den för att fyra vanliga meningar gav pengafel och varje tillagt skydd väckte två nya formuleringar. dinner 12-08 400 lästes som 12 kr, ravioli 600 lade till en medlem vid namn Ravindra, kirana 500 debiterade en medlem vid namn Kiran, och refund -483.50 blev en debitering på 483,50 kr. Att förstå en mening är modellens uppgift.
Vad returnerar amount_only-nivån egentligen?
amount_only-nivån returnerar ett tal och inget annat. Den svarar med ett belopp bara när texten innehåller exakt en otvetydig pengakandidat, och den namnger aldrig en deltagare, en betalare, en beskrivning eller en kategori. Två kandidater betyder inget belopp alls. Allt annat i tolkningskontraktet väntar på en modellnivå.
Varför rapporterar amount_only 0.3 i säkerhet i stället för ett riktigt värde?
0.3 är strukturellt, inte finjusterat. Vårt tolkningskontrakt överger en tolkning under 0.6 och släpper användaren till det enkla formuläret, och ett ensamt belopp är ingen tolkning, så nivån ligger på halva den gränsen oavsett vad den hittade. En fast konstant för varje svar hindrar att ett värde per fall petas uppåt senare.
Kan en registrering i naturligt språk bokföra i huvudboken utan en människa?
Nej. En registrering skapar ett förslag och en person bekräftar det, enligt briefens beslut D5. Regeln upprätthålls i .go-arch-lint.yml, som nekar registreringskontexten varje beroende av expense eller ledger, så CI fäller importen om en registrering någonsin sträcker sig efter en journal. Att bekräfta är det som skapar utgiften.
Vad händer med tolkningen av utgifter i naturligt språk när ingen modellnivå finns?
Dimesum nedgraderar till amount_only och visar tomma fält. Nivån cheap-fast är kopplad till Groqs openai/gpt-oss-120b och levereras utan nyckel, och mellannivån har ingen adapter, så att välja endera misslyckas vid start snarare än vid användarens första förfrågan. Registreringen behåller råtexten i vilket fall som helst.
Populära inlägg
- Journalen som håller delade utgifter exakta8 min läsning
- Varför en ändrad utgift måste ange delningen på nytt8 min läsning
- Sex pengabuggar i utgiftsdelning med flera valutor8 min läsning
- Gör upp: reglera gruppens utgifter med färre överföringar5 min läsning
- Dela notan när en rätt inte delades9 min läsning