ChatGPTの履歴データがExportできるようになっていました

2023.04.16

はじめに

データアナリティクス事業本部ビッグデータチームのkasamaです。
OpenAI社の公式の記事やTwitterからもChatGPTの履歴データがExportできるようになっていたので、その内容を調べてみたいと思います。

※ 本ブログは2023/04/16現在の機能を試してみたブログになります。今後、新機能の追加や修正が見込めれますのであらかじめご了承ください。

How do I export my ChatGPT history?

前提条件

  • OpenAI社の公式記事より、フリープラン、plusプランどちらでも使用できる機能であることがわかりますが、私はPlusプランに入っているのでそちらで検証していきます。
  • Modelとしての差も検証するため、GPT-3.5GPT-4に同一の質問を行い、履歴データを見てみます。
  • 質問内容は「Pythonプログラミングを学習する手順を200文字以内で教えてください。」とします。
  • フィードバックについては、どちらもgoodボタンと「とても参考になりました。ありがとうございます。」とします。

GPT-3.5

GPT-4

フィードバック

Exportしてみる

画面左側の'Settings'ボタンよりExport dataできますので、そちらからExportします。

Export Dataを押下するとすぐに登録済みのメールアドレスに以下のメールが届きます。ダウンロードリンクの有効期限が24時間以内なので、注意をする必要があります。

履歴データの確認

メールのリンクよりzipファイルがダウンロードされます。展開すると以下のファイルが格納されていましたので、それぞれ確認します。

chat.html

chat.htmlは、ユーザーとChatGPTとの会話履歴をHTML形式できます。発言者を識別するためにuserassistantで識別されています。ブラウザ上で簡単に確認したい際に便利です。

conversations.json

conversations.jsonは、ChatGPTを使用して生成された会話データを格納するjsonファイルです。 詳細な構造に関しては調査が必要ですが、ざっとみたところ、アクション毎に構造化されてidが割り振られており、roleでuserassistantの識別、partsで会話内容を取得できるようです。modelについてもmodel_slugの値より、使用しているmodelを確認できます。会話内容の日本語は、JSONファイルに出力する際、「\u30e6」のようなUnicodeエスケープ(シーケンス)という形式で出力しますので、文字列をデコードする必要があります。

conversations.json
[
    {
        "title": "Python\u5b66\u7fd2\u624b\u9806",
        "create_time": 1681601164.65984,
        "update_time": 1681601191.0,
        "mapping": {
            "c26cc27c-e5bd-4317-97f2-862ab97922e4": {
                "id": "c26cc27c-e5bd-4317-97f2-862ab97922e4",
                "message": {
                    "id": "c26cc27c-e5bd-4317-97f2-862ab97922e4",
                    "author": {
                        "role": "system",
                        "name": null,
                        "metadata": {}
                    },
                    "create_time": 1681601164.65984,
                    "update_time": null,
                    "content": {
                        "content_type": "text",
                        "parts": [
                            ""
                        ]
                    },
                    "end_turn": true,
                    "weight": 1.0,
                    "metadata": {},
                    "recipient": "all"
                },
                "parent": "037e2793-7290-4074-913f-f7db3f501beb",
                "children": [
                    "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657"
                ]
            },
            "037e2793-7290-4074-913f-f7db3f501beb": {
                "id": "037e2793-7290-4074-913f-f7db3f501beb",
                "message": null,
                "parent": null,
                "children": [
                    "c26cc27c-e5bd-4317-97f2-862ab97922e4"
                ]
            },
            "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657": {
                "id": "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657",
                "message": {
                    "id": "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657",
                    "author": {
                        "role": "user",
                        "name": null,
                        "metadata": {}
                    },
                    "create_time": 1681601164.6619,
                    "update_time": null,
                    "content": {
                        "content_type": "text",
                        "parts": [
                            "Python\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3092\u5b66\u7fd2\u3059\u308b\u624b\u9806\u3092200\u6587\u5b57\u4ee5\u5185\u3067\u6559\u3048\u3066\u304f\u3060\u3055\u3044\u3002"
                        ]
                    },
                    "end_turn": null,
                    "weight": 1.0,
                    "metadata": {
                        "timestamp_": "absolute",
                        "message_type": null
                    },
                    "recipient": "all"
                },
                "parent": "c26cc27c-e5bd-4317-97f2-862ab97922e4",
                "children": [
                    "8be7ff68-cb33-4c35-99c4-a7cd91709886"
                ]
            },
            "8be7ff68-cb33-4c35-99c4-a7cd91709886": {
                "id": "8be7ff68-cb33-4c35-99c4-a7cd91709886",
                "message": {
                    "id": "8be7ff68-cb33-4c35-99c4-a7cd91709886",
                    "author": {
                        "role": "assistant",
                        "name": null,
                        "metadata": {}
                    },
                    "create_time": 1681601190.963448,
                    "update_time": null,
                    "content": {
                        "content_type": "text",
                        "parts": [
                            "1. Python\u57fa\u790e\u3092\u5b66\u3076: \u516c\u5f0f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u3084\u30aa\u30f3\u30e9\u30a4\u30f3\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb\u3092\u5229\u7528\n2. \u5b9f\u8df5\u7684\u306a\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u53d6\u308a\u7d44\u3080: \u5c0f\u3055\u306a\u30bf\u30b9\u30af\u3092\u89e3\u6c7a\u3059\u308b\u30b3\u30fc\u30c9\u3092\u66f8\u304f\n3. \u30a8\u30e9\u30fc\u306b\u5bfe\u51e6: \u30b9\u30bf\u30c3\u30af\u30aa\u30fc\u30d0\u30fc\u30d5\u30ed\u30fc\u7b49\u3067\u60c5\u5831\u53ce\u96c6\u3057\u3001\u30c7\u30d0\u30c3\u30b0\u30b9\u30ad\u30eb\u3092\u8eab\u306b\u3064\u3051\u308b\n4. \u30b3\u30fc\u30c9\u54c1\u8cea\u5411\u4e0a: PEP 8\u306e\u30eb\u30fc\u30eb\u306b\u5f93\u3044\u3001\u30ea\u30fc\u30c0\u30d6\u30eb\u3067\u30e1\u30f3\u30c6\u30ca\u30d6\u30eb\u306a\u30b3\u30fc\u30c9\u3092\u66f8\u304f\n5. Python\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u4f7f\u3046: Numpy\u3001Pandas\u3001Matplotlib\u7b49\u306e\u4e00\u822c\u7684\u306a\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u7fd2\u5f97\n6. \u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306b\u53c2\u52a0: \u77e5\u8b58\u5171\u6709\u3084\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3092\u5f97\u308b\u305f\u3081\u306b\u6d3b\u52d5"
                        ]
                    },
                    "end_turn": true,
                    "weight": 1.0,
                    "metadata": {
                        "message_type": null,
                        "model_slug": "gpt-4",
                        "finish_details": {
                            "type": "stop",
                            "stop": "<|diff_marker|>"
                        },
                        "timestamp_": "absolute"
                    },
                    "recipient": "all"
                },
                "parent": "a0a6d4f1-5f11-43ef-ae51-3d12a0b69657",
                "children": []
            }
        },
        "moderation_results": [],
        "current_node": "8be7ff68-cb33-4c35-99c4-a7cd91709886",
        "plugin_ids": null,
        "id": "<id>"
    },
    {
        "title": "Python Learning Steps.",
        "create_time": 1681601151.659016,
        "update_time": 1681601157.0,
        "mapping": {
            "8f6da518-2767-426c-bd56-a8e7cae1c8b3": {
                "id": "8f6da518-2767-426c-bd56-a8e7cae1c8b3",
                "message": {
                    "id": "8f6da518-2767-426c-bd56-a8e7cae1c8b3",
                    "author": {
                        "role": "system",
                        "name": null,
                        "metadata": {}
                    },
                    "create_time": 1681601151.659016,
                    "update_time": null,
                    "content": {
                        "content_type": "text",
                        "parts": [
                            ""
                        ]
                    },
                    "end_turn": true,
                    "weight": 1.0,
                    "metadata": {},
                    "recipient": "all"
                },
                "parent": "d47bb8b9-e66b-4920-bee8-49859e4cf803",
                "children": [
                    "335bf015-2d56-4dbf-9148-eb6be0834b18"
                ]
            },
            "d47bb8b9-e66b-4920-bee8-49859e4cf803": {
                "id": "d47bb8b9-e66b-4920-bee8-49859e4cf803",
                "message": null,
                "parent": null,
                "children": [
                    "8f6da518-2767-426c-bd56-a8e7cae1c8b3"
                ]
            },
            "335bf015-2d56-4dbf-9148-eb6be0834b18": {
                "id": "335bf015-2d56-4dbf-9148-eb6be0834b18",
                "message": {
                    "id": "335bf015-2d56-4dbf-9148-eb6be0834b18",
                    "author": {
                        "role": "user",
                        "name": null,
                        "metadata": {}
                    },
                    "create_time": 1681601151.660363,
                    "update_time": null,
                    "content": {
                        "content_type": "text",
                        "parts": [
                            "Python\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3092\u5b66\u7fd2\u3059\u308b\u624b\u9806\u3092200\u6587\u5b57\u4ee5\u5185\u3067\u6559\u3048\u3066\u304f\u3060\u3055\u3044\u3002"
                        ]
                    },
                    "end_turn": null,
                    "weight": 1.0,
                    "metadata": {
                        "timestamp_": "absolute",
                        "message_type": null
                    },
                    "recipient": "all"
                },
                "parent": "8f6da518-2767-426c-bd56-a8e7cae1c8b3",
                "children": [
                    "527c93ba-febe-4bd3-9783-f17f8835da14"
                ]
            },
            "527c93ba-febe-4bd3-9783-f17f8835da14": {
                "id": "527c93ba-febe-4bd3-9783-f17f8835da14",
                "message": {
                    "id": "527c93ba-febe-4bd3-9783-f17f8835da14",
                    "author": {
                        "role": "assistant",
                        "name": null,
                        "metadata": {}
                    },
                    "create_time": 1681601156.501679,
                    "update_time": null,
                    "content": {
                        "content_type": "text",
                        "parts": [
                            "Python\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3092\u5b66\u7fd2\u3059\u308b\u624b\u9806\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002\n\n1. Python\u306e\u57fa\u672c\u6982\u5ff5\u3092\u5b66\u3076\uff1a\u30c7\u30fc\u30bf\u578b\u3001\u6f14\u7b97\u5b50\u3001\u5236\u5fa1\u69cb\u9020\u3001\u95a2\u6570\u306a\u3069\u306e\u57fa\u672c\u7684\u306a\u8981\u7d20\u3092\u5b66\u3073\u307e\u3059\u3002\n\n2. Python\u306e\u7d71\u5408\u958b\u767a\u74b0\u5883\uff08IDE\uff09\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\uff1a\u4f8b\u3048\u3070\u3001Anaconda\u3001PyCharm\u306a\u3069\u306eIDE\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3001\u4f7f\u3044\u65b9\u3092\u899a\u3048\u307e\u3059\u3002\n\n3. \u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u306e\u5b9f\u8df5\uff1a\u5b66\u7fd2\u3057\u305f\u3053\u3068\u3092\u6d3b\u304b\u3057\u3001\u5c0f\u3055\u306a\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u66f8\u3044\u3066\u5b9f\u8df5\u3057\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001\u7c21\u5358\u306a\u8a08\u7b97\u6a5f\u3084\u6587\u5b57\u5217\u51e6\u7406\u306a\u3069\u3092\u66f8\u3044\u3066\u307f\u307e\u3059\u3002\n\n4. \u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u5b66\u3076\uff1aPython\u306e\u5f37\u529b\u306a\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u52b9\u7387\u7684\u306a\u30d7\u30ed\u30b0\u30e9\u30e0\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001NumPy\u3001Pandas\u3001Matplotlib\u306a\u3069\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u5b66\u3073\u307e\u3059\u3002\n\n5. \u5b9f\u8df5\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u884c\u3046\uff1a\u5b66\u7fd2\u3057\u305f\u3053\u3068\u3092\u6d3b\u304b\u3057\u3001\u5b9f\u8df5\u7684\u306a\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u884c\u3044\u3001\u554f\u984c\u3092\u89e3\u6c7a\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001Web\u30b9\u30af\u30ec\u30a4\u30d4\u30f3\u30b0\u3001\u30c7\u30fc\u30bf\u5206\u6790\u3001\u6a5f\u68b0\u5b66\u7fd2\u306a\u3069\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u884c\u3044\u307e\u3059\u3002\n\n6. \u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306b\u53c2\u52a0\u3059\u308b\uff1aPython\u306e\u5b66\u7fd2\u8005\u30b3\u30df\u30e5\u30cb\u30c6\u30a3\u306b\u53c2\u52a0\u3059\u308b\u3053\u3068\u3067\u3001\u4ed6\u306e\u4eba\u3068\u60c5\u5831\u3092\u5171\u6709\u3057\u3001\u76f8\u4e92\u306b\u5b66\u3073\u5408\u3046\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001Stack Overflow\u3001GitHub\u3001Python\u30e6\u30fc\u30b6\u30fc\u4f1a\u306a\u3069\u306b\u53c2\u52a0\u3057\u307e\u3059\u3002"
                        ]
                    },
                    "end_turn": true,
                    "weight": 1.0,
                    "metadata": {
                        "message_type": null,
                        "model_slug": "text-davinci-002-render-sha",
                        "finish_details": {
                            "type": "stop",
                            "stop": "<|im_end|>"
                        },
                        "timestamp_": "absolute"
                    },
                    "recipient": "all"
                },
                "parent": "335bf015-2d56-4dbf-9148-eb6be0834b18",
                "children": []
            }
        },
        "moderation_results": [],
        "current_node": "527c93ba-febe-4bd3-9783-f17f8835da14",
        "plugin_ids": null,
        "id": "<id>"
    }
]

以下はテスト的にjsonファイルからデータを抽出したpython scriptです。

## conversations_decode.py
import json

with open("conversations.json", "r") as f:
    data = json.load(f)

for item in data:
    title = item["title"]
    create_time = item["create_time"]
    update_time = item["update_time"]
    current_node = item["current_node"]

    print(f"Title: {title}")
    print(f"Create time: {create_time}")
    print(f"Update time: {update_time}")
    print(f"Current node: {current_node}")

    mapping = item["mapping"]
    for key in mapping.keys():
        message = mapping[key]["message"]
        if message:
            message_id = message["id"]
            author_role = message["author"]["role"]
            content_parts = message["content"]["parts"]
            if "model_slug" in message["metadata"]:
                print("Model_slug:", message["metadata"]["model_slug"])
            print(f"Message ID: {message_id}")
            print(f"Author role: {author_role}")
            print(f"Content parts: {content_parts}")
    print("\n")

実行結果

(base) kasama.yoshikitmp % python conversations_decode.py

Title: Python学習手順
Create time: 1681601164.65984
Update time: 1681601191.0
Current node: 8be7ff68-cb33-4c35-99c4-a7cd91709886
Message ID: c26cc27c-e5bd-4317-97f2-862ab97922e4
Author role: system
Content parts: ['']
Message ID: a0a6d4f1-5f11-43ef-ae51-3d12a0b69657
Author role: user
Content parts: ['Pythonプログラミングを学習する手順を200文字以内で教えてください。']
Model_slug: gpt-4
Message ID: 8be7ff68-cb33-4c35-99c4-a7cd91709886
Author role: assistant
Content parts: ['1. Python基礎を学ぶ: 公式ドキュメントやオンラインチュートリアルを利用\n2. 実践的なプロジェクトに取り組む: 小さなタスクを解決するコードを書く\n3. エラーに対処: スタックオーバーフロー等で情報収集し、デバッグスキルを身につける\n4. コード品質向上: PEP 8のルールに従い、リーダブルでメンテナブルなコードを書く\n5. Pythonライブラリを使う: Numpy、Pandas、Matplotlib等の一般的なライブラリを習得\n6. プログラミングコミュニティに参加: 知識共有やフィードバックを得るために活動']


Title: Python Learning Steps.
Create time: 1681601151.659016
Update time: 1681601157.0
Current node: 527c93ba-febe-4bd3-9783-f17f8835da14
Message ID: 8f6da518-2767-426c-bd56-a8e7cae1c8b3
Author role: system
Content parts: ['']
Message ID: 335bf015-2d56-4dbf-9148-eb6be0834b18
Author role: user
Content parts: ['Pythonプログラミングを学習する手順を200文字以内で教えてください。']
Model_slug: text-davinci-002-render-sha
Message ID: 527c93ba-febe-4bd3-9783-f17f8835da14
Author role: assistant
Content parts: ['Pythonプログラミングを学習する手順は以下の通りです。\n\n1. Pythonの基本概念を学ぶ:データ型、演算子、制御構造、関数などの基本的な要素を学びます。\n\n2. Pythonの統合開発環境(IDE)をインストールする:例えば、Anaconda、PyCharmなどのIDEをインストールし、使い方を覚えます。\n\n3. プログラミングの実践:学習したことを活かし、小さなプログラムを書いて実践します。例えば、簡単な計算機や文字列処理などを書いてみます。\n\n4. ライブラリを学ぶ:Pythonの強力なライブラリを活用することで、効率的なプログラムを作成することができます。例えば、NumPy、Pandas、Matplotlibなどのライブラリを学びます。\n\n5. 実践プロジェクトを行う:学習したことを活かし、実践的なプロジェクトを行い、問題を解決することができるようになります。例えば、Webスクレイピング、データ分析、機械学習などのプロジェクトを行います。\n\n6. コミュニティに参加する:Pythonの学習者コミュニティに参加することで、他の人と情報を共有し、相互に学び合うことができます。例えば、Stack Overflow、GitHub、Pythonユーザー会などに参加します。']

(base) kasama.yoshikitmp %

message_feedback.json

message_feedback.jsonは、ChatGPTに対するユーザーからのフィードバックを格納するjsonファイルです。このファイルにはユーザーが提供したフィードバックや評価がjson形式で保存されます。会話毎に構造化されており、ratingで先ほどgoodボタンを押したので、thumbsUp(いいね)となっており、contentsのtextにユーザーのコメントが格納されています。

[
    {
        "message_id": "527c93ba-febe-4bd3-9783-f17f8835da14",
        "conversation_id": "78fd8d35e0a643bbac9b5702879712a1",
        "user_id": "<user-id>",
        "rating": "thumbsUp",
        "content": "{\"text\": \"\\u3068\\u3066\\u3082\\u53c2\\u8003\\u306b\\u306a\\u308a\\u307e\\u3057\\u305f\\u3002\\u3042\\u308a\\u304c\\u3068\\u3046\\u3054\\u3056\\u3044\\u307e\\u3059\\u3002\"}"
    },
    {
        "message_id": "8be7ff68-cb33-4c35-99c4-a7cd91709886",
        "conversation_id": "b84bf73cd71e4ed4b7e4a245107c61fc",
        "user_id": "<user-id>",
        "rating": "thumbsUp",
        "content": "{\"text\": \"\\u3068\\u3066\\u3082\\u53c2\\u8003\\u306b\\u306a\\u308a\\u307e\\u3057\\u305f\\u3002\\u3042\\u308a\\u304c\\u3068\\u3046\\u3054\\u3056\\u3044\\u307e\\u3059\\u3002\"}"
    }
]

model_comparisons.json

こちらについては4/16現段階では、使用方法がわかっていないため、空で出力されています。

[]

ChatGPTに質問した回答を載せておきますが、正確な情報ではないため、参考までにお願いします。

user.json

user.jsonは、ChatGPTに登録されているユーザーアカウント情報を格納するjsonファイルです。基本的な情報からchatgpt plusユーザーかどうかのフラグも保持しているようです。

{
    "id": "<user-id>",
    "email": "<email-address>",
    "chatgpt_plus_user": true,
    "phone_number": "<phone-number>"
}

おまけ

Clear conversationすると以前の履歴データはExportできなくなるので、注意が必要です。 あくまで、左のタブに表示されているスレッドのみをExportできます。

最後に

model_comparisons.jsonconversations.jsonについては、もう少し調査をしてどのような構造かを紐解きたいと思いました。公式documentについても最新情報を随時watchしていきたいと思います。