0biglife.

그래서 재봤다 — 내 AI 코딩 34일치 로그를 직접 측정한 기록

2026-08-08

들어가며

지난 글 빨라졌다는 착각에서 나는 AI 코딩 생산성을 우리는 측정하지 못한다고 썼다. 남들 데이터를 인용해서.

그 글을 올리고 나서 찜찜함이 남았다. 측정이 안 된다고 쓴 사람이 정작 자기 것은 재본 적이 없다. 데이터 엔지니어가 할 소리는 아니다.

그래서 재봤다. 내 ~/.claude/projects 아래 세션 로그와 28개 저장소의 git 히스토리를 직접 긁어서. 결론부터 말하면 처음 나온 숫자 네 개가 전부 틀렸고, 그 틀린 과정이 원래 하려던 얘기보다 더 재미있었다.

1. 무엇을 쟀나

측정 대상은 두 갈래다.

투입 — Claude Code 세션 로그(*.jsonl). 한 줄이 한 레코드고, 사람 메시지·에이전트 응답·툴 호출·토큰 사용량·타임스탬프가 전부 들어 있다. 계측하기에 이보다 좋은 형태가 없다.

산출 — 같은 기간의 git 커밋 수와 추가된 줄 수. 28개 저장소를 --since로 잘라서 합산했다.

의견을 섞지 않는 것이 유일한 규칙이었다. 로그에 있는 것만 센다.

2. 첫 결과는 전부 틀렸다

스크립트를 돌리고 나온 첫 화면이 이랬다.

누적 대화시간   2,324시간
사람이 친 글자  3,318,919자
툴 호출 0회 세션  79.9%

세 줄 다 말이 안 된다.

① 34일에 2,324시간. 물리적 상한이 816시간이다. 원인은 세션 시간을 마지막 타임스탬프 − 첫 타임스탬프로 잰 것. 세션을 열어두고 자러 간 시간이 전부 "작업 시간"으로 들어갔다. 커피 마시러 간 40분도, 회의 두 시간도.

→ 인접 메시지 간격을 하나씩 더하되 15분 넘는 침묵은 빼는 방식으로 바꿨다. 2,324시간이 102시간이 됐다. 22분의 1이다.

② 하루에 9만 7천 자를 타이핑. 손가락이 남아나지 않는다. 로그를 열어보니 user 역할로 들어오는 것이 사람이 친 것만이 아니었다.

784,338자 | Base directory for this skill: ... claude-api
152,857자 | # Update Config Skill ...
 32,138자 | This session is being continued from a previous conversation...
 19,646자 | ## Synthesis: research report ...
 19,213자 | <task-notification> ...

스킬 본문, 컨텍스트 요약, 서브에이전트가 돌려준 리포트, 시스템 알림. 전부 user 역할을 달고 들어온다. 사람 입력처럼 보이는 것의 3분의 2가 사람이 친 게 아니었다.

→ 주입 마커로 걸러내고, 4,000자를 넘으면 붙여넣기로 따로 셌다.

1INJECT = ("<system-reminder>", "<task-notification>", "<command-name>",
2          "This session is being continued from a previous conversation",
3          "Base directory for this skill", "## Synthesis:")
4
5if any(m in t[:400] for m in INJECT):
6    inject_chars += len(t)          # 시스템이 넣은 것
7elif len(t) > TYPED_MAX:
8    paste_chars += len(t)           # 내가 붙여넣은 것
9else:
10    typed_chars += len(t)           # 내가 실제로 친 것

330만 자가 105만 자로 줄었다.

③ 세션의 80%가 아무 일도 안 했다. 이것도 거짓이었다. 백그라운드 SDK 호출(sdk-cli 진입점)이 사람의 대화형 세션과 같은 통에 담겨 있었다. 121개가 그것이었고, 얘들은 출력 토큰이 0이다.

→ 진입점으로 분리하니 **실작업 세션 비율이 94%**로 바뀌었다.

④ 가장 많은 작업을 한 "프로젝트"가 (root). cwd~/projects 상위 폴더인 세션들이다. 어느 프로젝트 일인지 알 수 없다. 이건 고칠 수 없어서 귀속 불가로 따로 표시했다. 전체 출력 토큰의 26%가 여기 있다. 측정의 한계로 남겨두는 편이 낫다.

순진한 지표는 방향까지 틀리게 만든다. 네 개 중 셋은 사람의 노력을 3배로, 작업 시간을 22배로 부풀렸다. 그 방향이 우연이 아니다 — 틀린 계측은 대체로 자기에게 유리한 쪽으로 틀린다.

3. 고치고 나서 나온 숫자

항목
측정 기간2026-07-05 ~ 08-06 (세션 발생 14일)
대화형 세션33개
활성 시간102시간 (하루 평균 7.3시간)
내가 친 메시지1,485개 · 중앙값 125자
내가 친 글자1,054,719자
에이전트 출력 토큰35,678,827
툴 호출9,234회
같은 기간 커밋115건
같은 기간 추가된 줄176,646줄

여기서 파생되는 비율들이 본론이다.

  • 내가 1자 치면 에이전트가 33.8 토큰을 낸다.
  • 활성 1시간당 툴 호출 90.7회, 커밋 1.13건.
  • 커밋 1건당 출력 토큰 31만, 내가 친 글자 9,171자.
  • 캐시 적중 96.7%. 입력 비용의 대부분은 새 토큰이 아니라 캐시 읽기다.

4. 툴 분포가 통념을 뒤집는다

가장 의외였던 건 이거다.

호출비중
Bash3,90942%
Read1,52417%
Edit1,45516%
Write5926%
WebSearch / WebFetch8739%

코드를 쓰는 행위(Edit + Write)는 전체의 22%다. 나머지 78%는 명령을 실행하고, 읽고, 찾는다.

"AI가 코드를 대신 써준다"는 통념과 로그가 말하는 그림이 다르다. 로그 속의 에이전트는 대부분 확인하고 있다. 빌드를 돌리고, 테스트를 돌리고, grep 하고, 결과를 읽고, 다시 고친다.

이건 지난 글에서 인용했던 결론과 정확히 맞물린다. 병목이 생성에서 검증으로 옮겨갔다면, 시간의 대부분이 검증에 쓰이는 게 맞다. 남의 설문에서 본 문장을 내 로그에서 다시 만난 셈이다.

생성은 22%, 나머지는 확인이다. 검증세는 비유가 아니라 로그에 찍히는 숫자였다.

5. 이 숫자가 말하지 않는 것

여기서 멈추면 나도 똑같은 함정에 빠진다. 이 측정으로 답할 수 없는 것을 분명히 적어둔다.

"빨라졌나"에는 답하지 못한다. 비교군이 없다. AI 없이 같은 34일을 산 내가 없기 때문이다. 지난 글에서 소개한 METR 실험이 통제군을 둔 이유가 이것이고, 나는 그걸 못 한다. n=1에 대조군 0이면 그건 관찰이지 실험이 아니다.

커밋 수는 산출이 아니라 습관이다. 내가 잘게 쪼개 커밋하면 숫자가 오른다. 추가된 줄 수도 마찬가지다. 자동 생성된 파일 하나가 8만 줄을 만들기도 한다(실제로 이 기간에 그런 프로젝트가 있다).

커밋에서 사람 몫과 에이전트 몫을 분리하지 못한다. git은 누가 그 줄을 발상했는지 모른다.

로그 보존 기간에 잘렸다. 34일 구간인데 세션이 남아 있는 날은 14일이다.

그래서 이 글의 결론은 "AI로 N배 빨라졌다"가 아니다. 정반대다.

데이터 엔지니어의 시선

이 작업을 하면서 계속 겹쳐 보인 게 있다. 센서 캘리브레이션이다.

좌표계를 맞추지 못하면 아무것도 맞지 않는다고 쓴 적이 있다. 라이다와 카메라가 몇 도만 틀어져도 먼 물체는 미터 단위로 어긋난다. 그런데 화면에는 여전히 박스가 그럴듯하게 그려진다. 틀린 게 안 틀려 보이는 것이 캘리브레이션 문제의 본질이다.

내 첫 측정이 정확히 그랬다. 2,324시간이라는 숫자는 대시보드에서 멀쩡해 보였다. 물리 상한과 대조하지 않았으면 그대로 믿었을 것이다.

그래서 계측 코드에 세 가지를 박아뒀다.

  1. 물리적 상한과 대조한다. 34일이면 816시간이 최대다. 넘으면 지표가 틀린 거지 내가 대단한 게 아니다.
  2. 무엇을 제외했는지 함께 출력한다. 제외한 붙여넣기 107만 자, 시스템 주입 118만 자를 결과에 같이 찍는다. 제외량이 채택량보다 크면 그 지표는 의심 대상이다.
  3. 귀속할 수 없는 것은 귀속하지 않는다. (root) 26%를 억지로 나누지 않고 그대로 뒀다.

세 번째가 제일 어려웠다. 26%를 그럴듯하게 배분하면 표가 예뻐진다. 예쁜 표를 포기하는 것이 계측의 절반이다.

마치며

측정을 마치고도 원래 질문에는 답을 못 했다. 나는 빨라졌나? 여전히 모른다.

다만 하나는 얻었다. 무엇을 모르는지를 이제 안다. 활성 시간이 102시간이라는 것, 내가 치는 메시지의 중앙값이 125자라는 것, 에이전트가 쓰는 시간의 78%가 코드 작성이 아니라는 것. 이건 감각이 아니라 로그다.

그리고 지난 글의 마지막 문장을 조금 고쳐 쓰게 됐다. "체감은 데이터가 아니다" 라고 썼었는데, 여기에 한 줄을 더한다.

계측되지 않은 데이터도 데이터가 아니다. 숫자가 나왔다고 잰 것이 아니다. 무엇을 뺐는지 말할 수 있어야 잰 것이다.

계측 스크립트는 300줄 남짓이고 표준 라이브러리만 쓴다. 같은 걸 자기 로그에 돌려보고 싶은 사람이 있다면, 위의 필터 세 개(활성 시간 캡, 주입 마커 제외, 진입점 분리)만 옮겨가도 첫 세 개의 함정은 피할 수 있다.

방법

  • 대상: ~/.claude/projects/**/*.jsonl 세션 로그, ~/projects 아래 git 저장소 28곳
  • 기간: 2026-07-05 ~ 2026-08-06 (세션이 존재하는 14일)
  • 활성 시간: 인접 메시지 간격의 합, 15분 초과 간격 제외
  • 사람 입력: user 역할 텍스트에서 시스템 주입 마커 제외, 4,000자 초과는 붙여넣기로 분리
  • 세션: sdk-cli 진입점(백그라운드 호출) 분리
  • 산출: git rev-list --count --since--numstat 합산
  • 한계: 대조군 없음(n=1), 커밋·줄 수는 커밋 습관과 생성 파일에 좌우됨, 사람/에이전트 기여 분리 불가