生成AI入門 2026.06.12
ChatGPT会話履歴エクスポートできないときの対処法【2026年版】ClaudeへのJSON移行コード付き
エクスポート方法(公式手順)
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}")