AI 스터디 · 7주차

diagnose
AI에게 "체계적 디버깅"을 시키는 법 — 검증된 skill 하나를 해부한다

"그냥 고쳐줘"가 왜 실패하는가, 그리고 사람이 쓰는 디버깅 방법론을 어떻게 skill로 인코딩했는가

왜 이 주제? 디버깅은 BE·FE·Mobile·SRE 전 직군 공통 작업. 이번 발표는 "skill 소개"가 아니라 "skill 안에 담긴 방법론을 해부"합니다 — 발표 후 각자 자기 코드에 바로 적용 가능.

소재

diagnose SKILL.md (체계적 디버깅 6단계 규율)

오늘의 실측

이번 세션에서 /diagnose로 잡은 실제 버그 — div 균형 77/95 (+18)

1 / 10 문제

AI에게 "이 버그 고쳐줘" 했을 때

코드 생성은 잘하는 AI가, 어려운 버그 앞에선 자주 헛발질한다. 익숙한 장면:

흔한 AI 디버깅

  • 에러 메시지만 보고 "아마 여기겠죠" → 수정
  • 안 고쳐짐 → 다른 곳 또 수정
  • 여러 군데 동시에 바꿔서 뭐가 효과였는지 모름
  • "고친 것 같아요" (재현 확인 없이)

숙련 개발자의 디버깅

  • 먼저 재현부터 — 안정적으로 띄운다
  • 가설을 세우고 하나씩 검증
  • 고친 뒤 원래 증상이 사라졌는지 확인
질문: 이 차이는 "AI가 덜 똑똑해서"가 아니다. 방법(규율)이 없어서다. 그럼 사람의 디버깅 규율을 AI에게 어떻게 주입할까? — diagnose가 그 한 가지 답.

출처: mattpocock/skills — diagnose SKILL.md 도입부

2 / 10 왜 실패하나

추측-수정 루프(guess-and-patch)의 함정

기본 상태의 AI는 "증상 → 그럴듯한 원인 → 즉시 수정"으로 달린다. 세 가지가 동시에 무너진다.

함정무슨 일근본 원인
① 첫 가설 고착처음 떠오른 원인에 앵커링, 그것만 판다가설을 하나만 생성
② 다변수 동시 변경3곳 고치고 됐는데, 뭐가 효과였는지 모름한 번에 한 변수 원칙 없음
③ 검증 없는 완료"고친 듯" — 재현도 안 해봄pass/fail 신호가 없음
공통 뿌리: "측정 가능한 신호 없이 코드만 노려본다." diagnose의 표현 — "no amount of staring at code will save you." 코드를 아무리 노려봐도 신호가 없으면 못 고친다.

출처: mattpocock/skills — diagnose SKILL.md Phase 1

3 / 10 핵심 명제

"피드백 루프가 곧 디버깅이다"

diagnose의 1번 원칙: 빠르고·결정적이고·에이전트가 직접 돌릴 수 있는 pass/fail 신호를 먼저 만들어라. 나머지(이분법·가설검증·계측)는 전부 그 신호를 소비할 뿐이다.

원문: "This is the skill. Everything else is mechanical. … Build the right feedback loop, and the bug is 90% fixed." — 즉 디버깅의 핵심은 "어떻게 고치지"가 아니라 "어떻게 이 버그를 1초 만에 재현·확인하지"의 문제.

왜 이게 비직관적이고 깊은가

출처: mattpocock/skills — diagnose SKILL.md "Phase 1 — Build a feedback loop"

4 / 10 전체 그림

6단계 규율 — "정당한 이유 없이는 건너뛰지 마라"

1피드백 루프
2재현
3가설 3~5
4계측
5수정+회귀
6정리+사후
단계관문(통과 조건)
1 피드백 루프믿을 만한 루프가 생기기 전엔 2단계 금지
2 재현사용자가 말한 그 증상을 띄울 것 (근처 다른 버그 X)
3 가설테스트 전에 3~5개 순위 + 각자 반증 예측
4 계측예측 하나당 프로브 하나, 한 변수씩
5 수정(올바른 seam 있으면) 회귀 테스트 먼저 → 실패 확인 → 수정 → 통과
6 정리태그 로그 제거·회귀 통과·"무엇이 막았을까" 사후

핵심은 관문(gate)이 있다는 것 — 추측-수정 루프엔 없는 "다음으로 넘어가도 되나?" 체크.

출처: mattpocock/skills — diagnose SKILL.md Phase 1~6

5 / 10 심층 ① — 발표의 백미

피드백 루프 만드는 10가지 수 (난이도 순)

"재현이 안 돼요"는 끝이 아니라 시작. diagnose는 10가지를 순서대로 시도하라고 한다.

  1. 실패하는 테스트 (unit/integration/e2e)
  2. curl/HTTP 스크립트 (dev 서버 대상)
  3. CLI 실행 + 스냅샷 diff
  4. 헤드리스 브라우저 (Playwright)
  5. 트레이스 재생 (실제 요청 저장→재생)
  1. 버리는 하네스 (최소 부분만 띄워 함수 1콜)
  2. 속성/퍼즈 루프 (랜덤 1000개)
  3. 이분 하네스 (git bisect run)
  4. 차분 루프 (구버전 vs 신버전 출력 diff)
  5. HITL bash (최후 수단 — 사람을 구조화)
루프 자체를 제품처럼 개선: 더 빠르게(불필요 init 스킵)·더 날카롭게("안 죽음" 말고 그 증상)·더 결정적으로(시간 고정·RNG 시드). "30초짜리 깜빡이는 루프는 루프 없는 것과 비슷, 2초짜리 결정적 루프는 디버깅 초능력."

출처: mattpocock/skills — diagnose SKILL.md "Ways to construct one"

6 / 10 심층 ②

가설 — "느낌"을 "반증 가능한 예측"으로

왜 3~5개를 한꺼번에?

가설을 하나만 만들면 첫 그럴듯한 생각에 앵커링된다. diagnose는 테스트 전에 순위 매긴 3~5개를 강제한다.

각 가설은 반증 가능해야

형식: "만약 <X>가 원인이면, <Y>를 바꾸면 버그가 사라진다 /
                        <Z>를 바꾸면 더 심해진다."

예측을 못 쓰면 그건 "느낌(vibe)" → 버리거나 날카롭게. — 이게 과학적 방법(falsifiability)을 프롬프트에 인코딩한 것.

값싼 체크포인트: 순위 목록을 사람에게 먼저 보여줘라. "우리 #3 영역을 막 배포했는데" 한마디면 순위가 즉시 재정렬. 단 사람이 자리에 없으면 막지 말고 진행 — 인간 지식을 루프에 끼우되 병목은 안 만드는 설계.

출처: mattpocock/skills — diagnose SKILL.md Phase 3

7 / 10 심층 ③

계측 — 한 번에 한 변수, 그리고 태그 로그

프로브 규율

  • 프로브 하나 = Phase 3 예측 하나
  • 한 변수씩 변경
  • 디버거/REPL > 타겟 로그 > "다 찍고 grep"(금지)
  • "breakpoint 하나가 로그 열 개보다 낫다"

태그 로그 트릭

모든 디버그 로그에 고유 접두사:

[DEBUG-a4f2] payload=...

정리할 때 grep [DEBUG-a4f2] 한 방.
안 태그한 로그는 살아남아 쓰레기가 됨.

성능 회귀는 다르다: 로그는 대개 틀린 도구. 먼저 기준선 측정(timing harness, performance.now(), 프로파일러, 쿼리 플랜) → 그다음 bisect. 측정 먼저, 수정 나중.

출처: mattpocock/skills — diagnose SKILL.md Phase 4

8 / 10 심층 ④

수정 → 회귀 테스트 → 사후 분석

회귀 테스트를 "수정보다 먼저" — 단, 올바른 seam이 있을 때만

올바른 seam = 테스트가 실제 버그 패턴을 호출 지점 그대로 재현하는 자리. 너무 얕은 seam(단일 호출 테스트로 다중 호출 버그)은 거짓 안심을 준다.

깊은 통찰: "올바른 seam이 없다는 것 자체가 발견이다." 코드 구조가 버그를 잠그지 못하게 막고 있다는 신호 → 그대로 기록하고 다음 단계로. (없는 테스트를 억지로 만들지 않음)

완료 전 체크리스트 (Phase 6)

마지막 질문: "무엇이 이 버그를 막았을까?" 구조 문제면 아키텍처 개선으로 핸드오프 — 단 수정 후에(정보가 더 많아진 시점).

출처: mattpocock/skills — diagnose SKILL.md Phase 5~6

9 / 10 실제 진단 · 이번 세션

실제 케이스: div 균형이 77 / 95로 깨졌다 (+18)

이 스터디 카드 페이지에서 카드를 삭제하는 파이썬 스크립트를 돌린 뒤 HTML이 깨졌다. diagnose 6단계를 그대로 적용한 기록.

❌ 추측-수정이었다면

  • "닫는 태그가 많네" → 끝에서 </div> 18개 삭제
  • 어느 카드가 깨졌는지 모른 채 균형만 맞춤
  • 구조는 그대로 망가져 있음 (증상만 가림)

✅ /diagnose

  • ① 신호: grep -c로 1초 pass/fail
  • ② 재현: 77 open / 95 close 확인
  • ③ 가설: 검출기가 중첩 </div>에서 조기 종료
  • ④ 확정: 삭제 카드 수 × 잔여 1개 = +18 일치

① 1초짜리 pass/fail 신호 (Phase 1)

$ grep -c '<div'  week7-topic-candidates.html   77   # 여는 태그
$ grep -c '</div>' week7-topic-candidates.html   95   # 닫는 태그
# 95 - 77 = +18  → 닫는 태그가 18개 많다 (구조 깨짐)

③④ 가설과 확정

카드 삭제기가 <div class="card">부터 "첫 단독 </div>"까지를 한 카드로 봤다. 그런데 카드 안에는 중첩된 <div class="row">…</div>가 있어, 검출기가 그 첫 </div>에서 멈춰 카드를 일부만 지웠다 → 카드마다 트레일링 </div> 1개가 남는다.

77
<div> (여는 태그)
95
</div> (닫는 태그)
+18
초과 닫는 태그
18
삭제된 카드 수 × 잔여 1개
반증 가능한 예측이 그대로 맞았다: "카드당 정확히 </div> 1개씩 초과" → 삭제 카드 수와 초과분(+18)이 일치. 재현·확정 끝. 추측으로 끝에서 18개를 지웠다면 구조는 여전히 깨진 채 숫자만 맞았을 것.

출처: 이번 세션 실제 진단 (대상: week7-topic-candidates.html) · diagnose SKILL.md Phase 1~4

10 / 10 적용

정리 · 우리 팀에 적용

한 장 요약 (방법론)

코드를 노려보지 말고, 신호를 먼저 만들어라.

스터디 액션: 각자 최근 "AI한테 맡겼다 꼬인 버그" 하나를, diagnose 6단계로 다시 굴려보고 다음 모임에서 "어느 단계에서 막혔나" 공유.

출처: mattpocock/skills — diagnose SKILL.md 종합

감사합니다 🙏

질문 / 각자의 "꼬인 버그" 같이 굴려보기


참고 자료

1 / 11← / → 넘기기 · a: 스크롤 · n: 노트