Skip to content

Output Format

ClarusIubar edited this page Aug 17, 2026 · 6 revisions

Output Format

한국어 | English

세션(대화) 1개당 마크다운 노트 1개가 생성됩니다.

  • frontmatter에 title/session_id/url/date/turns_count/content_hash/tags를 담습니다.
  • 본문은 > [!question]- User (...) / > [!tip]- <Vendor> (...) callout으로 turn을 나열합니다 (Obsidian 표시 형식을 그대로 보존).
  • 이미지·파일 첨부는 Attachments/로 복사되고 가능하면 ![[...]]로 임베드됩니다.

turn 메타데이터 HTML 주석

각 callout 바로 앞에는 다음과 같은 형태의 HTML 주석이 붙습니다:

<!-- turn: {"turn_index": 0, "role": "user", "parent_turn_index": null, "has_attachment": false} -->

Obsidian 미리보기에는 보이지 않지만, RAG 청킹 파이프라인이 callout 문법 ([!question] vs [!tip])이나 "다음 질문 직전까지" 같은 순서 휴리스틱 없이 바로 QA 쌍·세션 경계·첨부 맥락을 읽어갈 수 있게 합니다.

  • turn_index: 그 노트 안에서의 turn 순번.
  • role: user 또는 벤더(assistant) 쪽 role.
  • parent_turn_index: 그 답변이 어느 질문(turn_index)에 대한 것인지. 질문 턴은 항상 null(새 turn window의 시작). 같은 질문에 답변이 여러 턴으로 나뉘어도(실제로 발생함 — 긴 응답이 메시지 여러 개로 쪼개지는 경우) 전부 같은 parent_turn_index를 가리킵니다.
  • has_attachment: 그 턴 바로 뒤에 첨부파일 블록이 붙는지 여부.

이 계산은 common/session_markdown.py::build_session_markdown() 한 곳에서, turn 리스트를 role 순서대로 훑으며 벤더 무관하게 이뤄집니다(vendors/chatgpt.py, vendors/gemini.py는 관여하지 않음).

content_hash

content_hash는 frontmatter를 제외한 본문(body) 전체를 SHA-256으로 해시한 값입니다. turn 메타데이터 주석도 본문에 포함되므로 자동으로 해시 대상에 들어갑니다. 이 값이 Configuration에서 설명한 upsert 판정(created/updated/unchanged)의 기준입니다.

주의: 파일명은 title이 아니라 session_id 기준이다

ChatGPT의 conversations.json은 대화마다 실제 title 필드를 제공합니다(사용자가 채팅 목록에서 보는 제목과 동일, 없을 때만 첫 사용자 메시지의 첫 문장으로 대체). 반면 Gemini의 내 활동.html에는 대화별 제목이 아예 없습니다 — 유일하게 제목처럼 보이는 필드 (class="... title")는 세션마다 다른 값이 아니라 "Gemini 앱"이라는 고정 제품명뿐입니다. 그래서 Gemini는 항상 첫 질문의 첫 문장을 title로 대신 씁니다(first_sentence(...)).

이 벤더 간 차이 때문에 두 벤더 모두 파일명은 title이 아니라 session_id로 통일했습니다(vendors/chatgpt.py/vendors/gemini.py의 sanitize_filename(cid/sid, ...)). title을 파일명 기준으로 썼다면:

  • Gemini의 title은 첫 메시지에서 유도된 값이라 벤더마다 안정성이 다르고, 서로 다른 세션이 같은 첫 문장을 가지면 파일명이 충돌할 수 있습니다.
  • upsert는 "같은 세션 = 같은 파일 경로"를 전제로 동작합니다(Configuration 참고). title을 파일명으로 쓰면 title 계산 로직이 바뀌거나 원본 첫 메시지가 살짝 달라지는 것만으로도 새 파일이 생기면서 기존 노트와의 연결이 끊깁니다.

session_id는 원본(ChatGPT의 conversation_id, Gemini의 세션 URL)에서 그대로 온 고유 식별자라 이런 문제가 없습니다 — title은 frontmatter에만 표시용으로 남고, 실제 파일 경로와 upsert 판정은 전부 session_id 기준입니다.

Claude는 conversations.json의 일반 대화엔 대체로 name이 채워져 있지만, design_chats/*.json의 프로젝트 대화는 사용자가 이름을 안 바꾸면 그냥 "Chat"처럼 제네릭한 값으로 남아있는 경우가 흔합니다 — Gemini와 같은 이유로 Claude도 파일명은 title이 아니라 대화 uuid(session_id) 기준입니다.

Claude 프로젝트 소속 대화는 하위 폴더로 분리

다른 벤더는 result/<vendor>/*.md로 평평하게 쓰지만, Claude는 프로젝트에 묶인 대화만 result/claude/<프로젝트명>/*.md처럼 프로젝트별 하위 폴더에 씁니다(프로젝트에 안 묶인 일반 대화는 다른 벤더와 동일하게 평평하게 씀). 프로젝트명은 design_chats/*.json에 인라인으로 박힌 project.name에서 얻고, 파일시스템에 못 쓰는 문자는 sanitize_filename()으로 정리합니다. --publish도 이 하위 폴더 구조를 그대로 vault에 재현합니다(Configuration 참고).

Claude 관련 범위 밖 항목

memories.json(기억 기능 요약), login_history.json(로그인 이력), users.json(계정 정보), projects/*.json의 docs 필드(프로젝트 지식 파일)는 대화가 아니므로 변환하지 않습니다. 이 export에는 첨부파일 실 바이트가 전혀 들어있지 않아서(참조 파일명만 있음) 첨부파일은 항상 "누락" 안내 텍스트로만 표시됩니다.

관련 문서: Architecture

Clone this wiki locally