🧳Przeniesienie do Claude — krok po kroku
Paweł SzczęsnySilabris · opracowanie

Przeniesienie do Claude — krok po kroku

Wersja 1.0 · 9.10.2026

Dostałeś konto Claude w organizacji, a dotychczas pracowałeś na koncie prywatnym albo w ChatGPT. Ten przewodnik pokazuje, jak zabrać ze sobą to, co ma wartość: pamięć i preferencje, projekty oraz historię rozmów. Każdy krok mówi, co klikasz, co wklejasz i po czym poznasz, że się udało.

🟠Z prywatnego Claude

Masz konto Claude Free, Pro albo Max i przechodzisz na konto w organizacji (plan Team lub Enterprise).

🟢Z ChatGPT

Pracowałeś w ChatGPT i chcesz przenieść pamięć oraz zachować historię rozmów jako archiwum, które Claude potrafi przeszukać.

Wybierz zakładkę na pasku u góry

Każda zakładka to osobna procedura z własnym licznikiem kroków. Postęp zapisuje się w tej przeglądarce, więc możesz przerwać i wrócić.

⏱ 30–90 minut, można na raty 💻 Windows · Mac · Linux 🔌 działa offline
0

Co da się przenieść, a co nie

≈ 3 min · tylko czytanie

Zanim zaczniesz klikać, zobacz, czego się spodziewać.

CoCzy da się przenieść
Pamięć i preferencje (to, co Claude o Tobie wie)Tak, jednym wklejeniem
Projekty (instrukcje i pliki wiedzy)Tak; w ścieżce B odtwarzasz je z eksportu, projekt po projekcie
Historia rozmów jako działające czatyTylko w ścieżce A (ten sam adres e-mail)
Historia rozmów jako archiwum do przeszukiwaniaTak, przez eksport danych
Własne skille, połączenia z aplikacjami, publiczne linkiNie; trzeba je odtworzyć
Najpierw przeczytaj zasady

Konto w organizacji należy do organizacji. Zanim cokolwiek przeniesiesz, przeczytaj sekcję Zanim cokolwiek przeniesiesz. Zajmie to dwie minuty.

1

Sprawdź, na jaki adres e-mail jest konto prywatne

≈ 2 min

Ten krok rozstrzyga, którą ścieżką idziesz.

  1. Zaloguj się na konto prywatne na claude.ai.
  2. Kliknij swoje inicjały w lewym dolnym rogu. Adres e-mail konta jest na górze menu.
  3. Porównaj go z adresem, na który dostałeś zaproszenie do organizacji.
Ten sam adres

Idziesz ścieżką A (krok 2). Claude przeniesie wszystko sam.

Inny adres, np. prywatny Gmail

Idziesz ścieżką B (kroki 3–5). Adresu konta Claude nie da się zmienić, więc przenosisz ręcznie to, co warto.

2

Ścieżka A: ten sam adres e-mail

≈ 10 min · pomiń, jeśli masz inny adres

Claude ma wbudowane przeniesienie konta prywatnego do organizacji.

Wybór pojawia się przy przyjmowaniu zaproszenia do organizacji. Później znajdziesz go w Settings → Account → Close your personal account. Masz dwie opcje:

  1. Keep both accounts. Oba konta zostają, przełączasz się między nimi w menu konta. Nic się nie przenosi.
  2. Use organization account only → Bring your data with you. Rozmowy, projekty, pliki, pamięć i ustawienia przechodzą do konta w organizacji, a konto prywatne jest zamykane.
⚠️ Opcja 2 jest nieodwracalna
  • Tego, co przeniesione, nie da się cofnąć na konto prywatne.
  • Przenosi się wszystko, także rozmowy prywatne. Nie wybierasz pojedynczych czatów.
  • Nie przenoszą się: własne skille, połączenia z aplikacjami, opublikowane artefakty i publiczne linki. Zapisz je wcześniej.
  • Płatny plan kupiony bezpośrednio jest anulowany automatycznie, ze zwrotem za niewykorzystany okres. Plan kupiony przez Apple App Store anulujesz samodzielnie.
Masz na koncie prywatnym sprawy, których nie chcesz w organizacji?

Wybierz opcję 1 i przenieś ręcznie tylko to, co służbowe, według kroków 3–5.

3

Ścieżka B: pamięć i preferencje

≈ 10 min

Najwięcej efektu przy najmniejszym wysiłku, dlatego od tego zaczynasz. Pracujesz w dwóch oknach przeglądarki: w jednym konto prywatne, w drugim konto w organizacji.

  1. Otwórz stronę claude.com/import-memory i kliknij Copy prompt.
  2. Wklej ten prompt w nowej rozmowie na koncie prywatnym. Claude wypisze to, co o Tobie zapamiętał.
  3. Przeczytaj wynik. Usuń to, czego nie chcesz mieć na koncie w organizacji.
  4. Na koncie w organizacji wejdź w Settings → Capabilities, znajdź pamięć i opcję importu, wklej wynik.
  5. Skopiuj też ręcznie swoje preferencje z Settings → Profile (pole z instrukcjami dla Claude'a) oraz własne style, jeśli ich używasz.
Pełniejsza wersja pamięci jest w eksporcie danych

Eksport z kroku 5 zawiera plik z całą pamięcią, także osobną dla każdego projektu. Skrypt zapisuje ją jako _pamiec.md. Jeśli prompt zwrócił mało, wróć tu po kroku 5 i wklej do importu treść tego pliku.

Po czym poznasz, że się udało

W nowej rozmowie na koncie w organizacji zapytaj: „Co o mnie wiesz?”. Odpowiedź powinna zawierać Twoją rolę i preferencje.

4

Ścieżka B: projekty

≈ 5–15 min na projekt

Przenosisz tylko projekty, które są Ci nadal potrzebne.

Dla każdego takiego projektu:

  1. Skopiuj instrukcje projektu i pobierz pliki wiedzy. Możesz to zrobić ręcznie w oknie projektu albo wziąć je z eksportu: po kroku 5 każdy projekt ma w folderze _projekty plik z opisem i instrukcjami oraz podfolder z treścią plików wiedzy.
  2. Na koncie w organizacji utwórz projekt o tej samej nazwie, wklej instrukcje i wgraj pliki.
  3. W starym projekcie poproś Claude'a o podsumowanie stanu (prompt niżej). Wynik zapisz jako plik i dodaj do wiedzy nowego projektu.
prompt · w starym projekcie
Napisz podsumowanie stanu tego projektu dla nowej rozmowy: cel, ustalenia, otwarte sprawy, ważne decyzje i dlaczego zapadły.
Pliki wiedzy z eksportu to sam tekst

Eksport przechowuje treść plików wiedzy jako tekst, bez oryginalnego formatu. Jeśli potrzebujesz oryginalnych plików PDF albo Word, pobierz je ręcznie z okna projektu.

Projekty, do których nie zaglądałeś od miesięcy, zostaw. Ich rozmowy i tak trafią do archiwum z kroku 5.

5

Ścieżka B: historia rozmów jako archiwum

≈ 30 min

Rozmów z konta prywatnego nie wgrasz na konto w organizacji jako działających czatów. Możesz je zachować jako archiwum, które Ty i Twój asystent przeszukujecie.

  1. Na koncie prywatnym: Settings → Privacy → Export data. Link do pobrania przyjdzie mailem na adres konta i wygasa po 24 godzinach.
  2. Rozpakuj paczkę do folderu poza folderami współdzielonymi, np. eksport-claude w folderze domowym. W środku są: conversations.json (wszystkie rozmowy), memories.json (pamięć) i folder projects.
  3. Sprawdź, czy masz Pythona: python --version (Windows) albo python3 --version (Mac, Linux). Gdy go brakuje, zobacz zakładkę „Z ChatGPT”, krok 5.
  4. Pobierz skrypt i zapisz go w dowolnym miejscu, np. w folderze domowym.

Otwórz terminal w folderze ze skryptem i podaj ścieżkę do folderu eksportu:

PowerShell · Windows
python convert_chats.py "$HOME\eksport-claude"
Co robi: zapisuje każdą rozmowę jako osobny plik Markdown, pamięć jako _pamiec.md, a projekty w folderze _projekty. Ścieżkę w cudzysłowie zmień na swoją.
Terminal · Mac i Linux
python3 convert_chats.py "$HOME/eksport-claude"
Co robi: to samo na Macu i Linuksie.

Poprawny wynik wygląda tak:

Po czym poznasz, że się udało

W folderze eksportu jest podfolder md z plikami rozmów, plikiem _pamiec.md i folderem _projekty. Pominięte rozmowy to takie, w których nie ma tekstu: puste albo przerwane na starcie.

Co dalej z archiwum

  • Rozmowy służbowe przenieś do folderu z materiałami referencyjnymi, np. Resources/archiwum-claude. Rozmowy prywatne trzymaj poza komputerem firmowym.
  • Skrypt zapisuje tekst rozmów i nazwy załączników. Samych załączników, obrazów ani kroków pośrednich asystenta nie przenosi.
  • Rozmowy nie są podzielone na projekty; wszystkie trafiają do jednego folderu.

Gdy archiwum jest gotowe, możesz prosić asystenta:

prompt · przykład użycia archiwum
Przeszukaj folder archiwum-claude pod kątem ustaleń o [temat] i streść je. Podaj nazwy plików, z których korzystasz.
6

Wątki, które chcesz kontynuować

≈ 3 min na rozmowę

Dla kilku rozmów, do których na pewno wrócisz, archiwum nie wystarczy.

W każdej takiej rozmowie, jeszcze na koncie prywatnym, wklej prompt niżej. Notatkę, którą dostaniesz, wklej na początku nowej rozmowy na koncie w organizacji.

prompt · w rozmowie do kontynuowania
Przygotuj notatkę przekazania tej rozmowy: kontekst, co ustaliliśmy, co zostało do zrobienia, jakie pliki i źródła były ważne.
7

Stare konto

≈ 2 min
  • W ścieżce B nie usuwaj konta prywatnego od razu. Zostaw je na co najmniej miesiąc. Płatny plan możesz obniżyć do bezpłatnego.
  • Chcesz dalej używać Claude'a prywatnie? Zostaw oba konta. To dozwolone i często najrozsądniejsze.
  • W ścieżce A z opcją „Bring your data with you” konto prywatne zamyka się samo.
0

Co da się przenieść z ChatGPT

≈ 3 min · tylko czytanie

ChatGPT i Claude to różne produkty. Rozmów nie da się przenieść jako działających czatów, ale ich treść możesz zabrać w całości.

CoJakKrok
Pamięć (to, co ChatGPT o Tobie zapamiętał)Prompt eksportujący w ChatGPT, import w Claude1
Własne instrukcje, projekty, własne GPT-yRęcznie: kopiujesz instrukcje i pliki2
Historia rozmówEksport danych, potem skrypt, który robi z niego osobny plik na każdą rozmowę3–8
Obrazy, pliki i nagrania głosowe z rozmówSą w paczce eksportu, skrypt ich nie przenosi do plików rozmów4
Najpierw przeczytaj zasady

Eksport zawiera wszystkie Twoje rozmowy, także prywatne. Zanim cokolwiek przeniesiesz, przeczytaj sekcję Zanim cokolwiek przeniesiesz.

1

Pamięć i personalizacja

≈ 10 min

Eksport danych nie zawiera pamięci ani personalizacji. Przenosisz je osobno, promptem.

  1. Otwórz stronę claude.com/import-memory i kliknij Copy prompt.
  2. Wklej ten prompt w nowej rozmowie w ChatGPT. Dostaniesz spis tego, co ChatGPT o Tobie zapamiętał.
  3. Porównaj wynik z listą w ChatGPT: Ustawienia → Personalizacja → Pamięć → Zarządzaj. Jeśli czegoś brakuje, dopisz ręcznie.
  4. Przeczytaj całość. Usuń to, czego nie chcesz mieć na koncie w organizacji.
  5. W Claude wejdź w Settings → Capabilities, znajdź pamięć i opcję importu, wklej wynik.
Po czym poznasz, że się udało

W nowej rozmowie w Claude zapytaj: „Co o mnie wiesz?”. Odpowiedź powinna zawierać Twoją rolę i preferencje.

2

Własne instrukcje, projekty i GPT-y

≈ 5–15 min na pozycję

Tych rzeczy nie przenosi ani prompt, ani skrypt. Kopiujesz je ręcznie i tylko te, których używasz.

W ChatGPTW Claude
Instrukcje niestandardowe (Personalizacja)Settings → Profile, pole z instrukcjami dla Claude'a
Projekt: instrukcje i plikiNowy projekt: instrukcje i pliki wiedzy
Własny GPT: instrukcje i pliki wiedzyNowy projekt z tymi samymi instrukcjami i plikami

Dla każdego projektu, który przenosisz, poproś w nim ChatGPT o podsumowanie stanu. Wynik zapisz jako plik i dodaj do wiedzy nowego projektu w Claude.

prompt · w projekcie ChatGPT
Napisz podsumowanie stanu tego projektu dla nowej rozmowy w innym narzędziu: cel, ustalenia, otwarte sprawy, ważne decyzje i dlaczego zapadły.
3

Zamów eksport danych z ChatGPT

≈ 2 min + czekanie na maila
  1. W ChatGPT kliknij swoje konto i wejdź w Ustawienia.
  2. Otwórz Zarządzanie danymi (po angielsku: Data controls).
  3. Przy pozycji Eksportuj dane kliknij Eksportuj i potwierdź.
  4. Poczekaj na maila z linkiem. Przychodzi na adres konta ChatGPT, zwykle w ciągu kilku do kilkudziesięciu minut.
  5. Pobierz paczkę ZIP od razu. Link jest ważny krótko.
Nie widzisz opcji eksportu?

Na kontach w przestrzeni firmowej ChatGPT eksport bywa wyłączony dla zwykłych użytkowników. Zapytaj administratora tej przestrzeni.

4

Rozpakuj paczkę i sprawdź, co w niej jest

≈ 5 min
  1. Utwórz folder roboczy poza folderami współdzielonymi, np. eksport-chatgpt w folderze domowym.
  2. Rozpakuj do niego paczkę ZIP. Windows prawy przycisk na pliku → Wyodrębnij wszystkie. Mac dwuklik.
  3. Znajdź plik z rozmowami. Nazywa się conversations.json albo jest ich kilka: conversations-000.json, conversations-001.json i tak dalej. Skrypt obsługuje oba warianty.

W paczce są też inne pliki: chat.html (cała historia do obejrzenia w przeglądarce) oraz obrazy i pliki z rozmów. Przy długiej historii paczka ma kilkadziesiąt megabajtów.

⚠️ Pliki z rozmowami muszą leżeć bezpośrednio w folderze, który wskażesz skryptowi

Po rozpakowaniu paczka często tworzy podfolder o długiej nazwie z ciągu liter i cyfr. To jego wskazujesz w kroku 7, a nie folder nadrzędny.

5

Sprawdź, czy masz Pythona

≈ 2 min

Skrypt jest napisany w Pythonie. Nie wymaga żadnych dodatkowych bibliotek.

PowerShell · Windows
python --version
Co robi: pokazuje wersję Pythona. Poprawny wynik to np. „Python 3.12.4”.
Terminal · Mac i Linux
python3 --version
Co robi: to samo; na Macu i Linuksie komenda nazywa się python3.
⚠️ Windows otwiera Microsoft Store albo pisze „nie rozpoznano”

Pythona nie ma na komputerze. Na komputerze firmowym poproś o instalację dział IT. Na własnym pobierz instalator z python.org i przy instalacji zaznacz Add python.exe to PATH. Potem zamknij i otwórz okno terminala.

6

Pobierz skrypt

≈ 2 min

Skrypt convert_chats.py czyta pliki rozmów i zapisuje każdą rozmowę jako osobny plik Markdown.

Zapisz plik w dowolnym miejscu, np. w folderze domowym. Jeśli przycisk nie działa, rozwiń kod niżej, skopiuj go i zapisz w edytorze tekstu jako convert_chats.py.

Pokaż kod skryptu
convert_chats.py
#!/usr/bin/env python3
"""
Zamienia eksport danych z ChatGPT albo z Claude na osobne pliki Markdown,
po jednym na rozmowe. Format eksportu rozpoznaje sam.

Uzycie:
    python convert_chats.py "C:\\sciezka\\do\\rozpakowanego\\eksportu"
    python convert_chats.py "folder eksportu" "folder na wynik"

Bez argumentow skrypt szuka eksportu w folderze, w ktorym sam lezy.
Wynik: podfolder "md" w folderze eksportu (albo folder podany jako drugi argument).
Z eksportu Claude powstaja dodatkowo: _pamiec.md (pamiec) i _projekty/ (instrukcje
i pliki wiedzy projektow). Plikow zrodlowych skrypt nie zmienia i nie laczy sie z siecia.

Wersja pierwotna (ChatGPT): zespol IT, u ktorego skrypt powstal.
Adaptacja i obsluga eksportu Claude: Silabris.
"""
import json
import re
import sys
from datetime import datetime, timezone
from pathlib import Path

UNSAFE_CHARS = re.compile(r'[/\\:*?"<>|]')
WHITESPACE = re.compile(r"\s+")
MAX_NAME = 80


# ---------- wspolne ----------

def slugify(title):
    slug = WHITESPACE.sub("_", str(title).strip())
    slug = UNSAFE_CHARS.sub("_", slug)
    slug = slug.lower()[:MAX_NAME].rstrip("._ ")
    return slug or "rozmowa"


def unique_path(out_dir, slug, used_counts, suffix=".md"):
    count = used_counts.get(slug, 0)
    used_counts[slug] = count + 1
    if count == 0:
        return out_dir / f"{slug}{suffix}", False
    return out_dir / f"{slug}_({count}){suffix}", True


def render(front_matter, title, messages):
    lines = ["---"] + [f"{k}: {v}" for k, v in front_matter] + ["---", "", f"# {title}", ""]
    for msg in messages:
        lines += [f"**{msg['author']}:**", "", msg["text"], "", "---"]
    return "\n".join(lines) + "\n"


def detect_format(conversation):
    if not isinstance(conversation, dict):
        return None
    if "mapping" in conversation:
        return "chatgpt"
    if "chat_messages" in conversation:
        return "claude"
    return None


# ---------- ChatGPT ----------

def iso(ts):
    if ts is None:
        return ""
    try:
        return datetime.fromtimestamp(ts, tz=timezone.utc).isoformat()
    except (TypeError, ValueError, OSError):
        return ""


def chatgpt_messages(conversation):
    """Idzie po conversation['mapping'] od current_node do korzenia,
    zbiera wiadomosci tekstowe i odwraca je do kolejnosci chronologicznej."""
    messages = []
    mapping = conversation.get("mapping") or {}
    current_node = conversation.get("current_node")

    while current_node is not None:
        node = mapping.get(current_node)
        if node is None:
            break

        message = node.get("message")
        if message:
            content = message.get("content") or {}
            parts = content.get("parts") or []
            author = message.get("author") or {}
            role = author.get("role")
            metadata = message.get("metadata") or {}

            is_text = (
                content.get("content_type") == "text"
                and len(parts) > 0
                and isinstance(parts[0], str)
                and len(parts[0]) > 0
                and (role != "system" or metadata.get("is_user_system_message"))
            )
            if is_text:
                if role == "assistant":
                    author_label = "ChatGPT"
                elif role == "system" and metadata.get("is_user_system_message"):
                    author_label = "Custom user info"
                else:
                    author_label = role
                messages.append({"author": author_label, "text": parts[0]})

        current_node = node.get("parent")

    messages.reverse()
    return messages


def chatgpt_conversation(conversation, number):
    if not conversation.get("mapping") or not conversation.get("current_node"):
        return None
    title = conversation.get("title") or f"conversation_{number}"
    front_matter = [
        ("source", "chatgpt"),
        ("conversation_id", conversation.get("id") or conversation.get("conversation_id") or ""),
        ("created", iso(conversation.get("create_time"))),
        ("updated", iso(conversation.get("update_time"))),
        ("model", conversation.get("default_model_slug") or ""),
        ("is_starred", bool(conversation.get("is_starred"))),
    ]
    return title, render(front_matter, title, chatgpt_messages(conversation))


# ---------- Claude ----------

def claude_message_text(message):
    parts = []
    for block in message.get("content") or []:
        if isinstance(block, dict) and block.get("type") == "text" and block.get("text"):
            parts.append(block["text"])
    text = "\n\n".join(parts) or (message.get("text") or "")
    names = [a.get("file_name") for a in (message.get("attachments") or []) if isinstance(a, dict)]
    names += [f.get("file_name") for f in (message.get("files") or []) if isinstance(f, dict)]
    names = [n for n in names if n]
    if names:
        text = (text + "\n\n" if text else "") + "Zalaczniki: " + ", ".join(names)
    return text


def claude_conversation(conversation, number):
    raw = conversation.get("chat_messages") or []
    messages = []
    for message in raw:
        if not isinstance(message, dict):
            continue
        text = claude_message_text(message)
        if not text:
            continue
        author = "Claude" if message.get("sender") == "assistant" else "Uzytkownik"
        messages.append({"author": author, "text": text})
    if not messages:
        return None
    created = conversation.get("created_at") or ""
    title = conversation.get("name") or f"rozmowa bez tytulu {created[:10] or number}"
    front_matter = [
        ("source", "claude"),
        ("conversation_id", conversation.get("uuid") or ""),
        ("created", created),
        ("updated", conversation.get("updated_at") or ""),
    ]
    return title, render(front_matter, title, messages)


def claude_memory(src_dir, out_dir):
    path = src_dir / "memories.json"
    if not path.is_file():
        return False
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
    except (OSError, ValueError):
        return False
    entries = data if isinstance(data, list) else [data]
    lines = ["# Pamiec z eksportu Claude", ""]
    found = False
    for entry in entries:
        if not isinstance(entry, dict):
            continue
        general = entry.get("conversations_memory")
        if general:
            lines += ["## Pamiec ogolna", "", str(general), ""]
            found = True
        projects = entry.get("project_memories") or {}
        if isinstance(projects, dict):
            for key, value in projects.items():
                if value:
                    lines += [f"## Pamiec projektu {key}", "", str(value), ""]
                    found = True
    if found:
        (out_dir / "_pamiec.md").write_text("\n".join(lines) + "\n", encoding="utf-8", newline="\n")
    return found


def claude_projects(src_dir, out_dir):
    folder = src_dir / "projects"
    if not folder.is_dir():
        return 0
    target = out_dir / "_projekty"
    used = {}
    count = 0
    for path in sorted(folder.glob("*.json")):
        try:
            project = json.loads(path.read_text(encoding="utf-8"))
        except (OSError, ValueError):
            continue
        if not isinstance(project, dict):
            continue
        name = project.get("name") or path.stem
        slug = slugify(name)
        lines = [
            "---",
            "source: claude",
            f"project_id: {project.get('uuid') or ''}",
            f"created: {project.get('created_at') or ''}",
            f"updated: {project.get('updated_at') or ''}",
            "---",
            "",
            f"# {name}",
            "",
        ]
        if project.get("description"):
            lines += ["## Opis", "", str(project["description"]), ""]
        if project.get("prompt_template"):
            lines += ["## Instrukcje projektu", "", str(project["prompt_template"]), ""]
        docs = [d for d in (project.get("docs") or []) if isinstance(d, dict)]
        if docs:
            lines += ["## Pliki wiedzy", ""]
        target.mkdir(parents=True, exist_ok=True)
        project_path, _ = unique_path(target, slug, used)
        docs_dir = project_path.with_suffix("")
        doc_used = {}
        for doc in docs:
            doc_name = doc.get("filename") or doc.get("file_name") or "plik"
            lines.append(f"- {doc_name}")
            content = doc.get("content")
            if isinstance(content, str) and content:
                docs_dir.mkdir(parents=True, exist_ok=True)
                doc_path, _ = unique_path(docs_dir, slugify(doc_name), doc_used, suffix=".txt")
                doc_path.write_text(content, encoding="utf-8", newline="\n")
        project_path.write_text("\n".join(lines) + "\n", encoding="utf-8", newline="\n")
        count += 1
    return count


# ---------- program ----------

def find_sources(src_dir):
    files = sorted(src_dir.glob("conversations-*.json"))
    single = src_dir / "conversations.json"
    if single.is_file():
        files.insert(0, single)
    return files


def main():
    if len(sys.argv) > 1:
        src_dir = Path(sys.argv[1]).expanduser().resolve()
    else:
        src_dir = Path(__file__).resolve().parent

    if not src_dir.is_dir():
        print(f"Nie ma takiego folderu: {src_dir}")
        return 1

    src_files = find_sources(src_dir)
    if not src_files:
        print(f"W folderze {src_dir} nie ma pliku conversations.json ani conversations-*.json.")
        print("Podaj folder z rozpakowanym eksportem ChatGPT albo Claude.")
        return 1

    if len(sys.argv) > 2:
        out_dir = Path(sys.argv[2]).expanduser().resolve()
    else:
        out_dir = src_dir / "md"
    out_dir.mkdir(parents=True, exist_ok=True)

    used_counts = {}
    total = written = skipped = collisions = 0
    formats = set()

    for src_file in src_files:
        with open(src_file, "r", encoding="utf-8") as f:
            conversations = json.load(f)

        if not isinstance(conversations, list):
            print(f"Pomijam {src_file.name}: to nie jest lista rozmow.")
            continue

        for conversation in conversations:
            total += 1
            fmt = detect_format(conversation)
            if fmt == "chatgpt":
                result = chatgpt_conversation(conversation, total)
            elif fmt == "claude":
                result = claude_conversation(conversation, total)
            else:
                result = None

            if result is None:
                skipped += 1
                print(f"  pomijam (brak tresci): {src_file.name}, rozmowa nr {total}")
                continue

            formats.add(fmt)
            title, content = result
            out_path, was_collision = unique_path(out_dir, slugify(title), used_counts)
            if was_collision:
                collisions += 1
            out_path.write_text(content, encoding="utf-8", newline="\n")
            written += 1

    print(f"Format eksportu:           {', '.join(sorted(formats)) or 'nierozpoznany'}")
    print(f"Rozmow w eksporcie:        {total}")
    print(f"Zapisanych plikow:         {written}")
    print(f"Pominietych (bez tresci):  {skipped}")
    print(f"Powtorzonych tytulow:      {collisions}")
    if "claude" in formats:
        print(f"Pamiec (_pamiec.md):       {'tak' if claude_memory(src_dir, out_dir) else 'brak w eksporcie'}")
        print(f"Projekty (_projekty):      {claude_projects(src_dir, out_dir)}")
    print(f"Folder z wynikiem:         {out_dir}")
    if total and not written:
        print("Zaden plik nie powstal. Sprawdz, czy to eksport z ChatGPT albo Claude.")
        return 1
    return 0


if __name__ == "__main__":
    sys.exit(main())

Co robi ten skrypt

  • Czyta conversations.json oraz conversations-*.json ze wskazanego folderu. Sam rozpoznaje, czy to eksport z ChatGPT, czy z Claude.
  • Dla każdej rozmowy odtwarza kolejność wypowiedzi i zapisuje plik .md: na górze źródło, identyfikator i daty, niżej tytuł i kolejne wypowiedzi z oznaczeniem, kto mówi.
  • Nazwę pliku tworzy z tytułu rozmowy. Powtarzające się tytuły dostają numer w nawiasie.
  • Wynik zapisuje w podfolderze md. Plików źródłowych nie zmienia i nie łączy się z siecią.

Czego nie robi

  • Nie przenosi obrazów, załączników ani nagrań; zapisuje tylko tekst.
  • Nie dzieli rozmów na projekty; wszystkie pliki trafiają do jednego folderu.
  • Zapisuje tę wersję rozmowy, która była widoczna jako ostatnia. Odrzucone warianty odpowiedzi pomija.
7

Uruchom skrypt

≈ 3 min

Otwórz terminal w folderze, w którym zapisałeś skrypt, i podaj ścieżkę do folderu z plikami rozmów.

PowerShell · Windows
python convert_chats.py "$HOME\eksport-chatgpt"
Co robi: zamienia rozmowy z folderu eksport-chatgpt na pliki Markdown. Ścieżkę w cudzysłowie zmień na swoją; jeśli paczka utworzyła podfolder, dopisz go.
Terminal · Mac i Linux
python3 convert_chats.py "$HOME/eksport-chatgpt"
Co robi: to samo na Macu i Linuksie.
Najprostszy sposób na ścieżkę

Wpisz python convert_chats.py ze spacją na końcu, a potem przeciągnij folder z plikami rozmów z Eksploratora albo Findera do okna terminala. Ścieżka wpisze się sama.

Poprawny wynik wygląda tak:

Po czym poznasz, że się udało

W folderze eksportu jest podfolder md, a w nim tyle plików, ile skrypt podał w wierszu „Zapisanych plikow”. Otwórz jeden z nich i sprawdź, czy rozmowa jest czytelna.

8

Gdzie położyć archiwum i jak z niego korzystać

≈ 10 min
  1. Przejrzyj listę plików i usuń rozmowy, których nie chcesz zachować.
  2. Rozdziel służbowe od prywatnych. Służbowe przenieś do folderu z materiałami referencyjnymi w miejscu, w którym pracujesz z asystentem, np. Resources/archiwum-chatgpt. Prywatne trzymaj poza komputerem firmowym.
  3. Jeśli używasz Obsidiana, wystarczy przenieść folder do sejfu. Pliki mają nagłówek z datami, więc da się je sortować i filtrować.
  4. Nie dodawaj archiwum do historii zmian (git) ani do folderów współdzielonych.

Od tej chwili możesz prosić asystenta w Claude Code albo w Claude z dostępem do tego folderu:

prompt · przykład użycia archiwum
Przeszukaj folder archiwum-chatgpt pod kątem ustaleń o [temat] i streść je. Podaj nazwy plików, z których korzystasz.

Pojedyncze rozmowy możesz też wgrać jako pliki wiedzy do projektu w Claude.

9

Wątki do kontynuacji i stare konto

≈ 3 min na rozmowę

Dla kilku rozmów, które chcesz prowadzić dalej w Claude, wklej w ChatGPT prompt niżej. Notatkę wklej na początku nowej rozmowy w Claude.

prompt · w rozmowie do kontynuowania
Przygotuj notatkę przekazania tej rozmowy do innego narzędzia: kontekst, co ustaliliśmy, co zostało do zrobienia, jakie pliki i źródła były ważne.

Konta ChatGPT nie usuwaj od razu. Zostaw je na co najmniej miesiąc; płatny plan możesz w tym czasie anulować. Po usunięciu konta eksportu nie da się już zamówić.

🚑

Kiedy coś nie działa

ObjawCo zrobić
„python nie jest rozpoznawany” albo otwiera się Microsoft StoreBrakuje Pythona. Wróć do kroku 5.
„can't open file … convert_chats.py”Terminal jest w innym folderze niż skrypt. Przejdź do folderu ze skryptem komendą cd albo podaj pełną ścieżkę do skryptu.
„nie ma pliku conversations.json ani conversations-*.json”Wskazałeś folder nadrzędny. Podaj podfolder, w którym faktycznie leżą pliki rozmów (krok 4).
„Zaden plik nie powstal”Wskazany folder nie zawiera eksportu z ChatGPT ani z Claude. Sprawdź, czy rozpakowałeś właściwą paczkę.
Mail z linkiem nie przyszedłSprawdź spam i adres konta ChatGPT. Po godzinie zamów eksport ponownie.
Link z maila nie działaWygasł. Zamów eksport ponownie i pobierz paczkę od razu.
W plikach brakuje obrazów i załącznikówTak ma być: skrypt zapisuje tylko tekst. Obrazy i pliki są w paczce eksportu.
🔒

Zanim cokolwiek przeniesiesz

  • Konto w organizacji należy do organizacji. Właściciel organizacji może wyeksportować jej dane, w tym rozmowy członków. Przenoś to, co służbowe, albo to, co świadomie chcesz tam mieć.
  • Eksport zawiera wszystko, także rozmowy prywatne. Paczkę trzymaj poza folderami współdzielonymi i poza historią zmian (git). Po zakończeniu usuń ją albo zarchiwizuj w bezpiecznym miejscu.
  • Dane innych firm i klientów. Jeśli na dotychczasowym koncie pracowałeś dla innego pracodawcy lub klienta, tych rozmów i plików nie przenoś.
  • Pamięć przeczytaj przed wklejeniem. To, co asystent zapamiętał prywatnie, po imporcie będzie wpływać na rozmowy służbowe.
  • Zasady Twojej organizacji mają pierwszeństwo. Jeśli firma ma politykę korzystania z narzędzi AI, sprawdź ją przed przeniesieniem.
📖

Źródła i stan wiedzy

Stan na 9.10.2026. Nazwy pozycji w menu zmieniają się; jeśli coś nazywa się u Ciebie inaczej, szukaj po sensie.

  • Anthropic: przeniesienie konta prywatnego do organizacji — support.claude.com/en/articles/9267400
  • Anthropic: eksport danych z Claude — support.claude.com/en/articles/9450526
  • Anthropic: zmiana adresu e-mail konta — support.claude.com/en/articles/8452276
  • Anthropic: import pamięci — claude.com/import-memory
Do potwierdzenia przy pierwszym użyciu
  • Dokładne położenie importu pamięci w ustawieniach konta w organizacji.
  • Czy prompt z claude.com/import-memory uruchomiony w samym Claude zwraca całą pamięć.
  • Ścieżka w menu ChatGPT: opisana według polskiej wersji interfejsu z jesieni 2026.

Skrypt convert_chats.py: sprawdzony na prawdziwym eksporcie z Claude (czerwiec 2026) i na próbnym eksporcie w formacie ChatGPT. Format eksportu może się zmienić; jeśli skrypt zgłosi „Zaden plik nie powstal”, daj znać autorowi przewodnika.