生成AI入門 2026.06.12

ChatGPT会話履歴エクスポートできないときの対処法【2026年版】ClaudeへのJSON移行コード付き

タグ:ChatGPT / Claude / トラブル解決 / エクスポート / 会話移行

エクスポート方法(公式手順)

ChatGPT → Settings → Data Controls → Export Data → 「Export」ボタン
  ↓(申請完了)
メールアドレスにダウンロードリンクが届く(数分〜数時間)

「conversations.json」を含むZIPファイルをダウンロード

原因別の対処法

原因症状対処法
セッション期限切れボタンを押しても何も起きないページリロード → 再ログイン
ブラウザキャッシュ別ブラウザでは成功するCache/Cookie全削除 → 再ログイン
VPN海外IPでブロックVPNをOFFにして再試行
大量会話履歴タイムアウトメール送付を待つ(最大24時間)
拡張機能の競合シークレットモードでは成功拡張機能を無効化して試す

エクスポートしたJSONをClaudeに移行するコード

# import_chatgpt_to_claude.py
# conversations.jsonをClaudeAPIで処理する

import json
import anthropic
import os

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

def load_chatgpt_conversations(json_path: str) -> list[dict]:
    """ChatGPTのエクスポートJSONを読み込む"""
    with open(json_path) as f:
        conversations = json.load(f)
    return conversations

def extract_messages(conversation: dict) -> list[dict]:
    """会話からメッセージを抽出してClaude API形式に変換する"""
    claude_messages = []
    
    mapping = conversation.get("mapping", {})
    for node_id, node in mapping.items():
        message = node.get("message")
        if not message or not message.get("content"):
            continue
        
        author_role = message.get("author", {}).get("role", "")
        content_parts = message.get("content", {}).get("parts", [])
        text = " ".join(str(p) for p in content_parts if isinstance(p, str))
        
        if not text.strip():
            continue
        
        if author_role == "user":
            claude_messages.append({"role": "user", "content": text})
        elif author_role == "assistant":
            claude_messages.append({"role": "assistant", "content": text})
    
    return claude_messages

def continue_with_claude(json_path: str, new_question: str) -> str:
    """ChatGPTの会話履歴を引き継いでClaudeで続ける"""
    conversations = load_chatgpt_conversations(json_path)
    
    if not conversations:
        return "会話が見つかりません"
    
    # 最新の会話を使用
    latest = conversations[-1]
    messages = extract_messages(latest)
    
    # 新しい質問を追加
    messages.append({"role": "user", "content": new_question})
    
    # 200Kコンテキストで長い会話も引き継げる
    response = client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=2048,
        system="ChatGPTからの会話履歴を引き継ぎました。前の文脈を踏まえて回答してください。",
        messages=messages[-50:]  # 最新50メッセージ(コンテキスト節約)
    )
    
    return response.content[0].text

# 使用例
# unzipしたconversations.jsonのパス
result = continue_with_claude(
    json_path="conversations.json",
    new_question="前回の議論の続きとして、実装の次のステップを教えてください"
)
print(result)

会話要約スクリプト(長い会話を圧縮してClaudeに渡す)

# summarize_for_context.py
# 長い会話を要約してClaude APIの入力を節約する

def summarize_conversation(messages: list[dict], max_chars: int = 10000) -> str:
    """長い会話をClaude Haikuで要約する"""
    full_text = "\n".join(
        f"{'ユーザー' if m['role'] == 'user' else 'AI'}: {m['content']}"
        for m in messages
    )
    
    if len(full_text) <= max_chars:
        return full_text  # 短い場合はそのまま
    
    summary_response = client.messages.create(
        model="claude-haiku-4-5-20251001",  # 要約は安いモデルで
        max_tokens=1024,
        messages=[{"role": "user", "content": f"""
以下の会話を300文字以内に要約してください。
重要な決定事項・前提条件・未解決の問題を含めてください。

会話:
{full_text[:20000]}
"""}]
    )
    return summary_response.content[0].text

# 使用例
messages = extract_messages(conversations[-1])
summary = summarize_conversation(messages)
print(f"要約 ({len(summary)}文字): {summary}")

あわせて読みたい

参考ソース