ChatGPT 导出 JSON — 将对话导出并保存为结构化数据(2026)
要点概览
- JSON 是程序化处理的最佳格式 — 使用 Python、jq 或任何语言解析它,对 ChatGPT 对话进行分析、转换或自动化。
- 三种方法可选:ChatGPT Exporter(即时导出、JSON 结构清晰)、OpenAI 官方数据导出(批量导出、嵌套格式复杂)、浏览器开发者工具(手动操作、原始 API 数据)。
- OpenAI 原生导出使用基于树形的
mapping结构,包含父子引用关系,需要大量解析工作——而 ChatGPT Exporter 提供扁平化、可直接用于脚本的格式。 - 独特数据保留:Deep Research 引用、o1/o3 思维过程、网页搜索来源和 Canvas 工件——这些是其他 JSON 导出工具无法捕获的功能。
1. 简介
JSON(JavaScript Object Notation)是结构化数据交换的标准格式——被几乎所有现代 Web API 使用,并被 Python、JavaScript、Go、R 以及其他所有主流编程语言原生支持。
如果你想分析 ChatGPT 对话模式、以编程方式提取代码块、构建微调数据集、在工具间迁移数据,或者为聊天记录创建完整备份,JSON 是让你完全掌控数据的格式。
本指南涵盖 2026 年将 ChatGPT 对话导出为 JSON 的所有方法。我们对比三种方案——从一键式 Chrome 扩展到 OpenAI 官方数据导出——并附有实用代码示例,让你可以立即开始处理数据。(想要更易读的格式?请参阅我们的 ChatGPT 导出 Markdown 指南 或 ChatGPT 导出 PDF 指南。)
2. 为什么要将 ChatGPT 导出为 JSON?
- 机器可读 — JSON 可以被任何编程语言通过内置库直接解析(Python 的
json、JavaScript 的JSON.parse()、Go 的encoding/json)。 - 完整保留数据 — 每条消息、角色、时间戳和 metadata 字段都以结构化形式捕获——不像 PDF 或纯文本那样会将一切扁平化。
- 易于转换 — 通过一段简短的脚本即可将 JSON 转换为 CSV、Markdown、HTML、SQL 或任何其他格式(示例见下文第 5 节)。
- 适合数据分析 — 将对话加载到 pandas、jq 或任何数据工具中,分析模式、字数统计、话题和回复长度。
- 备份与迁移 — JSON 是创建完整、无损备份最可靠的格式。你可以在数年后恢复、搜索或重新导入这些数据。
- API 兼容 — JSON 是 OpenAI API 的原生格式。通过简单的角色映射,你的导出可以直接转换为 API 消息格式。
- 适合自动化 — 将 JSON 数据输入脚本、工作流或管道(n8n、Make、Zapier)进行自动化处理。
- 版本控制 — JSON 文件可以配合 Git 使用,方便追踪变更和对比对话的历史差异。
3. 将 ChatGPT 导出为 JSON 的方法
3.1 ChatGPT Exporter(推荐)
ChatGPT Exporter 是一款 Chrome 扩展,可以一键将任意 ChatGPT 对话导出为 JSON。
使用方法:
- 从 Chrome Web Store 安装 ChatGPT Exporter。
- 打开任意 ChatGPT 对话(普通对话或群聊均可)。
- 点击 Select 按钮选择要导出的消息(全部、仅提示词、仅回复,或手动勾选/取消勾选单条消息)。
- 点击 Export 并选择 JSON 格式。
.json文件即刻下载——结构清晰、格式规范,可直接用于脚本。
你也可以在设置中开启 Copy to clipboard 选项,将 JSON 文本直接复制到剪贴板而非下载文件——非常适合快速粘贴到脚本或 API 工具中。
导出的 JSON 示例:
导出文件包含两个顶层部分:metadata(对话信息)和 messages(实际对话内容):
{
"metadata": {
"title": "How to Process CSV Files in Python",
"user": {
"name": "John Smith",
"email": "[email protected]"
},
"dates": {
"created": "2026/04/15 14:30:45",
"updated": "2026/04/15 15:22:10",
"exported": "2026/04/17 09:00:33"
},
"link": "https://chatgpt.com/c/abc123-def456"
},
"messages": [
{
"role": "Prompt",
"say": "How do I read a CSV file and filter specific columns in Python?",
"time": "2026/04/15 2:30:45 PM"
},
{
"role": "Response",
"say": "You can use the pandas library:\n\nimport pandas as pd\ndf = pd.read_csv('data.csv')\nresult = df[['name', 'age']]\n\nThis filters the name and age columns.",
"time": "2026/04/15 2:31:22 PM"
}
]
}注意这种清晰的扁平结构——一个可以直接遍历的 messages 数组,无需处理嵌套树或父子指针。
Metadata 字段
metadata 中的每个字段都可以在设置中单独开关:
| 字段 | 类型 | 描述 | 可配置 |
|---|---|---|---|
title | string | 对话标题 | 可在设置中开关 |
user.name | string | 你的显示名称 | 可独立开关 |
user.email | string | 你的邮箱地址 | 可独立开关 |
dates.created | string | 对话开始时间 | 可选择包含哪些日期 |
dates.updated | string | 最后一条消息时间 | 可选择包含哪些日期 |
dates.exported | string | 导出创建时间 | 可选择包含哪些日期 |
link | string | 原始对话的 URL | 可在设置中开关 |
日期和时间格式也可配置:日期可选择 MDY / DMY / YMD 格式,时间可选择隐藏 / 12 小时制 / 24 小时制。
消息字段
| 字段 | 类型 | 描述 |
|---|---|---|
role | string | "Prompt"(你的消息)或 "Response"(ChatGPT 的回复)。群聊中为 "Human" 和 "ChatGPT" |
say | string | 消息内容(纯文本)。如果某条消息未被选中导出,该字段为空字符串 ""(消息仍然保留以维持对话结构) |
time | string | 消息时间戳(需在设置中开启”每条消息时间戳”选项) |
内容处理
say 字段通过一套处理管线生成——DOM 解析、特征提取(Deep Research、网页搜索、推理)和格式化输出——因此代码块、数学公式和结构化内容都能被准确保留,而非简单地从浏览器中复制粘贴。
捕获的 AI 专属数据
| 功能 | 包含的内容 | 可配置 |
|---|---|---|
| Deep Research 报告 | 完整报告,含引用脚注和来源 URL | 可开关 |
| 网页搜索来源 | 来源列表,含标题和 URL | 可开关 |
| 思维过程(o1/o3) | 推理步骤、搜索查询、思考过程 | 可开关 |
| 代码块 | 完整代码,含语言标识符 | 始终包含 |
| 数学公式(KaTeX) | 保留 LaTeX 记法 | 始终包含 |
| Canvas 工件 | Canvas 模式下的代码和文档内容 | 始终包含 |
输出格式
- 编码:UTF-8
- 格式化:2 空格缩进(人类可读)
- 文件命名:
{前缀}{对话标题}.json——前缀可自定义(默认为ChatGPT-),文件名会进行操作系统兼容性清理和 Unicode 标准化(NFC) - MIME 类型:
application/json
3.2 OpenAI 官方数据导出
OpenAI 提供了一种内置方式来导出你的数据:
- 在 ChatGPT 中进入 Settings → Data Controls → Export Data。
- 等待包含 ZIP 文件的邮件(通常几分钟,但最长可能需要 24 小时)。
- 解压后找到
conversations.json。
这会生成一个包含所有对话的大型 JSON 文件。然而,其结构要复杂得多——使用的是 OpenAI 内部的树形格式:
{
"title": "Conversation Title",
"create_time": 1713350400.0,
"update_time": 1713354000.0,
"mapping": {
"aaa-msg-id-1": {
"id": "aaa-msg-id-1",
"message": {
"author": { "role": "user" },
"content": {
"content_type": "text",
"parts": ["Your message here"]
},
"create_time": 1713350400.0
},
"parent": null,
"children": ["aaa-msg-id-2"]
},
"aaa-msg-id-2": {
"id": "aaa-msg-id-2",
"message": {
"author": { "role": "assistant" },
"content": {
"content_type": "text",
"parts": ["The AI response here"]
},
"create_time": 1713350415.0
},
"parent": "aaa-msg-id-1",
"children": []
}
}
}为什么这种格式很难处理:
正如 OpenAI 开发者社区中的广泛讨论所指出的,这种树形结构需要你:
- 反向遍历父指针来重建对话顺序。
- 处理分支 — 当你编辑提示词时,ChatGPT 会在树中创建新分支,因此一段对话可能有多条路径。
- 从嵌套数组中提取文本 — 消息内容深埋在
content.parts[]数组中,而非简单的字符串。 - 转换 Unix 时间戳 — 时间以浮点数格式存储(如
1713350400.0),而非人类可读的格式。 - 应对格式变化 — 社区成员反映格式已多次改变,Canvas、网页搜索和图片生成等新功能增加了额外的复杂性。
优点: 一个文件包含完整历史记录;官方导出;无需第三方工具。
缺点: 最长需要等待 24 小时;深度嵌套的树形结构需要大量解析;不支持选择性导出;导出所有对话包括你可能不需要的内容;不支持实时导出。
3.3 浏览器开发者工具(手动方式)
适合想快速获取原始 API 数据的技术用户:
- 在浏览器中打开开发者工具(
F12)。 - 切换到 Network 标签页。
- 访问或刷新一个 ChatGPT 对话。
- 按
conversation或backend-api过滤请求。 - 找到包含对话数据的响应。
- 右键 → Copy response,粘贴到
.json文件中。
优点: 无需任何工具;可以获取原始 API 格式;即时。
缺点: 需要技术知识;处理多个对话时非常繁琐;格式因 API 端点不同而变化;导出之间没有统一结构;容易获取到不完整的数据。
4. 方法对比
| 功能 | ChatGPT Exporter | 官方数据导出 | 浏览器开发者工具 |
|---|---|---|---|
| 安装难度 | 低(Chrome 扩展) | 无需安装 | 无需安装(需技术) |
| 导出速度 | 即时(一键) | 几分钟到 24 小时 | 需逐个手动操作 |
| JSON 结构 | 清晰、扁平数组 | 嵌套树形 | 原始 API 格式 |
| 选择性导出 | 支持(按消息) | 不支持(导出所有对话) | 按对话 |
| 单对话导出 | 支持 | 不支持(单个批量文件) | 支持(手动) |
| 包含元数据 | 支持(可自定义) | 支持 | 支持(原始) |
| Deep Research 引用 | 支持 | 部分支持 | 支持(原始) |
| 思维过程(o1/o3) | 支持 | 部分支持 | 视情况而定 |
| 网页搜索来源 | 支持 | 部分支持 | 视情况而定 |
| Canvas 工件 | 支持 | 不支持 | 视情况而定 |
| 时间戳格式 | 可配置 | Unix 浮点数 | 视情况而定 |
| 复制到剪贴板 | 支持 | 不支持 | 支持(手动) |
| 可直接用于脚本 | 支持 | 需要解析 | 需要解析 |
| 从界面实时导出 | 支持 | 不支持 | 支持 |
5. 导出的 JSON 可以做什么:8 个实用示例
以下所有示例使用 ChatGPT Exporter 的 JSON 格式(包含 role、say 和 time 字段)。如果你使用的是 OpenAI 官方导出,需要先从 mapping 树中提取消息。
5.1 使用 Python 分析对话
将导出的 JSON 加载到 Python 中进行快速分析:
import json
from collections import Counter
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
# Count messages by role
roles = Counter(msg["role"] for msg in data["messages"])
print(f"Your prompts: {roles.get('Prompt', 0)}")
print(f"AI responses: {roles.get('Response', 0)}")
# Find longest response (skip unselected messages with empty "say")
responses = [m for m in data["messages"] if m["role"] == "Response" and m["say"]]
longest = max(responses, key=lambda m: len(m["say"]))
print(f"Longest response: {len(longest['say'])} chars")
# Average response length
avg = sum(len(m["say"]) for m in responses) // len(responses)
print(f"Average response: {avg} chars")5.2 提取所有代码块
从 AI 回复中提取每个代码块——非常适合构建个人代码片段库:
import json
import re
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
for msg in data["messages"]:
if msg["role"] == "Response" and msg["say"]:
blocks = re.findall(r"```(\w+)?\n(.*?)```", msg["say"], re.DOTALL)
for lang, code in blocks:
print(f"--- {lang or 'text'} ---")
print(code)5.3 转换为 CSV 用于电子表格
将 JSON 转换为 CSV,以便在 Excel 或 Google Sheets 中分析:
import json
import csv
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
with open("conversation.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["Role", "Content", "Time", "Word Count"])
for msg in data["messages"]:
if msg["say"]: # skip unselected messages
writer.writerow([
msg["role"],
msg["say"],
msg.get("time", ""),
len(msg["say"].split())
])5.4 构建微调数据集
将导出的对话转换为 OpenAI 微调格式(JSONL)。role 值需要从 ChatGPT Exporter 格式(Prompt/Response)映射为 API 格式(user/assistant):
import json
ROLE_MAP = {"Prompt": "user", "Response": "assistant"}
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
# Convert to OpenAI fine-tuning format
training_data = []
messages = [m for m in data["messages"] if m["say"]] # skip empty
for i in range(0, len(messages) - 1, 2):
if messages[i]["role"] == "Prompt" and messages[i+1]["role"] == "Response":
training_data.append({
"messages": [
{"role": "user", "content": messages[i]["say"]},
{"role": "assistant", "content": messages[i+1]["say"]}
]
})
with open("training.jsonl", "w") as f:
for item in training_data:
f.write(json.dumps(item) + "\n")
print(f"Created {len(training_data)} training examples")5.5 使用 jq 进行命令行处理
使用 jq 进行即时命令行分析,无需编写代码:
# Count total messages
jq '.messages | length' ChatGPT-my-conversation.json
# Get all your prompts (non-empty only)
jq -r '.messages[] | select(.role == "Prompt" and .say != "") | .say' ChatGPT-my-conversation.json
# Show conversation title and message count
jq '{title: .metadata.title, messages: (.messages | length)}' ChatGPT-my-conversation.json
# Count messages by role
jq '[.messages[].role] | group_by(.) | map({(.[0]): length}) | add' ChatGPT-my-conversation.json
# Word count per AI response
jq '.messages[] | select(.role == "Response" and .say != "") | {words: (.say | split(" ") | length)}' ChatGPT-my-conversation.json5.6 导入 SQLite
将对话数据加载到 SQLite 数据库中,使用 SQL 进行查询:
import json
import sqlite3
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
conn = sqlite3.connect("chatgpt.db")
conn.execute("""
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY,
role TEXT,
content TEXT,
time TEXT,
word_count INTEGER
)
""")
for msg in data["messages"]:
if msg["say"]: # skip unselected messages
conn.execute(
"INSERT INTO messages (role, content, time, word_count) VALUES (?, ?, ?, ?)",
(msg["role"], msg["say"], msg.get("time", ""), len(msg["say"].split()))
)
conn.commit()
print(f"Imported {sum(1 for m in data['messages'] if m['say'])} messages into chatgpt.db")然后使用 SQL 查询:
-- Message stats by role
SELECT role, COUNT(*) as count, AVG(word_count) as avg_words
FROM messages GROUP BY role;
-- Full-text search across all messages
SELECT role, content FROM messages WHERE content LIKE '%repository pattern%';5.7 供其他 AI 工具使用
将 ChatGPT 对话导出为 JSON,然后交给另一个 AI 进行结构化分析:
- 加载到 Claude 或 Gemini 中,获取对同一对话的不同视角。
- 用作 AI 驱动的摘要、翻译或情感分析管道的输入。
- 导入 LangChain 或 LlamaIndex,构建检索增强生成(RAG)系统。
JSON 完整保留了结构和角色标签,是程序化 AI 间工作流的理想格式——不像 PDF 在被读取时会丢失结构。
5.8 创建版本控制的备份
将导出的 JSON 文件存储在 Git 仓库中,实现版本控制的备份:
mkdir chatgpt-archive && cd chatgpt-archive
git init
# After each export, add and commit
git add ChatGPT-python-api-design.json
git commit -m "Export: Python API Design conversation"这样你就拥有了完整的导出历史,支持差异对比、时间戳追踪以及随时恢复任意版本。
6. JSON 与其他导出格式对比
| 功能 | JSON | Markdown | TXT | CSV | |
|---|---|---|---|---|---|
| 机器可读 | 是 | 部分 | 否 | 否 | 是 |
| 人类可读 | 一般 | 是 | 是 | 是 | 是 |
| 保留结构 | 完整(嵌套) | 部分 | 仅视觉 | 否 | 仅扁平 |
| 保留元数据 | 是 | 可选 | 否 | 否 | 可选 |
| 导出后可编辑 | 是 | 是 | 否 | 是 | 是 |
| 可编程处理 | 是 | 部分 | 否 | 否 | 是 |
| 适配笔记应用 | 否 | 是 | 有限 | 是 | 否 |
| 文件大小 | 中等 | 小 | 大 | 小 | 小 |
| 适合版本控制 | 是 | 是 | 否 | 是 | 是 |
| 适合数据分析 | 是 | 否 | 否 | 否 | 是 |
各格式适用场景:
- JSON — 当你计划分析、转换或以编程方式处理对话时。最适合开发者、数据分析师和自动化工作流。
- Markdown — 当你想阅读、编辑或将对话整合到知识管理工具(Obsidian、Notion、GitHub)中时。
- PDF — 当你需要与不使用技术工具的人分享格式化文档时。
7. 优化 JSON 导出的技巧
7.1 使用选择性导出获取更干净的数据
当你只需要特定对话时,不要导出整段对话。使用 ChatGPT Exporter 的选择功能,只勾选相关消息——未被选中的消息仍会出现在 JSON 中(以保持对话结构),但 say 字段为空,在代码中很容易过滤掉:[m for m in data["messages"] if m["say"]]。
7.2 验证你的 JSON
导出后,在处理之前确认文件格式正确:
# Using jq (install: brew install jq / apt install jq)
jq . ChatGPT-my-conversation.json > /dev/null && echo "Valid JSON"
# Using Python (no install needed)
python3 -m json.tool ChatGPT-my-conversation.json > /dev/null && echo "Valid JSON"7.3 先用 jq 探索再写代码
在编写完整 Python 脚本之前,先用 jq 交互式地探索数据:
# Pretty-print to understand the structure
jq '.' ChatGPT-my-conversation.json | head -30
# Quick look at metadata
jq '.metadata' ChatGPT-my-conversation.json
# Count messages by role
jq '[.messages[].role] | group_by(.) | map({(.[0]): length}) | add' ChatGPT-my-conversation.json7.4 合并多次导出
如果你分别导出了多段对话,可以将它们合并为一个数据集:
import json
import glob
all_conversations = []
for file in sorted(glob.glob("ChatGPT-*.json")):
with open(file) as f:
conv = json.load(f)
all_conversations.append({
"title": conv["metadata"]["title"],
"exported": conv["metadata"]["dates"]["exported"],
"messages": [m for m in conv["messages"] if m["say"]]
})
with open("all-conversations.json", "w") as f:
json.dump(all_conversations, f, indent=2, ensure_ascii=False)
print(f"Merged {len(all_conversations)} conversations")7.5 保持元数据开启
ChatGPT Exporter 在 JSON 输出中包含元数据(标题、时间戳、用户信息、对话链接)。保持这些字段开启——它们对于排序、过滤和整理导出文件至关重要,尤其是当你积累了数十个文件时。dates.exported 字段对于追踪每次备份的时间点特别有用。
8. 常见问题
Q1:ChatGPT 能原生导出 JSON 吗?
可以——但只能通过批量数据导出(Settings → Data Controls → Export Data),它会将所有对话导出到一个结构复杂的嵌套文件中。如果需要按单个对话导出且结构清晰扁平的 JSON,请使用 ChatGPT Exporter。
Q2:ChatGPT Exporter 的 JSON 和 OpenAI 官方导出有什么区别?
ChatGPT Exporter 生成的是包含 metadata 和 messages 的扁平结构——每条消息包含 role("Prompt" / "Response")和 say(文本内容),可以直接在循环中遍历。OpenAI 官方导出使用基于树形 mapping 的结构,包含父子引用关系、深埋在 parts[] 数组中的内容和 Unix 浮点时间戳,需要大量解析工作。详见第 3 节的对比。
Q3:可以将 JSON 导出转换为其他格式吗?
可以——JSON 是最通用的起始格式。你可以将其转换为 CSV(第 5.3 节)、用于微调的 JSONL(第 5.4 节)、SQL 数据库(第 5.6 节)或任何其他格式,只需一段简短的脚本。
Q4:JSON 导出文件有多大?
一段典型的对话(50-100 条消息)生成的 JSON 文件为 50-200 KB。包含代码块的长对话可能达到 500 KB 或更大。这比 Markdown 或 TXT 稍大,但比 PDF 小得多。
Q5:Deep Research 报告会包含在 JSON 导出中吗?
会的。ChatGPT Exporter 会完整捕获 Deep Research 报告,包括带有来源 URL 的引用脚注。这是 ChatGPT Exporter 的独有功能——OpenAI 官方导出和其他工具无法完整保留 Deep Research 数据。
Q6:代码块在 JSON 中会保留吗?
会的。内容处理管线会将代码块转换为纯文本,同时保留语言标识符和完整的代码内容。你可以使用正则表达式以编程方式提取它们——参见第 5.2 节的可用示例。
Q7:JSON 导出功能免费吗?
是的,JSON 导出在 ChatGPT Exporter 的免费版本中即可使用。无需账户或订阅。
Q8:能只导出 AI 回复而不包含我的提示词吗?
可以。点击 Select 并选择 Answers 即可只选择 ChatGPT 的回复。你也可以手动勾选/取消勾选单条消息。未被选中的消息仍会出现在 JSON 中以保持结构上下文,但 say 字段为空——在代码中很容易过滤掉。
Q9:导出的 JSON 可以用于 OpenAI API 吗?
可以,只需简单的角色映射。ChatGPT Exporter 使用 "Prompt" 和 "Response" 作为角色标签,而 API 使用 "user" 和 "assistant"。用一个字典映射即可:{"Prompt": "user", "Response": "assistant"}。参见第 5.4 节的完整微调转换示例。
Q10:支持群聊对话吗?
支持。对于群聊(ChatGPT 的 /gg/ 路径),角色标签会自动切换为 "Human" 和 "ChatGPT",而非 "Prompt" / "Response"。所有参与者的消息都会以相同的元数据和设置保留。
9. 总结
JSON 是 ChatGPT 导出的高级用户格式。当你需要分析对话模式、提取代码块、构建训练数据集或自动化数据工作流时,JSON 为你提供完整的结构化数据——不像 PDF 或纯文本那样将数据锁定在只能人类阅读的格式中。
虽然 OpenAI 官方数据导出提供 JSON,但其复杂的嵌套结构和长达数小时的等待时间使其不适合日常使用。ChatGPT Exporter 让你一键获取干净、结构规范的 JSON——扁平的 metadata + messages 格式、选择性导出、可自定义元数据,以及 Deep Research 引用、o1/o3 推理过程、网页搜索来源等其他工具无法捕获的 AI 专属功能。
立即开始使用: