하네스 엔지니어링이란? 코딩 에이전트가 같은 실수를 반복하지 않게 하는 법
코딩 에이전트가 같은 실수를 반복하면 프롬프트 대신 환경을 고칩니다. 실행 전 가이드와 실행 후 센서로 나눠 CLAUDE.md, 훅, 스킬, CI로 하네스를 만드는 방법을 예제와 함께 설명합니다.
하네스 엔지니어링이란 무엇인가
하네스 엔지니어링은 코딩 에이전트가 실수할 때마다, 같은 실수가 다시 일어나지 않도록 에이전트가 일하는 환경을 고치는 작업 방식입니다. 특정 제품이나 프레임워크의 이름이 아닙니다. 에이전트를 쓰는 개발자가 매일 반복하는 습관에 붙은 이름입니다.
고치는 대상은 두 종류입니다. 하나는 에이전트가 일을 시작하기 전에 읽는 것들입니다. CLAUDE.md나 AGENTS.md 같은 지시 파일, 설계 문서, 개발 환경을 한 번에 준비하는 스크립트가 여기에 속합니다. 다른 하나는 에이전트가 일을 마친 뒤 결과를 검사하는 것들입니다. 린터, 타입 검사기, 테스트, 리뷰용 에이전트가 여기에 속합니다. 앞의 것을 가이드(guide), 뒤의 것을 센서(sensor)라고 부릅니다.
원칙은 단순합니다. 에이전트에게 같은 지적을 두 번 하게 되면, 그 지적은 채팅창이 아니라 저장소에 있어야 합니다.
헷갈리기 쉬운 세 개념과 무엇이 다른가
에이전트 하네스 프로그램과의 차이
Claude Code나 Codex CLI 같은 프로그램 자체를 하네스라고 부릅니다. 모델을 감싸서 파일을 읽고, 명령을 실행하고, 그 결과를 다시 모델에게 넘기는 실행 환경입니다. 에이전트 하네스가 무엇이고 어떤 부품으로 이루어지는지는 따로 정리해 두었습니다. 하네스 엔지니어링은 그 프로그램을 만드는 일이 아닙니다. 이미 있는 하네스 위에 내 저장소와 내 팀에 맞는 규칙과 검사를 쌓는 일입니다. 뒤에서 소개할 Birgitta Böckeler는 이 둘을 빌더 하네스(builder harness)와 사용자 하네스(user harness)로 구분합니다. 이 글이 다루는 것은 사용자 하네스입니다.
프롬프트 엔지니어링과의 차이
프롬프트 엔지니어링은 요청 한 번을 잘 쓰는 기술입니다. 문장을 다듬으면 그 대화의 결과가 좋아집니다. 하지만 새 세션을 열면 그 문장은 남아 있지 않습니다. 하네스 엔지니어링은 고친 내용을 파일, 스크립트, 설정으로 저장소에 남깁니다. 그래서 다음 세션에도, 다른 팀원에게도, 다른 에이전트에게도 같은 효과가 납니다. 질문도 다릅니다. 프롬프트 엔지니어링은 "어떻게 말하면 잘 알아들을까"를 묻습니다. 하네스 엔지니어링은 "에이전트에게 무엇이 빠져 있어서 이 실수가 가능했을까"를 묻습니다.
루프 엔지니어링과의 차이
루프 엔지니어링은 에이전트가 도는 반복 구조를 설계하는 일입니다. 언제 다시 시도하고, 언제 멈추고, 언제 사람에게 넘길지를 정합니다. 하네스 엔지니어링은 그 루프가 한 바퀴 돌 때마다 에이전트가 무엇을 읽고 무엇에 걸리는지를 정합니다. 둘은 서로 맞물립니다. 루프가 "테스트가 통과할 때까지 반복"이라면, 그 테스트를 만들고 실패 메시지를 에이전트가 읽기 좋게 쓰는 일이 하네스 엔지니어링입니다.
하네스 엔지니어링이라는 말은 어디서 왔나
이 주제를 다루는 유료 강의도 여럿 있습니다. 그런데 개념의 뼈대는 무료로 공개된 글 세 편에 모두 들어 있습니다. 원문을 직접 읽기를 권합니다. 아래는 각 글이 실제로 말하는 내용만 추린 것입니다.
Mitchell Hashimoto: "Engineer the Harness" 단계
HashiCorp 공동 창업자이자 터미널 에뮬레이터 Ghostty를 만든 Mitchell Hashimoto는 블로그 글 "My AI Adoption Journey"에서 AI 도구를 받아들인 과정을 여섯 단계로 정리했습니다. 다섯 번째 단계의 이름이 "Engineer the Harness"입니다. 그는 이 단계를 이렇게 설명합니다. 에이전트가 실수하는 것을 발견할 때마다, 시간을 들여서 에이전트가 그 실수를 다시는 하지 않도록 해결책을 설계한다는 것입니다.
그가 든 방법은 두 가지입니다. 첫째, 에이전트가 잘못된 명령을 반복해서 실행하거나 엉뚱한 API를 찾는 것 같은 단순한 문제는 AGENTS.md(또는 그에 해당하는 파일)를 고칩니다. 그는 Ghostty 저장소의 AGENTS.md를 예로 듭니다. 그 파일의 각 줄은 에이전트의 나쁜 행동 하나에서 나왔고, 그렇게 쓴 줄들이 해당 문제를 거의 다 없앴다고 합니다. 둘째, 스크린샷을 찍는 스크립트나 일부 테스트만 골라 돌리는 스크립트 같은 도구를 직접 만듭니다. 그리고 그 도구가 있다는 사실을 AGENTS.md에 적어 에이전트에게 알려 줍니다.
이 정의에서 중요한 말은 "다시는"입니다. 실수 하나를 한 번 고치는 것이 목표가 아닙니다. 그 실수가 일어날 수 없는 환경을 만드는 것이 목표입니다.
OpenAI: 사람은 방향을 정하고, 에이전트는 실행한다
OpenAI 엔지니어링 블로그의 "Harness engineering: leveraging Codex in an agent-first world"(Ryan Lopopolo)는 사람이 코드를 직접 쓰지 않고 Codex에게 모두 쓰게 하면서 내부 제품을 만든 경험을 다룹니다. 글의 원칙은 "Humans steer. Agents execute."입니다. 사람은 방향을 정하고, 에이전트는 실행한다는 뜻입니다. 이 글에서 가져올 교훈은 네 가지입니다.
- 큰
AGENTS.md하나에 모든 것을 담는 방식은 실패했습니다. 내용이 많아지면 중요한 것이 묻히고, 금방 낡고, 맞는지 확인하기도 어려웠다고 합니다. 그래서AGENTS.md를 백과사전이 아니라 목차로 바꿨습니다. 약 100줄짜리 파일이 구조화된docs/디렉터리를 가리키고, 그docs/가 기준 문서(system of record) 역할을 합니다. - 아키텍처 규칙은 문서로만 두지 않고 기계로 강제했습니다. 직접 만든 린터와 구조 테스트(structural test)가 규칙을 검사합니다. 린터의 오류 메시지에는 고치는 방법이 들어 있습니다. 그래서 그 메시지가 그대로 에이전트의 컨텍스트에 들어가 다음 행동을 이끕니다.
- 무언가 실패하면 "더 열심히 해 보라"고 요구하지 않았습니다. 에이전트에게 빠진 능력이 무엇인지 찾고, 그것을 저장소에 넣었습니다.
- 에이전트는 저장소에 이미 있는 나쁜 패턴도 그대로 따라 합니다. 그래서 백그라운드 작업을 정기적으로 돌려, 팀이 정한 핵심 원칙에서 벗어난 코드를 찾아 정리했습니다. 글은 이것을 가비지 컬렉션(garbage collection)에 비유합니다.
Birgitta Böckeler: 가이드와 센서
Thoughtworks의 Birgitta Böckeler는 martinfowler.com에 "Harness engineering for coding agent users"라는 글을 썼습니다. 이 글은 앞의 경험들을 하나의 틀로 정리합니다. 출발점은 "Agent = Model + Harness"라는 식입니다. 에이전트는 모델과, 모델을 둘러싼 나머지 전부를 합친 것이라는 뜻입니다.
Böckeler는 하네스의 통제 장치를 두 축으로 나눕니다. 첫 번째 축은 시점입니다. 가이드는 피드포워드(feedforward) 통제입니다. 에이전트가 행동하기 전에 그 행동을 예상하고 방향을 잡아 줍니다. 그래서 첫 결과가 좋을 확률이 올라갑니다. 센서는 피드백(feedback) 통제입니다. 에이전트가 행동한 뒤에 결과를 관찰하고, 에이전트가 스스로 고치도록 돕습니다. 센서의 출력이 LLM(대규모 언어 모델)이 읽기 좋은 형태일 때 효과가 특히 큽니다.
두 번째 축은 실행 방식입니다. 계산형(computational) 통제는 CPU에서 도는 결정적인 검사입니다. 테스트, 린터, 타입 검사기가 여기에 속합니다. 밀리초에서 초 단위로 끝나고, 결과가 매번 같습니다. 추론형(inferential) 통제는 모델이 하는 의미 분석입니다. AI 코드 리뷰나 "LLM as judge"가 여기에 속합니다. 느리고 비싸고 결과가 매번 다를 수 있습니다. 대신 규칙으로 표현하기 어려운 것을 볼 수 있습니다.
이 글에는 실무에 바로 쓸 수 있는 원칙이 두 개 더 있습니다. 하나는 품질 검사를 배포 경로의 최대한 앞쪽에 두라는 것입니다. 문제를 일찍 찾을수록 고치는 비용이 싸기 때문입니다. 다른 하나는 사람의 역할입니다. 같은 문제가 반복되면 사람이 가이드와 센서를 고쳐서, 그 문제가 덜 일어나게 하거나 아예 일어나지 못하게 해야 합니다. 이것이 Hashimoto의 정의와 같은 말이라는 점에 주목하세요. 세 글은 서로 다른 출발점에서 같은 결론에 닿습니다.
Claude Code 사용자가 이미 가진 하네스 도구
하네스 엔지니어링을 하려고 새 도구를 살 필요는 없습니다. Claude Code를 쓰고 있다면 필요한 자리는 이미 다 있습니다. 각 기능이 가이드인지 센서인지 나눠 보면, 실수 하나를 어디에 고정해야 할지가 분명해집니다.
CLAUDE.md: 기본 가이드. Claude Code는 세션을 시작할 때 프로젝트 루트의 CLAUDE.md를 읽습니다. Hashimoto가 AGENTS.md에 하는 일을 Claude Code에서는 이 파일에 합니다. 다른 에이전트와 같이 쓰는 저장소라면 규칙은 AGENTS.md에 두고, CLAUDE.md 안에 @AGENTS.md 한 줄을 써서 가져올 수 있습니다. 사람이 읽을 문서와 에이전트가 읽을 문서를 어떻게 나눌지는 AGENTS.md와 HUMAN.md를 나눠 쓰는 방법에서 다룹니다. OpenAI의 교훈대로 이 파일은 짧은 목차로 두고, 긴 설명은 docs/로 보냅니다.
스킬: 필요할 때만 읽는 가이드. 스킬은 .claude/skills/<이름>/SKILL.md에 두는 지시 묶음입니다. 에이전트는 파일 앞부분의 description을 보고 지금 이 스킬이 필요한지 판단한 뒤 불러옵니다. 그래서 항상 필요한 규칙은 CLAUDE.md에 두고, 특정 작업에만 필요한 절차는 스킬에 둡니다. DB 마이그레이션을 쓰는 순서나 릴리스 절차가 좋은 예입니다. 이렇게 나누면 컨텍스트를 아끼면서 가이드를 늘릴 수 있습니다. 형식과 작성 요령은 에이전트 스킬을 직접 작성하는 방법에 정리했습니다.
권한 모드와 권한 규칙: 행동 자체를 막는 경계. Claude Code에는 default, acceptEdits, plan, auto, bypassPermissions 같은 권한 모드가 있습니다. 설정 파일의 allow와 deny 규칙으로 특정 도구나 명령을 허용하거나 막을 수도 있습니다. plan 모드에서 에이전트는 파일을 고치지 않고 계획만 세웁니다. 가이드가 "이렇게 해 주세요"라는 부탁이라면, 권한은 "이것은 할 수 없다"는 벽입니다. 각 모드가 실제로 무엇을 막는지는 Claude Code 자동 모드와 권한 설정에서 확인하세요.
훅: 계산형 통제를 끼우는 자리. 훅은 정해진 이벤트가 일어날 때 셸 명령을 실행합니다. PreToolUse 훅은 도구가 실행되기 전에 돕니다. 이 훅이 exit 코드 2로 끝나면 도구 호출이 막히고, stderr에 쓴 내용이 차단 이유로 Claude에게 전달됩니다. PostToolUse 훅은 도구가 실행된 뒤에 돕니다. 이미 실행된 것을 되돌리지는 못하지만, exit 코드 2로 끝나면 stderr 내용이 Claude에게 전달됩니다. 파일을 고칠 때마다 린터를 돌려 결과를 에이전트에게 돌려주는 센서는 이 자리에 만듭니다. 이벤트 종류와 입력 형식은 Claude Code 훅의 종류와 동작 방식에 정리했습니다.
서브에이전트: 추론형 센서. .claude/agents/ 아래에 정의하는 서브에이전트는 자기 컨텍스트를 따로 가집니다. 코드를 쓴 에이전트와 다른 컨텍스트에서 diff를 읽고 리뷰하게 하면, Böckeler가 말한 리뷰 에이전트가 됩니다. 결과가 매번 같지 않으므로 계산형 센서를 대신하지는 못합니다. 계산형 센서가 판정할 수 없는 것을 보는 보조 장치로 둡니다. 이름이 의도를 드러내는지, 변경이 docs/의 설계 문서와 맞는지 같은 것들입니다.
정리하면 이렇습니다.
- 가이드:
CLAUDE.md,AGENTS.md, 스킬,docs/아래의 설계 문서, 개발 환경 준비 스크립트 - 실행 전 차단: 권한 규칙,
PreToolUse훅 - 계산형 센서:
PostToolUse훅, 린터, 타입 검사기, 테스트 스위트, CI(continuous integration, 지속적 통합) - 추론형 센서: 리뷰용 서브에이전트
VPS에 에이전트를 두고 자리를 비우려면: 서버 쪽 센서
VPS(가상 사설 서버)에서 에이전트를 tmux 세션에 띄워 두고 퇴근하면, 그 시간 동안 결과를 보는 사람은 없습니다. 센서만 결과를 봅니다. 그래서 서버에서 도는 에이전트에게는 센서가 두 가지 조건을 지켜야 합니다. 실패하면 반드시 0이 아닌 exit 코드로 끝나야 합니다. 그리고 실패 메시지에 무엇을 고쳐야 하는지가 적혀 있어야 합니다.
첫 번째 조건이 깨지는 흔한 경우가 있습니다. 검사 스크립트가 중간에 실패해도 마지막 명령이 성공하면 스크립트 전체가 성공으로 끝나는 경우입니다. 에이전트는 exit 코드 0을 보고 "모든 검사 통과"라고 보고합니다. 저장소에 검사 스크립트를 하나 두고, 처음부터 크게 실패하도록 씁니다.
#!/usr/bin/env bash
# scripts/check.sh
set -euo pipefail
if [ -e package-lock.json ]; then
echo "FAIL: package-lock.json 파일이 있습니다. 이 저장소는 pnpm만 씁니다. rm package-lock.json 후 pnpm install 을 다시 실행하세요." >&2
exit 1
fi
if grep -rn "console.log" src/; then
echo "FAIL: src/ 에 console.log 가 남아 있습니다. 위 줄들을 src/lib/logger.ts 의 logger 호출로 바꾸세요." >&2
exit 1
fi
echo "== lint"; pnpm lint
echo "== typecheck"; pnpm typecheck
echo "== test"; pnpm test
echo "CHECK OK"set -e는 명령 하나가 실패하면 스크립트를 그 자리에서 멈추고 0이 아닌 코드로 끝냅니다. set -u는 정의되지 않은 변수를 쓰면 오류로 처리합니다. set -o pipefail은 파이프라인 중간의 실패를 숨기지 않습니다. 이 옵션이 없으면 pnpm test | tee test.log는 테스트가 실패해도 tee가 성공했기 때문에 성공으로 끝납니다. pnpm lint, pnpm typecheck, pnpm test는 package.json의 scripts에 같은 이름으로 정의되어 있다고 가정했습니다. 저장소에 맞게 바꾸세요.
chmod +x scripts/check.sh
./scripts/check.sh; echo "exit=$?"정상이라면 마지막 두 줄이 CHECK OK와 exit=0입니다. 검사 하나라도 실패하면 FAIL:로 시작하는 줄이나 실패한 도구의 출력이 보이고, exit=의 값은 0이 아닙니다.
실패 메시지를 쓰는 방식이 OpenAI 글의 핵심 교훈입니다. lint failed만 출력하면 에이전트는 원인을 추측해야 합니다. 무엇이 잘못됐고, 어디에 있고, 어떻게 고치는지를 한 줄에 쓰면 그 메시지 자체가 가이드가 됩니다. 센서의 출력이 다음 행동의 지시가 되는 것입니다.
같은 스크립트를 세 곳에서 씁니다. CLAUDE.md에는 "작업을 끝냈다고 말하기 전에 ./scripts/check.sh를 실행하고 exit=0을 확인할 것"이라고 적습니다. 이것은 가이드입니다. CI는 모든 push에서 같은 스크립트를 돌립니다. 이것은 에이전트가 건너뛸 수 없는 센서입니다. 검사 규칙이 한 파일에만 있으므로, 로컬과 CI의 기준이 서로 달라지는 일이 없습니다.
센서는 결과를 검사할 뿐입니다. 에이전트가 서버에서 무엇을 건드릴 수 있는지는 센서가 정하지 않습니다. 그 범위는 사용자 권한과 격리로 정합니다. 이 부분은 VPS에서 Claude Code를 안전하게 실행하는 방법과 일회용 VM에서 코딩 에이전트를 돌리는 방법에서 다룹니다.
실전 예제: 반복되는 실수 하나를 가이드와 센서로 바꾸기
상황은 이렇습니다. pnpm을 쓰는 저장소에서 에이전트가 의존성을 추가할 때마다 npm install을 실행합니다. npm은 pnpm-lock.yaml을 읽지 않습니다. 그래서 자기 잠금 파일인 package-lock.json을 새로 만들고, node_modules도 다른 구조로 채웁니다. git status에 package-lock.json이 새 파일로 나타나면 이 실수가 일어난 것입니다.
1단계: 가이드 한 줄. 처음에는 가장 싼 방법부터 씁니다. CLAUDE.md에 한 줄을 추가합니다.
- 패키지 설치는 pnpm만 씁니다. npm install, npm ci, yarn 은 쓰지 않습니다. package-lock.json 이 생기면 잘못된 것입니다.이유까지 같이 적는 것이 중요합니다. 규칙만 적으면 에이전트는 비슷하지만 다른 상황에서 판단할 근거가 없습니다. 대부분은 이 한 줄로 해결됩니다. Hashimoto가 말한 "단순한 문제는 AGENTS.md를 고친다"가 바로 이 단계입니다.
2단계: 그래도 반복되면 실행 전 차단. 긴 세션이나 복잡한 작업에서는 적어 둔 지시가 지켜지지 않을 때가 있습니다. 그 이유는 에이전트가 지시를 무시하는 이유에서 따로 다룹니다. 지시가 한 번이라도 어겨지면 안 되는 규칙이라면, 부탁을 벽으로 바꿉니다. PreToolUse 훅이 Bash 명령을 실행 전에 검사하게 합니다.
sudo apt install -y jq
mkdir -p .claude/hooks.claude/hooks/block-npm.sh 파일을 만듭니다.
#!/usr/bin/env bash
cmd=$(jq -r '.tool_input.command // ""')
if printf '%s' "$cmd" | grep -Eq '(^|[;&| ])npm (install|i|ci)( |$)'; then
echo "이 저장소는 pnpm만 씁니다. npm 대신 pnpm install 또는 pnpm add 를 실행하세요." >&2
exit 2
fi
exit 0훅은 실행하려는 도구 호출을 JSON으로 stdin에 받습니다. Bash 도구라면 실행할 명령이 tool_input.command에 들어 있습니다. 정규식은 명령 맨 앞이나 ;, &, |, 공백 뒤에 오는 npm install, npm i, npm ci만 잡습니다. 그래서 cd web && npm install은 막히고, pnpm install은 npm 앞에 p가 붙어 있으므로 통과합니다. npm run build 같은 다른 npm 명령도 통과합니다.
실행 권한을 주고, 프로젝트의 .claude/settings.json에 훅을 등록합니다.
chmod +x .claude/hooks/block-npm.sh{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/block-npm.sh"
}
]
}
]
}
}3단계: 훅이 동작하는지 직접 확인. 에이전트에게 맡기기 전에 훅을 손으로 실행해 봅니다. 훅이 받을 JSON을 흉내 내서 넣습니다.
echo '{"tool_input":{"command":"npm install lodash"}}' | .claude/hooks/block-npm.sh; echo "exit=$?"
echo '{"tool_input":{"command":"pnpm add lodash"}}' | .claude/hooks/block-npm.sh; echo "exit=$?"첫 줄은 안내 메시지를 출력하고 exit=2로 끝나야 합니다. 둘째 줄은 아무것도 출력하지 않고 exit=0으로 끝나야 합니다. 첫 줄이 jq: command not found를 출력하면 jq가 설치되지 않은 것입니다. 이때 cmd가 빈 문자열이 되므로 훅은 아무것도 막지 못합니다. Permission denied가 나오면 chmod +x를 빠뜨린 것입니다.
4단계: 센서로 뒤를 막기. 훅은 Claude Code 안에서만 동작합니다. 다른 에이전트나 사람이 터미널에서 직접 npm install을 실행하면 훅을 거치지 않습니다. 그래서 앞에서 본 scripts/check.sh의 package-lock.json 검사가 마지막 그물 역할을 합니다. CI에서 이 검사가 실패하면 누가 만든 실수든 머지 전에 잡힙니다. 메시지에는 고치는 방법이 적혀 있으므로, 에이전트는 그 메시지만 읽고 스스로 복구할 수 있습니다.
이 네 단계가 하네스 엔지니어링의 전체 모습입니다. 실수를 관찰하고, 가장 싼 가이드로 시작하고, 부족하면 차단과 센서로 올라갑니다. 그리고 각 단계가 실제로 동작하는지 손으로 확인합니다.
하네스를 키울 때 생기는 문제
지시 파일이 계속 길어집니다. 실수마다 한 줄씩 추가하면 CLAUDE.md는 몇 달 만에 수백 줄이 됩니다. OpenAI가 겪은 문제가 바로 이것입니다. 파일이 길어지면 중요한 줄이 묻히고, 이미 해결된 문제에 대한 줄이 남아 컨텍스트만 차지합니다. 기계로 판정할 수 있는 규칙은 센서로 옮기고, CLAUDE.md에서는 지웁니다. 특정 작업에서만 필요한 절차는 스킬로 옮깁니다. CLAUDE.md에는 목차와, 기계로 판정할 수 없는 판단 기준만 남깁니다.
가이드만 있고 센서가 없습니다. 규칙은 적혀 있는데 지켜졌는지 아무도 확인하지 않는 상태입니다. 에이전트가 규칙을 어겨도 아무 신호가 없으므로, 사람이 리뷰에서 우연히 발견할 때까지 문제가 쌓입니다. 반대로 센서만 있고 가이드가 없으면, 에이전트는 매번 같은 실수를 하고 매번 센서에 걸려서 고칩니다. 결과는 맞지만 시간과 토큰을 낭비합니다. 두 쪽이 다 있어야 하는 이유입니다.
센서의 메시지를 에이전트가 이해하지 못합니다. 테스트 실패가 수천 줄의 스택 트레이스로만 나오면, 에이전트는 핵심 줄을 찾느라 컨텍스트를 씁니다. 실패 요약을 맨 끝에 한 줄로 출력하게 하면 에이전트가 고치는 속도가 달라집니다.
동작의 정확성은 여전히 어렵습니다. Böckeler는 하네스를 세 종류로 나눕니다. 코드의 유지보수성을 지키는 하네스, 아키텍처 규칙을 지키는 하네스, 기능이 실제로 맞게 동작하는지를 지키는 하네스입니다. 이 중 마지막 것이 가장 덜 성숙했다고 말합니다. 에이전트가 직접 쓴 테스트는 에이전트가 잘못 이해한 요구사항을 그대로 검증할 수 있습니다. 테스트가 통과했다는 사실은 기능이 맞다는 증거가 아닙니다. 요구사항을 확인하는 일에는 아직 사람의 리뷰가 필요합니다.
오늘 바로 시작하는 순서
- 에이전트에게 같은 지적을 두 번 하게 되면 메모합니다. 이 메모가 하네스의 재료입니다.
- 메모마다 결정합니다. 기계가 맞고 틀림을 판정할 수 있으면 센서로, 판정할 수 없으면 가이드로 만듭니다.
- 검사 스크립트를 하나 만들고, 실패 메시지에 고치는 방법을 적습니다.
- 같은 스크립트를 CI에 연결하고, 꼭 막아야 하는 행동은 훅이나 권한 규칙으로 막습니다.
- 한 달에 한 번
CLAUDE.md를 처음부터 읽고, 센서로 옮겨졌거나 더 이상 필요 없는 줄을 지웁니다.
이 순서에는 비용이 드는 도구가 없습니다. 에이전트가 이미 쓰는 파일과 셸 스크립트, 그리고 실수를 기록하는 습관이면 충분합니다.
FAQ
하네스 엔지니어링과 프롬프트 엔지니어링은 무엇이 다른가요?
프롬프트 엔지니어링은 요청 한 번의 문장을 다듬는 일이고, 그 효과는 그 대화 안에서 끝납니다. 하네스 엔지니어링은 에이전트가 일하는 환경을 고치는 일입니다. 고친 내용이 CLAUDE.md, 스킬, 훅, 테스트, CI 같은 형태로 저장소에 남기 때문에, 다음 세션과 다른 팀원과 다른 에이전트에게도 같은 효과가 납니다.
하네스 엔지니어링을 하려면 특정 도구나 유료 강의가 필요한가요?
필요하지 않습니다. 하네스 엔지니어링은 제품이 아니라 작업 방식입니다. Claude Code 사용자라면 CLAUDE.md, 스킬, 권한 모드, 훅, 서브에이전트가 이미 있고, 서버 쪽에서는 셸 스크립트와 CI면 충분합니다. 개념은 Mitchell Hashimoto의 "My AI Adoption Journey", OpenAI의 "Harness engineering: leveraging Codex in an agent-first world", martinfowler.com의 "Harness engineering for coding agent users"에 무료로 공개되어 있습니다.
CLAUDE.md에 규칙을 적었는데 에이전트가 계속 어깁니다. 어떻게 해야 하나요?
규칙을 같은 파일에 더 강한 말투로 다시 쓰는 것으로는 잘 해결되지 않습니다. 반드시 지켜야 하는 규칙이라면 가이드를 차단이나 센서로 바꿉니다. 특정 명령을 막아야 하면 PreToolUse 훅이 exit 코드 2로 끝나게 해서 실행 전에 막고, stderr에 올바른 대안을 적습니다. 결과를 검사할 수 있는 규칙이라면 검사 스크립트에 넣고 CI에서 돌립니다. 그러면 에이전트가 규칙을 잊어도 결과가 머지되지 않습니다.
가이드와 센서 중 무엇부터 만들어야 하나요?
가장 싼 가이드부터 시작합니다. 실수 하나에 CLAUDE.md 한 줄과 그 이유를 적으면 대부분 해결됩니다. 같은 실수가 다시 나오거나, 한 번만 일어나도 피해가 큰 실수라면 센서나 실행 전 차단을 추가합니다. 오래 가는 하네스에는 둘 다 있어야 합니다. 가이드만 있으면 규칙이 지켜졌는지 아무도 모르고, 센서만 있으면 에이전트가 같은 실수를 매번 하고 매번 고칩니다.