V JSON datech ChatGPT (nebo i jiných chatových exportech) je klíč mapping zásadní strukturou, která popisuje stromovou strukturu celého rozhovoru. Není to prostý seznam zpráv v pořadí, ale spíš strom navazujících zpráv, kde každá má unikátní id a odkazy na parent a children.
🌳 Co je mapping?
mapping je slovník (dict), kde:
🔍 Co to znamená?
Tohle umožňuje:
-
Získat libovolný uzel zprávy podle jeho ID.
-
Rekonstruovat celý tok konverzace z uzlů (např. najít hlavní větev, alternativní větve atd.).
-
Rychle zjistit, kdo co řekl (message.author.role).
-
Navigovat zprávy např. od client-created-root až po poslední odpověď.
🧠 Příklad ze tvých dat:
"mapping": {
"client-created-root": {
"id": "client-created-root",
"message": null,
"parent": null,
"children": ["13f65eae-..."]
},
"13f65eae-...": {
"id": "13f65eae-...",
"message": {
"author": {"role": "system"},
...
},
"parent": "client-created-root",
"children": ["61b6910f-..."]
},
"61b6910f-...": {
"id": "61b6910f-...",
"message": {
"author": {"role": "user"},
...
},
"parent": "13f65eae-...",
"children": [...]
}
}
Z toho vyplývá:
-
Konverzace začíná „virtuálním“ kořenem client-created-root
-
První reálná zpráva je 13f65eae-... (např. systémové uvítání)
-
Uživatel odpovídá ve zprávě 61b6910f-...
🔄 Proč se to tak dělá?
-
Flexibilita: umožňuje větvení konverzace (např. pokud si vybereš jinou cestu nebo prompt).
-
Snadné spojení zpráv přes ID.
-
Zachování stromové hierarchie, ne jen lineárního seznamu.
🧰 Kódově:
Chceš-li iterovat všechny zprávy:
for node_id, node in mapping.items():
msg = node.get("message")
if msg and msg.get("author"):
print(f"{node_id}: {msg['author']['role']} – {msg['content']}")
Aby ses dostal k reálným zprávám (user/assistant), musíš filtrovat:
Chceš-li, můžu ti upravit funkci, která to celé přehledně vytáhne a uloží každou zprávu podle pořadí (nebo podle větví).
* * *
V JSON poli jsonData jsou na nejvyšší úrovni “sezení” – každé položce v tom seznamu odpovídá jedno celé chat-session. Tyto položky mají nejčastěji klíče:
-
title – lidsky čitelný název sezení (např. „Analýza TJV…“)
-
create_time / update_time – UNIX čas nebo ISO-string, kdy bylo sezení založeno a naposledy aktualizováno
-
mapping – slovník, který obsahuje všechny uzly (root, systémové zprávy, uživatelské vstupy, odpovědi), každý uzel se odkazuje na svůj parent a na pole children
Podle tebe tedy:
-
Položky v jsonData → to jsou jednotlivá sezení/chaty.
-
Uvnitř každé položky (sezení) najdeš právě ten klíč mapping, který ukrývá všechny zprávy a jejich vztahy.
Struktura jedné položky v jsonData
{
"title": "Název sezení…",
"create_time": 1748653404.439806,
"update_time": 1750666511.338081,
"mapping": {
"client-created-root": {
"id": "client-created-root",
"message": null,
"parent": null,
"children": ["13f65eae-…"]
},
"13f65eae-…": {
"id": "13f65eae-…",
"message": { … },
"parent": "client-created-root",
"children": ["61b6910f-…"]
},
"61b6910f-…": {
"id": "61b6910f-…",
"message": { … },
"parent": "13f65eae-…",
"children": [ … ]
},
// …
}
}
-
mapping je slovník všech uzlů.
-
Uzel s id: "client-created-root" je virtuální počátek (nemá message, ale má children).
-
Každý další uzel obsahuje message, které má:
Co si z toho odnést:
-
Sezení (session) ↔ jedna položka v poli jsonData
-
Zprávy ↔ jednotlivé uzly ve mapping (kde message != null)
-
parts uvnitř message.content jsou vlastní texty promptů/odpovědí
Jak na to prakticky:
-
Projdi pole jsonData – to jsou všechna sezení.
-
Pro každé sezení si vytáhni title, create_time atd.
-
Vnořený slovník mapping projdi dvojicí (id, node):
Např. v Pythonu:
for session in jsonData:
title = session["title"]
for node_id, node in session["mapping"].items():
msg = node.get("message")
if msg and msg.get("content"):
author = msg["author"]["role"]
text = msg["content"]["parts"][0] # první část
print(f"Sezení: {title} | Uzlu {node_id} | Autor: {author} | Text začíná: {text[:30]!r}")
Takhle dostaneš řádek po řádku všechny skutečné zprávy (user/assistant/system) uvnitř každého chat-sezení.