AI 에이전트 하네스 치트시트: 구성 요소, 파일, 문제 해결과 시작 체크리스트
AI 에이전트의 하네스는 다섯 구성 요소로 이루어집니다: 지침, 도구, 환경, 상태, 피드백. 최소한의 파일 세트는 다음과 같습니다: 지도 역할의 AGENTS.md, 검사 스크립트(make check, verify.sh), 진행 파일, 상태가 있는 기능 목록. 완료 표시는 에이전트가 아니라 스크립트가 찍습니다.
AI 에이전트 하네스의 다섯 구성 요소
| 구성 요소 | 의미 | 산출물 | 고장의 신호 |
|---|---|---|---|
| 지침 | 에이전트가 프로젝트에 대해 알아야 할 것 | AGENTS.md / CLAUDE.md, skills, docs/, ADR | 알려진 관례를 어김 |
| 도구 | 에이전트가 할 수 있는 것 | shell, 테스트, linter, 브라우저, MCP 서버 | "하고 싶은데 못 한다" |
| 환경 | 에이전트가 일하는 곳 | 잠금 파일, Docker/devcontainer, git worktree, sandbox, init.sh | 매 세션이 환경 수리로 시작 |
| 상태 | 재시작을 견디는 것 | PROGRESS.md, DECISIONS.md, feature_list.json, 커밋 | 새 세션이 어디서 멈췄는지 모름 |
| 피드백 | 에이전트가 실수를 아는 방법 | make check, E2E, hooks, arch-check, 평가자 | "완료"인데 작동하지 않음 |
처음부터 구축하는 순서: 피드백 → 지침 → 상태 → 환경 → 도구.
하네스 파일
| 파일 | 역할 | 규칙 |
|---|---|---|
| AGENTS.md / CLAUDE.md | 진입점: 프로젝트가 무엇인지, 어떻게 실행하고 검사하는지 | 짧은 라우터(약 80줄), "언제 읽을지" 조건이 붙은 문서 링크 |
| docs/*.md | 주제별 세부 내용 | 필요할 때만 읽고, 전부 읽지 않음 |
| .claude/skills/*/SKILL.md | 반복되는 절차(배포, 리뷰) | 작업 설명이 맞을 때 로드됨 |
| PROGRESS.md | 상태, 완료한 일, 막힌 부분, 다음 단계 | 매 세션 끝에 갱신 |
| DECISIONS.md | 결정, 이유, 기각된 대안 | 결과만이 아니라 경로도 기록 |
| feature_list.json | 기능: behavior, verification, state | 정확히 하나의 기능만 active (WIP=1) |
| scripts/verify.sh | 기능을 검사하고 passing으로 바꿈 | passing을 찍는 유일한 주체, commit SHA와 함께 |
| scripts/arch-check.sh | 아키텍처 경계 | 종료 코드 1 + 출력에 WHY와 FIX |
| scripts/init.sh | 작업 전 환경 점검 | 환경, 깨끗한 git, 초록색 make check, 활성 기능 |
| sprint contract | 코드 전에 맺는 기능 계약 | 범위 안 / 범위 밖 / 열린 질문 |
| .claude/settings.json | Claude Code 권한과 hooks | 검사는 이벤트에서 실행, 에이전트의 기억이 아니라 |
AGENTS.md 골격
# 프로젝트: 결제 백엔드 (FastAPI, PostgreSQL)
## 실행
docker compose up -d && ./scripts/init.sh
## 검사
make check # lint, 타입, unit, arch-check
make e2e # 엔드투엔드 시나리오
## Definition of Done
- make check와 make e2e — 코드 0
- 기능이 scripts/verify.sh로 passing 처리됨
- PROGRESS.md 갱신됨
## MUST
- 데이터베이스 요청은 repository를 통해서만
- 비밀 정보는 환경 변수에서만
## 문서
- docs/payments.md — 결제와 환불 관련 작업일 때
- docs/migrations.md — 데이터베이스 스키마를 바꿀 때
기능의 상태
| 상태 | 의미 | 누가 바꾸나 |
|---|---|---|
| pending | 대기 중 | 계획자 |
| active | 작업 중 (하나만) | 시작할 때 에이전트 |
| passing | 검사 통과 | verify.sh만 |
| blocked | 사람의 결정이 필요함 | 에이전트, 이유와 함께 |
검증 단계
| 단계 | 무엇 | 언제 |
|---|---|---|
| 1 | Lint, 타입 | 항상 |
| 2 | Unit 및 integration 테스트 | 항상 |
| 3 | E2E | 여러 계층이 영향을 받을 때; "완료" 전에 |
| 4 | arch-check | 새로운 계층 간 import |
"완료"라고 말할 권한은 가장 상위 단계를 통과한 뒤에만 있습니다. 초록색 unit 테스트는 완료가 아닙니다.
규칙의 기계화
| 단계 | 도구 | 비용 |
|---|---|---|
| grep-guard | 패턴을 찾고 WHY/FIX 메시지를 출력하는 스크립트 | 몇 분 |
| Linter 규칙 | import-linter(Python), dependency-cruiser, eslint-plugin-boundaries(JS/TS) | 한 시간 |
| 아키텍처 테스트 | 계층이 깨지면 실패하는 CI 테스트 | 더 많지만 make check에서 보임 |
#!/usr/bin/env bash
fail=0
if grep -rn "from app.db" app/services/; then
echo "WHY: 서비스는 데이터베이스와 직접 통신하지 않는다"
echo "FIX: app/repositories/의 repository를 사용하세요"
fail=1
fi
exit $fail
자주 생기는 문제와 해결책
| 문제 | 구성 요소 | 해결책 |
|---|---|---|
| CLAUDE.md의 규칙이 지켜지지 않음 | 지침 | 파일을 줄이고, 규칙을 검사나 hook으로 바꾸기 |
| 에이전트가 테스트를 실행하지 못함 | 도구 | 명령을 허용하고, 의존성을 이미지에 넣기 |
| 머신마다 동작이 다름 | 환경 | 잠금 파일, Docker/devcontainer, 고정된 런타임 버전 |
| 세션 간 건망증 | 상태 | PROGRESS.md, session handoff, 세션 시작 시 읽기 |
| 기능 세 개를 시작했는데 하나도 끝나지 않음 | 상태 | feature_list.json에서 WIP=1 |
| "완료"인데 작동하지 않음 | 피드백 | DoD, E2E, verify.sh, 독립 평가자 |
| 테스트는 초록, 기능은 깨짐 | 피드백 | 실제 데이터베이스와 설정을 쓰는 E2E |
| 에이전트가 나쁜 패턴을 복사함 | 피드백 | 첫날부터 arch-check |
| 에이전트가 무엇을 했는지 알 수 없음 | 상태 | 작은 커밋, PROGRESS.md와 DECISIONS.md 보고 |
| 에이전트가 밤사이 환경을 망가뜨림 | 환경 | sandbox, git worktree, 체크포인트, init.sh로 복구 |
| 같은 리뷰 코멘트가 두 번 나옴 | 하네스 전체 | make check에 검사로 만들고, 지침의 문장은 제거 |
긴 작업의 역할
| 역할 | 하는 일 | 하지 않는 일 |
|---|---|---|
| 계획자 | 인수 기준이 있는 기능 작성 | 코드를 쓰지 않음 |
| 생성자 | 기능 하나를 구현하고 테스트 실행 | 완료 여부를 결정하지 않음 |
| 평가자 | 루브릭으로 판정, 파일·줄·로그를 인용 | 생성자의 추론을 보지 않음 |
| 머지 | review == pass일 때 커밋 | 이것은 에이전트가 아니라 코드 |
자율 작업의 예산
- 목표는 한 문장으로 (예: 모든 기능을 passing으로 만들기).
- WIP=1, 기능당 시간과 시도 횟수 제한.
- 지표는 단조 증가해야 하며, 회귀는 즉시 롤백.
- Migration, 인프라, 돈: 사람에게 에스컬레이션.
- 여러 번 리뷰에 실패하면 기능을 깨끗한 context에서 다시 시작.
에이전트 시작 체크리스트
- AGENTS.md가 있다: 스택, 실행 방법, 검사 명령, DoD.
- make check가 깨끗한 클론에서 통과한다.
- 환경이 재현 가능하다: 잠금 파일, Docker 또는 devcontainer.
- 에이전트에게 필요한 명령이 열려 있고, 위험한 명령은 막혀 있거나 sandbox 안에 있다.
- 최소한 주요 시나리오에 대한 E2E가 있다.
- PROGRESS.md가 있고, 세션 시작 시 읽으라는 규칙이 있다.
- 기능이 상태와 함께 목록에 있고, 활성은 하나뿐이다.
- passing 표시는 스크립트가 찍는다.
- 검사 메시지에 WHY와 FIX가 있다.
- 작업이 인수 기준과 범위 경계와 함께 적혀 있다.
- 사람의 결정이 필요한 것이 무엇인지 정해져 있다.
- 변경 전에 verification gap을 측정해 비교 기준을 만들었다.
하네스 지표
| 지표 | 계산 방법 |
|---|---|
| Verification gap | 10개 작업에서 "완료"라고 했지만 검사로 확인되지 않은 비율 |
| MTTR | 고장에서 정상 상태 복구까지의 시간 |
| 콜드 스타트 | 새 세션이 "여기는 어디, 다음은 무엇"에 추측 없이 답할 수 있는지 |
| Ablation | 고정된 작업 세트에서 구성 요소 하나를 끌 때의 하락 |
요약
하네스는 파일이 아니라 순환입니다: 지침, 도구, 환경, 상태, 피드백. 검사에서 시작하고, AGENTS.md는 짧게 유지하고, 완료 표시는 스크립트에 맡기고, 하네스를 정기적으로 점검하세요. 이 모든 것은 실제 프로젝트에서 하나의 하네스로 묶어 실습 과정에서 가르칩니다.
자주 묻는 질문
AGENTS.md와 CLAUDE.md의 차이는 무엇인가요?
목적은 같습니다: 에이전트를 위한 지침 파일. CLAUDE.md는 Claude Code가 읽고, AGENTS.md는 여러 에이전트가 공유하는 형식입니다. CLAUDE.md에 <code>@AGENTS.md</code>만 써서 둘을 연결할 수 있습니다.
AGENTS.md는 몇 줄이어야 하나요?
정해진 상한은 없지만, 진입 파일은 목차처럼 짧게, 약 100줄 안팎으로 유지하세요. 세부 내용은 별도 문서로 옮깁니다.
작은 프로젝트에도 feature_list.json이 필요한가요?
일회성 작은 변경에는 필요하지 않습니다. 에이전트가 기능 여러 개를 연달아 또는 여러 세션에 걸쳐 작업할 때 가치가 생깁니다.
에이전트가 접근해야 하는 비밀 정보는 어디에 두나요?
환경 변수나 secrets 관리자에 두고, 지침 파일이나 코드에는 두지 마세요. 에이전트에게는 환경에 대한 접근을 주고, 값은 텍스트로 주지 마세요.
이 주제는 “Harness Engineering: инженерия надёжности AI-агентов” 강의에서 실습과 함께 자세히 다룹니다.
- Из чего состоит harness AI-агента: инструкции, инструменты, среда, состояние, обратная связь
- Харнес AI-агента с нуля: AGENTS.md, feature_list.json, verify.sh и автономный цикл