Een ChatGPT-export naar Markdown omzetten: het gesprek is een boom, geen lijst
Vraag je gegevens op bij ChatGPT en je krijgt een .zip waarvan de bruikbare inhoud één conversations.json is. Open die in de verwachting van een lijst met berichten en je vindt iets anders: een object genaamd mapping, vol met items op identifier, die elk verwijzen naar een ouder en een verzameling kinderen. De berichten zitten erin. Het gesprek dat je je herinnert is één pad door een graaf.
Deze pagina reconstrueert dat pad en schrijft het als Markdown. Sleep het archief of de uitgepakte JSON naar binnen; het wordt in dit browsertabblad geparseerd.
Waarom het als graaf wordt opgeslagen
Omdat de interface je de geschiedenis laat herschrijven. Bewerk een eerdere prompt en de draad splitst zich vanaf dat punt. Genereer een antwoord opnieuw en je krijgt een alternatief waar je met de kleine pijltjes tussen bladert. Beide versies bestaan nog; de interface toont er gewoon één.
Een platte array kan dat niet weergeven. Dus slaat de export elke aftakking op, en het transcript dat je werkelijk zag win je terug door bij de knoop zonder ouder te beginnen en naar beneden te lopen, waarbij je bij elke stap kiest tussen de kinderen. De conventie die overeenkomt met de interface is om het laatste kind te volgen, want een hergeneratie wordt achter het antwoord geplakt dat ze verving. Dat is wat dit gereedschap doet, en daarom leest de uitvoer als het gesprek dat je voerde in plaats van als een dooreenweving van alle pogingen.
Tijdens het lopen zit er een cyclusbeveiliging in. Die zou bij een correcte export nooit mogen afgaan, maar een oneindige lus in een parser is een slechtere uitkomst dan een afgekapt transcript.
Inhoud die je nooit hebt gezien
De export bevat materiaal dat de interface verbergt, en dat letterlijk overnemen geeft je een transcript dat niet klopt met je herinnering aan het gesprek:
- Het systeembericht. Elk gesprek opent met instructies die je niet hebt geschreven en die je niet zijn getoond. Het staat als volwaardig bericht in het bestand.
- Toolverkeer. Zoekopdrachten op het web, code-uitvoering en beeldgeneratie laten elk hun eigen verzoek- en resultaatknopen achter, gericht aan een andere ontvanger dan de gebruiker. Dat is de machinerie achter een antwoord, geen onderdeel van de dialoog.
- Expliciet verborgen knopen. Sommige berichten dragen een vlag die ze markeert als niet getoond in het gesprek. De export is daar eerlijk over, en die vlag wordt gerespecteerd.
Alle drie worden eruit gefilterd, zodat de beurten van gebruiker en assistent overblijven.
Berichtinhoud is niet altijd een string
Het contentveld is in de loop van de tijd gegroeid. Een beurt met platte tekst draagt een array parts met strings. Sommige berichttypes gebruiken in plaats daarvan een veld text. Multimodale beurten zetten objecten in de parts-array, één per element, waarbij een geüploade afbeelding en de bijbehorende vraag aparte items zijn. Resultaten van de code-interpreter komen weer in hun eigen vorm binnen.
De parser leest de stringvorm, de array-van-strings-vorm en de array-van-objecten-vorm, en haalt uit elk de tekst. Niet-tekstuele onderdelen dragen niets bij in plaats van een markering of een fout op te leveren, wat betekent dat een gesprek met afbeeldingen binnenkomt als de woorden eromheen.
Waarom Markdown het juiste doel is
De assistent schrijft al Markdown. Zijn antwoorden bevatten fenced codeblokken, koppen, opsommingen en tabellen, en die tekens staan als tekens in de export. Omzetten naar platte tekst zou ze daar laten staan als letterlijke backticks en hekjes — de opmaak niet gerenderd en niet verwijderd, maar gestrand.
Markdown behouden betekent dat de codeblokken codeblokken blijven. Plak het resultaat in een notitie-app, een statischesitegenerator, een documentatietool of een wiki en het rendert. Sprekersnamen worden vet gezet en elk gesprek krijgt een kop uit zijn titel, zodat een export van meerdere jaren een navigeerbaar document wordt in plaats van een ongedifferentieerde lap tekst.
Exports zijn groot
Een paar jaar regelmatig gebruik levert een conversations.json op van tientallen of honderden megabytes, met duizenden gesprekken erin. Dat is een probleem voor een teksteditor, die het geheel zal proberen te kleuren, en voor elk gereedschap dat eerst pretty-print voordat het je iets laat zien.
Het parsen gebeurt hier één keer, in het geheugen, en alleen de leesbare uitvoer wordt gerenderd. Elk gesprek wordt een sectie onder zijn eigen titel met een scheiding tussen de secties, zodat je het resultaat kunt doorzoeken op een zinsnede die je je half herinnert in plaats van te scrollen.
Je export aanvragen
In ChatGPT: Settings, dan Data Controls, dan Export Data. Het archief wordt naar je gemaild, meestal binnen enkele minuten, als downloadlink die verloopt. De zip bevat ook een HTML-viewer en allerlei media; hier is alleen de JSON nodig, en het hele archief naar binnen slepen werkt prima.
Er wordt niets geüpload
Je ChatGPT-geschiedenis is een gedetailleerd verslag van waar je aan hebt gewerkt, waar je over hebt ingezeten en waar je hulp bij hebt gevraagd. Het is een van de onthullendere bestanden die de meeste mensen bezitten. Het parsen draait in JavaScript in dit tabblad en er is geen uploadstap, dus geen enkele server ontvangt het en er valt achteraf niets te verwijderen.
Claude-exports hebben hun eigen pagina op Claude-export naar Markdown, en de algemene chatexportpagina handelt elk ondersteund platform af.