Zes maanden later is het eerste team nog iedere week prompts aan het finetunen en durft niemand het model te upgraden. Het tweede team heeft al twee keer van model gewisseld zonder dat iemand het heeft gemerkt.
Het verschil zit niet in het model. Het zit in zeven keuzes over de plek van het model in de architectuur, wat het mag teruggeven en wat er gebeurt als het fout zit. Bij iedere integratie maken we deze keuzes opnieuw. Hieronder vind je ze, in de volgorde waarin we ze aanpakken.
1. Eerst deterministische logica, dan pas het model
De meeste bedrijfsdocumenten zijn gestructureerder dan ze op het eerste gezicht lijken. Een bestek volgt een nummeringsschema, een factuur heeft een vaste lay-out en een exportbestand bevat kolommen. Parseer die structuur met gewone code, filter de informatie tot wat je daadwerkelijk nodig hebt en roep pas daarna het model aan.
Onlangs deden we dit voor een fabrikant van laad- en losvoorzieningen. Een bouwbestek van 299 pagina's bevatte precies vijf paragrafen over hun producten. Een parser vond die binnen twee seconden. Het hele document naar een model sturen zou per uitvoering bijna een miljoen tekens hebben betekend, waarbij het model zelf moest inschatten welke pagina's relevant waren. Door alleen die vijf paragrafen te sturen, volstond een goedkope, gerichte aanroep per paragraaf, met bij ieder antwoord een citaat uit de bron.
Code kun je bovendien testen. De parser heeft unittests; bij een prompt kun je alleen maar hopen.
2. Het model levert bewerkingen op, geen vrije tekst
Vraag het model niet om een antwoord. Vraag het om een lijst met bewerkingen op basis van een catalogus die je zelf beheert: voeg deze eigenschap toe met die waarde, verwijder dit item of markeer deze vraag.
Je code valideert iedere bewerking aan de hand van de catalogus voordat er iets wordt toegepast. Onbekende eigenschap? Genegeerd. Waarde buiten het toegestane bereik? Genegeerd en vastgelegd in de logging.
Zo verander je het model van een orakel in een partij die voorstellen doet. Het kan niet naar je database schrijven, zelf queries uitvoeren of nieuwe velden verzinnen. Het kan alleen kiezen uit de mogelijkheden die jij aanbiedt.
Nieuwe functionaliteit toevoegen wordt daarmee een kwestie van de catalogus aanpassen in plaats van prompts wijzigen. Bovendien is de catalogus de plek waar domeinexperts kunnen nalezen wat het systeem wel en niet mag doen.
3. Leg de herkomst van ieder veld vast
Een waarde die uit een model komt, moet een label krijgen dat aangeeft waar die vandaan komt. Bij de fabrikant van laad- en losvoorzieningen krijgt iedere geconfigureerde eigenschap een van vier labels: letterlijk overgenomen uit het bestek, doorgeschoven naar een technische tekening, een standaardwaarde die een expert normaal gesproken zou toepassen, of een openstaande vraag.
De reviewer ziet zestien waarden die letterlijk zijn overgenomen, vier die naar een tekening zijn doorgeschoven, twee standaardwaarden en zes openstaande vragen. Zo is meteen duidelijk waar extra aandacht nodig is.
Eén algemene betrouwbaarheidsscore biedt die duidelijkheid niet. Een score van 0,8 vertelt de reviewer niet of het model de waarde daadwerkelijk heeft gelezen of gewoon goed heeft gegokt. Herkomstinformatie doet dat wel.
Het is ook wat de uitvoer verdedigbaar maakt wanneer een configuratie de productie aanstuurt en een verkeerde waarde niet zomaar een typefout oplevert, maar een productiefout.
4. Eén toegangspoort voor alle modellen
Plaats een gateway tussen je applicaties en alle modelproviders. Applicaties praten met een alias, zoals 'het extractiemodel', in plaats van rechtstreeks met een endpoint van een leverancier.
De gateway beheert de sleutels, koppelt de alias aan een provider en modelversie, logt iedere aanroep en rapporteert de kosten per applicatie.
Wij beheren zelf één gateway. Wanneer een provider een modelversie uitfaseert — en dat gebeurt volgens de eigen planning van die provider — wordt de alias omgezet en hoeven de applicaties niet te veranderen.
Wil een team voor één use case een andere modelfamilie uitproberen? Dan is dat een routeringsregel en geen codewijziging. En de kosten per verwerkt document, het cijfer dat een business owner kan afzetten tegen de opbrengst, rollen rechtstreeks uit de logs in plaats van uit een spreadsheet.
5. Een oplossing die blijft werken als het model uitvalt
Rate limits, storingen of een sleutel die op vrijdagavond verloopt. Bepaal vóór livegang wat de feature in zulke situaties doet.
In de twee systemen die we dit najaar hebben gebouwd, bestaat de fallback uit een parser op basis van trefwoorden. Die levert dezelfde bewerkingen op als het model, alleen minder slim, en markeert de resultaten als offline gegenereerd. Het scherm blijft werken. De gebruiker ziet dat het antwoord minder goed is en waarom.
Die fallback is geen luxe. Het is wat je nodig hebt om het systeem te demonstreren op het netwerk van een klant waar je gateway onbereikbaar is. En het is wat je in staat stelt een modelupgrade uit te rollen in de wetenschap dat een slechte dag de functionaliteit verslechtert in plaats van het hele systeem plat te leggen.
6. Cache op basis van inhoud en speel resultaten opnieuw af wanneer dat nodig is
Modelaanroepen zijn traag en kosten geld, terwijl veel aanroepen hetzelfde werk doen. Bereken een hash op basis van de invoer en de versie van de catalogus en cache het resultaat. Een tweede uitvoering op hetzelfde document is dan direct klaar en kost niets extra aan modelaanroepen.
De cache maakt ook het opnieuw afspelen van resultaten mogelijk: de exacte uitvoer die het model vorige maand gaf, bijvoorbeeld voor een audit waarin wordt gevraagd waarom het systeem een bepaalde waarde heeft voorgesteld.
Vernieuw de cache bewust. Een nieuwe catalogus of modelversie levert een nieuwe hash op, zodat oude antwoorden niet per ongeluk opnieuw worden gebruikt. Voor gevallen waarin een medewerker een nieuwe beoordeling wil, volstaat een knop 'Vernieuwen' die de cache omzeilt.
7. Bouw autonomie stapsgewijs op, met een beoordelingsscherm
Pramod Sadalage en Prem Chandrasekaran beschrijven dit goed op de website van Martin Fowler: het model doet eerst aanbevelingen, bereidt vervolgens acties voor die een persoon goedkeurt en handelt uiteindelijk zelfstandig binnen vastgestelde grenzen.
Iedere fase levert het bewijs voor de volgende. En iedere fase is een veilige plek om te stoppen.
Daarvoor heb je een beoordelingsscherm nodig waarop de voorgestelde bewerkingen, de herkomstinformatie en de openstaande vragen zichtbaar zijn. Een medewerker moet voorstellen kunnen accepteren, aanpassen of afwijzen.
Het is misschien het minst spectaculaire onderdeel van het systeem, maar wel het onderdeel dat bepaalt of mensen het vertrouwen. Meet hoe vaak reviewers veranderen wat het model voorstelt. Daalt dat percentage naar nul, dan is het model óf uitstekend, óf niemand leest de voorstellen nog.
Wat we willen weten voordat de eerste prompt wordt geschreven
- Structuur: hoeveel van de invoer kan gewone code verwerken voordat een model eraan te pas komt, en welk percentage van het totale volume dekt dat?
- Catalogus: welke bewerkingen mag het model voorstellen en wie beheert die lijst?
- Herkomst: kan de reviewer bij ieder uitvoerveld zien of de waarde is overgenomen, afgeleid, als standaardwaarde ingevuld of onbekend is?
- Gateway: kunnen we deze feature binnen één dag naar een ander model verplaatsen zonder de applicatiecode te wijzigen?
- Terugvalscenario: wat ziet de gebruiker wanneer het model een uur niet beschikbaar is, en is dat acceptabel?
- Opnieuw afspelen: kunnen we de exacte uitvoer reproduceren die het systeem drie maanden geleden voor een bepaalde invoer heeft gegeven?
- Autonomie: in welke fase begint de feature, welk bewijs is nodig om naar de volgende fase te gaan en hoe vaak passen reviewers de voorstellen momenteel aan?
Een model dat alleen uit jouw catalogus kan kiezen, kan je niet verrassen. Een model dat vrije tekst naar je ERP schrijft, gaat dat vroeg of laat wel doen.
Waar je kunt beginnen
Als je al een taalmodel in productie hebt, of daar bijna bent, zijn deze zeven punten een halve dag met je architect meer dan waard. De meeste systemen hebben er al twee of drie op orde en missen juist de onderdelen die op een slechte dag het verschil maken.
We lopen ze graag samen met je door, aan de hand van je eigen integratie.