Situationen
En produkt för mental hälsa med tre verksamheter inuti: ett abonnemang för konsumenter, en arbetsgivarportal såld till företag för deras anställda, och en marknadsplats där användarna bokar videosessioner med behandlare. Ovanpå allt det en rekommendationsmotor som föreslår vad en person bör göra härnäst, utifrån hur personen säger sig må.
Den tredje är anledningen till att det här projektet är värt att skriva om. En rekommendationsmotor som föreslår en andningsövning till någon som är lätt stressad är en trevlig funktion. Samma motor som föreslår en andningsövning till någon i kris är ett allvarligt fel. Den tekniska frågan är inte hur du bygger den - det är hur du vet att den inte kommer att göra det.
Vad jag byggde
En backend i Django och DRF med en React 18-applikation framför, levererade som ett enda system: abonnemang och fakturering, arbetsgivarportalen med sin egen platshantering, marknadsplatsen för distansvård på Zoom Video SDK, community-funktionerna, gamification och en komplett administrativ backoffice för redaktionsteamet.
Rekommendationsmotorn
En hybrid, inte en ren modell. Ur en strukturerad check-in kommer en graderad bedömning av nervsystemets tillstånd, och den graden driver en viktad sampling ur en katalog i stället för en statisk rankad lista - så kontexten slår populariteten, och två personer i olika tillstånd får aldrig samma svar bara för att ett objekt generellt har högt betyg. Upptäcktsplatser med cooldown hindrar katalogen från att kollapsa till samma tjugo objekt, och den kritiska vägen går helt förbi ORM:en, för den körs på varje skärm.
Två AI-leverantörer sitter bakom en enda abstraktion, med möjlighet att växla i adminen, med cachning av svaren för att hålla kostnaden per användare förutsägbar. Valet av leverantör är ett konfigurationsbeslut, inte ett arkitekturbeslut - vilket spelade roll redan samma år, när priserna ändrades.
Retrieval som förblir förankrad
Ungefär trettiotusen distinkta lösningar extraherades ur omkring nittiofem böcker och indexerades för retrieval. Förankringen är hela poängen: systemet svarar ur den korpusen, inte ur en modells allmänna intryck av wellnessråd. Viktning efter lämplighet i krissituationer håller olämpliga förslag borta från svåra tillstånd, diversitetstak hindrar en enda källa från att dominera, och ett vitlistat näringsindex hindrar modellen från att glida in i medicinska råd den inte har någon anledning att ge.
Den konversationella coachen ovanpå har beständigt minne mellan sessioner, en kadenskontroll som driver samtalet mot en konkret handling i stället för att låta det vandra trevligt omkring, och en tillståndsmaskin för moderering med tre varningar för innehåll som bör avsluta utbytet och lämna över.
Delen jag är stoltast över
Ingenting av det ovanstående är värt något som rent påstående. Så jag byggde en Monte Carlo-rigg som genererar syntetiska användare med varierade och adversariella tillstånd och kör dem genom den riktiga motorn.
Hundratjugotusen sessioner över två körningar, som kontrollerar två egenskaper: att ingen session i kristillstånd någonsin får en olämplig rekommendation, och att inget element i katalogen är onåbart - ett dött kort är innehåll som någon har skrivit och som ingen någonsin kommer att se. Båda höll.
Riggen finns som en enklicksåtgärd i adminen, så redaktionsteamet kör om den efter varje innehållsändring i stället för att vänta på en utvecklare. Det är den delen som gör det till en säkerhetsegenskap i stället för en skärmdump från lanseringsdagen: det kontrolleras av de människor som kan ha sönder det, precis i det ögonblick då de skulle kunna göra det.
En AI-funktion som ingen har mätt är inte en funktion. Det är en risk som ingen har satt pris på och som råkar ta sig bra ut i demo.
Handel och compliance
Stripe-abonnemang med en tvåspråkig motor för planer och rabatter, redigerbar i adminen, e-fakturering med automatisk utfärdning och avstängning vid förfallen betalning, en provisionsmotor för ambassadörer i flera nivåer, tio integrationer med wearables över OAuth och lead scoring som kombinerar regler, en modell och en genomgång med AI.
Vad jag skulle göra annorlunda
Jag skulle skriva utvärderingsriggen före motorn, inte strax efter den. Jag byggde rekommendationsmotorn, sedan byggde jag det som bevisar den - och förlorade en vecka på att ändra rekommendationsmotorn för att kunna testa den. Hade jag utgått från ”vad kommer jag att behöva bevisa om det här?” hade designen blivit bättre och kommit en vecka tidigare.