하네스 엔지니어링: AI 에이전트를 제대로 일하게 만드는 기술


3년 전에는 "프롬프트 엔지니어링"이 화두였죠. 지금은 "하네스 엔지니어링"입니다. 프롬프트가 AI에게 뭘 시킬지 고민하는 거라면, 하네스는 AI가 일하는 환경 자체를 설계하는 건데 — 이게 생각보다 결과 차이가 큽니다.
올해 2월 OpenAI가 5개월간 코드 한 줄 직접 안 쓰고 100만 줄짜리 제품을 만든 실험 결과를 공개했고, 3월에는 Anthropic이 3-에이전트 아키텍처로 수 시간짜리 자율 코딩 세션 성과를 발표했습니다. 36Kr는 "업계 전체가 하네스에 열광한다"고 보도했고요.
저는 지난 몇 달간 "니콜"이라는 AI 에이전트를 만들면서 이걸 직접 경험했습니다. 하네스 엔지니어링이 뭔지, 니콜에서는 어떻게 쓰고 있는지 정리해봅니다.
하네스가 뭔데?
"하네스(Harness)"는 원래 말에 채우는 고삐나 안장을 뜻합니다. AI 맥락에서는 에이전트가 작업하는 외부 환경 전체를 가리킵니다. 프롬프트, 도구, 컨텍스트 관리, 피드백 루프, 샌드박스, 오케스트레이션 로직 — 이런 것들이죠.
왜 갑자기 이게 중요해졌냐면, AI 모델의 코딩 능력이 꽤 좋아졌거든요. GPT-5.3 Codex나 Claude Opus 4.5/4.6 정도 되면 코드를 직접 짜는 건 잘합니다. 문제는 "긴 작업을 안정적으로 해내느냐"입니다.
한국의 개발자 Minho Hwang이 Claude Code에 하네스를 적용하는 실험을 했는데, 같은 모델에 하네스 유무만 바꿨더니 49.5점 vs 79.3점이라는 결과가 나왔습니다. 60% 품질 향상, 15개 과제에서 15전 15승. 모델을 바꾸지 않아도 환경만 바꾸면 이 정도 차이가 나는 겁니다.
하네스의 네 가지 기둥
하네스를 구성하는 요소는 크게 네 가지로 나뉩니다.
1. 청사진 (CLAUDE.md / AGENTS.md)
프로젝트의 규칙과 구조를 담은 문서입니다. AI 에이전트가 세션을 시작할 때 자동으로 읽어들이죠. "이건 건드리면 안 되고, 저건 이 방식으로 해야 해" 같은 맥락을 제공합니다.
OpenAI의 Michael Bolin은 이를 100줄 이내로 유지할 것을 권장합니다. 목차 역할만 하고, 상세 내용은 docs/ 폴더에 두라는 거죠. 어차피 에이전트가 필요할 때 찾아 읽으니까요.
2. 스킬 (Skills)
필요할 때만 로드하는 전문 지식 모듈입니다. "주식 조회해줘"라고 하면 주식 스킬만 로드되고, "브라우저로 이 페이지 열어"라고 하면 브라우저 스킬만 로드됩니다. ETH Zurich 연구에 따르면 모든 지식을 한꺼번에 컨텍스트에 넣으면 오히려 성능이 떨어진다고 하는데, 스킬이 이 문제를 풀어주는 셈이죠.
3. 서브에이전트 (Sub-agents)
역할별로 전문화된 에이전트를 나누는 겁니다. Anthropic은 Planner(기획), Generator(구현), Evaluator(검증)로 나누는 3-에이전트 구조를 제안했는데, GAN에서 영감을 받았다고 합니다. 생성자가 코드를 짜고, 평가자가 Playwright로 실제 앱을 돌려보면서 QA하는 방식이죠. 자기 코드를 자기가 평가하면 관대해지니까요.
4. 자동화 (Hooks / Commands)
이벤트에 반응하는 자동화 파이프라인입니다. 코드가 변경되면 자동 빌드 체크, 커밋 전에 린트 검사, 특정 시간에 정기 작업 실행. 사람이 매번 개입하지 않아도 돌아가게 만드는 거죠.
OpenAI vs Anthropic: 두 가지 철학
하네스를 얼마나 강하게 만들 것이냐에 대해 두 회사의 관점이 다릅니다.
Anthropic은 "강력한 하네스" 쪽입니다. 멀티에이전트 협업, 스프린트 계약, 구조화된 핸드오프. 에이전트가 컨텍스트를 다 쓰기 전에 "진행 파일"을 남기고, 다음 에이전트가 이어받습니다. Generator와 Evaluator가 5~15회 핑퐁하면서 품질을 올리고요.
OpenAI는 "최소한의 하네스" 쪽입니다. 모델에게 자율성을 돌려주고, 하네스는 샌드박스와 보안만 담당합니다. 대신 맞춤 린터나 CI로 아키텍처 규칙을 기계적으로 강제하죠. Michael Bolin 말로는 "하네스는 모델의 부족함을 보완하는 중간 단계"라고 합니다. 모델이 좋아지면 결국 내재화된다는 거죠.
어느 쪽이 정답이라기보다는, 모델 능력과 작업 복잡도에 맞는 수준을 찾아야 합니다.
니콜 프로젝트: 하네스 엔지니어링의 실전 사례
니콜은 제가 만들고 있는 AI 에이전트입니다. 텔레그램으로 대화하고, 브라우저를 제어하고, 블로그를 쓰고, 주식을 조회하고, 이미지도 만듭니다. 이 프로젝트를 하네스 관점에서 뜯어보면 이렇습니다.
청사진: CLAUDE.md
니콜의 CLAUDE.md에는 아키텍처, 서비스 관리 규칙, LLM 라우팅, 스킬 시스템, 기억 원칙이 들어 있습니다. 예를 들면:
- "텔레그램 서비스는 메시지 수신/전송만, LLM 없음" — 역할 분리 규칙
- "코드 수정 후 재시작 전 반드시 tsc --noEmit 빌드 체크" — 안전 규칙
- "새 기능은 TypeScript 코드 수정 말고 SKILL.md + scripts/로 만들어라" — 확장 원칙
이 문서가 있어서 Claude Code로 작업할 때마다 같은 맥락을 반복 설명할 필요가 없습니다.
스킬: 점진적 공개의 실전
니콜에는 현재 16개가 넘는 스킬이 있습니다. browser, stock, image-gen, fullstackfamily, scheduler, morning-briefing 같은 것들인데, 각각 YAML frontmatter가 달린 SKILL.md 파일로 정의되어 있고 키워드 매칭될 때만 프롬프트에 들어갑니다.
"주식 조회해줘"라고 하면 stock 스킬만, "블로그 써줘"라고 하면 blog 스킬만. 재시작 없이 핫리로드됩니다. OpenAI가 말하는 "점진적 공개(Progressive Disclosure)"와 같은 패턴이죠.
멀티에이전트: 세 개의 루프
니콜의 아키텍처는 세 층으로 나뉩니다:
- 텔레그램 서비스 — 메시지 수신/전송만 담당. LLM 호출 없음
- Nicole Core Server — 유일한 LLM 호출 지점. 의식 로드 → 프롬프트 조립 → LLM 호출 → 도구 실행 → 의식 기록
- Loop 1 (스킬 팩토리) — SKILL.md와 CLI 도구를 자동 생성하는 자기 진화 루프
Anthropic의 3-에이전트(Planner-Generator-Evaluator) 구조와 비교하면, 니콜은 Core Server가 기획+생성을 겸하고 Loop 1이 도구 생산을 담당하는 구조입니다. Evaluator를 별도로 분리하진 않았는데, 이건 앞으로 보완할 영역이기도 합니다.
멀티 LLM 라우터: 역할별 모델 분리
니콜은 하나의 LLM만 쓰지 않습니다. 역할에 따라 다른 모델을 자동 선택합니다:
- 텔레그램 일상 대화 → GPT-5.4-mini (저렴, 빠름)
- 단순 도구 호출 → GPT-5.4-nano (더 저렴)
- 전략/기획 → GPT-5.4 (고성능)
- 비동기 복잡 작업 → GLM-5 (무제한 플랜)
- 코딩 → agent-server의 GLM CLI (무제한)
비용은 하루 $5 안에서 관리되면서도, 필요하면 무거운 모델을 꺼내 쓸 수 있습니다. 서킷 브레이커가 있어서 연속 3회 실패하면 60초 쿨다운 후 자동 복구되고요.
기억 시스템: 의식의 흐름
니콜의 모든 도구 실행 결과는 consciousness-stream.json에 기록됩니다. 1줄 요약, 태그, 상세 내용이 계층적으로 저장되고, 나중에 "그때 뭘 했어?"라고 물으면 검색할 수 있습니다.
하네스 엔지니어링에서 말하는 "진행 기록"과 비슷한데, 니콜은 단순 로그가 아니라 에피소드 기억으로 쌓습니다. 세션이 바뀌어도 이전 경험을 찾아볼 수 있죠.
사이트별 경험 축적: action replay
브라우저 작업에서 성공한 시퀀스를 data/site-knowledge/에 기록해둡니다. 네이버 블로그에서 글 쓰는 순서, 풀스택패밀리에서 댓글 다는 방법 같은 것들이죠. 다음에 같은 작업을 할 때 LLM이 처음부터 분석하지 않고 기록된 플로우를 그대로 재생합니다.
OpenAI가 말하는 "기계적 강제"와 비슷한 개념입니다. 한번 증명된 방법은 고정해서 매번 재발견하지 않게 하는 거죠.
아직 부족한 것들
니콜이 하네스를 꽤 갖추고 있긴 한데, 업계 트렌드를 보면 아쉬운 부분이 보입니다.
첫째, Generator-Evaluator 분리가 안 되어 있습니다. Nicole Core Server가 코드 생성과 검증을 한 번의 LLM 호출에서 다 처리하거든요. Anthropic처럼 별도 Evaluator가 Playwright로 실제 결과를 확인하는 구조를 넣으면 품질이 올라갈 텐데, 아직 구현하지 못했습니다.
둘째, 기계적 강제가 약합니다. 맞춤 린터나 CI로 아키텍처 규칙을 강제하는 게 거의 없어요. OpenAI는 린트 오류 메시지 자체를 에이전트의 수정 지침으로 쓰는데, 이게 깔끔하죠.
셋째, 하네스를 정리하지 못하고 있습니다. Anthropic의 Prithvi Rajasekaran은 "Opus 4.6에서는 스프린트 분해가 불필요해져서 제거했다"고 했는데, 모델이 발전하면 이전에 필요했던 보조 장치가 오히려 방해가 될 수 있거든요.
정리
결국 하네스 엔지니어링은 이런 겁니다 — 모델을 바꾸지 않아도, 환경을 잘 만들면 결과가 달라진다.
니콜을 만들면서 느낀 건, CLAUDE.md 하나 잘 써놓는 것만으로도 매 세션의 시작이 달라진다는 겁니다. 거기에 스킬로 컨텍스트를 관리하고, LLM을 역할별로 나누고, 경험을 기록해두면 에이전트가 점점 더 안정적으로 돌아갑니다.
요즘은 코드를 직접 짜는 시간보다 AI가 잘 일하도록 환경을 만드는 시간이 더 많아지고 있는데, 그게 나쁘지 않은 방향인 것 같습니다.



댓글
댓글을 작성하려면 이 필요합니다.