이 글은 「AI 공부 지도 20부작」의 14편(M4) 입니다.
앞 편: M3 — Agent 가 LLM 과 다른 순간은 언제부터인가
다음 편: M5 — Evaluation, agent 가 “끝났다” 를 어떻게 판정하는가
0. 시리즈 안내 — 여기는 실무 섹션 M 의 네 번째 편
AI 공부 지도가 F(Foundation) → B(Bridge) → M(Meta·실무) 로 흐른다고 말씀드렸죠. F 여섯 편에서 LLM·Transformer·embedding·gradient descent 같은 기초 감각을 잡았고, B 세 편에서 프롬프트·에이전트·RAG 선택을 붙였습니다. M 시리즈로 넘어와서는 M1 에서 retrieval 4층, M2 에서 long-context 와 memory, M3 에서 agent 와 LLM 의 경계를 다뤘어요. 이제 M4 입니다.
M3 에서 잡은 감각이 하나 있었어요. Agent 는 LLM 한 번 호출이 아니라, LLM 을 시스템 안에 끼워 넣은 구조 라는 것. 이번 편은 그 “시스템” 의 안쪽을 뜯어봅니다. Agent 가 올라타는 운영 환경 자체 를 부품 단위로 분해해 보는 편이에요. 이 운영 환경을 실무에서는 하네스 (harness) 라고 부릅니다.
이 글을 다 읽고 나면 다음 세 가지가 되실 거예요.
- “같은 Claude 를 쓰는데 왜 누구는 agent 를 잘 굴리고 누구는 매번 헛돈을 쓰나” 라는 질문에 부품 단위로 답할 수 있음
- AGENTS.md · CLAUDE.md · skills · hooks · permissions · sandbox 같은 용어가 한 지도 위에서 읽힘
- 새 프로젝트를 시작할 때 하네스 체크리스트를 한 바퀴 돌릴 수 있음
시작할게요.
1. 같은 Claude 인데 결과가 다르다 — 원인은 하네스다
현장에서 자주 보는 장면이 하나 있습니다. A 개발자가 Claude Code 로 버그 하나를 15분 만에 고쳐요. 같은 회사 B 개발자가 같은 Claude 에 같은 모델 버전으로, 비슷한 복잡도의 버그를 두 시간 동안 붙잡고 있어요. 답답한 심정에 B 가 옆자리 A 에게 물어봅니다. “야, 너는 뭘 어떻게 시키길래 이게 돼?”
A 가 프롬프트를 보여줍니다. 별 거 없어요. “이 파일에서 이런 에러가 난다. 고쳐줘.” 딱 그 정도. 그런데 결과는 다릅니다. B 는 이 대답을 들으면서 속으로 “얘가 뭘 숨기고 있는 거지” 라고 생각해요.
숨기고 있는 게 아니에요. A 가 쓰는 건 프롬프트 자체가 아니라 프롬프트가 올라타는 판 전체 입니다.
A 의 레포에는 잘 관리된 CLAUDE.md 가 있어서, agent 가 파일을 열자마자 “이 프로젝트에서는 TypeScript strict 를 쓰고, 테스트는 vitest 로 돌리고, 커밋 전에 lint 가 돌고” 같은 규칙을 다 알고 시작합니다. .claude/skills/ 폴더에는 “버그 조사 루틴” 이라는 재사용 가능한 절차 문서가 있어요. 에디터 저장마다 자동으로 도는 pre-commit hook 이 있고, Claude 가 위험한 명령을 날릴 수 없게 settings.json 의 permissions 가 촘촘히 짜여 있어요. 테스트 실행은 sandbox 안에서 돌기 때문에 실수해도 밖이 안 터져요. 세션이 길어져서 컨텍스트가 넘칠 것 같으면 자동으로 compaction 이 돌고, 작업 끝에 “이거 정말 끝난 거 맞아?” 를 체크하는 검증 루프가 세워져 있어요.
B 는 그 모든 게 없어요. 같은 모델이지만 운영 환경이 완전히 다른 거 예요.
이걸 한 줄로 정리하면 이렇습니다.
같은 모델이라도 어떤 하네스 위에서 돌리느냐에 따라 품질이 판이하게 달라진다.
그리고 이 감각은 실무에서 돈과 시간으로 바로 증명돼요. Agent 가 좋은 하네스 위에 있으면 같은 예산으로 작업량이 2~3배 많아지고, 디버그 사이클이 짧아지고, 실수가 덜 쌓입니다. 하네스가 없거나 엉성하면 좋은 모델도 실력을 못 보여줘요. 모델 스펙 시트만 보고 도구를 고르다가 이 부분을 놓치면, “왜 유튜브에서는 잘 되는데 내 손에서는 안 되나” 라는 답답함이 계속 남습니다.
2. 하네스는 “긴 프롬프트” 가 아니다 — 흔한 오해 정리
이 단어를 처음 들으시는 분들은 “하네스” 를 긴 프롬프트 한 덩어리 정도로 오해하는 경우가 많아요. “system prompt 를 잘 쓰면 그게 하네스겠지” 라고 생각하는 거죠. 저도 처음엔 그랬습니다.
그런데 하네스는 훨씬 넓은 개념입니다. 비유로 시작해 볼게요.
Agent 가 도시를 돌아다니는 택시 기사라고 상상해 봐요. 기사는 LLM 이고, 운전 실력은 모델 능력이에요. 그런데 이 기사가 실제로 승객을 잘 모시려면 기사 혼자 잘해서는 안 돼요. 도시에 신호등이 있어야 하고, 도로가 깔려 있어야 하고, 내비가 있어야 하고, 차량에 브레이크가 제대로 있어야 하고, 사고 났을 때 구급차가 오는 체계가 있어야 해요. 승객에게 “이 기사가 특정 동네에는 못 들어갑니다” 라는 구역 제한도 걸려 있어야 하고요.
하네스는 그 도시 전체 예요. 기사 (모델) 만 좋은 게 아니라, 기사가 일하는 환경이 통째로 잘 정비되어 있어야 서비스가 굴러가는 겁니다.
조금 더 기술적으로 말하면 하네스는 이렇게 정의돼요.
하네스 = LLM 호출을 감싸는 운영 환경 전체. 규칙 문서, 도구 정의, 권한 경계, 실행 격리, 기억 관리, 검증 루프 같은 부품들의 합.
“긴 프롬프트” 와 어디서 갈라지냐면, 이렇게 갈라집니다.
- 프롬프트: LLM 한 번 호출에 넣는 텍스트 묶음. 휘발성. 세션 끝나면 사라짐.
- 하네스: 세션과 세션 사이, 프로젝트와 프로젝트 사이에 계속 남아서 agent 의 행동을 일관되게 만드는 운영 체계. 내구성 있음.
Mitchell Hashimoto 같은 개발자가 “AGENTS.md 를 쓴다” 고 말할 때 이 사람이 하고 있는 건 프롬프트 작성이 아니에요. 반복되는 지시를 운영 artifact 로 승격 하는 겁니다. 매번 입으로 말하던 걸 파일로 내려놓고, 그 파일이 모든 세션에 자동으로 적용되게 만드는 거죠. 이게 하네스예요.
그래서 하네스는 프롬프트 엔지니어링의 연장선 이 아니라 시스템 설계의 한 분야 라고 봐야 정확합니다. 코드 품질을 다루는 방식, 인프라를 구축하는 방식, 팀 규칙을 세우는 방식이랑 겹쳐요. 개별 천재성에 기대지 않고 덜 흔들리는 구조 를 짜는 기술이에요.
이 감각이 있으면 “좋은 하네스 = 좋은 운영체제 같은 것” 이라는 비유가 자연스럽게 들어옵니다. OS 가 잘 짜여 있어야 앱이 좋아 보이는 것처럼, 하네스가 잘 짜여 있어야 agent 가 좋아 보여요.
3. 하네스의 8 가지 층 — 지도 한 번 펼쳐보기
층 하나씩 뜯기 전에 전체 지도를 한 번 펼쳐볼게요. 외울 필요는 없어요. 이 글 다 읽을 때쯤엔 손에 붙을 겁니다.
| 층 | 짧은 이름 | 하는 일 |
|---|---|---|
| 1 | System Prompt | agent 의 기본 정체성과 금지사항 |
| 2 | Rule Docs (AGENTS.md · CLAUDE.md) | 프로젝트별 규칙북 |
| 3 | Skills | 재사용 가능한 작업 절차 정의 |
| 4 | Hooks | 이벤트 트리거, pre/post edit, session start 등 |
| 5 | Permissions | 어떤 도구·경로에 접근 가능한가 |
| 6 | Sandbox | 실행 격리, 네트워크·파일시스템 |
| 7 | Compaction | 긴 세션 압축 전략 (M2 연결) |
| 8 | Verification Loop | 완료 전 체크 (M5 연결) |
위에서 아래로 갈수록 “말해주는 장치” 에서 “막아주는 장치” 로, 그리고 “확인해주는 장치” 로 성격이 바뀌어요. 1~3 층은 agent 에게 말해주는 층, 4~6 층은 agent 의 행동을 제어하고 막는 층, 7~8 층은 그 전체 동작을 감시하고 마무리하는 층입니다.
한 층씩 들어가 볼게요. 각 층에서 “이게 뭐다”, “실제로 어디에 들어간다”, “없으면 어떤 실패가 생긴다” 를 붙여 나가겠습니다.
3-1. System Prompt — “네가 누구인지” 를 심는 층
가장 안쪽 층이에요. 모든 LLM 호출의 맨 처음에 들어가는 고정 텍스트. Claude Code 라면 “You are Claude Code, Anthropic’s official CLI for Claude” 같은 문장으로 시작하는 그 덩어리가 바로 여기예요.
역할은 세 가지입니다.
- 정체성: “너는 Claude Code 다” “너는 고객 지원 에이전트다” 처럼 역할을 박는 문장.
- 기본 금지사항: “파일을 지우기 전에 반드시 확인해라” “개인정보를 외부로 보내지 마라” 같은 절대 규칙.
- 출력 스타일 기본값: “짧고 직접적인 답변을 기본으로 한다” 같은 톤 설정.
이 층이 왜 중요하냐면, 프로젝트별 문서 (AGENTS.md, CLAUDE.md) 보다 더 우선 순위가 높게 작동하기 때문이에요. 다른 말로 하면, system prompt 에 박혀 있는 것은 바꿀 수 없는 바닥 이에요. 프로젝트 문서로 아무리 다른 말을 해도 system prompt 에 금지된 행동은 agent 가 안 합니다.
실무자 입장에서 보면 system prompt 는 대개 플랫폼 쪽이 관리해요. Claude Code 의 system prompt 는 Anthropic 이 짜서 박아놨죠. 우리가 직접 수정할 일은 거의 없어요. 대신 그 바닥이 어떻게 생겼는지 알고 있는 것 이 중요해요. 그래야 “이건 내 AGENTS.md 로 어떻게 해도 안 바뀌는 행동이다” 라는 판단이 되거든요.
반대로 API 를 직접 써서 자체 agent 를 만들 때는 system prompt 설계가 당신 몫이에요. 이때 흔한 실수는 system prompt 에 너무 많이 때려넣는 것 이에요. “이 prompt 가 정체성이다” 라는 감각이 희미해서 막 쌓다 보면 3,000 자짜리 system prompt 가 나와요. 그런데 길어질수록 모델이 그 지시를 무시하기 시작합니다. System prompt 는 짧고 굵게. 세부 규칙은 다음 층으로 밀어 넣는 게 원칙이에요.
3-2. Rule Docs — AGENTS.md · CLAUDE.md 라는 프로젝트별 규칙북
두 번째 층은 프로젝트 루트에 놓는 규칙 문서예요. 이름은 플랫폼마다 달라요.
이름은 달라도 하는 일은 비슷해요. “이 프로젝트에서는 agent 가 이렇게 행동해라” 를 문서로 내려놓는 거예요. GitHub 기준으로 2,500 개 이상의 레포지토리가 AGENTS.md 를 쓰고 있고, 관련 설정 파일을 둔 프로젝트는 6만 개를 넘어갑니다. 이미 업계 표준 비슷한 관행이에요.
이 문서 안에는 보통 이런 것들이 들어갑니다.
- 빌드·테스트 커맨드: “pnpm test 로 테스트 돌려” “vite build 로 빌드해”
- 코드 스타일: “ESLint airbnb-base 규칙 따름” “주석은 JSDoc 스타일”
- 금지 행동: “master 에 직접 푸시하지 마” “환경 변수는 수정하지 마”
- 도메인 지식: “이 앱은 의료 기록을 다룬다, 로그에 PII 남기지 마”
- 완료 정의: “테스트 통과 + lint 통과 + 타입 체크 통과 이후에 commit”
매번 프롬프트에 “참고로 우리 프로젝트는 TypeScript strict 에 vitest 쓰고…” 를 복붙하는 대신, 한 번 CLAUDE.md 에 박아놓으면 그 이후 모든 세션이 이걸 자동으로 읽어요. 이게 durable guidance 라는 개념이에요. Mitchell Hashimoto 가 AI 워크플로를 설명할 때 제일 강하게 미는 축이 이 층입니다.
이 층의 힘은 반복 실수를 규칙 승격으로 돌려막는 것 에서 나와요. Agent 가 계속 같은 실수를 해요. “테스트 안 돌리고 commit 하네.” 그러면 한 번 잔소리하고 끝나는 게 아니라, CLAUDE.md 에 “commit 전 반드시 pnpm test 를 돌린다” 한 줄을 추가해요. 그 순간부터 이 실수는 세션 메모리 가 아니라 프로젝트 메모리 가 돼요. 다음 세션에서도 그 다음 세션에서도 자동으로 먹힙니다.
이 층이 약하면 agent 가 계속 “이 프로젝트에 처음 온 사람” 처럼 행동해요. 그때마다 설명해야 하고, 그때마다 같은 실수를 해요. 팀으로 쓰는 레포라면 이 층 하나만 잘 세워도 생산성 차이가 크게 납니다.
3-3. Skills — 재사용 가능한 “작업 레시피”
Skill 은 Rule Docs 의 한 단계 위에 있는 개념이에요. Rule Docs 가 “우리 동네 규칙” 이라면, Skill 은 “우리 동네에서 특정 작업을 할 때 쓰는 레시피 모음집” 이에요.
예를 들어 볼게요. 블로그 운영 팀이라면 “기사 발행 전에 SEO 점검을 13 개 체크리스트로 돈다” 라는 고정된 절차가 있어요. 이걸 매번 Claude 에게 “이런 거 해줘” 라고 말하면 매번 다른 결과가 나와요. 그래서 이걸 publish-gate 라는 skill 로 문서화해서 ~/.claude/skills/publish-gate/SKILL.md 에 넣어둡니다. 그러면 “publish gate 돌려” 라는 한 마디로 agent 가 그 절차를 정확히 그대로 실행해요.
Skill 은 대개 세 가지로 구성돼요.
- SKILL.md: 이 skill 이 무엇을 하는지, 언제 쓰는지, 입출력이 뭔지
- 보조 스크립트: Python · Bash 같은 실제 실행 파일 (선택)
- 참고 문서: 템플릿, 예시, 관련 규칙
이 패턴을 Anthropic 이 Agent Skills 라는 공식 프레임워크로 정리하고 있어요. Skill 은 모델 독립적 이에요. Claude 가 쓰는 skill 구조가 다른 agent 환경에도 거의 그대로 이식됩니다. 작업 절차를 skill 로 만들어 놓으면 모델이 바뀌어도, agent 환경이 바뀌어도, 그 자산이 남아요.
여기서 미묘한 지점이 하나 있어요. Skill 과 Rule Docs 는 레이어가 다르다 는 점이에요.
- Rule Docs: “항상 이 규칙을 지켜라” (선언적, 배경에서 계속 작동)
- Skill: “이 작업을 시킬 때는 이 절차를 불러라” (절차적, 호출 시에만 작동)
둘 다 있어야 해요. Rule Docs 만 있으면 agent 가 “뭘 지켜야 하는지” 는 알지만 “뭘 어떻게 하는지” 는 매번 새로 생각해야 해요. Skill 만 있으면 “특정 작업의 절차” 는 알지만 배경 규칙 이 빠져서 미묘한 실수가 쌓여요. 둘을 같이 쓸 때 하네스가 단단해집니다.
경험자가 느끼는 비자명한 포인트 하나. Skill 을 너무 많이 만들면 발견 비용 이 올라가요. Agent 가 “지금 이 작업에 어떤 skill 을 불러야 하지” 를 판단하는 데 컨텍스트를 써버려요. 그래서 skill 은 “자주 쓰는 작업 10~30 개” 정도로 유지하는 게 현실적이에요. 100 개 쌓아놓고 “자동으로 필요한 걸 불러라” 하면 오히려 품질이 떨어지는 경우가 많습니다.
3-4. Hooks — 동작 사이에 끼워넣는 검증·로그 장치
Hook 은 하네스에서 “자동 반응 회로” 를 담당합니다. Agent 가 어떤 이벤트를 일으켰을 때, 그 이벤트를 감지해서 자동으로 돌아가는 외부 코드 조각이에요.
Claude Code 기준 hook 의 대표적인 이벤트들이 이렇게 있어요.
- PreToolUse: agent 가 어떤 도구를 쓰기 직전. 여기서 도구 실행을 막거나, 경고를 던지거나, 값을 고칠 수 있음.
- PostToolUse: 도구 사용 직후. 결과를 로그에 남기거나, 후속 검증을 돌림.
- UserPromptSubmit: 사용자가 메시지를 보낸 직후. 메시지에 따라 컨텍스트를 자동으로 추가함.
- SessionStart: 세션 시작 시. 매번 처음에 실행되는 초기화 스크립트.
- Stop: agent 가 응답을 끝냈을 때. 결과 요약, 외부 알림 등.
예를 들어 볼게요. “파일을 편집할 때마다 자동으로 lint 를 돌리고 싶다” 라는 요구를 hook 없이 해결하려면 매번 프롬프트에 “편집 후 lint 돌려줘” 라고 써야 해요. Agent 가 기억할 수도 있고 안 할 수도 있어요. Hook 으로 해결하면 settings.json 에 PostToolUse 를 걸어서 Edit 툴이 돌아간 직후에 pnpm lint 가 자동으로 실행되게 해요. Agent 의 의지에 의존하지 않고 하네스가 강제 합니다.
이게 결정적인 지점이에요. Hook 은 “자동 반응 회로” 이지 agent 의 기억이 아닙니다. Agent 가 까먹거나, agent 가 실수하거나, agent 가 지시를 무시해도 hook 은 돌아요. 그래서 “잊지 마, 매번 ~~ 해” 같은 요구는 대부분 memory 로 해결하지 말고 hook 으로 승격하는 게 맞아요.
Mitchell Hashimoto 가 말하는 “프로그래밍된 검증 도구” 가 이 층입니다. 같은 실수가 두 번 반복되면 문구로 잔소리하지 말고 hook 을 새로 짜서 에이전트가 그 실수를 구조적으로 못 하게 막는 것. 그 순간부터 그 실수는 사라지거든요.
Hook 이 없는 하네스는 결국 잔소리 기반 하네스 가 됩니다. 작동은 하지만 실수가 계속 리셋돼요. Hook 이 있는 하네스는 자가 강화 됩니다. 실수가 쌓일수록 hook 이 늘어나고, 하네스가 점점 단단해져요.
3-5. Permissions — “이 정도는 OK, 이건 금지”
Permissions 는 agent 가 쓸 수 있는 도구와 경로의 화이트리스트·블랙리스트 예요. Claude Code 의 settings.json 안에 다음 같은 블록이 들어가요.
{
"permissions": {
"allow": ["Bash(ls *)", "Bash(git status)"],
"deny": ["Bash(rm -rf *)", "Edit(.env)"]
}
}
이 짧은 블록 하나로 agent 의 행동 범위가 어마어마하게 달라져요. 그냥 rm 을 돌리려다가 막히면 agent 는 다른 방법을 찾아야 해요. .env 파일을 수정하려다 막히면 agent 는 승인을 구하게 돼요. 무턱대고 실행하는 대신 협상하는 agent 가 됩니다.
Permissions 의 효과는 세 가지 층에서 나와요.
- 안전: 복구 불가능한 명령 (
rm -rf,git push --force같은) 이 agent 손에서 안 돌아감. - 경계: “이 경로 밖은 건드리지 마” 를 agent 에게 가르치는 효과.
- 비용: API 호출이 비싼 외부 서비스 접근을 제한해서 비용 폭주 방지.
Agent 가 위험한 행동을 하려고 할 때마다 permissions 에 걸려서 승인을 구하게 되면, 사람이 한 번씩 개입 하게 돼요. 그게 병목처럼 보여도 실제로는 실수 방지 역할을 해요. 흔한 실수 중 하나가 “permissions 는 귀찮으니까 전부 allow 해둔다” 인데, 그 상태에서 한 번 큰 사고가 나면 그동안 절약한 시간이 전부 사라집니다.
실무 팁이 하나 있어요. Permissions 는 두 단계로 설계 하는 게 좋아요.
- User 전역 설정 (
~/.claude/settings.json): “ls, git status, pwd 같은 읽기 전용 명령은 항상 허용” - Project 로컬 설정 (
.claude/settings.local.json): “이 프로젝트에서 자주 쓰는 명령은 여기서 추가 허용, 위험 명령은 deny”
이렇게 나누면 프로젝트마다 다르게 짜인 permissions 가 agent 의 행동을 알아서 맞춰줘요. 공용 레포면 deny 를 엄격하게, 개인 연습용 레포면 allow 를 넓게.
3-6. Sandbox — 실행을 통째로 가둬두는 층
Permissions 가 “어떤 명령을 쓸 수 있냐” 의 층이라면, Sandbox 는 “쓸 수 있는 명령이 어디에서 도느냐” 의 층이에요.
예를 들어 agent 가 테스트를 돌린다고 해봐요. 그 테스트가 당신의 실제 파일 시스템에서 돌아요. 테스트 중에 실수로 파일을 지우는 코드가 있으면, 진짜 파일이 사라져요. 네트워크 호출이 있으면 진짜 외부 서비스에 요청이 날아가요.
Sandbox 는 이 실행을 격리된 공간 에 가둬요. Docker 컨테이너, VM, 혹은 프로세스 수준의 격리 같은 기술이 쓰여요. Sandbox 안에서 파일이 지워져도 바깥 파일은 그대로고, 네트워크 호출이 나가도 sandbox 가 중간에서 막거나 가상으로 응답해줘요.
Claude Code 자체는 호스트 OS 위에서 돌지만, 최근 버전들은 Bash tool 안에 dangerouslyDisableSandbox 같은 플래그가 있을 정도로 sandbox 의식이 뚜렷해졌어요. 기본 모드는 “네트워크·파일 시스템에 자동 제약이 있는 상태” 이고, 명시적으로 풀 때만 풀리는 구조예요.
Sandbox 가 왜 실무에서 점점 중요해지냐면, agent 가 실행할 수 있는 작업의 범위가 넓어지고 있기 때문 이에요. 과거에는 agent 가 텍스트만 만들었어요. 지금은 파일을 편집하고, 명령을 실행하고, 웹을 돌아다니고, 결제까지 시키려는 시도가 있어요. 이 범위가 넓어질수록 실수 한 번의 파급력이 커져요. Sandbox 는 그 파급력을 한 공간 안에 가두는 보험 이에요.
Sandbox 와 permissions 의 관계는 이렇게 기억하시면 돼요. Permissions 가 “이 명령은 쓰지 마” 의 담장이라면, sandbox 는 “혹시 담장 넘어도 옆 동네로 못 가게” 의 울타리예요. 담장만 있고 울타리가 없으면, 담장을 우회하는 버그 하나로 시스템이 터져요. 울타리만 있고 담장이 없으면, 울타리 안에서 agent 가 멋대로 날뛰어요. 두 층이 함께 있을 때 안전해집니다.
3-7. Compaction — 하네스의 “기억 관리” 전략
M2 에서 long-context 와 memory 를 다룰 때 잠깐 나왔죠. 컨텍스트 윈도우가 100만 토큰이라도 무한대가 아니고, 넘치면 품질이 떨어진다 는 얘기. 그 문제를 하네스 층에서 푸는 장치가 compaction 이에요.
Compaction 은 긴 세션 안의 대화 히스토리를 요약해서 덮어쓰는 동작이에요. Agent 가 하루 종일 한 세션에서 작업을 하면 수십만 토큰이 쌓여요. 그 안에는 중요한 결정도 있고, 이미 끝난 작업의 잡다한 로그도 있어요. Compaction 은 오래된 잡담은 한 줄 요약으로 압축하고, 결정 사항만 뼈대로 남겨요. 이 요약본이 다음 세션의 시작점이 돼요.
실무자가 여기서 놓치기 쉬운 지점이 있어요. Compaction 은 “그냥 요약” 이 아니라 하네스의 정책 이라는 점이에요. 뭘 남기고 뭘 버릴지를 결정하는 규칙이 있어야 해요. 좋은 compaction 정책은 이런 걸 남겨요.
- 사용자가 명시적으로 내린 결정 (“이 방식으로 가자”)
- 이미 만들어진 artifact 의 경로 (파일 경로, PR 번호 등)
- 중요한 실패 사례 (“이 접근은 안 먹혔다”)
- 현재 진행 중인 task 의 상태
버리는 건 이런 것들이에요.
- 이미 성공한 중간 단계의 상세 로그
- 중복되는 설명
- 사용자가 철회한 제안
Claude Code 에는 /compact 같은 수동 명령이 있고, “strategic-compact” 같은 skill 이 적절한 타이밍에 compaction 을 제안 하는 역할을 맡아요. 이게 잘 돌아가면 한 세션이 며칠에 걸쳐 이어져도 컨텍스트가 깔끔하게 유지돼요.
이 층이 없는 하네스는 세션이 길어질수록 agent 가 점점 멍청해져요. 옛날 얘기에 컨텍스트를 쓰느라 지금 문제에 집중을 못 해요. 이 층이 잘 돌아가는 하네스는 긴 프로젝트 내내 agent 품질이 유지돼요. Long-context 가 아무리 커져도 compaction 이 없으면 장기 세션에서 품질 저하가 나타나요.
3-8. Verification Loop — “끝났다” 를 어떻게 판정하는가
마지막 층. M5 에서 본격적으로 다룰 주제인데, 여기서 핵심만 짚고 갈게요.
Agent 의 가장 은근한 실패 패턴이 “다 했다고 말하는데 실제로는 안 된 상태” 예요. 테스트가 통과했다고 말하는데 실제로는 안 돌렸다든가, 버그를 고쳤다고 말하는데 실제로는 다른 버그를 만들었다든가. 사람이 최종 확인을 하지 않으면 이게 그대로 통과돼요.
Verification Loop 는 이 “끝났다” 를 하네스가 직접 검증 하는 층이에요. Agent 의 주장을 믿지 않고, 실제 상태를 확인하는 외부 체크들로 구성돼요.
- Lint 통과 여부: 정적으로 확인 가능한 코드 품질
- 테스트 통과 여부: 실제로 기대 동작이 맞는지
- 타입 체크 통과 여부: 컴파일러·타입 시스템이 동의하는지
- 스크린샷 체크: 화면이 의도한 대로 나오는지
- 사람 승인: 어떤 작업은 자동 검증으로 부족해서 사람이 봐야 함
이 체크들은 hook 으로 돌아가기도 하고 skill 로 돌아가기도 해요. 형태는 여러 가지지만 공통점은 agent 의 자기 보고를 검증하는 독립 장치 라는 점이에요.
Verification loop 가 잘 세워져 있으면 agent 가 “끝났다” 고 말해도 믿을 만해요. Loop 가 약하면 매번 사람이 마지막을 확인해야 해서 병목이 돼요. 반대로 loop 가 너무 엄격하면 agent 가 한 발짝도 못 나가요. 이 균형을 잡는 게 verification 설계의 기술이에요.
M5 에서 이 주제를 통째로 다룰 거라서 여기서는 “하네스의 마지막 층” 이라는 지도상 위치만 잡아두고 갈게요.
4. Claude Code 의 실제 하네스 — .company/blog/CLAUDE.md 가 하는 일
이론으로만 계속 설명하면 손에 안 잡혀요. 실제로 제가 돌리는 프로젝트 하나를 열어서 보여드릴게요.
shuntailor.net 이라는 블로그를 운영하면서 .company/blog/ 라는 폴더를 Claude Code 의 “블로그 운영 공간” 으로 쓰고 있어요. 그 폴더 맨 위에 .company/blog/CLAUDE.md 가 있습니다. 이 파일이 실질적으로 블로그 운영 에이전트의 하네스 상당 부분을 담당해요.
이 파일 안에 들어가 있는 걸 층별로 나눠보면 이래요.
Rule Docs 층 (2 층):
– 부서 미션 (“월수익 ¥120,000”, “주 3~4 편 발행” 같은 목표)
– 기사 길이 기준 (4,000~6,000 자)
– Rank Math SEO 81 점 이상이라는 합격 기준
– CTA 배치 규칙 (뉴스레터 가입 박스를 본문 50~60% 지점에 반드시 삽입)
– 금지 CTA 목록 (PDF 판매, AdSense, 배너 광고)
Skills 층 (3 층):
– “Publish Gate” 라는 13 항목 체크리스트. publish_gate.py 라는 실행 스크립트로 묶여 있어요.
– “SEO 자동 수정” 스크립트. seo_auto_fixer.py 를 호출하는 skill.
– “아이키워드 생성” 루틴. 발행 전 필수.
Hooks 층 (4 층):
– 기사 발행 직후 자동으로 wiki/published/ 폴더에 아카이브 저장
– 발행 후 audit-log, daily-log, agent-activity 세 곳에 자동 기록
– 발행 후 memory/project_blog_articles.md 자동 갱신
Permissions 층 (5 층):
– WordPress REST API 호출은 허용하되, 파일 삭제는 deny
– Playwright 사용 시 특정 패턴 외에는 사전 승인 필요
Verification 층 (8 층):
– Publish Gate 13 개 항목 전부 PASS 하지 않으면 “발행 완료” 보고 금지
– Gate 통과 후에도 GSC 수동 등록 안내까지 한 다음에야 끝
이 하네스가 없을 때 어떻게 됐냐면, 기사 한 편 발행하려면 제가 매번 “이런 거 체크해줘, 저런 거 빠뜨리지 마” 를 다 말해야 했어요. 빠뜨리는 것도 많았고, 체크리스트 13 개 중 서너 개는 누락됐어요. SEO 점수가 75 점에서 주저앉았어요.
하네스를 세우고 나서는 제가 “오늘 이 주제로 기사 하나 써” 라고만 말해도 agent 가 알아서 13 개 게이트를 다 돌고, 아카이브까지 저장하고, 로그 세 곳에 다 남기고, 점수 안 나오면 스스로 재생성해요. 같은 Claude 인데 결과가 다르다 의 전형적인 예예요.
여기서 통찰 하나. 이 파일은 한 번에 완성된 게 아니에요. 6 개월 동안 “agent 가 실수하면 규칙 하나 추가, 또 실수하면 hook 하나 추가” 를 반복한 결과물이에요. Mitchell Hashimoto 가 말하는 correction → rule extraction → enforcement 루프가 실제로 돌아간 거죠. 그래서 이 하네스는 지금도 계속 진화해요. 완성이 없어요.
5. Skills 구조 — 재사용 가능한 “작업 레시피” 를 풀어보면
Skill 을 조금 더 뜯어볼게요. 아까 3-3 에서 개념만 잡았는데, 이번엔 실제 구조를 한 번 열어볼게요.
Claude Code 의 skill 은 보통 이런 경로에 놓여요.
skill 설명
실행 스크립트
보조 템플릿
SKILL.md 는 이런 식으로 시작해요.
---
name: publish-gate
description: WordPress 발행 전 13 항목 SEO/품질 게이트를 돌린다
---
이 skill 을 언제 쓰나:
- 새 기사를 WordPress 에 발행하기 직전
- 발행 후 재검증이 필요할 때
어떻게 쓰나:
- 입력: JP_POST_ID, KO_POST_ID
- 실행: `python3 publish_gate.py --jp-id X --ko-id Y --auto-fix`
- 출력: ALL PASS 또는 BLOCKED (미통과 항목 리스트)
이게 파일로 있다는 것만으로 agent 가 “아 이 작업을 할 때는 이 skill 을 불러야지” 를 판단할 수 있어요. Description 을 읽고, 상황을 매칭하고, 실행해요. 사람 입장에서는 “publish gate 돌려” 한 마디면 끝나요.
Skill 의 가치는 세 가지 포인트에서 나와요.
- 재사용: 같은 작업을 다시 시킬 때 매번 설명 안 해도 됨.
- 표준화: 누가 시켜도 같은 결과. 팀이 쓰는 경우 중요.
- 진화: 실수가 쌓이면 skill 문서를 고치면 끝. Agent 행동이 자동으로 바뀜.
여기서 비자명한 포인트 하나. Skill 은 외우는 것보다 찾는 것 이에요. Agent 가 모든 skill 을 머리에 들고 있을 필요가 없어요. 필요할 때 검색해서 읽어요. 그래서 skill 을 설계할 때 description 을 검색 가능한 문장으로 쓰는 게 중요 해요. “이 skill 은 publish-gate 입니다” 보다는 “WordPress 발행 전에 SEO 13 항목을 검사한다” 라고 쓰는 게 agent 가 매칭하기 쉬워요. SEO 용어로 하면 “검색되는 문장” 이에요.
또 하나. Skill 은 계층을 가질 수 있어요. 큰 skill 이 작은 skill 들을 부르는 구조. publish-gate 가 내부적으로 seo-check, eyecatch-generate, auto-translate-ko 같은 작은 skill 을 불러요. 이렇게 구성하면 작은 skill 은 혼자서도 쓸 수 있고, 큰 skill 의 부품으로도 쓸 수 있어요. 재사용성이 두 층으로 늘어나요.
Anthropic 의 Agent Skills 프레임워크는 이 패턴을 공식화한 거예요. 앞으로 이 형식으로 skill 을 주고받는 마켓플레이스 같은 게 생길 수도 있고, 다른 agent 플랫폼에 이식하는 경로도 생길 수 있어요. 지금 skill 을 잘 짜두면 그게 모델 교체 비용을 줄이는 자산 이 됩니다.
6. Hooks — Agent 동작 사이에 끼워넣는 검증·로그
Hook 의 실제 설정을 한 번 열어볼게요. Claude Code 의 ~/.claude/settings.json 안에는 이런 식의 블록이 들어가요.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{ "type": "command", "command": "pnpm lint --fix" }
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{ "type": "command", "command": "scripts/inject-context.sh" }
]
}
]
}
}
이 두 줄이 하는 일을 풀어볼게요.
PostToolUse / Edit: Claude 가 Edit 도구로 파일을 편집한 직후, pnpm lint --fix 가 자동으로 돌아요. 린트 오류가 있으면 자동 수정되고, 실패한 검사는 다음 턴에 Claude 에게 보고돼요. Claude 가 까먹어도 린트는 돌아요. 결과는 린트 없는 코드가 절대 commit 되지 않는 구조.
UserPromptSubmit: 사용자가 메시지를 보내는 순간 inject-context.sh 라는 스크립트가 먼저 돌아요. 이 스크립트는 예를 들어 “지금이 2026 년 4 월이고, 오늘의 TODO 는 이렇다” 같은 현재 상태를 자동으로 컨텍스트에 심어요. 매번 사용자가 “지금 날짜 알려줘” 를 말할 필요가 없어요.
Hook 의 진짜 힘은 반복되는 실수의 구조적 제거 예요. Agent 가 같은 실수를 두 번 이상 하면, 그 실수를 막는 hook 을 짜는 게 합리적인 순서예요. “주의해, 다음엔 이렇게 하지 마” 같은 잔소리는 세션이 바뀌면 리셋되는데, hook 은 설정 파일에 박혀 있어서 안 리셋돼요.
실무에서 자주 쓰는 hook 패턴 몇 가지를 정리해 볼게요.
- Edit 직후 테스트 자동 실행: 변경된 파일에 영향받는 테스트만 선택해서 돌리면 피드백이 빨라짐.
- Bash 실행 직전 위험 명령 검사:
rm -rf,DROP TABLE같은 패턴이 있으면 자동으로 사용자 승인 요구. - Session Start 시 컨텍스트 주입: 오늘의 TODO, 현재 브랜치, 마지막 commit 같은 상태를 자동 주입.
- Stop 시 작업 요약 기록: agent 가 세션을 끝낼 때 한 작업을 audit-log 에 자동 기록.
이 네 개만 잘 세팅해둬도 agent 의 체감 품질이 한 단계 올라가요. 그리고 hook 은 쌓이면 쌓일수록 좋다 는 성질이 있어요. Rule Docs 는 너무 길어지면 agent 가 무시하기 시작하는데, hook 은 100 개가 쌓여도 각자 자기 타이밍에만 돌기 때문에 부담이 안 돼요.
비자명한 포인트 하나. Hook 은 실행이 빨라야 해요. PostToolUse 에서 lint 가 10 초씩 걸리면 agent 의 매 tool 사용마다 10 초가 추가돼요. 사용자 체감은 “Claude 가 느려졌다” 로 나타나지, “lint 때문이다” 로 잘 안 보여요. 그래서 hook 안에 도는 스크립트는 짧게, 오래 걸리는 건 비동기·백그라운드로 분리하는 게 원칙이에요.
7. Permissions 와 Sandbox — 안전 두 층을 같이 보기
다시 돌아와서 permissions 와 sandbox 를 한 번에 봅시다. 둘의 관계가 처음에 애매한 분들이 많아서, 실제 예로 풀어볼게요.
장면 1: 읽기 전용 명령
Agent 가 ls src/ 를 돌리고 싶어해요. Permissions 에 "allow": ["Bash(ls *)"] 가 있어요. 통과. 명령이 실행돼요. Sandbox 안에서 돌든 바깥에서 돌든 큰 차이는 없어요. 읽기만 하니까.
장면 2: 파일 편집
Agent 가 src/app.ts 를 수정하려고 해요. Permissions 에 이 경로 편집이 허용돼 있어요. 그런데 에이전트가 실수로 같은 tool 호출 안에서 rm src/other.ts 같은 부수효과를 유발한다고 상상해 봐요. Sandbox 는 이걸 실제 파일 시스템이 아니라 작업용 복사본 에서 돌려요. 실수가 바깥 파일에 반영 안 돼요. 최종 변경만 하나의 commit 이나 PR 로 바깥에 흘러 나가요. 사람이 확인한 후에.
장면 3: 네트워크 호출
Agent 가 외부 API 를 부르려 해요. Permissions 에는 “특정 도메인만 허용” 이 박혀 있어요. 그 외 도메인은 deny. Sandbox 는 이걸 네트워크 레벨에서도 강제해요. Agent 가 어떤 꼼수를 써도 sandbox 바깥으로 패킷이 못 나가요. 두 층의 방어 가 겹쳐 있는 상태.
장면 4: 위험 명령
Agent 가 rm -rf / 를 돌리려 해요. Permissions 의 deny 에 걸려 바로 차단. 여기서 끝이 아니에요. 만약 어떤 버그나 jailbreak 로 이 deny 를 우회했다고 쳐도, sandbox 안이라면 진짜 / 가 안 날아가요. Sandbox 안의 가짜 / 만 날아가요. 재시작하면 회복됩니다.
이 네 장면을 보시면 permissions 와 sandbox 는 기능이 겹치지 않는다 는 게 감이 오실 거예요. Permissions 는 의도를 필터링 하고, sandbox 는 영향을 격리 해요. 둘이 같이 있어야 진짜 안전해요.
실무 가이드 하나. Permissions 의 허용 패턴을 짤 때, “자주 쓰면서 안전한 명령” 을 먼저 allow 에 넣고, 나머지는 기본 deny 로 두는 게 좋아요. 그래야 처음 쓰는 명령마다 한 번씩 승인 요청이 올라와서, 사용 패턴을 시간이 지나면서 자연스럽게 파악할 수 있어요. “일단 전부 허용” 은 처음엔 편한데 나중에 꼭 사고가 나요.
8. Compaction — 하네스의 “기억 관리” 전략
M2 에서 잠깐 건드렸지만 하네스 층에서 다시 한 번 정리해 볼게요.
Agent 세션이 길어질수록 컨텍스트에 쌓이는 정보는 시간 역전 구조 가 돼요. 즉 오래된 게 앞에, 최근 게 뒤에 와요. 그런데 모델은 보통 최근 것을 더 강하게 본다 는 성질이 있어요. 그래서 세션이 길어지면 이런 문제가 생겨요.
- 초반에 내린 중요한 결정이 묻혀요. “우리는 절대 X 를 하지 않기로 했다” 같은 합의가 3,000 턴 앞에 있으면, agent 가 그걸 잊고 X 를 다시 제안해요.
- 쓸데없는 디테일이 계속 섞여요. 이미 끝난 중간 단계 로그가 컨텍스트 공간을 먹어요.
- 비용이 선형으로 올라가요. 턴마다 모든 누적 히스토리가 다시 프롬프트로 들어가요.
Compaction 은 이 세 문제를 한 번에 풀어요. 방식은 “오래된 구간을 요약본으로 덮어쓴다” 에요. 요약본은 짧지만 중요 결정은 빠지지 않게 유지돼요. 남는 공간은 최근 작업에 할당돼요.
Compaction 정책 설계에서 까다로운 지점이 있어요. 뭘 남길지, 뭘 버릴지의 기준 이에요. 단순히 “오래된 건 요약” 으로 하면 중요한 초기 결정이 날아가요. 좋은 하네스는 이런 정책을 명시적으로 둡니다.
- 사용자가 명시적으로 말한 요구사항은 원본 유지
- Agent 가 만든 artifact 의 경로·버전 정보는 원본 유지
- 과거의 실패 사례는 요약해서 유지 (“이 접근은 X 때문에 안 됐다”)
- 중간의 자잘한 로그는 삭제 가능
Claude Code 에는 /compact 명령이 있고, strategic-compact 같은 skill 이 이 타이밍과 정책을 제안해줘요. Hook 과 결합하면 세션이 특정 토큰 수를 넘어가면 자동으로 compact 제안이 뜨는 구조를 만들 수 있어요.
여기서 M2 와 M4 의 연결이 생겨요. M2 에서 “long-context 가 커져도 memory adaptation 이 필요한 이유” 를 얘기했죠. 그 memory adaptation 이 하네스 층에서 구체화되는 장치 중 하나가 compaction 이에요. 컨텍스트 윈도우가 100만 토큰이어도, compaction 없이는 실제 장기 프로젝트에서 agent 품질이 유지 안 돼요.
9. Verification Loop — 하네스가 “끝났다” 를 어떻게 판정하는가
M5 에서 본격적으로 다룰 주제이지만, 하네스 지도상 위치를 먼저 잡아둘게요.
Agent 작업의 가장 은근한 실패 모드 세 가지.
- 허위 완료 보고: “다 했어요” 라고 말했는데 실제로는 안 돌린 상태.
- 부분 완료: 주요 작업은 했는데 부수 작업 (테스트 갱신, 문서 갱신) 은 안 한 상태.
- 퇴행 유발: 새 기능은 넣었는데 옛 기능을 깬 상태.
세 실패 모두 사람이 마지막에 확인하지 않으면 그대로 통과해요. Agent 가 자기 입으로 “문제없다” 고 말하는 걸 그대로 믿는 순간, 이 실패들이 쌓여요.
Verification Loop 는 하네스 층에서 이 실패를 막는 장치예요. 구성은 보통 이렇게 돼요.
- 정적 검사: lint, 타입 체크, 포매터. 빠르고 객관적.
- 단위 테스트: 작게, 자동으로, CI 에서도 돌아가는 수준.
- 통합 테스트: 실제 workflow 가 도는지 확인. 느리지만 중요.
- 스크린샷 검증: UI 작업은 시각적 비교. Mitchell 이 말하는 “프로그래밍된 검증 도구” 의 대표 예.
- 사람 게이트: 어떤 작업은 자동 검증으로 충분하지 않아서 사람 승인이 필요.
좋은 verification loop 는 여러 층이 겹쳐 있어요. 하나가 놓쳐도 다른 하나가 잡아요. 나쁜 loop 는 한 층에만 의존 해요. 테스트는 돌지만 lint 가 없으면 품질이 미묘하게 깎여요. 스크린샷만 보면 로직 버그가 통과해요.
Verification 설계의 핵심 질문이 하나 있어요. “이 작업이 끝났다” 를 어떤 조건으로 정의하느냐 예요. 이게 명확하지 않으면 agent 가 아무리 잘해도 평가 자체가 흔들려요. Rule Docs 의 “완료 정의” 와 연결돼요. CLAUDE.md 에 “완료 = 테스트 통과 + lint 통과 + 타입 통과 + 스크린샷 기대치와 일치” 라고 박혀 있고, 그걸 실제로 검사하는 verification loop 가 hook 과 skill 로 만들어져 있으면, agent 는 그 조건을 맞추기 전까지 “끝났다” 고 말하지 못해요.
자세한 건 M5 에서. 여기서는 하네스의 마지막 층 이라는 지도상 위치와, 앞 일곱 층을 다 꿰는 역할 이라는 것만 기억하고 가시면 됩니다.
10. 왜 좋은 하네스가 좋은 모델보다 중요할 때가 많은가
이 글의 핵심 주장으로 돌아가요. 같은 모델이라도 하네스에 따라 품질이 판이하게 달라진다. 왜 그런지 메커니즘으로 한 번 더 정리할게요.
1. 모델 능력은 매번 변동성이 있어요. 같은 모델이라도 프롬프트가 달라지면 결과가 달라져요. 같은 프롬프트라도 온도에 따라 달라져요. 하네스가 약하면 이 변동성이 그대로 작업 품질의 변동성으로 나타나요. 하네스가 강하면 변동성이 하네스 안에서 흡수돼요. 테스트가 매번 돌기 때문에 모델이 흔들려도 최종 출력은 일정한 품질 이상이 돼요.
2. 실수는 누적돼요. 하네스가 없으면 같은 실수를 매번 반복해요. 하네스가 있으면 실수가 규칙 승격을 통해 구조적으로 사라져요. 시간이 지날수록 격차가 벌어져요. 한 달이 지나면 같은 모델로 하네스 있는 팀이 2~3 배 생산성이 나오는 게 드물지 않아요.
3. 모델 교체가 쉬워져요. 하네스가 모델과 독립적이면, 더 좋은 모델이 나왔을 때 그 모델로 교체하기 쉬워요. 프롬프트 엔지니어링에 기댄 팀은 모델 바뀌면 프롬프트 전부 다시 짜야 해요. 하네스 기반 팀은 같은 AGENTS.md·skills·hooks 를 그대로 쓰면서 모델만 바꿔요.
4. 사람의 역할이 바뀌어요. 하네스 없는 팀에서는 사람이 매 작업을 감독해야 해요. 하네스 있는 팀에서는 사람이 하네스를 개선하는 역할 을 해요. 훨씬 레버리지가 큰 작업이에요. 한 번의 hook 개선이 수백 번의 agent 실행에 영향을 줘요.
5. 품질의 하한선이 올라가요. 좋은 모델의 최대 능력치보다 중요한 게 최악의 경우에도 어느 선 이상을 보장하는 것 이에요. 하네스는 그 하한선을 올리는 장치예요. “가끔 천재적, 가끔 엉망” 에서 “매번 80 점 이상” 으로 바꿔요.
이 다섯 지점이 합쳐지면 하네스가 모델 선택보다 더 큰 레버리지를 가진다는 감각이 자연스러워요. 회장님 입장에서 “우리 팀에 Claude 를 도입할까 GPT 를 도입할까” 같은 질문보다 먼저 물어야 하는 게 “우리 팀의 하네스 상태는 어떤가” 라는 얘기예요.
다만 한 가지 중요한 단서. 하네스가 모델 능력 차이를 완전히 대체하지는 않아요. 같은 하네스에 Claude Opus 와 GPT-3.5 를 올리면 결과는 여전히 다릅니다. 모델이 어느 수준 이상이어야 하네스가 의미를 가져요. 바닥 모델에 아무리 좋은 하네스를 깔아도 한계가 있어요. 하네스는 모델을 대체하는 게 아니라, 모델이 가진 능력이 실제 작업에서 낭비되지 않게 만드는 구조 예요.
11. 하네스 설계 실수 7 가지
실무에서 제가 가장 자주 보는 실수들을 정리해 볼게요. 이 목록은 “하네스 체크리스트” 로도 쓸 수 있어요.
1. System prompt 에 전부 다 넣으려는 실수. System prompt 가 5,000 자를 넘어가면 모델이 내부 지시를 무시하기 시작해요. Prompt lost in the middle 현상이 system prompt 안에서도 일어나요. 필수 정체성과 금지사항만 남기고, 세부 규칙은 Rule Docs 층으로 밀어 넣어야 해요.
2. Rule Docs 가 너무 긴 실수. CLAUDE.md 가 2 만 자짜리로 부풀면 agent 가 읽는 비용이 너무 커요. 주제별로 쪼개는 게 맞아요. 루트에 간단한 CLAUDE.md 가 있고, 하위 폴더마다 세부 CLAUDE.md 가 있는 구조. Agent 는 자기가 작업하는 폴더의 문서만 읽어요.
3. Skill 을 너무 많이 만드는 실수. 30 개를 넘어가면 agent 가 “지금 어떤 skill 을 써야 하지” 를 판단하는 데 컨텍스트를 써버려요. 자주 쓰는 10~20 개로 유지하고, 나머지는 on-demand 로 구성하는 게 낫습니다.
4. Hook 없이 잔소리로 막으려는 실수. 같은 실수가 두 번 반복되면 무조건 hook 으로 승격해야 해요. “다음엔 조심해” 라는 문장은 세션이 바뀌면 리셋돼요. Hook 은 안 리셋돼요. 이 전환이 하네스 엔지니어링의 핵심이에요.
5. Permissions 를 다 allow 로 두는 실수. 편하려고 "allow": ["*"] 로 설정하면 처음엔 빠른데, 한 번 사고 나면 복구에 며칠이 걸려요. 기본은 deny, 자주 쓰는 안전 명령만 allow 가 합리적인 시작점이에요.
6. Sandbox 없이 호스트에서 바로 돌리는 실수. 간단한 스크립트라면 괜찮지만, 네트워크 호출이나 파일 시스템 조작이 들어가는 작업은 sandbox 안에서 돌리는 게 기본이에요. Docker Dev Container 나 별도 사용자 계정 같은 저렴한 격리 수단도 많아요. 안 쓰는 건 보험료 아까워서 사고 나는 것과 비슷해요.
7. Verification loop 가 빠진 실수. Hook, skill, rule 이 다 있는데 “끝났다” 를 검증하는 장치가 없으면 agent 의 자기 보고를 그대로 믿어야 해요. 이게 누적 되면 품질이 서서히 떨어져요. Lint + 테스트 정도만 돌려도 검증 구조가 생겨요. Before 에는 사람이 매번 확인, after 에는 자동 검증이 먼저 돌고 사람이 마지막만 보는 구조. 이 전환이 장기 품질 유지의 핵심이에요.
이 7 가지를 하나씩 점검하시면 현재 하네스의 약한 지점이 보여요. 한 번에 다 고치려고 하지 말고, 제일 아픈 부분부터 하나씩 개선하는 게 낫습니다. Hook 하나, rule 한 줄이 며칠 뒤 체감 품질을 바꾸는 경험을 하시면 하네스 엔지니어링이 왜 디자인 시스템 같은 분야인지 감이 옵니다.
12. Meta-Harness 예고 — 하네스 자체를 최적화 대상으로
마지막으로 한 걸음 더 나간 얘기. 하네스 자체를 agent 가 개선하게 하는 패턴 이 최근 뜨고 있어요. 이걸 meta-harness 라고 불러요.
기본 하네스는 사람이 손으로 짜요. Rule Docs 를 쓰고, skill 을 만들고, hook 을 설정해요. 시간이 지나면서 실수가 쌓이면 사람이 규칙을 추가해요. 이 과정 자체가 수작업이에요.
Meta-harness 는 이걸 한 단계 끌어올려요. Agent 가 자기 세션을 돌아보고 “같은 실수가 세 번 반복됐다, 이 실수를 막는 규칙을 추가하자” 를 스스로 제안 해요. 사람은 제안을 승인만 해요. 이게 잘 돌아가면 하네스가 자가 진화 합니다.
Mathbullet 채널이 이 주제를 정리한 영상이 최근에 나왔어요. 제목 그대로 Meta-Harness. Correction 을 기록하고, 패턴을 추출하고, 규칙으로 승격하고, 다음 세션에 자동 적용하는 루프를 만드는 방법이에요. Continuous learning 계열 skill 이 이 방향을 가리키고 있어요.
다만 경고 하나. Meta-harness 는 기본 하네스가 단단할 때만 의미 가 있어요. 기본이 엉성한 상태에서 자동화하면 엉성함이 자동으로 퍼져요. 그래서 순서가 중요해요.
- 먼저 손으로 단단한 기본 하네스를 세운다 (Rule Docs + Skills + Hooks + Permissions + Verification)
- 그 하네스가 3~6 개월 동안 실전에서 돌면서 안정되게 한다
- 그 위에 meta-harness 를 올려서 추가 개선을 agent 에게 맡긴다
이 순서를 건너뛰면 meta-harness 가 오작동을 자동 강화하는 재앙이 돼요. “좋은 도구를 늦게 쓰는 게 더 낫다” 는 원칙이 meta-harness 에는 특히 잘 맞아요.
이 주제는 다른 글에서 본격적으로 다루겠지만, AI 공부 지도 시리즈 끝부분에 가서 다시 한 번 지도에 위치를 잡아볼 예정이에요.
한 문장 닫음
하네스는 긴 프롬프트가 아니라 agent 가 올라타는 운영체제급 작업 환경이고, System Prompt · Rule Docs · Skills · Hooks · Permissions · Sandbox · Compaction · Verification 이라는 8 층으로 돌아간다. 같은 모델이라도 이 8 층이 단단한 하네스 위에서는 훨씬 덜 흔들린다. 좋은 agent 는 좋은 모델보다 먼저 좋은 하네스를 가진다.
다음 읽기
- M5 — Evaluation, agent 가 “끝났다” 를 어떻게 판정하는가 [준비 중]
시리즈 앞편: M3 — Agent 가 LLM 과 다른 순간 · M2 — Long-context 와 Memory · M1 — RAG 4 층 구조
자주 묻는 질문 (FAQ)
Q1. 하네스와 프롬프트 엔지니어링은 다른 건가요?
다릅니다. 프롬프트 엔지니어링은 한 번의 LLM 호출 에 들어가는 텍스트를 설계하는 기술이에요. 하네스는 그 호출을 감싸는 운영 환경 전체 를 설계하는 기술이에요. 프롬프트 엔지니어링은 휘발성이라서 세션 끝나면 사라지고, 하네스는 내구성이라서 세션·프로젝트·모델이 바뀌어도 남아요. 좋은 프롬프트 엔지니어링이 나쁜 하네스를 구해줄 수는 있지만, 좋은 하네스는 평범한 프롬프트를 꾸준히 괜찮은 결과로 만들어줘요. 실무 레버리지는 하네스 쪽이 훨씬 커요.
Q2. 하네스 8 층을 전부 다 갖춰야 agent 를 시작할 수 있나요?
아니에요. 처음부터 8 층을 다 세우려고 하면 부담이 커서 아예 시작을 못 해요. 실무 순서는 보통 이래요. 먼저 Rule Docs 한 장 (CLAUDE.md) 을 쓰는 것부터 시작해요. 그 다음 가장 자주 쓰는 작업 1~2 개를 skill 로 정리해요. 실수가 쌓이기 시작하면 그중 반복되는 것만 hook 으로 승격시켜요. 위험한 작업이 보이기 시작하면 permissions 를 촘촘히 해요. 그다음에 sandbox · compaction · verification 순서로 붙여 나가요. 한 달에 한 층씩 추가한다고 생각하시면 부담이 없어요. 완성된 하네스를 목표로 하지 마시고, 계속 진화하는 하네스 를 목표로 하시면 됩니다.
Q3. 혼자서 쓰는 작은 프로젝트에도 하네스가 필요한가요?
필요합니다. 다만 규모에 맞춰요. 1 인 프로젝트면 CLAUDE.md 30 줄 + skill 서너 개 + permissions 한 장 + 테스트 hook 한두 개로 충분해요. 이 정도면 “매번 잔소리하는 상태” 에서 “한 마디로 일이 돌아가는 상태” 로 넘어가요. 1 인 프로젝트에서도 이 전환의 체감 차이가 커요. Agent 를 쓰는 사람이 자기 자신에게 덜 반복 설명하게 되는 것 이 생산성의 첫 도약이에요. 큰 조직의 복잡한 하네스를 흉내낼 필요는 없지만, 가장 작은 형태의 하네스는 1 인 프로젝트에도 분명히 의미가 있어요.
뉴스레터 구독 안내
매주 월요일, AI · LLM · 에이전트 관련 실무 정리를 한 통씩 보내드립니다. 하네스 · 에이전트 설계 · LLM 실무 같은 주제를 차분히 쌓아가고 싶으시면 구독해 주세요.
시리즈 안내 (14/20)
– F1~F6: LLM · Transformer · Attention · Embedding · 학습 · 딥러닝 (완)
– B1~B3: Agent 정의 · 프롬프트 메커니즘 · Fine-tuning vs RAG vs Prompt (완)
– M1: Retrieval Layer 4 층
– M2: Long-context 와 Memory
– M3: Agent 가 LLM 과 다른 순간
– M4: Harness 이해 — agent 의 작업 환경 (현재 글)
– M5: Evaluation, “끝났다” 를 어떻게 판정하는가
– (이하 20 편까지)
📚 전체 지도 보기
같은 Claude를 써도 품질이 천차만별인 진짜 원인. 하네스를 system prompt·rule docs·hooks·sandbox·compaction 8층으로 해부한다.
소스 리스트
- 태일러 지식백과사전 — AI 공부 지도 카테고리 (본 시리즈 20편 전체)
- AI 공부 지도 엔트리맵 — 전체 구조 + 3가지 독법
- “Attention Is All You Need” (Vaswani et al., 2017)
- Anthropic · OpenAI · Google 공식 docs
- mathbullet (YouTube) / Jay Alammar “Illustrated Transformer” / 3Blue1Brown 영상 — 쉬운 설명 레퍼런스
著者: 바이브코딩 태일러 (VibeCoding Tailor) — Lovable公式アンバサダー. AI·バイブコーディング専門メディアshuntailor.net運営.
本シリーズ “AI 공부 지도” 22편은 위키 자료와 공식 논문·공식 문서를 근거로 정리한 체계적 학습 커리큘럼입니다.




