返回 Skill 列表
extension
分类: 数据与分析无需 API Key

Gemini Openai Chat Export Analyze

在用户需要导出并分析 Gemini(Google)或 ChatGPT(OpenAI)网页版全部聊天记录时激活本技能。常见触发词包括:导出 gemini 对话、gemini 聊天记录、chatgpt 数据导出、OpenAI conversations.json 等。

person作者: shaoqing404hubclawhub

Gemini / ChatGPT 聊天历史导出与分析

适用边界

本 skill 覆盖两个产品:

| 产品 | 路径 | 产物 | 文件格式 | |---|---|---|---| | ChatGPT(OpenAI) | Settings → Data controls → Export | ZIP,内含 conversations.json 等 | JSON | | Gemini(Google) | Google Takeout → Gemini Apps | ZIP,内含 My Activity/Gemini/*.html | HTML(不是 JSON) |

关键差异:ChatGPT 给 JSON,Gemini 给 HTML——本 skill 两套都要处理。


Part A:ChatGPT(OpenAI)导出

A.1 引导文案(可直接复制)

把跟 ChatGPT 的全部对话导出,大概走这几步:

  1. 打开 https://chatgpt.com(或 chat.openai.com)并登录
  2. 右上角点你的头像Settings
  3. 左侧菜单选 Data controls
  4. 找到 Export your data 区域,点 Request export
  5. 弹窗里勾上"Include chat history"(这是必须项),点 Confirm request
  6. 等 1~48 小时——OpenAI 会把下载链接发到你注册邮箱
  7. 邮件点链接下 ZIP,链接 7 天后失效,别拖
  8. ZIP 里找 conversations.json

文件可能 10MB~1GB+,别打开,告诉我解压后的完整路径。

A.2 文件结构(校验用)

# 顶层是 array
jq 'type' /path/to/conversations.json
# → "array"

# 总数
jq 'length' /path/to/conversations.json

# 单条 session 字段(实测是这些,版本可能小变)
jq '.[0] | keys' /path/to/conversations.json
# 预期: ["create_time","default_model_slug","id","mapping","moderation_results","title","update_time","user_id"]

注意 ChatGPT 的结构和 Claude 完全不同:

  • ChatGPT 用 mapping(嵌套树)而不是 chat_messages(线性数组)
  • 时间戳是 Unix timestamp(秒),不是 ISO 字符串
  • 消息角色在 mapping.[id].message.author.role 里,值是 "user" / "assistant" / "tool"

A.3 把 mapping 拍平为线性 messages

# 提取所有 user/assistant 消息,按树遍历顺序
jq -r '
  .[] as $c
  | $c.id as $cid
  | $c.title as $title
  | $c.create_time as $ct
  | [
      ($c.mapping | to_entries[]
        | .value.message
        | select(. != null and .author.role != "tool")
        | {
            sender: (.author.role | if . == "user" then "human" else . end),
            text: ([.content.parts[]? | select(type == "string")] | join("\n")),
            created_at: (.create_time // null)
          })
    ] as $msgs
  | $cid + "|" + ($ct | tostring) + "|" + $title + "|" + ($msgs | length | tostring)
' /path/to/conversations.json

A.4 常见的 4 类问题(参考 Claude skill 里的 A-G 模板)

| 用户问题 | 对应处理 | |---|---| | 找关键词对话 | 用 jq 配合 test() 过滤 text 字段 | | 列总览 | 用上面的"拍平"输出,按 create_time 排序 | | 找强建议 | 搜 "我建议|建议你|不应该" | | 找最长对话 | 排序 mapping 节点数 |

完整命令模板参见 claude-chat-export-analyze skill——结构差异处理完,jq 关键词搜索/时间线/主题提炼的逻辑完全通用


Part B:Gemini(Google)导出

B.1 引导文案(可直接复制)

把跟 Gemini 的全部对话导出,大概走这几步:

  1. 打开 https://myaccount.google.com 并登录
  2. 左上角菜单点 数据和隐私
  3. 向下滚到 数据下载(或"下载你的数据")区域,点进入 Google Takeout
  4. 取消全选,只勾 "我的活动"(My Activity)
  5. 点"我的活动"右边的下拉,确认"Gemini Apps"子项已勾选——只勾"Gemini"不一定包含完整对话
  6. 下一步,选 一次性导出.zip 格式、大小 1~2GB/卷
  7. 创建导出
  8. 异步处理,可能几小时到几天,完成后 Google 邮箱会收到下载链接
  9. 下载 ZIP,解压后看 My Activity/Gemini/ 目录,里面是 HTML 文件(不是 JSON)

提示我解压后的目录路径(整目录,不只是单个文件)。

B.2 文件结构(HTML 格式)

Gemini 导出的是 HTML 不是 JSON——这是最大的坑。

# 先看目录里有什么
ls /path/to/My\ Activity/Gemini/

# 典型:My\ Activity.html 是单文件聚合,或者 Gemini\ Apps.html 等分文件
# 文件结构:每个 <div class="outer-cell"> 是一个对话轮次

B.3 HTML → 结构化文本

用 python 快速解析:

from bs4 import BeautifulSoup
from pathlib import Path
import json, re

src = Path("/path/to/My Activity/Gemini")
out = []
for html_file in src.glob("*.html"):
    soup = BeautifulSoup(html_file.read_text(encoding="utf-8"), "html.parser")
    # 提取每条对话
    cells = soup.find_all("div", class_=re.compile(r"outer-cell|content-cell"))
    for cell in cells:
        text = cell.get_text("\n", strip=True)
        out.append({"file": html_file.name, "text": text})

print(json.dumps(out, ensure_ascii=False, indent=2))

或用 html2text:

html2text "/path/to/My Activity/Gemini/My Activity.html" > /tmp/gemini.txt
# 然后用 grep 搜
grep -n "我建议\|离职\|辞职" /tmp/gemini.txt

B.4 Gemini 导出的局限

⚠️ 跟 ChatGPT / Claude 相比,Gemini 导出有几个明显短板:

  1. HTML 格式,不能直接 jq——必须先解析
  2. 没有结构化的 role 字段——要靠 DOM 节点区分"用户问题"和"Gemini 回复"
  3. 时间戳可能不准确——Takeout 导出时区处理有时出问题
  4. 附件/图片元信息缺失——Google 通常把附件归到独立 Drive 文件,不在 Takeout 里

如果用户要做严肃分析(时间线/语义检索),建议额外说明这些局限,或让用户优先用 ChatGPT/Claude 那边。


Part C:跨平台统一分析(用户同时导出了多个时)

如果用户同时给了 Claude + ChatGPT + Gemini 三份数据,做"跨平台时间线"时:

C.1 把三家产物统一到同一份 JSONL

import json, sys, re
from pathlib import Path
from datetime import datetime, timezone

def normalize(rec):
    """统一字段:sender, text, created_at, source, session_id, session_name"""
    return {
        "sender": "assistant" if rec["sender"] in ("assistant", "model", "gemini") else "human",
        "text": rec["text"],
        "created_at": rec["created_at"],
        "source": rec["source"],  # "claude" / "chatgpt" / "gemini"
        "session_id": rec["session_id"],
        "session_name": rec["session_name"],
    }

# 然后写出 jsonl
with open("/tmp/unified.jsonl", "w", encoding="utf-8") as f:
    for rec in records:
        f.write(json.dumps(normalize(rec), ensure_ascii=False) + "\n")

C.2 跨平台查询

# 在所有平台上找"离职"相关
grep -E "离职|辞职|跳槽" /tmp/unified.jsonl | head -20

# 按平台分布
jq -r '.source' /tmp/unified.jsonl | sort | uniq -c

# 按月份聚合
jq -r '.created_at[0:7]' /tmp/unified.jsonl | sort | uniq -c

Part D:安全与隐私(必须告知)

  • ChatGPT 导出里包含 user.json,里面有用户邮箱、账号信息
  • Gemini 导出里可能包含 Google 账户关联的其他活动记录(搜索、YouTube)
  • 一律建议用户导出任务完成后移出工作目录
  • 输出报告时默认对邮箱/手机/身份证/银行卡打码

Part E:常见坑(踩过标这里)

  • ChatGPT 的 conversations.json 顶层是 array,但 mapping 字段是嵌套 dict——别用 .chat_messages[] 这种 Claude 习惯的语法
  • ChatGPT 时间戳是 Unix 秒数,不是 ISO 字符串——1633072800 这种,需要 | todate
  • Gemini 是 HTML,不是 JSON——jq 没法直接处理,先转文本
  • ChatGPT 导出的 message_feedback.json 包含用户 thumbs up/down——隐私敏感,不要 echo
  • 三家产物的时区都是 UTC——跨平台对照时统一换算到用户本地时区
  • 如果文件 > 500MB,优先按时间窗口分片——不要一次性 cat/jq
  • ChatGPT mapping 可能含 "current_node" 链,要把这条链的节点按顺序拍平,不是 to_entries 的字典序