你点了 Settings → Data Export,等到邮件、下载 zip,里面有 chat 文字稿(conversations.json、HTML 版本)——但你传进 Project 的 PDF、图片、附件都不在。这是一个已知缺口:标准导出主要包含文本和元数据,Project Files 和 chat 上传的二进制文件按订阅和时间不同会部分或全部缺失。修法是别完全依赖导出,要从每个 Project 手动拉一份文件备份;Team / Enterprise 有更完整的管理员导出。
常见原因
按命中率从高到低:
1. 标准导出按设计就不包含二进制上传
最常见。个人 Data Export 把 conversations、custom instructions、元数据打包成 JSON / HTML,但上传的二进制(PDF、PNG、XLSX)存在另一个对象存储里,不进导出 zip。
如何判断:解压 zip 搜 *.pdf 或 *.png,搜不到 = 二进制按设计被排除了。
2. Project Files 导出是单独的 UI 动作
要单独拿 Project Files,必须进每个 Project 一个个下——没有”一键导出所有 Project + Files”按钮。
如何判断:Settings → Data Export 只给你 chat,下载文件需要走 Project → Files → 单文件 Download。
3. 刚上传不久的文件还没进导出 pipeline
如果你触发导出前 1-2 小时才上传文件,pipeline 可能还没把它索引进导出范围,即使是平时会包含文件的订阅也一样。
如何判断:旧的 Project 文件出现(或元数据里有引用),但今早传的那份找不到。
4. 个人导出但文件在 Team 工作区里
你跑了个人 Data Export,但 Project 其实在 Team 工作区里。个人导出只覆盖个人工作区的数据。
如何判断:Team 工作区里的 chat 也没在导出里,不光是文件 = 走错导出通道了。
5. 文件标记为”工作区所有”会跟工作区不跟个人
Team / Enterprise 里某些文件属于工作区不属于你,即使是你上传的,个人导出也不会包含。
如何判断:Admin Console 显示这些文件是 workspace-owned,你的个人导出里没有。
6. 导出生成在文件存在之前
导出抓的是请求那一刻的状态。第 1 天触发导出、第 3 天才传文件,那份 day-1 的导出里自然没有 day-3 的文件。
如何判断:导出文件名时间戳早于上传时间 = 重新触发一次导出。
动手前先确认
- 想清楚”完整”对你意味着什么:只要 chat、只要文件、还是两个都要——不同导出覆盖的范围不一样。
- 列出你关心的文件分别在哪些 Project 里——可能要挨个跑。
- 确认订阅类型:Free / Plus 导出和 Team / Enterprise 管理员导出有差异。
需要收集的信息
- 导出请求时间 + 邮件送达时间。
- 订阅类型 + 工作区(个人 vs Team / Enterprise)。
- 期望的文件清单(文件名、属于哪个 Project、上传日期)。
- 期望文件清单和 zip 实际内容的 diff。
- 这次备份是为合规、迁移还是个人留档——决定走哪条策略。
最短修复路径
按收益从高到低,前两步覆盖大多数个人备份需求。
Step 1:挨个 Project 手动下载 Files
最稳的备份路径:
对每个 Project:
Project → Files 面板
→ 悬停文件 → Download
→ 存到 /backup/<project-name>/
要批量自动化的话,桌面 App 目前没暴露批量下载 API。5-10 个 Project 手动跑 15 分钟搞定;50+ 看 Step 6。
Step 2:单独保存 Project Instructions 和元数据
Instructions 在 JSON 导出里有,但更方便的是当成 Markdown 留底:
对每个 Project:
Project → Edit instructions → 复制文本
→ 存成 /backup/<project-name>/instructions.md
→ 同时记下 Project 名、创建日期、文件清单
需要的话能照着这个在别处重建 Project。
Step 3:chat 历史从 conversations.json 里解析
标准导出包含 conversations.json,重新解析把 Project 相关的 chat 抽出来:
import json
with open("conversations.json") as f:
convos = json.load(f)
# 每条 conversation 有 conversation_id,Project 关联
# 可能在某个 metadata 字段里——先打印看一下
for c in convos[:3]:
print(c.keys())
print(c.get("conversation_template_id")) # 可能映射到 Project
按 Project 过滤,再把每条 chat 导成 Markdown。
Step 4:Team / Enterprise 用管理员导出
Admin Console(Team / Enterprise):
Admin Console → Compliance → Export workspace data
→ 勾选 Projects + Files + Chats
→ 提交 → 等完成邮件
→ 下载更完整的 zip
管理员导出通常包含文件本体。你没管理员权限的话,找 org 管理员协调。
Step 5:长期备份就镜像到外部存储
别指望一次性导出。重要文件的做法:
source-of-truth 模式:
本地文件夹(或 Google Drive) → 同步到 Project Files
→ 永远不在 Project 里单独编辑
→ 哪天失去 Project 访问,源还在
把 Project Files 当缓存用,不要当唯一来源。
Step 6:50+ Project 的脚本绕路
个人 Plus 账号没有官方批量导出 API。可选绕路:
- 用桌面自动化工具(Hammerspoon、AutoHotkey)驱动每个 Project 的 Files 面板。
- Team / Enterprise 让管理员通过工作区导出端点跑一次程序化导出。
- 去 help.openai.com 提一个”一次性完整导出”的工单——迁移场景有时会被处理。
Step 7:验证导出可用、不只是”存在”
下完之后:
对 /backup/<project-name>/ 里每个文件:
- 打开看(PDF 阅读器、图片浏览器)
- 页数 / 尺寸和印象里的一致
- 文件名和时间戳对得上 Project Files 面板
“有但坏了”的备份比”知道没有”更糟糕。
怎么确认已经修好
- 你清单里每个 Project 都有自己的备份文件夹,里面有 Files + instructions.md。
- 从备份里随机挑 3 份 PDF 打开——都能正常渲染。
- 你关心的 chat 都以 Markdown / JSON 的形式存在,按 Project 名能找到。
- Team / Enterprise:管理员导出的 manifest 列出来的文件数对得上。
常见坑
- 以为个人 Data Export 是”完整版”——它是文本 + 元数据,不是文件。
- 触发导出之后又传了文件,期望旧导出能包含它。
- 数据在 Team 工作区里却跑的是个人导出——走错通道。
- 备份了文件引用(JSON 里的文件名)但没拿到二进制本体。
- 把一次性导出当永久备份——文件会变,重要 Project 要按周期重新导出。
FAQ
Q:Data Export 多久能到? A:个人账号一般 5-30 分钟。Team / Enterprise 管理员导出按数据量可能要几个小时。
Q:能单独请求某个 Project 的数据吗? A:标准导出不能直接做。手动下载那个 Project 的 Files,再在 conversations.json 里过滤这个 Project 的 chat。
Q:对话里的图片会被导出吗? A:JSON 里有内联图片 URL,但二进制经常是外部 host 的、可能会失效。重要的图片在 chat 还新鲜的时候就存一份。
Q:Custom GPT Knowledge 能备份吗? A:能——Custom GPT 设置页 → Configure → Knowledge → 一个个下载。同样没有批量导出。
Q:取消订阅后文件会被删吗? A:失去工作区访问后,文件就拿不到了。取消订阅前先备份,不要取消后再想起来。