하네스 엔지니어링

seongha_h·2026년 4월 12일

개요

사내에서 AI 도입이 활발하게 이루어지면서, 최근 하네스 엔지니어링(Harness Engineering)이라는 개념이 등장했습니다.
이는 단순히 LLM을 사용하는 것을 넘어, 틀을 만들고 보다 효율적으로 활용하기 위한 접근 방식입니다.

기존에는 AI에게 “~~ 해줘”와 같이 요청하면, 별도의 설계 없이 결과를 생성하는 방식이 일반적이었습니다.
하지만 이러한 방식은 생성된 결과를 사람이 다시 읽고 이해한 뒤, 수정하거나 문서화해야 하는 부담이 뒤따릅니다.

하네스 엔지니어링은 이러한 문제를 해결하기 위한 개념입니다.
AI에게 자유롭게 맡기는 것이 아니라, 제약사항과 구조를 통해 워크플로우를 설계하는 것에 초점을 둡니다.

여기서 중요한 점은,
LLM 모델 자체를 변경하거나 조작하는 것이 아니라,
모델이 원하는 작업을 잘 수행할 수 있도록 통제 가능한 환경을 만드는 것입니다.

즉, 하네스 엔지니어링은
AI를 단순한 도구로 사용하는 것을 넘어,
예측 가능하고 재사용 가능한 시스템으로 만드는 방법론이라고 볼 수 있습니다.

제가 기존 llm 을 사용하는 방식은 다음과 같았습니다.

  1. 프로젝트의 배경과 해야 할 일을 설명합니다. — 매 대화를 새로 열 때마다 "우리 서비스는 이러이러한 구조고, 이번엔 이 기능을 만들 건데…" 를 매번 복붙합니다. 같은 컨텍스트를 반복 입력하니 시간·토큰 비용이 계속 이중으로 나갑니다.

  2. 작업 계획(To-do) 작성을 요청합니다. — 그런데 AI는 계획을 다 짜기도 전에 "그럼 먼저 이 파일부터 수정하겠습니다" 하며 바로 구현으로 점프합니다. 설계 단계가 사실상 생략되기 일쑤입니다.

  3. 잘못된 작업 계획을 제가 수정합니다. — 누락된 케이스, 엉뚱한 파일 경로, 팀 컨벤션에서 벗어난 네이밍을 제가 매번 다시 잡아줍니다. 결국 사람이 품질 게이트가 되고, 같은 종류의 실수를 대화마다 반복 교정하게 됩니다.

  4. 참조해야 하는 DB, 성능 우려, 피해야 할 패턴을 입력합니다. — 이 규칙들은 어디까지나 현재 대화창 안에만 존재합니다. 다음 날 새 대화를 열면 그 지식은 증발해 있고, 저는 또 같은 내용을 타이핑하고 있습니다.

  5. 구현 과정에서 검토하며 잘못된 부분을 계속 수정합니다. — 대화가 길어질수록 컨텍스트가 오염되고, 테스트·리뷰·문서화는 "일단 다 만들고 나중에"로 밀려납니다. 결국 PR에는 구현만 달랑 올라오고, 리뷰와 문서는 사람이 뒷수습합니다.

정리하면 이 방식의 본질적인 문제는 이렇습니다. 품질을 유지하는 책임이 전부 사람(=저)한테 몰려 있다는 것. AI는 "가장 그럴듯한 코드"를 만들어 줄 뿐, 질문을 해야 할지, 설계를 먼저 해야 할지, 테스트부터 써야 할지는 매 대화마다 제가 직접 몰아붙여야 했습니다.


하네스가 필요한 이유

AI에게 어떻게 하면 일을 더 잘 시킬 수 있을지 고민하며 프롬프트를 다듬어오던 저에게, 하네스 엔지니어링은 새로운 방향이었습니다.

하네스 엔지니어링이라는 용어를 접하고 나서야, 기존에 겪고 있던 문제들이 개인의 프롬프트 기술 부족이 아니라 구조적인 문제라는 것을 받아들이게 되었습니다. 배경 컨텍스트를 반복해서 입력해야 하는 번거로움, 설계 없이 결과를 만들어내는 방식, 사람이 직접 품질을 검증해야 하는 구조, 규칙이 쉽게 사라지는 문제, 그리고 긴 대화로 인해 발생하는 컨텍스트 오염까지 — 이 모든 문제는 프롬프트를 아무리 잘 작성하더라도 "하나의 대화창 안에서 모든 것을 해결하려는 방식"을 유지하는 한 계속 반복될 수밖에 없습니다.

결국 필요한 것은 더 정교한 프롬프트가 아니라, AI 바깥에 규칙과 워크플로우를 고정해 두는 별도의 레이어입니다.

  • 대화가 바뀌어도 유지되는 배경 지식
  • 질문이나 단계를 건너뛸 수 없도록 만드는 흐름 제어
  • 역할별로 분리된 실행 컨텍스트

이 세 가지를 실제 파일과 실행 구조로 만들어 둔 것이 바로 하네스입니다.


하네스 구현 — dev-harness/ 만들기

그렇다면 위에서 정리했던 작업 5단계의 고통을 하네스로 어떻게 풀 수 있는지, 실제로 디렉터리를 하나 만들어 가며 보겠습니다. Claude Code를 기준으로 설명하지만, 개념 자체는 다른 에이전트 프레임워크에도 그대로 적용됩니다.

디렉터리 구조

dev-harness/
├── CLAUDE.md              # 프로젝트 규칙 — 매 대화 자동 주입
├── memory/
│   ├── team-rules.md      # 팀 컨벤션, 금지 패턴 (문제 4 해결)
│   └── stack.md           # 기술 스택, DB 스키마 요약 (문제 1 해결)
├── skills/
│   ├── plan/SKILL.md      # /plan — 설계 단계 강제 (문제 2)
│   ├── implement/SKILL.md # /implement — 설계 없이 실행 거부 (문제 2, 3)
│   └── review/SKILL.md    # /review — 체크리스트 기반 검증 (문제 3, 5)
└── agents/
    ├── planner.md         # 설계만 하는 격리 에이전트 (문제 5)
    ├── implementer.md     # 설계 범위 안에서만 구현 (문제 5)
    └── reviewer.md        # diff만 보고 판정 (문제 5)

각 파일이 5가지 문제를 어떻게 해결하는지 하나씩 보겠습니다.


문제 1: 배경을 매번 다시 설명한다 → CLAUDE.md + memory/

기존: 새 대화창마다 "우리 서비스는 NestJS + Prisma + MySQL이고, users 테이블은 소프트 삭제 쓰고, 세션은 Redis에 있고, 비동기 작업은 Amazon SQS로 넘기고…"를 복붙합니다. 토큰과 시간이 이중으로 나갑니다.

하네스: 자주 쓰는 배경을 파일로 옮깁니다. Claude Code는 CLAUDE.mdmemory/ 아래 지정된 파일을 매 대화 자동 주입하므로, 사용자는 더 이상 배경을 타이핑할 필요가 없습니다.

<!-- dev-harness/memory/stack.md -->
# Stack

## Backend
- TypeScript, Node.js 20, NestJS
- Prisma + MySQL 8, Redis 7
- 큐: Amazon SQS

## 주요 테이블
- `users(id, email, created_at, deleted_at)` — 소프트 삭제.
  조회 시 `deleted_at IS NULL` 필수.
- `sessions(id, user_id, refresh_token_hash, expires_at)`

이제 "users 조회 시 deleted_at 체크해줘"를 매번 말할 필요가 없습니다. 모델은 대화 시작 시점부터 이미 알고 있습니다.

핵심: 반복 입력은 "프롬프트를 잘 쓰는 문제"가 아니라 "어디에 적어두는가"의 문제입니다. 대화창은 휘발 메모리, 파일은 영속 메모리입니다.


문제 2: 계획을 다 짜기도 전에 구현으로 점프한다 → /plan Skill + Guard

기존: "기능 A 만들어줘" → AI가 한두 줄 생각하더니 바로 파일을 열고 편집을 시작합니다. 설계가 없으니 범위도, 엣지 케이스도, 테스트 전략도 없습니다.

하네스: 워크플로우를 슬래시 커맨드로 고정하고, 다음 단계 진입에 가드를 겁니다.

<!-- dev-harness/skills/implement/SKILL.md -->
## 사전 조건 (Guard)

- 설계 문서 경로가 **반드시** 인자로 주어져야 합니다.
- 경로가 없거나 파일이 존재하지 않으면 **즉시 거부**하고
  `/plan`부터 돌리라고 안내합니다.
- 설계 문서의 "오픈 퀘스천" 섹션이 비어있지 않으면 **거부**하고
  먼저 해소하라고 요청합니다.

/implement는 설계 문서 없이는 호출 자체가 거부됩니다. 구현으로 점프하려면 /plan을 먼저 돌려서 designs/<slug>.md를 만들어야만 합니다. 물리적으로 설계 단계를 건너뛸 수 없게 만든 것이 핵심입니다.

프롬프트로 "계획부터 세워줘"라고 부탁하는 것과, 파일이 없으면 실행을 거부하는 것은 완전히 다릅니다. 전자는 모델의 선의에 기대지만, 후자는 하네스가 강제합니다.


문제 3: 잘못된 계획을 사람이 매번 잡아준다 → 템플릿 + Reviewer 체크리스트

기존: AI의 계획에 누락된 케이스와 팀 컨벤션 위반을 제가 매번 잡아냅니다. 같은 종류의 실수를 대화마다 교정합니다.

하네스: 품질 게이트를 체크리스트로 외부화합니다. /plan은 템플릿에 따라 정해진 섹션(배경, 범위, 영향 파일, 데이터 모델, 테스트 전략, 리스크, 오픈 퀘스천)을 반드시 채우게 만들고, /review는 체크리스트의 모든 항목을 검증하지 않으면 Approve를 낼 수 없게 만듭니다.

<!-- dev-harness/skills/review/SKILL.md -->
## 체크리스트

### 팀 규칙
- [ ] `SELECT *` 없음
- [ ] N+1 쿼리 없음
- [ ] `any` 타입 없음
- [ ] 소프트 삭제 테이블 조회 시 `deleted_at IS NULL` 포함

### 테스트
- [ ] 통합 테스트 **최소 1개** 존재
- [ ] Mock DB 아닌 **실제 DB** 기반

## 금지
- 체크리스트 중 하나라도 미충족이면 Approve 금지.

이제 "N+1 쿼리 있는지 봐줘"를 제가 말할 필요가 없습니다. 리뷰 에이전트가 체크리스트를 기계적으로 훑습니다. 사람의 머릿속에 있던 암묵지가 파일로 옮겨오는 순간, 그것은 재사용 가능한 자산이 됩니다.


문제 4: 규칙이 대화창 안에만 존재한다 → memory/team-rules.md

기존: "우리 팀은 SELECT * 금지야", "통합 테스트는 실제 DB에 붙여야 해"를 대화창에서 말합니다. 다음 날 새 대화를 열면 그 지식은 사라져 있습니다.

하네스: 규칙을 파일로 영속화하고, memory/team-rules.md 안에 왜 그 규칙이 생겼는지도 같이 적어둡니다. 이유가 없는 규칙은 곧 잊힙니다.

<!-- dev-harness/memory/team-rules.md -->
## 테스트
- 통합 테스트는 **실제 DB**에 붙입니다. Mock DB 금지
  (작년 Q3 마이그레이션 사고 재발 방지).

운영 원칙 한 가지: "대화창에서만 말한 규칙은 존재하지 않는 규칙" 으로 취급합니다. 새 규칙이 나오면 즉시 memory/에 커밋합니다. 이 원칙 하나만 지켜도 "어제 분명히 말했는데 또 까먹었네"가 사라집니다.


문제 5: 대화가 길어질수록 컨텍스트가 오염된다 → 에이전트 분리

기존: 하나의 대화창에서 설계 → 구현 → 리뷰 → 버그 수정 → 리팩터까지 모두 진행합니다. 중반쯤 지나면 초반의 설계 의도는 스크롤 저 위로 밀려나 있고, 모델은 최근 몇 턴의 코드 냄새만 기억합니다.

하네스: 각 단계를 별도 컨텍스트를 가진 에이전트에 위임합니다. 메인 대화창은 오케스트레이션만 담당합니다.

<!-- dev-harness/agents/reviewer.md -->
당신은 **리뷰어**입니다. 구현자의 맥락을 모릅니다.
diff와 체크리스트만 봅니다.

## 금지
- "대충 괜찮아 보인다"로 Approve 금지.
- 구현자의 의도에 휘둘리지 않습니다.
  당신은 의도를 모르는 게 정상입니다.

리뷰어가 구현자의 맥락을 모르는 것이 버그가 아니라 기능입니다. 구현자의 논리에 설득당하지 않고 독립적으로 판정하기 때문입니다. 사람으로 치면 "방금 짠 사람에게 직접 리뷰받지 말고, 코드만 보여주고 리뷰받아라"와 같은 이야기입니다.

실제 작동 방식:

사용자: /plan "사용자 리프레시 토큰 순환 기능"
  └─ [planner Agent, 격리 컨텍스트] → designs/refresh-rotation.md

사용자: /implement designs/refresh-rotation.md
  └─ [implementer Agent, 격리 컨텍스트] → 코드 + 테스트

사용자: /review
  └─ [reviewer Agent, 격리 컨텍스트] → Approve / Request Changes

메인 창은 3줄짜리 대화만 남습니다. 컨텍스트가 오염될 여지가 없습니다.


정리

5가지 문제와 하네스 해결책을 표로 정리하면 이렇습니다.

#기존 고통원인하네스 해결
1배경을 매번 복붙대화창이 휘발 메모리CLAUDE.md + memory/stack.md 자동 주입
2설계 생략, 구현으로 점프모델의 선의에 기대는 구조/implement 사전 조건 Guard
3사람이 품질 게이트암묵지가 사람 머릿속에만 존재템플릿 + /review 체크리스트
4규칙 증발규칙이 대화창 안에만 존재memory/team-rules.md 영속화
5컨텍스트 오염하나의 창에서 모든 단계 진행역할별 Agent 격리

공통 주제는 이것입니다. 프롬프트를 더 잘 쓰는 것으로 풀리지 않던 문제들이, AI 바깥에 파일과 구조를 만들어 두는 것만으로 풀렸습니다. 하네스 엔지니어링의 본질은 결국, 모델에게 던지는 말을 다듬는 일이 아니라 모델이 일하는 작업장을 설계하는 일 입니다.

적용 순서 제안

한 번에 전부 만들 필요는 없습니다. 저는 이 순서를 추천합니다.

  1. memory/stack.md 먼저. 반복 입력이 가장 즉각적인 고통이고, 효과도 가장 빠르게 체감됩니다.
  2. memory/team-rules.md. "같은 지적을 또 하고 있네" 싶을 때마다 한 줄씩 추가합니다.
  3. /plan Skill. 설계 없이 구현으로 점프하는 버릇이 사라집니다.
  4. /review Skill과 Reviewer Agent. 품질 게이트가 사람에서 체크리스트로 넘어갑니다.
  5. Planner/Implementer Agent 분리. 대화가 길어져 컨텍스트가 오염되는 게 느껴질 때 도입합니다.

작게 시작해서, 같은 실수가 두 번째 반복될 때마다 규칙을 파일로 옮기면 됩니다. 하네스는 한 번 만들고 끝나는 산출물이 아니라, 팀의 경험이 누적되는 살아있는 레이어입니다.


참고 자료

  • Anthropic, Building effective agents — 에이전트 루프와 워크플로우 패턴
  • Claude Code 공식 문서 — CLAUDE.md, Skills, Subagents, Hooks
  • 이 블로그에 함께 포함된 dev-harness/ 디렉터리 — 위 설명과 1:1로 대응하는 실제 파일들
profile
https://github.com/Fixtar

0개의 댓글