-
하네스 엔지니어링 9단계 베스트 프랙티스 #8. 측정과 회고IT 2026. 4. 27. 22:20
시리즈 맥락 복기 — 마지막 편입니다
긴 여정의 마지막 편입니다. 여기까지 오면서 우리는 지도(#0), 규칙(#1), 지형도(#2), Skill(#3), Hook(#4), 자동 트리거(#5), HITL(#6), 감사 로그(#7)를 차례로 쌓아 올렸습니다. 이제 남은 건 "이 모든 것이 실제로 잘 작동하고 있는가"를 숫자로 검증하는 단계입니다.
- #0 업무 프로세스 매핑
- #1 프로젝트 규칙 설정
- #2 Code Wiki 작성
- #3 Skill 정의
- #4 검증(Hook)
- #5 자동 트리거 + 완료 조건
- #6 HITL 정책
- #7 감사 로그
- #8 측정 + 회고 ← 이번 편
이 단계의 의미 — Step 8은 하네스의 '계기판'
Step 8은 말에 채운 마구를 다 정비한 뒤, "지금 시속 몇 km로 달리고 있는가"를 보는 계기판입니다. 계기판 없이 달리면 속도 조절을 못 하고, 엔진이 과열되어도 모릅니다. 같은 이유로 자동화도 측정 지표 없이는 개선 방향을 못 정합니다.
해결하려는 문제
- "자동화 한 것 같은데 시간이 왜 안 줄지?": Before/After를 측정하지 않으면 개선 효과가 체감되지 않습니다.
- 좀비 상태 파일: 파이프라인이 도중에 죽으면 상태 파일이 남아서 다른 세션까지 영향을 줍니다.
- 세션 간섭: 터미널 두 개에서 동시에 에이전트를 돌릴 때 한쪽의 진행 상태가 다른 쪽을 막는 사고.
효과 — 측정이 바꾸는 것
측정이 되면 "이 파이프라인은 하루 평균 X번 돌고, 성공률은 Y%" 같은 문장을 쓸 수 있게 됩니다. 그러면 "다음에 어디를 개선할까"가 감이 아니라 숫자로 정해집니다. 개인 경험상 측정을 시작한 이후, 자동화 품질이 주관적 체감 → 객관적 지표로 바뀌면서 개선 속도가 눈에 띄게 빨라졌습니다.
베스트 프랙티스 1 — 파이프라인 상태 추적
각 Skill이 PostToolUse 훅에서 상태 파일을 업데이트합니다. 상태 파일은 파이프라인이 지금 몇 단계까지 진행됐는지를 기록하는 스냅샷입니다.
# calendar_sync.py — 단계 완료 추적 예시 def track_bash(cmd, data): if "calendar_sync.main sync" in cmd: state = { "step1_sync": True, "step2_voice": False, "step3_ai_organizer": False, "step5_git": False, "step6_notify": False, "claude_pid": find_claude_pid(), } save_state("calendar_sync", state) return True이 상태 파일 덕분에 두 가지가 가능해집니다.
- Stop 훅이 미완료 감지: "6단계 중 3단계에서 끊긴 파이프라인이 있다"고 경고.
- 측정 가능: "step5_git까지 간 비율"을 집계하면 각 단계의 실패율이 나옵니다.
베스트 프랙티스 2 — 세션 격리로 충돌 방지
터미널 A와 터미널 B에서 동시에 에이전트를 쓰면, 한쪽 세션의 상태 파일이 다른 쪽 세션의 종료를 차단하는 사고가 생깁니다. 이를 세션 격리로 해결합니다.
def find_claude_pid(): pid = os.getpid() while pid > 1: try: comm = Path(f"/proc/{pid}/comm").read_text().strip() if comm == "claude": return pid ppid = int(Path(f"/proc/{pid}/stat").read_text().split()[3]) pid = ppid except Exception: break return None def is_same_session(state): stored = state.get("claude_pid") current = find_claude_pid() if stored and current and stored != current: return False return True훅은 Claude Code의 자식 프로세스로 실행됩니다.
/proc트리를 거슬러 올라가 claude 프로세스의 PID를 찾아, 이를 세션 식별자로 사용합니다. 상태 파일에 기록된 PID와 지금 훅이 속한 세션의 PID가 다르면 "다른 세션의 상태"로 보고 무시합니다.베스트 프랙티스 3 — 2시간 TTL로 좀비 파일 정리
세션이 비정상 종료되면 상태 파일이 남습니다. 이를 방치하면 다음 세션의 판단을 흐립니다. 간단한 TTL 로직으로 해결합니다.
def is_stale(name): path = STATE_FILES[name] try: return time.time() - path.stat().st_mtime > STALE_SECONDS # 2시간 except Exception: return TrueStop 훅이 실행될 때마다 이 함수를 돌려, 2시간 이상 업데이트되지 않은 상태 파일을 삭제합니다. 사람이 청소할 필요가 없어집니다.
측정 지표 — 감사 로그로 계산하기
#7의 감사 로그 JSONL과 상태 파일을 조합하면, 이런 지표들을 바로 뽑을 수 있습니다.
지표 측정 방법 무엇을 알려주는가 파이프라인별 실행 횟수 jq '.pipeline' audit.jsonl | sort | uniq -c어느 Skill이 많이 쓰이는가 차단된 위험 명령 수 jq 'select(.tags[]=="blocked")' | wc -lHITL 정책이 얼마나 방어했는가 일일 작업량 날짜 필터 + count 에이전트 활용도 세션당 평균 명령 수 session별 그룹핑 count 세션당 작업 밀도 단계별 실패율 상태 파일의 step_N true 비율 파이프라인 병목 지점 테스트 통과율 pytest 결과 파싱 TDD 품질 지표 Before / After 비교 구조
그림에 나온 네 가지 지표(실행 횟수 · 차단 수 · 실패 단계 · 통과율)가 각각 Before/After 비교에 어떻게 쓰이는지 구체적 예시로 풀어보겠습니다.
① 실행 횟수 — "얼마나 자주 쓰이는 자동화인가"
Before: 일정 동기화를 손으로 할 때는 주 2~3회 정도 겨우 했습니다. 귀찮고 시간 드니까요. 이때의 "실행 횟수"는 사람 기억에 의존해야 하고, 기록도 없습니다.
After: 감사 로그에 파이프라인 실행 이벤트가 남으니
jq '.pipeline' audit.jsonl | sort | uniq -c한 줄로 지난 한 달 수치가 바로 나옵니다.147 calendar_sync 42 photo-enhance 8 vlm-analysis해석: 일정 동기화가 하루 평균 5회 — 즉 기존 주 2회에서 일 5회로 15배 증가했다는 결론이 숫자로 나옵니다. "자동화했더니 귀찮은 게 없어져서 더 자주 쓴다"는 체감이 실제 수치로 확인되는 순간이죠.
② 차단 수 — "HITL 정책이 얼마나 사고를 막아줬나"
Before: Deny 정책이 없으니 사고가 나면 사후에 복구해야 합니다. 복구 비용은 측정돼도, 예방된 사고는 측정 불가능했죠.
After: 감사 로그에서
tags: ["blocked"]인 이벤트를 집계합니다.jq 'select(.tags[]=="blocked")' audit.jsonl | wc -l # 결과: 7해석: 지난 달 7번의 위험 명령이 차단됐다는 뜻입니다. 차단된 명령 내용을 함께 확인하면 더 생생합니다.
jq -r 'select(.tags[]=="blocked") | .cmd' audit.jsonl # git reset --hard HEAD~3 # rm -rf ~/.cache/models # git push --force origin main # ...이 중 한두 건이라도 실제 실행됐다면 복구에 몇 시간 걸렸을 일입니다. 즉 차단 수는 "예방된 사고의 대리 지표"가 됩니다.
③ 실패 단계 — "파이프라인 어디서 자꾸 막히는가"
Before: 작업이 중간에 끊겼을 때 "몇 단계에서 주로 멈추는가"는 아예 측정 대상이 아니었습니다. 다시 수동으로 돌릴 뿐이었죠.
After: 상태 파일(
/tmp/.calendar_pipeline_state등)에 각 단계의 완료 여부가 남습니다. Stop 훅이 실행될 때 미완료 상태를 로그에 찍어두면, 한 달 치를 집계할 수 있습니다.단계 완료 횟수 미완료 횟수 step1_sync 147 0 step2_voice 145 2 step3_organizer 140 7 ← 여기! step5_git 139 8 step6_notify 139 8해석: step3(내용 정리)에서 자꾸 끊긴다는 사실이 숫자로 드러납니다. 이 단계가 병목이니, #3 Skill 정의 편으로 돌아가 이 Skill의 워크플로우를 재설계할 근거가 됩니다. "그냥 자꾸 안 되네"가 아니라 "step3 실패율 5%"가 개선 타깃이 됩니다.
④ 통과율 — "품질 게이트가 실제로 잘 작동하는가"
Before: 커밋을 푸시할 때 테스트를 돌렸는지, 린트는 봤는지 전부 기억에 의존했습니다. "대충 되는 것 같아서 올렸다"가 흔했죠.
After: #4 Hook이
pytest결과를 감지해 상태 파일에test_ran,test_passed를 기록합니다. 이걸 집계하면 통과율이 나옵니다.commit 시도 120회 test_ran=true 118회 (98%) test_passed=true 112회 (93%) → 6회는 테스트 실패로 commit 차단됨해석: TDD 규칙이 실제로 지켜지고 있다는 것이 숫자로 확인됩니다. 동시에 6건은 테스트 실패로 Hook이 잘 작동해 차단해준 것. Before 시절엔 이 6건이 그대로 푸시되어 CI에서 깨졌을 가능성이 있습니다. 통과율은 "내가 얼마나 규율 있게 일하는가"를 객관화한 지표이기도 합니다.
네 지표를 한 줄로 읽는 법
위 예시를 조합하면 한 달 치 회고를 이렇게 요약할 수 있습니다.
"이번 달 자동화 파이프라인은 총 197회 실행(실행 횟수). 위험 명령 7건이 HITL로 차단(차단 수). 일정 동기화 step3에서 7번 끊겼으니 해당 Skill을 손볼 것(실패 단계). 커밋 시 테스트 통과율 93%로 규율은 잘 유지됨(통과율)."
이 한 문단이 "Before/After 비교"의 실제 모습입니다. 감사 로그와 상태 파일이 없었다면 이 중 어느 것도 숫자로 말할 수 없었겠지만, 있으니 회고가 감이 아니라 근거 있는 개선 계획으로 바뀝니다.
회고 루프 — 측정값을 정책으로 환원하기
측정만 하고 끝나면 의미가 없습니다. 지표가 다음 주기의 정책 조정으로 이어져야 합니다.
- Ask가 잦다면 → 해당 패턴을 Allow로 승격 검토 (#6 HITL)
- 특정 단계 실패율이 높다면 → 해당 Skill의 워크플로우 재설계 (#3)
- 차단 이력이 0건이라면 → Deny 패턴이 과하게 넓은지 점검 (#6)
- 한 파이프라인이 거의 안 돈다면 → 트리거가 잘못됐는지, Skill description이 모호한지 재검토 (#5, #3)
자주 빠지는 실수
- 측정 지표는 많을수록 좋다는 착각: 지표가 10개를 넘으면 보지 않게 됩니다. 핵심 3~5개만 대시보드에 띄우세요.
- Before 측정을 건너뜀: 자동화 전에 걸리던 시간을 안 재두면 비교할 기준이 없어집니다. "30분" 같이 대략이라도 기록.
- 회고 없이 측정만: 측정값을 보고 나서 정책을 바꾸지 않으면 측정 자체가 의미를 잃습니다.
시리즈를 마무리하며
9단계 시리즈를 요약하면 다음 표 한 장에 담깁니다.
Step 핵심 한 줄 #0 프로세스 매핑 수동 구간을 "동사"로 표시하면 자동화 후보가 보인다 #1 프로젝트 규칙 계층형 CLAUDE.md — 전역 상속 + Constraint 명시 #2 Code Wiki 아키텍처 + 도메인 용어 + ADR로 "안 읽히는 것"만 문서화 #3 Skill 정의 트리거 + 번호 붙인 워크플로우 + 환경변수를 한 파일에 #4 검증(Hook) Dispatcher 패턴 · 10초 타임아웃 · exit(2)로 차단 #5 자동 트리거 cron·GitHub·메시지 + 기계적 완료 조건 #6 HITL 정책 위험도 = 비가역성 × 영향 범위 + 이중 방어 #7 감사 로그 JSONL + 자동 태깅 · 실패해도 작업 안 막음 #8 측정 + 회고 상태 추적 + 세션 격리 + 감사 로그 기반 정량 측정 한 줄 요약: "측정되지 않는 자동화는 개선되지 않는다. 9단계의 마지막은 계기판이다."
이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.
'IT' 카테고리의 다른 글
개인 프로젝트 12개에 보안 스캔 훅 달기 — pip-audit·bandit·gitleaks 3중 방어 (0) 2026.04.28 테스트 커버리지 11개 프로젝트에 도입하기 — baseline-lock + 외부 wrapper 제외 전략 (2) 2026.04.28 mypy로 파이썬 프로젝트 5개에 타입 에러 0 만들기 — 단계적 도입과 Hook 강제 (0) 2026.04.28 shellcheck로 bash 스크립트 정리하기 — 그리고 Hook으로 재발 방지까지 (0) 2026.04.28 ruff로 10개 프로젝트 린트 통과시키기 — 246 → 0, 그리고 실제 버그 2건 발견 (1) 2026.04.28 하네스 엔지니어링 9단계 베스트 프랙티스 #7. 감사 로그 (0) 2026.04.27 하네스 엔지니어링 9단계 베스트 프랙티스 #6. HITL 정책 (0) 2026.04.27 하네스 엔지니어링 9단계 베스트 프랙티스 #5. 자동 트리거와 완료 조건 (0) 2026.04.27 하네스 엔지니어링 9단계 베스트 프랙티스 #4. 검증 (Hook) (0) 2026.04.27 하네스 엔지니어링 9단계 베스트 프랙티스 #3. Skill 정의 (0) 2026.04.27