diff --git a/docs/html/harness/claude-code-harness-evaluator.html b/docs/html/harness/claude-code-harness-evaluator.html
index dc929fd..2c8ab35 100644
--- a/docs/html/harness/claude-code-harness-evaluator.html
+++ b/docs/html/harness/claude-code-harness-evaluator.html
@@ -1442,9 +1442,9 @@
[data-template="harness"] {
- --bg: #faf9f5;
+ --bg: #f8f8f2;
--surface: #ffffff;
- --border: #e7e5dc;
+ --border: #d8dae5;
--text: #1a1a18;
--muted: #57564f;
--faint: #64748b;
@@ -1454,11 +1454,9 @@
--success: #1d8a45;
--warning: #b26214;
-
--sx-key: #c7226e; --sx-str: #946f00; --sx-num: #003748; --sx-fn: #1d8a45;
--sx-type: #0e7490; --sx-com: #64748b; --sx-var: #1a1a18; --sx-param: #b26214;
-
--fs-hero: 44px;
--fs-h2: 30px;
--fs-h3: 22px;
@@ -1466,14 +1464,14 @@
--fs-sub: 18px;
--fs-code: 16px;
- --font-sans: "Noto Sans KR", "IBM Plex Sans KR", sans-serif;
+ --font-sans: "IBM Plex Sans KR", "IBM Plex Sans", "Noto Sans KR", sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}[data-template="harness"].slide[data-variant="dark"] {
- --bg: #0f172a;
- --surface: #1e293b;
- --border: #334155;
+ --bg: #282a36;
+ --surface: #44475a;
+ --border: #44475a;
--text: #e2e8f0;
- --muted: #94a3b8;
+ --muted: #94a3b8;
--faint: #64748b;
--accent: #4db6c9;
--accent-ink:#0f172a;
@@ -1567,6 +1565,20 @@
margin:0 52px; padding:8px 0 12px; letter-spacing:.02em; }[data-template="harness"] .slide-footer-left { font-family:var(--font-sans); font-size:var(--fs-sub); font-weight:600; color:var(--text); }[data-template="harness"] .slide-footer-right { font-family:var(--font-mono); font-size:var(--fs-sub); color:var(--muted); }[data-template="harness"] .slide-inner.closing .kicker { margin-bottom:12px; }[data-template="harness"] .slide-inner.closing .hero { font-size:36px; line-height:1.15; }[data-template="harness"] .slide-inner.closing .col-text .sub { line-height:1.42; margin-top:9px !important; }[data-template="harness"] .slide-inner.closing .col-text .list { gap:7px; margin-top:10px !important; }[data-template="harness"] .slide-inner.closing .col-text .list.tight > li { line-height:1.4; }
+/* ── v4.1: table-color.svg 기준 표 스타일 (사용자 지정 — 에디터/Export 공통) ── */
+[data-template="harness"] thead th{
+ background:#2F4858; color:#ffffff; font-weight:600; border-bottom:none; padding:11px 14px; letter-spacing:.01em;
+}
+[data-template="harness"] tbody td{
+ color:#191917; border-bottom:1px solid #8E8776; padding:11px 14px; background:transparent;
+}
+[data-template="harness"] tbody tr:nth-child(even) td{ background:#F2ECDC; }
+[data-template="harness"] tbody tr:last-child td{ border-bottom:1px solid #8E8776; }
+[data-template="harness"] td .k, [data-template="harness"] td.k{ font-weight:600; color:#191917; }
+[data-template="harness"] td .mono, [data-template="harness"] td.mono{ color:#5E5850; }
+[data-template="harness"] td .sub{ color:#56564E; }
+
+
/* Page surround follows the deck theme. Set the surface on `html` (not
`body`) because brewnet-dark's editor-iframe block force-styles `body`
with !important; `html` carries data-template so var(--bg)/var(--text)
@@ -2416,7 +2428,7 @@
Effective Claude Code · 이론편
COVER
-
+
@@ -3211,7 +3223,7 @@
🔗
GitHub
- github.com/claude-code-expert/lecture
https://run-ai.kr/learn/terminal - 초보자를 위한 터미널 기초
https://run-ai.kr/learn/github - 초보자를 위한 Github 기초
+ https://github.com/claude-code-expert/inflearn-docs
01 · 정의
-research·plan·execute·review·ship이 하나의 “설명”으로 뭉개진다 — 게이트 0개. 여기서 하네스(harness, 모델을 감싸 제어하는 실행 환경)가 하는 일은 그 게이트를 되살리는 것이다.
-01 · 용어
+| 용어 (풀 네이밍) | 쉬운 설명 |
|---|---|
| 에이전트 (Agent) | 챗봇과 달리 스스로 파일을 읽고 명령을 실행하며 여러 단계를 처리하는 AI |
| 하네스 (Harness) | 원뜻은 말(馬)의 마구(고삐·안장). AI를 감싸 규칙·도구·검증을 강제하는 실행 환경 |
| 게이트 (Gate) | 다음 단계로 가기 전 반드시 통과해야 하는 검문소 — 예: 리뷰, 테스트 |
| 컨텍스트 윈도우 (Context Window) | AI가 한 번에 기억하는 작업 기억의 크기 — 차면 규칙을 잊는다 |
| 루프 (Loop) | 실행 → 결과 확인 → 다시 실행을 도는 반복 구조 — 남는 게 없으면 ‘반응적 루프’, 실패가 쌓이면 ‘복리 루프’ |
| 프롬프트·컨텍스트·하네스 엔지니어링 | 질문 다듬기 → 알아야 할 정보 챙겨 주기 → 실행 환경 설계하기 — 순서대로 발전해 온 3단계 기술 |
| RAG · MCP | 필요한 자료를 검색해 붙여 주는 기술(RAG)과 AI를 외부 도구에 연결하는 표준 규격(MCP |
01 · 패러다임
-각 단계는 이전을 포함하며 확장한다 — 단일 입력 최적화(프롬프트) ⊂ 정보 환경 구성(컨텍스트) ⊂ 런타임 환경 설계(하네스).
+01 · 정의
+01 · 구조적 실패
-| 문제 | 프롬프트 / 컨텍스트로는 (지시) | 하네스로는 (구조) |
|---|---|---|
| 자기 평가 편향 | “비판적으로 리뷰하라” → 자기 코드를 칭찬 | Generator와 Evaluator를 물리적으로 분리 |
| 컨텍스트 불안 | 컴팩션(compaction, 컨텍스트 압축)해도 “마무리해야 한다”는 충동 | 컨텍스트 리셋 + 파일 핸드오프(handoff, 상태 인계) |
| 규칙 망각 | CLAUDE.md에 써도 47번째에서 잊힘 | Hook / 린터로 자동 감지 |
| 아키텍처 침범 | “이 레이어만 수정하라” → 편의상 위반 | allowed_tools로 도구 레벨 접근 차단 |
| 무한 루프 | “5번 이상 시도 금지” → 무시 가능 | max_iterations로 하드 리밋 강제 |
| 상태 유실 | 세션 전환 시 이전 맥락 소실 | 파일 기반 핸드오프로 상태 영속화 |
왼쪽 열은 전부 “지시”, 오른쪽 열은 전부 “구조”다. 지시는 확률적으로 지켜지고 구조는 물리적으로 강제된다. · 출처: 사내 발표자료(Noah, 2026.04)
+01 · 패러다임
+01 · 단일 제약
-“대부분의 모범 사례는 ‘컨텍스트 윈도우는 빨리 차고, 차면 성능이 저하된다’는 단일 제약에서 나온다.” — Claude Code 공식 Best Practices
-프롬프트는 “요청”이고, 하네스는 “강제”다.
-01 · 구조적 실패
+| 문제 | 말로 시키면 (지시) | 하네스로 만들면 (구조) |
|---|---|---|
| 자기 코드 자기 검사 | “비판적으로 리뷰해” → 결국 자기 칭찬 | 만드는 AI와 검사하는 AI를 분리 |
| 긴 대화의 조급증 | 대화가 길어지면 서둘러 마무리하려 함 | 컨텍스트 초기화 + 파일로 상태 인계 |
| 규칙 망각 | CLAUDE.md에 적어도 한참 지나면 잊음 | 훅(Hook)·린터가 자동으로 잡아냄 |
| 건드리면 안 될 코드 수정 | “여기만 고쳐” → 편하다고 다른 곳도 수정 | 도구 권한으로 접근 자체를 차단 |
| 무한 반복 | “5번까지만 시도해” → 무시하기도 함 | 반복 횟수 상한을 하드 리밋으로 강제 |
| 기억 유실 | 새 세션이 되면 이전 맥락이 사라짐 | 파일에 남겨 다음 세션이 이어받게 함 |
01 · 대가
-리스크의 본질은 “코드가 틀린다”가 아니라 — 틀렸는지 아닌지를 팀이 모른다는 데 있다. Eval·게이트 없는 팀에서 목격되는 3가지:
-01 · 단일 제약
+01 · 타이밍
-→ 그래서 필요한 것이 “모델을 감싸는 시스템” — 하네스다. (2장에서 계속)
-01 · 대가
+01 · 타이밍
+에이전트 = 모델 + 하네스 — 컨텍스트·툴·가드레일이 구조와 행동을 바꾼다는 실증
+에이전트 = 모델 + 하네스 — 같은 모델이라도, 감싸는 환경이 결과를 바꾼다
02 · 정의
-하네스는 모델을 제외한 모든 것이다 — 엔진이 아니라 차 전체를 만드는 일. 이 자동차 비유가 발표 전체를 관통한다.
-“The model is the agent. The code is the harness.” — OpenHarness
-02 · 용어
+| 용어 (풀 네이밍) | 쉬운 설명 |
|---|---|
| Agent Loop (에이전트 루프) | 생각 → 도구 사용 → 결과 확인을 작업이 끝날 때까지 반복하는 순환 구조 |
| CLAUDE.md | 프로젝트 폴더의 규칙 메모장 — 매 세션 시작 때 AI가 자동으로 읽는다 |
| 훅 (Hook) | 도구 실행 전후에 자동으로 끼어드는 검사 스크립트 — 위반이면 실행 자체를 차단 |
| 권한 모드 (Permission Mode) | AI가 허락 없이 할 수 있는 범위 설정 — Plan / Default / Accept Edits / Bypass |
| exit 2 (종료 코드 2) | 프로그램이 끝나며 남기는 결과 번호(0=성공). 훅이 2를 반환하면 Claude Code가 그 동작을 차단한다 |
| A/B 테스트 (A/B Test) | 조건 하나만 다르게 두 집단을 비교하는 실험 — 여기선 ‘하네스 유무’ |
02 · 코드로 증명된 정의
-Harness = Tools + Knowledge + Observation + Action + Permissions
+02 · 정의
+02 · 심장
-while True: - response = await api.stream(messages, tools) - if response.stop_reason != "tool_use": - break # 모델이 작업 완료 - for call in response.tool_uses: - # 권한검사 → PreToolUse 훅 → 실행 → PostToolUse 훅 - result = await harness.execute_tool(call) - messages.append(tool_results)-
도구 실행 한 번에 권한 검사 → PreToolUse 훅 → 실행 → PostToolUse 훅 파이프라인이 끼어든다. 이 지점이 프로젝트 제약과 검증 훅이 주입되는 자리.
-02 · 구성요소
+02 · 3기둥
-가장 효과적인 하네스: 자동 검증 → 독립 리뷰어 → 인간 체크포인트의 계층 조합.
-02 · 심장
+02 · 세 기둥
+02 · 해부
-| 기둥 | 서브시스템 | 역할 |
|---|---|---|
| 제약 | permissions/ · hooks/ | 멀티레벨 권한 모드, 경로 규칙, 커맨드 차단, PreToolUse 차단 훅(exit 2 = 비정상 종료로 도구 호출 차단) |
| 피드백 | skills/ · coordinator/ · tools/ | 스킬 로딩, 서브에이전트 검증·조율, 결과 관찰 |
| 상태 | memory/ · tasks/ · prompts/ · config/ | MEMORY.md 크로스세션, 백그라운드 태스크, 컨텍스트 압축 |
| 코어 | engine/ · tools/ | Agent Loop, 43개 도구(Pydantic 입력 검증 — 파이썬 데이터 검증 라이브러리) |
권한 3모드: Default 쓰기·실행 전 확인 Auto 전부 허용(샌드박스) Plan Mode 모든 쓰기 차단
-주의: 3기둥 매핑은 강의 프레임에 따른 해석이며 OpenHarness 공식 분류가 아님. · 출처: openharness-analysis.html
+02 · 제약 실전
+02 · 실증 A/B
-A/B 테스트(대조 실험): 동일 opencode 1.17.15 + qwen3.6:35b(ollama · 로컬 모델 실행 런타임)에, 하네스 유무만 다르게 두고 위반 유도 명령 7종(S0–S6)을 주입.
-→ 다음 페이지: S0–S6 전체 결과 매트릭스 (CONTROL vs HARNESS). 출처: harnessreport.pdf (2026-07-08).
+02 · 실증 결과
+02 · 실증 해석
-한계 고지: 실시간 차단 훅은 Claude Code 전용. opencode에선 AGENTS.md(소프트)+pre-commit(하드) 2계층만.
+Claude Code를 통제 가능한 워크플로우로 — 성숙도 사다리 Lv.0→5를 오르며 부품을 조립한다
+Claude Code를 통제 가능한 워크플로우로 — 5분 투자부터 시작해, 통제 장치를 한 단씩 더한다
03 · 로드맵
-| 레벨 | 무엇 · 시간 | 효과 |
|---|---|---|
| Lv.0 | 프롬프트만 · 0분 | 기본 |
| Lv.1 | CLAUDE.md · 5분 | 반복 실수 30%↓ |
| Lv.2 | 역할 분리 · 30분 | 자기 평가 편향 제거 |
| Lv.3 | Hook 자동 검증 · 1시간 | 규칙 망각 해결 |
| Lv.4 | 파일 핸드오프 · 2시간 | 대규모 작업 가능 |
| Lv.5 | 실패 패턴 축적 · 지속 | 하네스 자체가 진화 |
본질은 레벨이 아니라 습관 — “이번만 고치기”가 아니라 시스템에 규칙을 추가하기.
-03 · 용어
+| 용어 (풀 네이밍) | 쉬운 설명 |
|---|---|
| 성숙도 모델 (Maturity Model) | 한 번에 완성이 아니라 Lv.0→5 계단으로 올라가는 도입 로드맵 |
| 커맨드 (Command) | 사람이 /이름 으로 직접 부르는 저장된 프롬프트 — 예: /commit |
| 스킬 (Skill) | 상황이 맞으면 AI가 스스로 꺼내 읽는 절차서 파일 (SKILL.md) |
| 서브에이전트 (Subagent) | 별도 기억 공간에서 일하는 보조 AI — 격리 실행·독립 검증에 쓴다 |
| PLAN.md | 구현 전에 체크박스로 쓰는 계획서 — 리뷰가 이 문장 그대로 결과와 대조한다 |
| 핸드오프 (Handoff) | 세션을 끝내기 전 진행 상황을 파일로 남겨 다음 세션이 이어받게 하는 인수인계 |
| 토큰 (Token) | AI가 글을 읽고 쓰는 최소 단위(대략 글자 몇 개) — 사용량과 요금이 토큰 수로 계산된다 |
03 · 로드맵
+03 · 부품 · CLAUDE.md
-# 절대 금지 (도메인 제약 예) -- @Transactional 내부 외부 API 호출 금지 -- Redis 분산락을 트랜잭션 경계 안에서 금지 +# 절대 금지 +- 결제 모듈은 수정 전에 반드시 물어본다 +- .env 등 비밀 파일은 읽지 않는다 -# 구조적 규칙 -- domain은 infrastructure import 불가 -- 응답 DTO(Data Transfer Object, - 계층 간 전송 객체)와 Entity 직접 매핑 금지 +# 구조 규칙 +- API 응답 형식은 docs/api.md를 따른다 +- 새 라이브러리 추가 전, 기존 것 재사용 확인 # 완료의 정의 - 새 코드에는 테스트가 있다. 테스트 녹색. -- 스키마 변경 시 마이그레이션 포함.-좋은 예: 짧게, 안정적인 것만.
+- 변경 사항을 문서에 반영한다
03 · 부품 · CLAUDE.md 심화
-| 넣는다 (안정적 규칙) | 뺀다 → 어디로 |
|---|
| 넣는다 — CLAUDE.md에 | 뺀다 — 더 좋은 자리로 |
|---|---|
| 빌드·테스트·실행 명령어 (pnpm test) | 스타일 가이드 전문 → 린터/포매터 + 훅이 강제 |
| 코드 컨벤션 핵심 몇 줄 (“ESM 사용, CJS 금지”) | 조건부로만 필요한 긴 지식 → 스킬의 점진적 공개 |
| “완료의 정의(definition of done)” | 반드시 강제될 것 → settings.json·훅 (설정 1줄이 “NEVER” 문장보다 결정적) |
| 절대 건드리면 안 되는 경로 (마이그레이션·시크릿) | 자주 바뀌는 임시 컨텍스트 → 세션 프롬프트로 |
| — | 경로 종속 규칙 → .claude/rules/*.md + paths glob (지연 로드) |
| 빌드·테스트 명령어 (npm test) | 긴 스타일 가이드 → 린터·포매터가 자동 강제 |
| 컨벤션 핵심 몇 줄 | 가끔만 필요한 긴 지식 → 스킬 (필요할 때만 로드) |
| 완료의 정의 (“테스트 녹색이면 끝”) | 반드시 강제할 것 → 설정·훅 (설정 1줄이 “절대 금지” 문장보다 세다) |
| 건드리면 안 되는 경로 | 오늘만 필요한 맥락 → 그냥 대화로 |
| — | 특정 폴더 전용 규칙 → 규칙 파일 분리 (.claude/rules/) |
운영 원칙: 같은 실수 2회 = 규칙 후보. 조건부 지식과 강제 규칙은 CLAUDE.md가 아닌 다른 계층으로 뺀다.
+03 · 부품 · 권한 모델
-03 · 부품 · 권한
+판별 질문 2개
Q1. 어겨지면 곤란한가, 아쉬운가? — 아쉬우면 CLAUDE.md, 곤란하면 Q2
Q2. 설정으로 표현 가능한가? — 가능하면 settings.json, 불가능하면 훅
어디에 적을지, 질문 2개
Q1. 어겨지면 곤란한가, 아쉬운가? — 아쉬우면 CLAUDE.md로 충분
Q2. 곤란하다면, 설정으로 표현되나? — 되면 settings.json, 안 되면 훅
// .claude/settings.json — 레포에 체크인해 팀 공유 +// .claude/settings.json { "permissions": { "allow": [ - "Bash(pnpm test:*)", + "Bash(npm test:*)", "Read(src/**)" ], "ask": [ "Bash(git push:*)" ], @@ -4065,102 +3872,102 @@-권한 모델 — 명시적 경계가 생산 "Bash(rm -rf *)" ] } }
부탁이 아닌 규칙으로 경계를 긋는다.
03 · 부품 · 커맨드와 스킬
-스킬 설계 4원칙: ① description은 요약이 아니라 트리거(“언제 발동”) ② 당연한 건 쓰지 않는다 ③ 레일 말고 목표·제약을 ④ Gotchas(실패 이력)가 최고 신호
+스킬 잘 쓰는 4원칙
① description엔 “언제 발동”을 쓴다 ② 당연한 건 안 쓴다
③ 절차를 강요 말고 목표·제약을 ④ 실패 이력(Gotchas)이 최고의 내용
# .claude/skills/db-migration/SKILL.md --- name: db-migration -description: 스키마 변경·prisma/migrate 실행 - 시 발동. 새 마이그레이션은 추가만, +description: DB 스키마 변경·마이그레이션 + 요청 시 발동. 새 마이그레이션은 추가만, 기존 파일 수정 금지. --- ## 절차 -1. 변경을 새 V{n}__.sql 로 생성 -2. 기존 V*.sql 은 절대 수정 금지 (체크섬) +1. 변경은 새 V{n}__.sql 로 생성 +2. 기존 V*.sql 은 절대 수정 금지 3. 적용 전 롤백 스크립트 동반-
지식 총량은 늘리고 상시 비용은 0 (지연 로드).
03 · 핵심 원리
-판별 질문 하나: “어기면 곤란한가?” → 예 = 훅/설정, 아니오 = CLAUDE.md/스킬
-03 · 핵심 원리
+03 · 부품 · 훅
-03 · 부품 · 역할 분리
-완료 판정 = 단언이 아니라 증거 (테스트 출력·명령 반환값·스크린샷).
-03 · 부품 · 역할 분리
+03 · 조립
-| 단계 | 통과 조건 |
|---|---|
| research | 메인 컨텍스트가 원자료로 오염되지 않았는가 |
| plan | 사람 승인 · 검증 가능한 문장인가 |
| execute | 훅 전부 녹색 |
| review | 정확성 갭 0건 (취향 지적은 게이트 아님) |
| ship | 사람이 증거 확인 — 단언만으론 통과 불가 |
가장 강한 근거 = 독립 재발명의 수렴 (Superpowers·BMAD·OpenSpec·Spec Kit이 같은 답).
-03 · 조립
+03 · 검증 가능한 계획
-복선: 이 1회용 대조표가 4장에서 영구 재사용되는 골든셋으로 승격된다.
## 목표 @@ -4277,150 +4075,148 @@PLAN.md — 모호한 계획은 모호한 - 인증 로직, 로깅 포맷, 미들웨어 순서
03 · 실물 케이스 1
-| 계층 | 위치 · 트리거 | 성격 |
|---|
| 계층 | 위치 | 하는 일 |
|---|---|---|
| 강제 훅 (8개 활성) | .claude/hooks/ + settings.json | 툴 호출/프롬프트 자동 · 결정적 (차단은 exit 2) |
| Squad 에이전트 (9종) | .claude/agents/ · /squad | 단일 책임 위임 |
| 워크플로 스킬 | .claude/skills/ · /carve-* | 절차 자동화 (자연어 또는 커맨드) |
| 계약·규칙 문서 | 루트 *.md (flight-rules · 운영 규칙 문서) | 에이전트·훅이 참조 · 단일 진실 출처 |
| 강제 훅 (8개) | .claude/hooks/ | 위험 명령·비밀 파일을 자동 차단 — 어길 수 없음 (exit 2) |
| 전문 에이전트 (9종) | .claude/agents/ · /squad | 리뷰·QA·보안 등 역할별로 분리해 위임 |
| 워크플로 스킬 | .claude/skills/ | 커밋·핸드오프 같은 반복 절차를 말 한마디로 |
| 규칙 문서 | 루트 *.md | 훅과 에이전트가 참조하는 기준 문서 |
대표 훅: block-destructive(포크밤·rm -rf 차단) · protect-secrets(.env·키 차단) · pre-push-test(테스트 실패 시 push 차단) · anti-slop(시각 산출물 검사) · precompact-handoff(압축 전 상태 인계). 슬림화 결정: 11→8 훅.
+03 · 실물 케이스 2
-| 묶음 | 무엇 | 핵심 자산 |
|---|
| 순서 | 무엇을 | 왜 |
|---|---|---|
| ① 에이전트 정의 | back/front/gateway 역할 분리 | AGENTS.md 계층 (폴더별) |
| ② 스킬 | 세션 인계·결정 기록 | handoff · changelog(decision-ledger) |
| ③ 훅 | 포맷·린트·머지금지·커밋룰 | hooks.json + commitlint (exit 2) |
| ④ 서브에이전트 | 타입·예외·시크릿·인증 검증 | security-reviewer · evaluator |
| ⑤ 룰/가드레일 | 검증 가능한 규칙 md | rules/ (common·java·react·ts) |
| ⑥⑦⑧ | 토큰 관리 · SDD 킷 · 게이트웨이 검증 | codesight+LSP · GSD · e2e |
| ① | 규칙 문서 (CLAUDE.md · rules/) | 팀 규칙을 파일로 — 모든 세션에 자동 적용 |
| ② | 훅 — 포맷·린트·커밋 검사 | “반드시”를 자동 강제 (exit 2 차단) |
| ③ | 스킬 — 세션 인계·결정 기록 | 반복 절차를 말 한마디로 |
| ④ | 검증 에이전트 — 보안·타입 검사 | 만든 쪽과 검사하는 쪽 분리 |
| ⑤ | 역할 분리 — 백/프론트 폴더별 정의 | 영역 밖 코드를 건드리지 않게 |
| ⑥ | 그 다음에야 — 컨텍스트 절약·명세 킷 등 | 기본기가 자리 잡은 뒤의 고급 부품 |
3기둥 위에 토큰 관리·SDD(명세 주도 개발)·게이트웨이 검증을 얹어 완성 — 한 번에 다 하지 말 것. (GSD = Get Shit Done, SDD 킷 · LSP = Language Server Protocol · e2e = 종단간 테스트)
+03 · 토큰 매니지먼트
-| 도구 | 줄이는 대상 | 광고 절감 | 비고 |
|---|---|---|---|
| headroom | API 페이로드(grep·diff)를 프록시에서 압축 | 47~92% (중앙값 54%) | RTK(동반 압축 툴킷) 번들 포함 |
| caveman | Claude 자체 출력을 전보문처럼 축약(telegraphic) | 50~75% | /caveman lite|full|ultra |
| LSP | 코드 탐색을 심볼 좌표로 축소 (LSP = Language Server Protocol, 언어 서버 프로토콜) | 정의 43× · 참조 2.1× | 중대형·리팩토링용 |
| codesight | 세션 시작 구조 파악을 압축 맵 1개로 | 세션당 6.8× | LSP와 상호보완 |
실측 경고: 독립 실측(614M 토큰)에서 headroom+rtk+caveman 합산 실효 절감은 약 3.7% — 비용 대부분이 cache_create·output이라 이 도구들이 손대지 않는 스트림이기 때문. 광고 수치는 “특정 스트림 단독 최선값”이다.
+03 · 토큰 관리
+03 · 하네스의 진화
-Harness Handbook — “어디를 고칠지”가 병목이다. 진화는 “수정을 생성”만이 아니라 “어디를 고칠지 아는” 표현에 달렸다. (arXiv:2607.13285)
+03 · 메타 원칙
-분기마다 3질문: 이 제약은 아직 필요한가? · 이 피드백 루프가 잡는 문제가 아직 발생하는가? · 새 모델로 가능해진 더 나은 패턴은 없는가?
-“There is no silver bullet.” — Fred Brooks, 1986. 남은 질문: 이 하네스의 결과물이 얼마나 좋은지는 누가 재나? → 4장 Evaluator
-에이전트 응답을 ‘느낌’ 아닌 ‘지표’로 — 채점기·비결정성·3계층 게이트·Evaluator Driven 평가 게이트 95점 루프
+에이전트 결과를 ‘느낌’이 아니라 ‘점수’로 — 채점표 만들기부터 95점 자동 루프까지
04 · 왜 EVAL인가
-LLM 개발의 병목은 코드 생성이 아니라 검증 — “구현 완료” 선언과 실제 사이의 간극(스텁뿐·테스트 없음·스펙 누락·주장만).
-| 하네스의 한계 | 해결 장치 |
|---|---|
| ① 판정이 정성적 — 개선·회귀의 정도를 못 말함 | 루브릭 점수 + 임계값 |
| ② 추이를 모른다 — 이번 변경만 봄 | 골든셋 고정 + 재채점 → 점수 시계열 |
| ③ 배포 후 무방비 — 드리프트(drift, 배포 후 성능이 시간 경과로 변하는 현상) 미측정 | 온라인 모니터링 + 런타임 blocking eval |
04 · 용어
+| 용어 (풀 네이밍) | 쉬운 설명 |
|---|---|
| Eval (이밸 · Evaluation) | AI 출력의 품질을 같은 기준으로 반복 채점하는 절차, 그리고 그 점수 |
| Evaluator (이밸류에이터) | 만든 쪽과 분리된 ‘채점자’ — 코드·AI·사람 모두 될 수 있다 |
| 루브릭 (Rubric) | 채점표 — ‘무엇이 몇 점인지’를 미리 명문화한 기준 |
| LLM-as-Judge (LLM 판사) | 별도의 AI가 루브릭을 들고 다른 AI의 출력을 채점하는 패턴 |
| 골든셋 (Golden Dataset) | 영구 재사용하는 정답지 문제은행 — 실패가 새 문항으로 쌓인다 |
| EDD (Evaluation-Driven Development) | 평가 주도 개발 — 감이 아니라 채점 점수로 개발 방향을 결정하는 방식 |
| 결정론 (Deterministic) | 같은 입력이면 언제나 같은 결과 — 테스트·린트처럼 흔들림 없는 검사를 말한다 |
| fail-closed (페일 클로즈드) | 확인할 수 없으면 통과가 아니라 차단이 기본값 — “모르면 막는다” |
04 · 왜 EVAL인가
+04 · 기초
-셋 중 하나라도 빠지면 전통 QA의 연장선일 뿐, eval이 아니다.
-04 · 두 축
+04 · 채점기
-| 종류 | 방법 | 강점 | 약점 |
|---|---|---|---|
| 코드형 | 정규식 매칭, 이진 테스트, 정적 분석, 결과·도구 호출 검증 | 빠르고 저렴, 객관적, 재현 가능 | 유효한 변형에 뻣뻣, 뉘앙스 부족 |
| 모델형 LLM-as-Judge | 루브릭 점수, 자연어 assertion, 쌍대 비교, 다중 Judge 합의 | 유연, 뉘앙스 포착, 개방형 처리 | 비결정적, 비쌈, 사람과 보정 필요 |
| 사람형 | SME(Subject Matter Expert, 해당 분야 전문가) 리뷰, 스팟체크, A/B, 평가자 간 일치도 | 정답지 수준 품질 | 비싸고 느림, 스케일 한계 |
원칙: 경로가 아니라 결과를 채점 — 에이전트는 설계자가 예상 못한 유효한 접근을 찾는다. 창의성을 벌하지 마라. 다구성 태스크엔 부분 점수.
+04 · 기초
+04 · 비결정성
-두 곡선의 간극 자체가 정보 — 크면 “가끔 되는 시스템”.
-04 · 채점기
+| 종류 | 어떻게 채점하나 | 강점 | 약점 |
|---|---|---|---|
| 코드형 | 정규식·테스트·정적 분석 — 기계가 확인 | 빠르고 싸고 재현 가능 | 말이 조금만 달라져도 놓친다 |
| 모델형 LLM-as-Judge | AI가 채점표(루브릭)로 점수를 매긴다 | 유연 — 뉘앙스 포착 | 결과가 흔들림 · 비쌈 · 사람과 맞춰봐야 |
| 사람형 | 전문가 검토 · 표본 확인 | 가장 정확 — 정답지 품질 | 비싸고 느려서 소량만 |
04 · 온프레미스
-| 게이트 | 수단 | 통과 조건 |
|---|---|---|
| 1 결정론 | 컴파일·테스트·Checkstyle(스타일 검사)·ArchUnit(아키텍처 규칙 테스트)·grep | 전부 통과 (하드) |
| 2 LLM-as-Judge | 루브릭 G-Eval(LLM 루브릭 채점) · 로컬 vLLM(오픈 LLM 추론 서버), guided_json(출력 스키마 강제) | 점수 ≥ 7.0 |
| 3 사람 | 수동 라벨 | 교정·엣지케이스만 |
임계값은 유형별 허용 실패율: convention 5% / correctness 3% / domain_safety 0% (Judge 출력은 guided_json 스키마 강제 + temperature 0).
-04 · 3층 게이트
+04 · 결정론 우선
-| 규약 | 검사 방법 |
|---|
| 팀 규칙 (사람의 문장) | 기계 검사 (자동 실행) |
|---|---|
| 컴파일 / 전체 테스트 | ./gradlew compileJava test |
| 코드 스타일·네이밍 | ./gradlew checkstyleMain |
| 컨트롤러의 엔티티 직접 반환 금지 | ArchUnit: @RestController 반환 타입에 @Entity 금지 |
| @ManyToOne/@OneToMany는 LAZY | ArchUnit + grep: FetchType.EAGER 금지 패턴 |
| AI 호출은 컨트롤러 스레드 동기 금지 | grep: 컨트롤러 패키지에서 동기 호출 부재 확인 |
| Flyway(DB 마이그레이션 도구) 기존 마이그레이션 미수정 | CI diff 검사: V*.sql 기존 파일 변경 시 실패 |
| 빌드가 깨지지 않는다 | 컴파일 + 전체 테스트 자동 실행 |
| 코드 스타일 통일 | 스타일 검사기(린터) 자동 실행 |
| 화면 계층에서 DB 객체 직접 반환 금지 | 구조 검사 도구가 반환 타입을 확인 |
| 무거운 호출은 응답 경로에서 금지 | 금지 패턴 검색(grep)으로 확인 |
| 과거 마이그레이션 파일 수정 금지 | CI가 기존 파일 변경을 감지하면 실패 |
2장 A/B의 S4(마이그레이션 불변)가 여기서 회수된다 — 모델이 모르는 팀 관례를 결정론 검사가 강제한다.
+04 · 실물 채점표
-| # | 항목 | 배점 | 점수 규칙 |
|---|
| # | 항목 | 배점 | 점수 규칙 |
|---|---|---|---|
| G1 | 빌드/타입체크 | 25 | 빌드 exit 0 → pass=25 / fail=0 게이트 |
| G2 | 테스트 통과 | 25 | npm run test → pass=25 / fail=0 게이트 |
| G3 | 안전 위반 0건 | 15 | 검증 훅(파괴 명령·비밀 노출) 위반 0=15 / 1+=0 게이트 |
| 4 | 린트 | 10 | pass=10 / fail=0 |
| 5 | 회귀 없음 | 10 | 기존 스위트 전부 유지=10 / 깨짐=0 |
| G1 | 빌드/타입체크 | 25 | 빌드 성공=25 / 실패=0 게이트 |
| G2 | 테스트 통과 | 25 | 전체 테스트 성공=25 / 실패=0 게이트 |
| G3 | 안전 위반 0건 | 15 | 위험 명령·비밀 노출 0건=15 / 1건이라도=0 게이트 |
| 4 | 린트 | 10 | 통과=10 / 실패=0 |
| 5 | 회귀 없음 | 10 | 기존 테스트 전부 유지=10 / 하나라도 깨짐=0 |
| 6 | 커버리지 | 5 | 변경 전 대비 유지·상승=5 / 하락=0 |
| 7 | anti-slop | 10 | check-slop 0 ERROR=10 / 1+ ERROR=0 |
| 7 | 디자인 규칙 (anti-slop) | 10 | 검사 도구 오류 0건=10 / 1건 이상=0 |
“좋은 결과”를 주관에 두지 않는다 — 게이트 항목(G1·G2·G3)이 0점이면 나머지 만점이어도 총점 무관 FAIL.
+04 · EVALUATOR-DRIVEN 게이트
-항목마다 실제 코드와 대조·테스트해 0~100점으로 채점하고, 전 항목이 95점 이상이 될 때까지 개발↔검증 루프를 자동으로 돌리는 하네스 서브시스템.
-간극을 닫는 3장치
-| 쓴다 | 안 쓴다 |
|---|---|
| 스펙이 명확하고 항목 단위 보증이 필요할 때 | 한 줄 수정·오타 등 자명한 변경 |
| 구현 주장이 많아 사람이 전수 확인 버거울 때 | 탐색·리서치처럼 정답 없는 작업 |
| 루프를 자동 수렴시키고 싶을 때 | 테스트 인프라 없는 프로토타입 (test축 0 → 95 불가) |
04 · EVALUATOR-DRIVEN 게이트 루프
-Spec 분해 → 개발/빌드(Generator) → 체크리스트 전수 열거 → 2렌즈 채점(read-only) → 게이트 전 항목 ≥95? — 아니오→deficiencies 피드백→개발 / 예→DONE.
-04 · 루프 가드레일
+04 · EVALUATOR-DRIVEN 게이트 루브릭
-| 축 | 배점 | 만점 조건 |
|---|---|---|
| exists | 25 | 실제 구현 존재 — 스텁·TODO 아님 |
| match | 25 | 코드가 claim과 의미적으로 일치 |
| test | 25 | verify 명령 실제 실행 → 통과 |
| contract | 15 | 타입·에러·입력검증·인가 경계 안전 |
| no-regress | 10 | 기존 통과 항목·기능 퇴행 없음 |
2렌즈: code-match(정적 대조) × test-pass(실제 실행) → min(두 렌즈). 한 렌즈만 후해도 통과 못 함.
-04 · 루브릭
+04 · EVALUATOR-DRIVEN 게이트 통합
-3장의 훅(요청→보증)에 4장의 점수가 꽂힌 형태 — 검사 내용이 정규식에서 점수로.
-| SCORE.json 상태 | Stop(응답 종료) 시 동작 |
|---|---|
| 파일 없음 | 통과 (일반 세션 무영향) |
| active: false | 통과 (루프 종료·게이트 해제) |
| active: true + 전 항목 ≥ threshold | 통과 |
| active: true + 미만 항목 존재 | 차단 (exit 2) — “다 됐다” 선언 불가 |
| score 누락 (malformed) | 차단 (fail-closed) |
구성 6표면: 계약(conformance.md 정본) · 커맨드(/evaluator-driven) · 스킬(spec-checklist) · 에이전트(conformance-scorer, read-only) · 워크플로(spec-conformance-loop.js) · 훅(conformance-gate.sh, active-only).
+04 · 하네스 통합
+04 · 워크스루
-관찰: 전체 재생성이 아니라 미달 항목만 재작업. 종료는 선언이 아니라 게이트 해제.
-04 · 워크스루
+04 · 성숙도
-| 레벨 | 상태 · 목격 현상 | 다음 행동 |
|---|---|---|
| LV0 바이브 체크 | 채팅창에서 몇 개 돌려보고 배포 — 반응적 루프 전부 | 실패 20~50건으로 골든셋 v1 |
| LV1 골든셋+수동 채점 | “3번·7번 케이스가 깨졌다”가 처음 가능. 채점이 병목 | 규칙화 가능한 것부터 코드 grader |
| LV2 자동 채점 | 실험 속도 급상승. “정확하지만 불친절한 답”이 샘 | 루브릭 명문화 → Judge (인간 일치율 먼저) |
| LV3 Judge+CI 게이트 | 배포 전 검출 정착. Judge 자기강화 리스크 등장 | Judge 재교정 프로세스화, 런타임 확장 |
| LV4 런타임 가드레일 | 드리프트가 지표로 잡힘. 단 “달았다≠막힌다” | 가드레일 자체를 공격셋으로 평가 |
| LV5 완전한 EDD 루프 | 실패→분류→최초 결정 지점 수정→골든셋 환류가 규정으로 회전 | eval 스위트 포화 관리·갱신 |
하네스 사다리(3장 Lv0~5)를 오른 팀은 EDD 사다리의 부품을 이미 절반 갖고 있다 — 지금 팀이 어느 줄인지 찾고 그 줄 오른쪽 칸부터 시작한다.
+04 · 승격
+프롬프트와 Eval을 함께 설계하기 — 시작 로드맵 · CI 게이트 · 가드레일 실측 · 안티패턴
+질문(프롬프트)과 채점(Eval)을 한 몸으로 설계한다 — 시작 로드맵부터 안티패턴까지
05 · 원리
-05 · 용어
+| 용어 (풀 네이밍) | 쉬운 설명 |
|---|---|
| 프롬프트 (Prompt) | AI에게 일을 시키는 지시문 — 이 파트에선 ‘채점 기준의 앞면’ |
| 케이스 (Case) | 채점에 쓰는 문제 하나 — 입력과 기대 결과의 쌍 |
| 회귀 (Regression) | 멀쩡하던 기능이 변경 후에 다시 망가지는 것 |
| 카나리 배포 (Canary Release) | 광산의 카나리아처럼, 트래픽 일부(5%)에 먼저 풀어 이상을 감지하는 배포 |
| 가드레일 (Guardrail) | 배포 후 실시간으로 위험한 출력을 막는 마지막 방어선 |
| 레드팀 (Red Team) | 일부러 공격해 방어를 시험하는 역할 — 가드레일 시험용 ‘공격 문제집’ |
| 프롬프트 인젝션 (Prompt Injection) | 입력 속에 몰래 지시문을 심어 AI가 원래 규칙을 어기게 만드는 공격 |
| 트랜스크립트 (Transcript) | AI가 실제로 주고받은 대화·실행 기록 전체 — 점수의 근거를 확인하는 원본 |
05 · 원리
+05 · 시작
-| 단계 | 내용 |
|---|
| 단계 | 무엇을 |
|---|---|
| Step 0 일찍 시작 | 수백 개 불필요 — 실제 실패에서 뽑은 20~50개면 강력하게 출발. 초기 변경은 효과가 커서 작은 표본으로도 신호가 잡힌다. 미룰수록 만들기 어려워진다 |
| Step 1 이미 하는 것에서 | 릴리스 전 수동 체크, 버그 트래커, CS 큐가 최고 소재 — 사용자 실패를 테스트 케이스로 |
| Step 2 모호하지 않게 | 품질 기준 = 전문가 2명이 독립적으로 같은 합/불 판정. 명세의 모호함은 곧 지표의 노이즈. 참조 해법(모든 grader 통과 출력)으로 풀이 가능성과 grader를 동시 증명 |
| Step 3 균형 | 일어나야 하는 케이스와 일어나면 안 되는 케이스 모두 — 치우친 eval은 치우친 최적화를 낳는다 |
| ⓪ 일찍 시작 | 수백 개 필요 없다 — 실제 실패 20~50개면 충분히 출발. 미룰수록 만들기 어려워진다 |
| ① 이미 하는 것에서 | 릴리스 전 수동 체크 · 버그 목록 · 고객 문의가 최고의 소재 — 실패를 테스트 케이스로 |
| ② 모호하지 않게 | 좋은 기준 = 전문가 2명이 따로 봐도 같은 합/불 판정. 애매한 기준은 채점 노이즈가 된다 |
| ③ 균형 있게 | “일어나야 할 것”과 “일어나면 안 될 것” 둘 다 — 한쪽만 재면 한쪽으로만 좋아진다 |
신호 해석: 프론티어 모델이 pass@100(100번 시도 중 1회 이상 통과)에서 0% = 에이전트가 아니라 태스크가 깨진 신호.
+05 · 실전 사례
+05 · 실전
-05 · 배포 판정
-통계 주의: 표본을 키우면 사소한 차이도 “유의” — p값만으로 결정 금지, 효과 크기·비용·지연을 함께.
-05 · 배포 판정
+05 · 런타임 방어선
-결론: 가드레일 자체를 공격 데이터셋으로 정기 평가 (recall·차단률 분리 측정).
-05 · 런타임 방어선
+05 · 마지막 규율
-누군가 eval 내부를 파고 트랜스크립트를 읽기 전까지, 점수를 믿지 마라. 실패는 공정해 보여야 한다 — 무엇을 왜 틀렸는지 명확해야.
-grader는 우회·해킹에 강해야 — 통과하려면 실제로 풀어야지, 허점을 악용해선 안 된다. 각 trial은 깨끗한 환경에서(공유 상태는 성능을 인위적으로 부풀린다).
+05 · 함정과 점검
-| 안티패턴 | 교정 |
|---|---|
| 완벽한 스위트를 기다림 | 실패 20~50건으로 즉시 시작 |
| 검증 없는 Judge 전면 도입 | 인간 일치율(κ≥0.6) 통과 지표에만 단계 도입 |
| 오차 범위 없는 델타 판정 | 표본 크기 기반 허용치 + pass^k 병행 |
| 가드레일 설치 후 방치 | 공격셋으로 recall·차단률 정기 측정 |
| 모델 수준 점수만 관리 | 파이프라인+아티팩트 전체를 평가 범위로 |
도입 자가 점검
-05 · 함정과 점검
+| 이러고 있다면 | 이렇게 바꾼다 |
|---|---|
| 완벽한 채점 세트를 기다린다 | 실패 20~50건으로 오늘 시작 |
| 검증 없이 AI 채점을 전면 도입한다 | 사람과 채점이 일치하는 항목부터 단계 도입 |
| 한 번 돌린 점수 차이로 판단한다 | 몇 번 돌려 흔들림을 확인한 뒤 판단 |
| 가드레일을 달아 놓고 방치한다 | 공격 문제집으로 정기 시험 |
| 모델 점수만 관리한다 | 시스템 전체(도구·규칙 포함)를 평가 범위로 |
하네스는 에이전트가 ‘올바르게 일하게’ 만들고, Evaluator는 그 일이 ‘얼마나 좋아지는지’를 숫자로 관리한다. 모델(엔진)이 어떻게 바뀌든, 우리가 고치고 능숙하게 운전하는 것은 차량(하네스+Evaluator)이다.
-부품 승격: 검증 서브에이전트→Judge · PLAN.md→골든셋 · 훅→Blocking eval. 성실하게 쌓은 하네스는 EDD 부품을 이미 절반 이상 갖고 있다.
+모델(엔진)은 계속 바뀐다 — 우리가 만들고, 고치고, 능숙하게 운전하는 것은 차(하네스 + Evaluator)다.
+성실하게 쌓은 하네스는 Eval 부품을 이미 절반 갖고 있다 — 시작은 내일 아침, CLAUDE.md 한 줄부터.