유실된 줄 알았던 리서치는 세션 트랜스크립트에 남아 있다

서브에이전트에게 시킨 대량 조사에서 최종 요약만 기록하고 원본은 버린 줄 알았는데, 세션 JSONL 은 삭제되지 않고 영구 보존된다. 위치와 파싱 방법.

과거 세션에서 서브에이전트를 여러 개 띄워 대량 조사를 시킨 적이 있다. 영상 수십 편의 자막을 나눠 분석하는 작업이었다.

결론 몇 줄만 노트에 옮겨 적고 세션을 닫았다. 나중에 “그때 더 자세히 뭐라고 했지?“가 필요해졌을 때, 원본 조사 내용은 어디에도 없었다.

착각이었다. 원본은 파일로 남아 있었다. 위치를 몰랐을 뿐이다.

세션 JSONL 은 지워지지 않는다

Claude Code 의 세션과 그 안에서 실행한 서브에이전트의 전체 트랜스크립트는 세션이 끝나도 삭제되지 않는다.

~/.claude/projects/<project-slug>/<sessionId>.jsonl
~/.claude/projects/<project-slug>/<sessionId>/subagents/agent-<agentId>.jsonl

서브에이전트 JSONL 안에는 세 가지가 다 들어 있다.

  • 원래 지시 — line 0 근처
  • 중간 tool_result — 자막 원문 같은 원시 데이터
  • 최종 요약 — 마지막 assistant text

즉 “최종 요약만 살아남았다”가 아니라 요약과 원본이 같은 파일에 함께 있다. 요약은 노트로 옮겼고 원본은 안 옮겼을 뿐이다.

찾는 순서

1. 시간대로 세션 후보를 좁힌다. 그 조사를 언제 했는지 대략 알고 있으면 충분하다.

ls -la ~/.claude/projects/<slug>/*.jsonl

mtime 을 보고 후보를 몇 개로 줄인다.

2. 그 세션의 subagents/ 폴더를 본다. 파일 크기가 좋은 힌트다. 수백 KB 이상이면 원문 데이터가 들어 있을 가능성이 높고, 수 KB 짜리는 지시와 짧은 결론만 들어 있다.

3. 메인 세션 JSONL 을 grep 해서 역추적한다. 최종 결론 텍스트나 에이전트가 인용한 문구로 검색하면, 어느 서브에이전트가 어느 주제를 맡았는지 매칭된다. 각 에이전트의 지시 프롬프트가 파일 앞부분에 있으므로 그것만 봐도 담당이 갈린다.

통째로 읽지 말 것

서브에이전트 JSONL 은 수백 KB 에서 수 MB 다. 파일 읽기 도구로 통째로 읽으면 컨텍스트를 크게 낭비한다. 정작 필요한 건 그중 몇 KB 다.

라인 단위로 파싱해서 먼저 길이만 스캔한다.

import json

path = 'agent-<id>.jsonl'
with open(path, encoding='utf-8') as f:
    for i, line in enumerate(f):
        obj = json.loads(line)
        content = obj.get('message', {}).get('content')
        if isinstance(content, list):
            for c in content:
                if c.get('type') == 'text':
                    print(i, len(c['text']))   # 라인 번호와 텍스트 길이만

출력을 보면 실질 콘텐츠가 있는 라인이 금방 드러난다. 큰 tool_result 는 보통 몇 개 라인에 몰려 있다. 그 라인만 골라서 상세히 읽으면 된다.

다시 캘 때도 병렬로

과거 조사가 N 개 서브에이전트로 분산돼 있었다면, 재발굴도 N 개로 나누는 게 낫다. 각 에이전트에게 JSONL 파일 하나씩 배정하고 “이 파일 파싱해서 이 카테고리들 인사이트를 뽑아와”라고 시킨다.

신규 수집이 아니라 기존 원문의 재해석이라서 훨씬 싸고 빠르다. 원본 데이터가 고정돼 있으니 재현성도 높다. 같은 파일을 다시 돌리면 같은 결과가 나온다.

이게 왜 중요한가

“예전에 이거 했었는데 왜 지금은 못 해?“라는 질문을 받았을 때의 순서 이야기다.

웹에서 새로 찾기 전에 두 가지를 먼저 확인한다. 노트나 메모리에 방법론이 남아 있는지, 그리고 과거 세션 자체에 원본 데이터가 남아 있는지.

능력의 한계로 단정하기 전에 이미 있는 것부터 찾는다. 이 경우 답은 디스크에 있었고, 찾는 데 몇 분 걸렸다. 다시 수집했다면 몇 시간에 더해 원본과 다른 결과를 얻었을 것이다.