왜 diff를 읽는 방식이 먼저 무너지나
diff는 코드가 어디서 어떻게 바뀌었는지를 줄 단위로 늘어놓은 목록이다. 사람이 조금씩 고치던 시절에는 이걸 읽는 것이 곧 리뷰였다. 변경이 작고, 그 변경을 만든 사람이 곧 나였기 때문에 목록만 봐도 머릿속에서 그림이 그려졌다.
에이전트가 코드를 쓰기 시작하면 두 전제가 동시에 깨진다. 한 번에 수십 개 파일이 바뀌고, 그 변경을 만든 것은 내가 아니다. 목록을 끝까지 넘겨도 남는 게 없는 이유가 이것이다. 정보가 없어서가 아니라, 이해에 필요한 순서가 아니기 때문이다.
여기서 흔한 오해가 하나 있다. 사람이 코드를 이해해야 하는 이유가 '검증' 때문이라는 생각이다. 에이전트가 엉뚱한 짓을 하니 사람이 감시해야 한다는 것이다. 그런데 검증은 에이전트가 점점 잘하게 되는 영역이다. 테스트를 붙이고 검증 루프를 주면 맞고 틀림 판정은 기계가 더 잘한다.
진짜 이유는 다른 데 있다. 이해는 '참여'하기 위한 것이다. 이번 변경을 이해하고 나면 그 이해가 다음 판단의 재료가 된다. 머릿속에 개념 구조가 쌓여 있어야 다음 아이디어가 나오고, 그게 사람이 하는 몫이다. 이해를 건너뛰면 판정은 계속할 수 있어도 제안은 못 하게 된다.
이걸 가리키는 말이 인지 부채(cognitive debt)다. 빅토리아대의 Margaret-Anne Storey 교수가 제안하고 Simon Willison이 널리 알린 개념으로, 기술 부채와 짝을 이룬다. 기술 부채는 코드에 쌓이고 인지 부채는 사람 머릿속에 쌓인다. 코드 부채는 정적 분석으로도 보이지만 인지 부채는 눈에 안 보이다가, 어느 날 '내 프로젝트인데 내가 제일 모른다'는 형태로 청구서가 온다.
좋은 설명은 어떤 순서로 쓰이나

그러면 diff 대신 무엇을 읽어야 하나. Geoffrey Litt가 던진 질문은 이것이다 — 이 코드 변경 하나를 나에게 설명하기 위해 팀 하나를 1년간 붙여 커리큘럼을 짜게 한다면, 그 결과물은 어떻게 생겼을까.
그 답이 explain-diff 스킬이 만드는 문서다. 구조는 네 덩어리이고, 순서 자체가 교육학이다. 좋은 수학 교사가 하는 일과 같다 — 세부를 던지기 전에 감을 먼저 잡아 준다.
실제 예시가 발표에 나온다. 젠 가든을 그리는 게임에서 시점을 위에서 내려다보는 방식(top-down)에서 비스듬한 방식(isometric)으로 바꾼 변경이었다. 문서는 이번에 무엇이 바뀌었는지부터 말하지 않는다. 쓰는 게임 엔진이 무엇이고 좌표계가 어떻게 생겼는지부터 깔아 준다. 이미 아는 사람은 건너뛰라는 안내와 함께.
그다음이 직관이다. "이번 변경의 목표는 2D 그림 기술만으로 정원이 입체처럼 느껴지게 만드는 것이다." 잘 쓴 커밋 메시지를 한 겹 더 파고든 문장에 가깝다. 코드를 들이밀기 전에 본질을 먼저 준다.
코드는 세 번째다. 그것도 파일 목록 순서가 아니라 이해되는 순서로, 파일마다 무엇이 일어나는지 산문으로 먼저 말한 뒤에 나온다. Litt는 이걸 literate code diff라고 부르고, 인쇄해서 카페에서 읽는다고 말한다. IDE에 붙어 있어야 했던 작업이 텍스트북 읽기가 된 셈이다.
| 구간 | 들어가는 것 | 왜 이 자리인가 |
|---|---|---|
| Background | 이 시스템이 원래 어떻게 돌아가는가. 입문자용 깊은 배경과 이번 변경에 직접 닿는 좁은 배경을 나눠서 | 읽는 사람이 어디까지 아는지 모르므로, 이해의 출발선을 먼저 맞춘다 |
| Intuition | 세부를 걷어낸 핵심 한 줄, 장난감 데이터로 만든 구체 예시, 그림 | 본질을 먼저 잡아야 코드가 사례로 읽힌다 |
| Code | 변경의 상위 수준 워크스루. 파일 순서가 아니라 이해 순서로 묶고 정렬 | 코드는 근거지 출발점이 아니다 |
| Quiz | 중간 난이도 객관식 5문항. 클릭하면 정오답과 해설 | 읽었다는 착각과 이해를 갈라놓는 유일한 장치 |
스킬이 무엇이고 어디에 두는가
explain-diff는 프로그램이 아니라 스킬(skill) 파일 하나다. 설치할 게 없다는 뜻이라 처음 듣는 사람은 오히려 헷갈린다.
Claude Code에서 스킬은 "이런 상황에서는 이렇게 해 달라"를 적어 둔 마크다운 문서다. 정해진 자리에 두면 필요할 때 알아서 불려 나온다. 자리는 두 곳이다 — 내 컴퓨터 전체에서 쓰려면 홈 폴더의 ~/.claude/skills/, 특정 프로젝트에서만 쓰려면 그 저장소의 .claude/skills/ 안이다.
파일 이름은 반드시 SKILL.md이고, 폴더 이름이 곧 스킬 이름이 된다. 즉 ~/.claude/skills/explain-diff-html/SKILL.md 라는 경로 자체가 등록 절차다. 별도 설정 파일이나 재빌드는 없다.
문서 맨 위에는 세 줄짜리 머리말(frontmatter)이 붙는다. name은 스킬 이름, description은 '언제 이 스킬을 쓸 것인가'다. 이 description이 중요하다 — 사용자가 스킬 이름을 부르지 않아도, 지금 상황이 이 설명에 맞으면 에이전트가 알아서 이 문서를 읽는다. explain-diff-html의 description은 "코드 변경·diff·브랜치·PR에 대한 풍부한 설명을 요청할 때 쓰라"로 돼 있다.
머리말 아래는 전부 사람 말이다. 어떤 섹션을 넣을지, 어떤 문체로 쓸지, 다이어그램은 어떻게 그릴지, 파일은 어디에 저장할지가 평범한 문장과 목록으로 적혀 있다. 코드가 한 줄도 없다. 그래서 뒤에서 볼 '내 팀에 맞게 고치기'가 그냥 문서 편집으로 끝난다.
---
name: explain-diff-html
description: Use when the user asks for a rich explanation of a code change, diff, branch, or PR. Produces HTML output.
---설치 — 명령 두 줄

원본은 Geoffrey Litt가 올린 공개 gist 한 개이고, 그 안에 파일이 두 개 있다. explain-diff-html.md는 HTML 한 장을 만들고, explain-diff-notion.md는 노션 페이지를 만든다. 둘 중 하나만 깔아도 되고 둘 다 깔아도 된다. 둘 다 깔면 상황에 맞는 쪽이 알아서 불려 나온다.
설치는 폴더를 만들고 파일을 그 안에 SKILL.md라는 이름으로 내려받는 것이 전부다. 아래 명령을 터미널에 그대로 붙여 넣으면 된다. 관리자 권한도, 패키지 설치도 필요 없다.
여기서 자주 나오는 실수가 파일 이름이다. explain-diff-html.md 그대로 저장하면 인식되지 않는다. 폴더 이름이 스킬 이름이고 파일 이름은 항상 SKILL.md여야 한다. 위 명령의 -o 뒤 경로가 그래서 그렇게 생겼다.
제대로 들어갔는지는 머리말을 찍어 보면 바로 안다. name 줄이 보이면 성공이다. 이미 열려 있던 Claude Code 세션에는 방금 만든 스킬이 아직 안 보일 수 있으니, 세션을 새로 열고 쓰는 편이 확실하다.
mkdir -p ~/.claude/skills/explain-diff-html
curl -sL https://gist.githubusercontent.com/geoffreylitt/a29df1b5f9865506e8952488eac3d524/raw/explain-diff-html.md -o ~/.claude/skills/explain-diff-html/SKILL.md
# 확인 — 머리말의 name 줄이 보이면 설치된 것이다
head -4 ~/.claude/skills/explain-diff-html/SKILL.mdmkdir -p ~/.claude/skills/explain-diff-notion
curl -sL https://gist.githubusercontent.com/geoffreylitt/a29df1b5f9865506e8952488eac3d524/raw/explain-diff-notion.md -o ~/.claude/skills/explain-diff-notion/SKILL.md돌려보기 — 무엇을 말하면 되나
설치가 끝나면 별도 명령을 외울 필요가 없다. 코드 저장소 안에서 Claude Code를 켜고 평범한 한국어로 요청하면 된다. "이번 브랜치에서 main과 달라진 부분을 설명해 줘" 정도면 충분하다. 스킬의 description이 이 상황과 맞으므로 에이전트가 알아서 그 문서를 따른다.
설명 대상은 세 가지 형태로 지정할 수 있다. 브랜치 전체(main과의 차이), 특정 커밋 범위, 혹은 아직 커밋하지 않은 작업 트리의 변경이다. 에이전트가 diff만 보는 게 아니라 주변 코드까지 넓게 읽으라고 스킬에 적혀 있어서, 배경 섹션의 품질이 여기서 갈린다.
결과물은 자체 완결형 HTML 파일 한 장이다. CSS와 자바스크립트가 전부 그 안에 들어 있어서, 브라우저로 열기만 하면 퀴즈까지 동작한다. 탭으로 쪼개지 않고 한 장으로 길게 이어지며 맨 위에 목차가 붙는다. 휴대폰에서도 읽히도록 기본적인 반응형 스타일이 들어간다.
저장 위치가 스킬에 못 박혀 있다. 코드 저장소 바깥의 공용 위치에 두고, 파일 이름은 반드시 오늘 날짜로 시작한다. 예를 들어 /tmp/2026-08-01-explanation-isometric-view.html 같은 모양이다. 이유는 두 가지다 — 시간순으로 정렬되고, 버전 관리에 딸려 들어가지 않는다.
만든 문서를 여는 건 맥이면 open 명령 한 줄이다. 리눅스면 xdg-open, 윈도우면 start를 쓴다.
이번 브랜치에서 main과 달라진 부분을 설명해 줘
# 다른 지정 방식
최근 커밋 3개를 설명해 줘
아직 커밋 안 한 변경을 설명해 줘# 오늘 만들어진 설명 문서 찾기
ls -t /tmp/$(date +%F)-explanation-*.html
# 열기 (macOS)
open /tmp/2026-08-01-explanation-isometric-view.html퀴즈를 속도 조절기로 쓰기

문서 맨 아래 붙는 5문항이 이 스킬의 핵심이다. 난이도 지시가 구체적이다 — 중간 난이도, 함정 문제는 금지, 다만 변경의 실질을 이해하지 않으면 못 푸는 수준. 객관식이고, 답을 고르면 그 자리에서 정오답과 해설이 나온다.
왜 퀴즈인가. Litt는 Andy Matuschak의 "Books don't work"를 근거로 든다. 책을 다 읽고도 이해하지 못했다는 사실을 스스로 알아채기가 대단히 어렵다는 주장이다. Matuschak과 Michael Nielsen은 그래서 에세이 본문 중간에 간격 반복 퀴즈를 심어, 이해하지 않고는 끝까지 통과할 수 없는 글을 만들었다.
같은 장치를 코드 리뷰에 옮긴 것이다. Litt가 자기에게 건 규칙은 한 문장이다 — 내가 퀴즈를 통과하지 못하면, 에이전트가 쓴 코드를 팀에 리뷰 요청으로 보내지 않는다. 유치해 보이지만 실제로 자주 걸린다고 말한다. 다 읽었다고 생각한 PR에서 동료가 가장 기본적인 질문을 던졌을 때 답하지 못한 경험이 출발점이었다.
이걸 그는 속도 조절기라고 부른다. AI 관련 도구는 전부 더 빨리 가라는 방향으로 압력을 넣는다. 정확성의 속도만 올리고 이해의 속도를 안 올리면 인지 부채가 그만큼 쌓인다. 퀴즈는 그 두 속도를 억지로 붙여 두는 장치다.
팀에 도입한다면 규칙을 개인 수칙으로 두는 편이 낫다. 통과 못 하면 못 보내는 게이트를 CI에 걸 수는 없다. 대신 "리뷰 요청 본문에 설명 문서 링크를 붙인다" 정도로 시작하면, 문서를 만들다가 자연히 퀴즈를 풀게 된다.
노션 버전은 무엇이 다른가
explain-diff-notion.md는 결과물을 파일이 아니라 노션 페이지로 만든다. 내용 구조(배경·직관·코드·퀴즈)는 같고 출력만 갈린다.
차이는 협업이다. 파일은 내 컴퓨터에 있지만 노션 페이지는 팀이 같이 본다. 문단마다 코멘트를 달 수 있으니, 설명 문서 자체가 토론 장소가 된다. 에이전트가 세운 계획에 팀원이 코멘트로 이견을 남기는 식이다. Litt가 노션에서 일하기 때문이기도 하지만, 이해를 개인이 아니라 팀 단위로 쌓는다는 점이 이 변형의 목적이다.
전제가 하나 붙는다. Notion MCP가 연결돼 있어야 한다. MCP는 에이전트가 외부 서비스에 직접 말을 걸 수 있게 해 주는 표준 연결 방식이고, 노션 MCP를 붙여 두면 에이전트가 페이지를 만들고 그 URL을 돌려준다. 연결이 없으면 이 스킬은 페이지를 못 만든다.
퀴즈 표현도 다르다. HTML 버전은 자바스크립트로 클릭 판정을 하지만, 노션에는 그런 인터랙션이 없어서 토글 블록을 쓴다. 보기를 하나씩 펼치면 그 선택지가 왜 맞고 틀렸는지 설명이 나온다. 답이 바로 안 보인다는 점에서 역할은 같다.
덧붙이면, 발표 시연에서는 노션 페이지 안에 인터랙티브 시뮬레이션까지 들어갔다. 좌표를 드래그해 보면서 이번 변경이 무엇을 바꿨는지 만져 보는 식이다. 다만 Litt 본인이 경고를 붙인다 — 인터랙션은 목발이 되기 쉽고 슬롭이 되기도 쉽다. 정적인 그림으로 안 되는 것만 인터랙션으로 만든다.
내 팀에 맞게 고치기, 그리고 남은 두 기법
스킬 파일은 평범한 마크다운이라 그대로 고쳐 쓰면 된다. 실제로 손대게 되는 지점은 넷이다. 첫째, 섹션 구성 — 우리 팀이 늘 묻는 질문(예: 롤백 계획, 성능 영향)을 섹션으로 추가한다. 둘째, 퀴즈 문항 수와 난이도. 셋째, 저장 경로와 파일명 규칙 — 회사 공용 폴더에 쌓고 싶으면 여기만 바꾼다. 넷째, 문체 지시다. 원본에는 Martin Kleppmann의 명료함으로 쓰라고 적혀 있는데, 우리 팀이 좋아하는 문서를 대신 지목해도 된다.
고칠 때 건드리지 않는 편이 좋은 대목도 있다. 원본은 다이어그램을 ASCII로 그리지 말고 HTML로 그리라고 못 박고, 코드 블록은 pre 태그를 쓰되 굳이 직접 스타일링한 div를 쓴다면 white-space를 pre-wrap으로 두고 저장 전에 확인하라고까지 적어 두었다. 실제로 자주 깨지는 지점이라 남겨 두는 편이 낫다.
같은 발표에는 기법이 둘 더 나온다. 하나는 마이크로월드다. 이해를 돕기 위해서만 존재하고 배포하지 않는 소프트웨어를 에이전트에게 만들게 하는 방식이다. Litt는 자기가 만든 Prolog 인터프리터의 내부 동작을 타임라인으로 스크럽하며 보는 디버거를 만들었고, 개인 웹사이트를 다른 프레임워크로 옮길 때는 이전 작업을 버튼 클릭으로 한 단계씩 진행하는 작은 게임을 만들어 직접 눌러 가며 옮겼다. 스크립트가 알아서 다 하면 결과는 같지만 감각이 안 남는다는 이유에서다.
다른 하나는 공유 공간이다. 사람과 에이전트가 같은 스레드에서 대화하고, 문서에 코멘트로 토론하고, 코딩 에이전트를 팀 문서 공간 안으로 들이는 방향이다. 각자 자기 에이전트와 1:1로 대화하면 팀의 이해가 쪼개진다는 문제의식이다.
세 기법의 공통점은 하나다. 에이전트에게 코드를 짜게 하는 데서 멈추지 않고, 그 코드를 이해하기 위한 도구를 짜게 한다. 코드가 싸졌으니 이해를 돕는 일회용 도구도 싸졌다. 그렇다면 이해를 덜 하는 방향이 아니라 더 하는 방향으로 쓸 수 있다는 게 이 발표의 결론이다.
