ID.nl logo
Programmeren in Python met ChatGPT - Deel 5
© Limitless Visions - stock.adobe.com
Huis

Programmeren in Python met ChatGPT - Deel 5

In de vorige delen van de workshopreeks over de OpenAI-API hebben we teksten samengevat, vertaald en er informatie uit gehaald. Dat bleef telkens beperkt tot één vraag en één antwoord. In dit laatste deel gaan we een stap verder: je gaat in je eigen Python-programma’s volwaardige conversaties voeren met het taalmodel van ChatGPT.

In dit laatste deel laten we zien dat je in Python een conversatie met ChatGPT kunt voeren.

  • We breiden de basiscode uit met 'messages'
  • We creëren een spelpersonage

Lees ook: Babbelen met bijdehante bots: er is meer dan ChatGPT

Code downloaden In dit deel worden wat voorbeelden van stukken code gegeven. Omdat overtikken van code erg foutgevoelig is, kun je die code beter downloaden en daarna bekijken of kopiëren. Het bestand, gptcode-dl5.txt is beschikbaar via deze webpagina.

Je weet ondertussen hoe je in je Python-programma’s een vraag aan ChatGPT stelt via de OpenAI-API. We hebben dit in de vorige vier delen van deze workshopreeks geïllustreerd met talloze toepassingen. Maar onze programma’s hadden daarbij telkens dezelfde structuur: je stelt een vraag (de prompt), je krijgt een antwoord (de completion) en dan stopt de interactie.

Als je al eens van ChatGPT gebruikgemaakt hebt op de OpenAI-website, weet je dat je er ook volledige conversaties mee kunt voeren. Die mogelijkheid gaan we nu ook in onze eigen Python-programma’s inbouwen. In plaats van een klassieke, beperkte interface met invoer in een vast patroon, creëer je zo een conversationele interface. 

Basiscode

In de vorige delen van deze reeks maakten we altijd gebruik van een basisfunctie get_completion waaraan we een gebruikersprompt en eventueel een systeemprompt gaven, met optioneel ook een model. Die functie stuurde de prompt(s) door aan de OpenAI-API en gaf het antwoord terug.

Om een conversatie te voeren, moet het taalmodel toegang tot de hele context hebben, met de vorige boodschappen die het taalmodel en jij hebben uitgewisseld. Daarom maken we in dit deel een nieuwe hulpfunctie: get_completion_from_messages. Daaraan geef je de hele geschiedenis van boodschappen door. Onze basiscode ziet er dan als volgt uit:

De code kun je bekijken in het bestand gptcode-dl5.txt, te downloaden via deze pagina.

Klik daarom in Visual Studio Code op File / New File en kies Python File. Plaats daarin de voorgaande Python-code. De API-sleutel moet je zelf aanmaken in je account bij OpenAI, net zoals in de vorige delen van deze workshopreeks.

Google Nest Mini

Een apparaat dat ook luistert naar wat jij te zeggen hebt

Rollen

Waaruit bestaan die boodschappen nu? Het argument messages dat we aan de functie get_completion_from_messages moeten doorgeven, is een lijst van Python-dictionary’s, een datastructuur die sleutels en waardes heeft. Elke dictionary in de lijst messages heeft twee sleutels: "role" en "content". De eerste beschrijft de rol van de boodschap in de conversatie en de tweede de inhoud (de tekst).

De OpenAI-API kent drie rollen: system, user en assistant. Een boodschap met de rol system beschrijft een systeemprompt. Zoals we in de vorige delen uitlegden, geeft een systeemprompt algemene instructies aan het taalmodel. Een boodschap met de rol user beschrijft een vraag van de gebruiker. En een boodschap met de rol assistant beschrijft een antwoord van het taalmodel.

Een conversatie met de OpenAI-API kan er dan in Python als volgt uitzien in de vorm van boodschappen met een rol en inhoud:

De code kun je bekijken in het bestand gptcode-dl5.txt, te downloaden via deze pagina.

Voeg deze lijst aan je code toe. Daarna kun je aan de OpenAI-API vragen om de conversatie in deze boodschappen voort te zetten:

De code kun je bekijken in het bestand gptcode-dl5.txt, te downloaden via deze pagina.

Sla dit bestand in Visual Studio Code op met Ctrl+S en geef het een naam. Klik dan op Terminal / New Terminal, waarna er onder je code een nieuw deelvenster opent met een opdrachtprompt. Klik rechts bovenaan op het afspeelknopje (het driehoekje met de tooltip Run Python File als je erboven blijft hangen). Als alles goed gaat, krijg je nu in de terminal een antwoord als “Voor het geval dat de cloud gaat regenen!”.

Met deze kennis over de rollen weet je nu ook waarom er in de laatste regel van de functie get_completion_from_messages (en de functie get_completion die we in de eerdere workshops gebruikten) response.choices[0].message["content"] staat. Het stukje message["content"] geeft de tekst van het antwoord van het taalmodel terug. Als je message["role"] in die functie zou tonen, zou je "assistant" te zien krijgen.

Aan ChatGPT is geen originele komiek verloren gegaan.

Wat onthoudt de chatbot?

Je hebt gezien dat elke conversatie die je met het taalmodel voert, bestaat uit een lijst van boodschappen. Het taalmodel houdt rekening met alle informatie die in deze boodschappen te vinden is. Vertel je bijvoorbeeld in één boodschap je naam, dan kun je daar in een van de boodschappen erna naar vragen en kan het taalmodel daar perfect op antwoorden. Vervang de lijst messages uit het vorige voorbeeld maar eens door deze lijst en voer het programma uit:

De code kun je bekijken in het bestand gptcode-dl5.txt, te downloaden via deze pagina.

De conversatie is eenvoudig. Het taalmodel krijgt de instructie dat het een vriendelijke chatbot is. Daarna stelt de gebruiker zich voor en vraagt het taalmodel wat het kan doen. De gebruiker vraagt dan wat zijn naam is.

Als je dit programma uitvoert, zul je zien dat het taalmodel de naam heeft onthouden. Je krijgt dan immers een antwoord als: “Je naam is Koen. Dat heb je net verteld! Is er nog iets specifieks waar je meer over wilt weten?”

In een andere conversatie waarin je je naam niet vertelt, zal de chatmodel niet op de vraag kunnen antwoorden wat je naam is. Deze conversatie bijvoorbeeld:

De code kun je bekijken in het bestand gptcode-dl5.txt, te downloaden via deze pagina.

Dan krijg je als antwoord iets als: “Sorry, maar ik ben een chatbot en heb geen toegang tot persoonlijke informatie. Ik ken je naam niet.”

Het is belangrijk om te weten dat elke conversatie die je met het taalmodel voert volledig losstaat van de andere. Dat je eerder je naam verteld hebt in de andere conversatie, is geen informatie die in de nieuwe conversatie beschikbaar is. Het taalmodel kent alleen de algemene informatie waarop het is getraind en de lijst met boodschappen die je eraan doorgeeft. 

Conversaties voeren

Hierboven hebben we de boodschappen in de programmacode gezet. Maar we willen de gebruiker zelf invoer laten geven. Hoe doen we dat? Met nog een extra hulpfunctie, die de lijst met boodschappen opbouwt en telkens nieuwe invoer vraagt en de uitvoer toont. Dat doen we door de basiscode uit te breiden met:

De code kun je bekijken in het bestand gptcode-dl5.txt, te downloaden via deze pagina.

Als je dit programma uitvoert, kun je een vraag intypen en met een druk op Enter doorsturen. De functie converse voegt je vraag als prompt toe aan de lijst met boodschappen in de variabele context. Ook het antwoord van het taalmodel voegt de functie aan de lijst toe en dat antwoord wordt getoond. We blijven in een oneindige lus (met while True) de functie oproepen, waarbij de context telkens wordt uitgebreid met je vraag en het antwoord. Daardoor onthoudt het taalmodel de voorgaande boodschappen en kunnen we een echte conversatie voeren.

Het taalmodel onthoudt zaken die je in eerdere boodschappen hebt verteld.

Conversationele interface

We hebben nu in wezen een eenvoudige interface voor ChatGPT gebouwd in een terminalvenster. Maar we willen hier een conversationele interface van maken om op een gebruiksvriendelijke manier invoer voor een groter programma te verkrijgen. Als voorbeeld nemen we een computerspel, waarbij je in het begin je spelpersonage moet ontwerpen.

Pak een momentje van ontspanning

Met je favoriete spelpersonage

Een spelpersonage bestaat uit enkele eigenschappen, zoals naam, vaardigheid, uitrusting en ras. Het spel zou je dat allemaal in een formulier kunnen laten invullen, maar waarom niet in een conversatie? Dat gaan we in de rest van dit artikel programmeren. Als eerste stap moeten we dus een uitgebreide systeemprompt creëren die de conversatie kadert:

De code kun je bekijken in het bestand gptcode-dl5.txt, te downloaden via deze pagina.

Ja, de systeemprompt moet echt zo lang zijn. Als we niet expliciet zeggen wat de chatbot wel en niet mag doen, krijgen we uiteindelijk niet wat we willen: een JSON-string met de eigenschappen van het personage. 

Doet je programma niet wat het moet doen? Zodra je een taalmodel in je programma integreert, ben je afhankelijk van de grillen van het taalmodel. Het is een zwarte doos, waarvan je niet weet hoe het exact werkt en wat het doet. Dat contrasteert heel sterk met de ijzeren logica van een programmeertaal als Python. Het is dus goed mogelijk dat het programma van dit artikel niet doet wat je wilt, omdat je een net iets andere invoer geeft dan verwacht of omdat OpenAI ondertussen zijn taalmodel een update heeft gegeven die zich anders gedraagt. Je zult dus waarschijnlijk continu je programma moeten testen en de systeemprompt moeten finetunen, zodat het gewenste gedrag behouden blijft. Dat is het nadeel van de flexibiliteit van een taalmodel in je programma’s te integreren.

JSON

Een groot deel van onze systeemprompt bestaat uit instructies om de uiteindelijke keuzes van de gebruiker in de vorm van JSON (JavaScript Object Notation) te geven. Waarom is dat zo belangrijk? Omdat we de rest van ons programma alleen met gestructureerde gegevens kunnen laten omgaan, niet met tekst.

Dus als de gebruiker in een conversatie met onze assistent een speler met de naam Born heeft gekozen, die een orkenschurk is met een boog, dan moet ons programma dit uiteindelijk in de volgende vorm kunnen inlezen:

Converseren naar een doel

Het doel van onze conversatie is dus dat we uiteindelijk een JSON-string als hierboven krijgen, zodat het programma verder kan en we het spel kunnen spelen. We kunnen onze conversatie dus laten stoppen wanneer de uitvoer van de assistent een geldige JSON-string is.

Om JSON in Python te gebruiken, importeer je eerst de gelijknamige bibliotheek helemaal in het begin van het programma:

import json

Daarna komt onze basiscode en de systeemprompt met de uitgebreide instructies van hierboven, en daarna creëren we de volgende functie converse:

De code kun je bekijken in het bestand gptcode-dl5.txt, te downloaden via deze pagina.

Deze functie vraagt dus invoer van de gebruiker, voegt die aan de context toe en stelt de vraag aan de OpenAI-API. Het antwoord van de assistent voegen we aan de context toe.

Daarna probeert de functie om het antwoord van de assistent als een JSON-object in te laden. Lukt dat, dan geeft de functie dit JSON-object terug. Lukt dat niet, dan geeft Python de foutmelding json.decoder.JSONDecodeError terug en reageren we daarop door gewoon het antwoord van de assistent te tonen. Het is dan immers niet het laatste antwoord met de gestructureerde data in JSON-vorm, maar een vraag. In dat geval geeft de functie None terug, omdat de data nog niet volledig zijn.

Gestructureerde data

Hoe maken we nu van die functie converse gebruik? Dat doen we met de volgende code:

De code kun je bekijken in het bestand gptcode-dl5.txt, te downloaden via deze pagina.

We initialiseren eerst de variabele properties door ze de waarde None te geven. Dan tonen we de eerste boodschap van de assistent, waarin we de gebruiker naar de naam van het spelpersonage vragen.

Daarna roepen we de hele tijd de functie converse met de context aan, zolang de waarde die deze functie teruggeeft None is. Zoals we in die functie gezien hebben, geeft ze een JSON-string terug als de assistent JSON-data teruggeeft en anders None. Als de assistent de instructies correct volgt (zie het kader “Doet je programma niet wat het moet doen?”), stopt de conversatie dus wanneer de data volledig zijn.

Op dat moment wordt de code na het while-blok uitgevoerd. We kunnen nu de eigenschappen van het spelpersonage op een gestructureerde manier uit het JSON-object properties halen. We tonen ze hier één voor één. Uiteraard zou je nog wat controles moeten uitvoeren, zodat er geen ongeldige waardes in staan wanneer het taalmodel niet goed werkt. Maar dat is een oefening voor de lezer!

Onze spelassistent weet dat we met ‘human’ een mens bedoelen en met ‘staf’ een toverstaf, maar negeert in dit geval ons verbod om begeleidende tekst bij de JSON-string te geven.

Lees ook:

▼ Volgende artikel
WhatsApp voegt live foto's, AI-thema's en slimme zoekfunctie toe
© ER | ID.nl
Huis

WhatsApp voegt live foto's, AI-thema's en slimme zoekfunctie toe

WhatsApp rolt de komende tijd opnieuw een reeks functies uit die het chatten en videobellen persoonlijker en praktischer moeten maken. Van creatieve AI-hulpmiddelen tot betere zoekopties in groepsgesprekken: dit zijn de belangrijkste vernieuwingen.

In dit artikel lees je meer over de nieuwste WhatsApp-functies, waaronder:
  • Live foto's (iOS) en bewegende foto's (Android) delen

  • Eigen chatthema's en achtergronden maken met Meta AI

  • Nieuwe stickerpakketten downloaden

  • Groepschats makkelijker terugvinden via zoekfunctie

  • Documenten scannen en delen op Android

Rijkere momenten met live en bewegende foto’s

Gebruikers kunnen nu live foto's (iOS) en bewegende foto's (Android) delen. Die bevatten niet alleen beeld, maar ook geluid en beweging. Het idee is dat gesprekken zo meer diepte krijgen en dat je herinneringen realistischer kunt doorsturen, ongeacht of je gesprekspartner iOS of Android gebruikt. In de praktijk betekent dit dat je niet langer gebonden bent aan statische kiekjes: een lach, een begroeting of een spontaan moment komt beter tot zijn recht, compleet met de sfeer van dat moment. WhatsApp wil hiermee de beleving dichter bij die van een echte ontmoeting brengen, zodat een chat niet alleen informatief is, maar ook emotioneel rijker en levendiger aanvoelt.

Chatthema's en achtergronden met Meta AI

WhatsApp zet ook verder in op kunstmatige intelligentie. Met behulp van Meta AI kun je eigen chatthema's maken en zo je gesprekken een volledig unieke stijl geven. Denk aan kleurenpaletten die aansluiten bij je persoonlijke voorkeuren of achtergronden die zijn geïnspireerd op je favoriete muziek, seizoen of stemming. Daarnaast is het mogelijk om AI-gegenereerde achtergronden te gebruiken tijdens videogesprekken, waardoor je jezelf in een virtuele omgeving plaatst, zoals een tropisch strand of een futuristische skyline. Ook kun je deze achtergronden direct toevoegen bij het maken van foto's en video's in de chat, wat creatieve experimenten eenvoudig maakt. WhatsApp benadrukt dat de uitrol stap voor stap gebeurt: sommige gebruikers zien de opties al, terwijl anderen nog even moeten wachten tot de update beschikbaar is.

©WhatsApp

Nieuwe stickerpakketten

Wie zich liever uitdrukt zonder woorden, krijgt meer keuze uit stickers. WhatsApp voegde pakketten toe met veelzeggende namen als 'Onverschrokken vogel', 'Schooldagen' en 'Vakantie'. De stijl varieert van speels tot gezellig en schattig, zodat er ongetwijfeld voor elke stemming wel een passende illustratie is.

Groepen makkelijker terugvinden

Groepschats hebben vaak creatieve namen die je niet altijd paraat hebt. WhatsApp maakt het daarom eenvoudiger om groepen terug te vinden: zoek in je tabblad Chats gewoon op de naam van een contactpersoon, en de groepen waarin jullie samen zitten worden automatisch getoond.

Documenten scannen op Android

Tot slot is de mogelijkheid om documenten te scannen nu ook beschikbaar voor Android. Gebruikers kunnen rechtstreeks vanuit WhatsApp bestanden vastleggen, bijsnijden, opslaan en verzenden. Daarmee wordt het eenvoudiger om bijvoorbeeld contracten, bonnetjes of formulieren snel te delen zonder eerst een aparte scanner- of camera-app te openen. De functie herkent de randen van het document automatisch en zorgt dat het beeld wordt rechtgetrokken voor een nette weergave. iPhone-gebruikers hadden deze optie al langer, maar door de uitbreiding naar Android is het nu voor vrijwel alle WhatsApp-gebruikers mogelijk om documenten direct in de app te digitaliseren en door te sturen.

▼ Volgende artikel
Van stoofpot tot nagerecht: waarom de slowcooker zo handig is
© Dirk Weischenberg
Huis

Van stoofpot tot nagerecht: waarom de slowcooker zo handig is

Je kent het wel: je hebt een drukke dag, weinig zin om koken, maar wel trek in iets warms en voedzaams. Kom er maar in slowcooker! Je vult hem 's ochtends, zet hem aan en later op de dag staat er een complete maaltijd te wachten. Zeker in de herfst, dé tijd voor stevige soepen en stoofgerechten, is de slowcooker een uitkomst. En: je kunt er veel meer mee maken dan je denkt!

In dit artikel lees je:

– Hoe de slowcooker werkt – Wat je er allemaal mee kunt maken – Welke apparaten je deels kunt vervangen door een slowcooker – Het verschil tussen slowcooker, multicooker en snelkookpan – Tips en aandachtspunten bij gebruik – Twee recepten: apple crumble en pompoensoep uit de slowcooker

Lees ook: 5 veelgemaakte fouten met de slowcooker

Hoe werkt de slowcooker precies?

Een slowcooker werkt anders dan de pan op het fornuis of een braadslee in de oven. Hij gaart gerechten langzaam op lage temperatuur, vaak tussen de 70 en 95 graden. De warmte verspreidt zich gelijkmatig rondom een keramische of metalen binnenpan, terwijl het deksel de stoom en smaken vasthoudt. Omdat er nauwelijks vocht ontsnapt, blijven ingrediënten mals en vol van smaak. Vlees valt na uren sudderen uit elkaar en groente wordt zacht zonder zijn structuur helemaal te verliezen.

Van stoofpot tot nagerecht

Wie denkt dat de slowcooker alleen geschikt is voor stoofpotten, heeft het mis. Natuurlijk kun je er klassiekers als rundvleesstoof of chili con carne mee maken, maar net zo goed linzenstoof, curry of een rijke groentesoep. Voor het ontbijt kun je de avond ervoor havermout in de pan doen, zodat je 's ochtends wakker wordt met een warme kom pap. Zelfs nagerechten zoals rijstepap of een appelcrumble met kaneel (recept verderop) komen goed uit de slowcooker. Sommige modellen hebben bovendien een braadfunctie, zodat je vlees eerst kunt dichtschroeien voordat je het rustig laat garen.

©from_my_point_of_view

Welke apparaten vervangt de slowcooker?

De kracht van de slowcooker zit niet alleen in variatie, maar ook in vervanging. Veel bereidingen die je normaal in de oven of op het fornuis zou doen, kunnen ook prima met de slowcooker. Een stoofpot die je anders urenlang in de gaten moet houden, pruttelt hier vanzelf rustig door zonder dat je steeds hoeft te roeren. Zelfs een rijstkoker, stoommandje of au-bain-marie-apparaat kun je soms links laten liggen, want ook rijst, groente en custard kunnen prima langzaam garen. De slowcooker vervangt niet alle apparatuur in je keuken, maar wel deels.

Slowcooker, multicooker en snelkookpan: dit zijn de verschillen

De slowcooker is niet het enige apparaat dat koken makkelijker maakt. Hij wordt vaak vergeleken met de multicooker en de snelkookpan, maar de werking verschilt duidelijk. De slowcooker werkt op lage temperatuur en heeft vooral tijd nodig. Het voordeel is dat je gerechten kunt laten garen zonder dat je er de hele tijd bij hoeft te blijven en dat smaken zich rustig ontwikkelen. De multicooker is veelzijdiger: die combineert meerdere functies in één toestel, zoals stomen, bakken, rijst koken en vaak ook slowcooken. Daarmee vervangt hij meer losse apparaten, al vraagt het soms om meer instellingen en handelingen. De snelkookpan werkt juist tegengesteld aan de slowcooker. Met hoge druk en hoge temperatuur verkort hij kooktijden drastisch. Waar de slowcooker zes uur nodig heeft voor een stoofpot, staat het gerecht uit een snelkookpan binnen een uur op tafel. Het resultaat is minder diep van smaak, maar wel een snelle uitkomst voor drukke dagen. Kortom: de slowcooker draait om gemak en smaakontwikkeling, de multicooker om veelzijdigheid en de snelkookpan om snelheid.

De voordelen van langzaam garen

Het gebruik van de slowcooker brengt een aantal voordelen met zich mee. Doordat de temperatuur laag blijft, brandt er zelden iets aan en kun je gerust de deur uit terwijl het eten staat te pruttelen. De smaken trekken dieper in de ingrediënten en vlees wordt malser dan dan wanneer je het op hoog vuur bereidt. Bovendien heb je minder olie of boter nodig en kun je vaak goedkopere vleessoorten gebruiken die dankzij het lange garen bijzonder zacht worden. Het energieverbruik is doorgaans lager dan bij een oven of kookplaat, omdat het apparaat constant op een laag pitje werkt.

Waar je op moet letten

Er zijn ook dingen om rekening mee te houden. Omdat er nauwelijks vocht verdampt, is het beter om zuinig te zijn met bouillon of water. Te veel vocht maakt de maaltijd dunner dan de bedoeling is. Kruiden ontwikkelen zich anders bij lage temperaturen en hebben soms minder kracht, waardoor het slim is om vlak voor het serveren je gerecht nog even extra op smaak te brengen. En omdat gerechten vaak vier tot acht uur nodig hebben, vraagt het koken met een slowcooker om planning. Zet hem tijdig aan, zodat je eten op het juiste moment klaar is.

De slowcooker in de herfst

Juist in de herfst laat de slowcooker zich van zijn beste kant zien. Het seizoen van pompoensoep, erwtensoep, goulash en linzenstoof vraagt om comfort food dat langzaam kan trekken. Terwijl de regen tegen de ramen slaat en de dagen korter worden, vult je huis zich met de geur van een gerecht dat urenlang rustig staat te garen. Na een boswandeling of werkdag hoef je alleen nog maar de deksel te lichten en te genieten.

Recept: pompoensoep uit de slowcooker

Pompoensoep past perfect bij de herfst en is eenvoudig te maken in de slowcooker. Gebruik een middelgrote flespompoen, twee winterwortels, een grote ui, twee teentjes knoflook, een liter groentebouillon en een theelepel gemalen komijn. Snijd de pompoen in blokjes (schil mag blijven zitten als hij dun is) en doe samen met wortel, ui en knoflook in de slowcooker. Voeg de bouillon en komijn toe, zet de pan zes uur op de lage stand of drie uur op de hoge stand. Pureer de soep met een staafmixer glad en breng eventueel verder op smaak met peper en zout. Voor een romige variant kun je een scheutje kokosmelk toevoegen. Serveer met brood of een beetje geroosterde pompoenpitten als topping. 

©posinote - stock.adobe.com

Recept: apple crumble uit de slowcooker

Een klassieker die verrassend goed lukt in de slowcooker is apple crumble. Je hebt nodig: zes zoetzure appels, een eetlepel kaneel, twee eetlepels suiker, 100 gram bloem, 75 gram havermout, 100 gram koude boter in blokjes en een snuf zout. Schil de appels, snijd ze in stukjes en leg ze op de bodem van de ingevette slowcooker. Meng bloem, havermout, boter, suiker en zout tot een kruimelig deeg en verdeel dit over de appels. Zet de slowcooker drie uur op de hoge stand, of vijf uur op de lage stand, met een theedoek onder het deksel om condens op te vangen (zodat de crumble-topping knapperig blijft). Zorg er wel voor dat het deksel en de pan goed afgesloten blijven. Serveer de crumble warm, eventueel met een bolletje vanille-ijs of slagroom.

Slowcooker? Ja, graag!

De slowcooker laat zich goed inpassen in een druk dagelijks leven. Hij neemt je een deel van het werk uit handen en zorgt voor supersmaakvolle gerechten. Heb je wat plek over in je keuken, dan is een slowcooker dus zeker aan te raden!

Nog veel meer recepten?

Slowcookerboeken genoeg!