AI 스터디 · 7주차

AI가 추측하지 않게
— diagnose · Spec Kit, 두 도구의 구현을 깊게 뜯어본다

diagnose · Spec Kit — "쓰면 이렇게 됩니다"가 아니라 "이런 프롬프트·룰·코드라서 그 결과가 나옵니다"를 실제 소스로 확인

왜 이 묶음? (1~6주차와의 연결) 1주차 OT · 2주차 하네스 · 3주차 LLM Wiki · 4주차 OMC/Octopus · 5주차 superpowers · 6주차 Vectorless RAG. 이번 주는 도구를 얕게 나열하는 게 아니라, "AI의 추측을 줄이는 한 가지 원리"가 두 도구에 어떻게 구현됐는지 깊게 봅니다. 전부 Claude Code 구독 안에서(추가 과금 없이) 쓸 수 있는 것들.
시작하며

"이 버그 고쳐줘" → AI가 재현도 안 해보고 코드 세 군데를 바꾼다.
됐는지 물으면 "고친 것 같아요." …정말?

우리가 매일 겪는 장면. AI는 똑똑한데, 빈칸을 만나면 그럴듯하게 추측하고 밀어붙인다.

비유: 지도를 안 보고 "이쪽 같은데?" 하며 운전하는 내비게이션. 빠를 때도 있지만, 틀리면 끝까지 틀린 길로 간다.
오늘 볼 것: 잘 만든 AI 도구가 "추측이 들어갈 자리"를 어떻게 막는지 — 쓰는 법이 아니라 그 안의 구현을 뜯어본다. 끝나면 그 방법론을 본인 일에 옮길 수 있다.
지도

관통하는 한 가지: "추측 대신 구조·근거"

기본 상태의 AI는 빈칸을 만나면 그럴듯하게 추측한다. 두 도구는 추측이 들어갈 자리에 각기 다른 장치를 끼운다 — 같은 원리, 다른 구현.

도구어디의 추측을 막나무엇으로 대체
diagnose버그 원인 추측재현 피드백 루프 + 반증 가능한 가설
Spec Kit"무엇을 만들지" 추측코딩 전 명세 문서
오늘의 메타 교훈(마지막에 다시): "좋은 AI 도구 = 사람이 쓰던 방법론을 AI가 매번 따르도록 구조로 굳힌 것." 그래서 우리는 "도구를 쓴다"를 넘어 그 안의 방법론을 읽고 내 일에 옮길 수 있다.

각 도구를 같은 틀로 봅니다: 막는 추측 → 실제 구현 한 조각 → 왜 통하나 → 내 직군 적용.

━━━━━ ① diagnose — 체계적 디버깅 (실습 대상) ━━━━━
diagnose 1/3 diagnose · 구현 해부

구현 해부: SKILL.md가 "신호부터"를 강제하는 문구

🚫 막는 추측: "에러 보니 여기겠지" → 재현 없이 바로 수정

diagnose엔 코드가 거의 없다 — 구현체는 SKILL.md(프롬프트/룰). 그 텍스트가 어떻게 행동을 바꾸나. 실제 원문(skills/engineering/diagnose/SKILL.md):

# Phase 1 — Build a feedback loop  (원문 인용)
"**This is the skill.** Everything else is mechanical.
 ... no amount of staring at code will save you."
"Spend disproportionate effort here. Be aggressive.
 Be creative. Refuse to give up."
"Do not proceed to Phase 2 until you have a loop you believe in."

👉 이 코드 한 마디로: "믿을 만한 재현 루프가 없으면 다음 단계 금지."

비유: 의사가 진단 전에 처방하지 않는 것. 먼저 "열을 재는 체온계"(=재현 루프)부터 만들고, 그게 있어야 원인을 좁힌다.
왜 그 행동이 나오나: 단순 안내가 아니라 차단 규칙(gate)이라서다. 기본 AI의 추측-수정(①첫 가설 고착 ②다변수 변경 ③검증 없는 완료)을, "루프 먼저"라는 룰 한 줄로 막는다. skill = 잘 쓴 프롬프트 + 진행 게이트, 마법이 아니라 읽을 수 있는 룰.

출처: mattpocock/skills — skills/engineering/diagnose/SKILL.md (Phase 1 원문)

diagnose 2/3 diagnose · 구현 해부 (SKILL.md 원문)

6단계 규율 + "피드백 루프 만드는 10가지 수"

1 루프
2 재현
3 가설3~5
4 계측
5 수정+회귀
6 정리+사후

각 단계엔 관문이 있다(추측-수정엔 없는 "넘어가도 되나?" 체크). "재현 안 됨"은 끝이 아니라 시작 — diagnose는 10가지를 순서대로 시도하라 한다:

  1. 실패 테스트
  2. curl/HTTP 스크립트
  3. CLI + 스냅샷 diff
  4. 헤드리스 브라우저
  5. 트레이스 재생
  1. 버리는 하네스
  2. 퍼즈 루프
  3. 이분(git bisect run)
  4. 차분(구/신 출력 diff)
  5. HITL bash(최후)

직군 매핑: SRE=트레이스 재생·차분 · FE=헤드리스 브라우저 · BE=실패 테스트·bisect · Mobile=차분·HITL.

출처: diagnose SKILL.md — "6 Phases" + "10 ways to construct a feedback loop"

diagnose 3/3 diagnose · 구현 해부 (번들 스크립트)

구현 해부: 10번째 수단이 실제 .sh 파일이다

"사람이 클릭해야만 재현되는 버그"조차 구조화하려고, diagnose는 bash 템플릿을 번들로 넣어둔다(scripts/hitl-loop.template.sh). 실제 코드:

step() {    # 지시를 띄우고 Enter를 기다림
  printf '\n>>> %s\n' "$1"; read -r -p "[Enter when done] " _
}
capture() { # 질문을 띄우고 사람 답을 변수에 담음
  local var="$1" q="$2" a; printf '\n>>> %s\n' "$q"
  read -r -p "> " a; printf -v "$var" '%s' "$a"
}
step "http://localhost:3000 열고 로그인하세요."
capture ERRORED "'Export' 클릭 → 에러 났나요? (y/n)"
# 끝에 ERRORED=... 를 출력 → 에이전트가 파싱해 루프에 피드백

👉 이 코드 한 마디로: 사람의 클릭·확인을 read로 받아 변수에 담고, KEY=VALUE로 뱉어 에이전트가 읽게 한다.

비유: 자동화 못 하는 마지막 한 칸을 "사람에게 묻는 설문지"로 끼워 넣어, 그 답까지 루프 안으로 끌어들인다.
왜 그게 동작하나: 비결정적 인간 단계조차 구조화된 입력으로 바꿔 Phase 1 명제("신호를 만들어라")를 끝까지 관철 — "재현 불가능한 버그"의 핑계를 없앤다.

나머지 단계도 같은 결: 가설 3~5개(반증 예측) · 한 변수씩 계측 + [DEBUG-a4f2] 태그 · 회귀는 올바른 seam에만("seam 없음=발견"). 전부 SKILL.md에 글로 박힌 룰.

🧪 실습 diagnose · 실습 (이 발표의 유일한 시연 · 실제 사례)

🧪 실제로 난 버그를 /diagnose로 잡은 과정

이 발표 자료 만들다 진짜 난 버그. 디버깅은 전 직군 매일 작업이라 실습 대상으로 골랐다. 가짜 데모가 아니라 이 세션에서 실제로 일어난 일.

상황 — 카드 삭제 스크립트가 HTML을 깨뜨림

week7-topic-candidates.html에서 카드를 지우는 파이썬 스크립트를 돌렸다. 로직: "<div class="card">부터 첫 단독 </div>까지를 한 카드로 보고 삭제." 돌린 뒤 페이지 레이아웃이 깨졌다.

77
<div> 여는 태그
95
</div> 닫는 태그
+18
닫는 태그 초과
단계❌ 추측-수정이었다면✅ 실제로 한 것 (/diagnose)
P1·2
신호·재현
"닫는 태그 18개 지우면 되겠지" → 원인 모른 채 균형만 맞춰 더 꼬임 원인 추측 전에 1초 pass/fail 신호부터:
grep -c '<div' / grep -c '</div>'. 첫 fixture가 증상과 안 맞자 즉시 "이건 그 버그가 아니다"라고 루프를 교정.
P3
가설
가설 1개에 앵커링 반증 가능한 가설: "detector가 카드 안에 중첩된 <div class="row">…</div>의 첫 </div>에서 멈춰 카드를 일부만 지운다. → 트레일링 </div> + .note가 남는다."
확정 "고친 듯" (검증 X) 예측 검산: 지운 카드 수 × (카드당 잔여 </div> 1개) = +18. 관측된 초과와 정확히 일치 → 재현·확정.
왜 detector가 틀렸나(근본 원인): "첫 단독 </div>까지"라는 규칙이 중첩 구조를 모른다. 카드 안 .row가 먼저 닫히면 거기서 멈춰, 카드의 진짜 끝(.note 포함)을 못 지운다. 카드당 </div> 1개씩 살아남아 18개 카드 → +18.
한 줄 교훈: "닫는 태그 18개 지우기"(증상 땜질)로 시작했으면 영영 못 잡았다. 재현 신호부터 만든 덕에 진짜 원인(중첩 미인식)에 도달.

출처: 실제 진단 대상 ~/Desktop/study/week7-topic-candidates.html · 방법론 diagnose SKILL.md — Phase 1

━━━━━ ② Spec Kit — 명세 우선 ━━━━━
Spec Kit 1/2 Spec Kit · 원리

구현 해부: /speckit-specify는 사실 "마크다운 프롬프트"

🚫 막는 추측: "대충 말하면 알아서 만들겠지" → AI가 요구사항을 멋대로 채움

"명세→코드"가 마법 같지만, 커맨드 정의(templates/commands/specify.md)를 열면 그냥 구조화된 프롬프트 파일이다:

# 설치본: .claude/skills/speckit-specify/SKILL.md (실측)
---
name: "speckit-specify"
description: "Create or update the feature specification..."
metadata:
  source: "templates/commands/specify.md"   # ← 빌드 원본
user-invocable: true
---
## User Input
```text
$ARGUMENTS              # ← 사용자가 친 기능 설명이 여기로
```
## Pre-Execution Checks  # extensions.yml 훅 검사 → Outline → ...

👉 핵심: $ARGUMENTS로 내 말을 받아 정해진 지시문에 끼우고, Pre-Execution Checks로 훅을 검사한 뒤 단계를 진행한다.

비유: 빈칸 있는 관공서 서식. 내가 자유롭게 말해도 정해진 칸(요구사항·수용기준)에 옮겨 적게 만들어, 빠뜨림을 막는다.
청강자가 못 뜯어볼 것: 슬래시 커맨드 = frontmatter + $ARGUMENTS 치환 + 단계별 지시문. "방법론"이 아니라 프롬프트 엔지니어링을 파일로 굳힌 것 — 그래서 누구 환경에서나 같은 절차가 재현된다.

출처: github/spec-kit — templates/commands/specify.md · 설치본 .claude/skills/speckit-specify/SKILL.md (직접 설치 실측)

Spec Kit 2/2 Spec Kit · 깊이 + 한계

무엇(spec)과 어떻게(plan)를 분리하는 이유

specify는 요구사항·유저스토리·엣지케이스(무엇)만, plan은 스택·데이터모델·API 계약(어떻게)만. 섞으면 AI가 "어떻게"를 추측하며 "무엇"을 흐린다.

잘 쓴 스펙

  • 유저스토리 + 수용 기준
  • 경계 조건 명시(비로그인·중복 등)
  • 한 기능 = 한 spec(작게)

못 쓴 스펙

  • "X 만들어줘"(한 줄)
  • 수용 기준 없음 → 추측
  • 기술 결정을 spec에 섞음
한계: 스펙 품질 = 결과 품질. "방법론 한 겹"이 있어 추상적으로 느껴질 수 있음 → 검토를 없애는 게 아니라 검토 지점을 명확히 하는 것. 설치(검증): uv tool install specify-cli ... · 한국어 자료 풍부.

출처: github/spec-kit · GitHub Blog — Spec-driven development with AI

실습 · 설치+사용 설치 & 실제 사용 흐름 (오늘 따라 할 수 있게)

설치 & 한 번에 보는 사용 흐름

diagnose — 설치 1줄, 호출 1줄

npx skills@latest add mattpocock/skills   # 130k★·MIT, 구독 안에서 무료
# → .claude/skills/ 에 diagnose 등 스킬 설치됨. 추가 API 키·과금 없음
실제 사용: 버그를 만나면 평소 프롬프트 앞에 /diagnose 만 붙인다 → 에이전트가 "원인 추측"이 아니라 ① 재현 신호(피드백 루프) → ② 가설 3~5개 → ③ 한 변수씩 검증 순서로 강제 진행. 끝나면 디버그 로그 정리·후속 점검까지.

Spec Kit — CLI 설치 후 슬래시 커맨드로

uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z
specify init my-project --integration claude   # 현재 docs는 --integration (구 --ai)
# 현재 폴더에 바로:  specify init .   또는   specify init --here
실제 사용(에이전트 대화창에서 슬래시로):
/speckit.constitution원칙
/speckit.specify무엇(요구사항)
/speckit.clarify모호점 확인
(plan 전 권장)
/speckit.plan어떻게(설계)
/speckit.tasks작업 분해
/speckit.implement구현
선택/speckit.analyze
/speckit.checklist
현행 커맨드는 5개를 넘는다 — /speckit.clarify(plan 전 모호점 제거 권장)·/speckit.analyze(아티팩트 정합성)·/speckit.checklist("영어로 쓴 단위 테스트")·/speckit.taskstoissues(작업→GitHub 이슈)가 추가됐다.

출처: mattpocock/skills · github/spec-kit (설치·슬래시 커맨드 현행 docs, 2026-06 확인)

━━━━━ 종합 ━━━━━
종합 메타 교훈

두 도구가 가르치는 한 가지

도구인코딩한 사람의 방법론무료 경로
diagnose체계적 디버깅(재현 루프 우선)skill (구독 내)
Spec Kit명세 우선 개발CLI(자체)·에이전트 연동

좋은 AI 도구는 마법이 아니다.
사람의 방법론을, AI가 매번 따르도록 구조로 굳힌 것이다.

그래서 우리는 도구를 쓰는 데 그치지 않고, 그 안의 방법론을 읽어서 내 일·사이드 프로젝트에 옮길 수 있다 — 오늘 두 도구를 뜯어본 이유.
📌 이번 주에 해볼 것 (딱 하나): 다음에 버그를 만나면 프롬프트 앞에 /diagnose 한 번 붙여보기. "왜 안 고치고 재현부터 하지?" 하는 순간이 오면 — 오늘 발표가 몸으로 이해된 것. 다음 모임에서 그 경험 공유.

감사합니다 🙏

질문 / 각자의 "추측이 만든 사고" 공유


참고 자료

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