요약: 네이티브 개발자의 FE 개발을 돕기 위해 AI Agent 하네스를 만들었습니다. 무엇을 담았고, 어떻게 Agent를 강제하고 운영했는지, 그리고 왜 금방 레거시가 되었는지 돌아봅니다.
💡 리뷰어 한줄평
sueaty.cho 트렌드가 워낙 빠른 마켓이라 이제는 모델의 발전에 따라 하네스의 필요성에 물음표를 던지는 요즘입니다. 그럼에도 회사에서 전문 분야가 다른 개발자들 간 협업을 할 때 최소한의 규칙과 가이드를 제공하고 싶은 팀이 있다면 꼭 읽어봤으면 하는 글입니다.
시작하며
안녕하세요. 카카오페이에서 FE 개발을 하고 있는 오프라인결제클라이언트 팀의 홀트입니다.
1편에서는 AI Agent를 쓰기 전에 알아두면 좋을 Tool, MCP, Skill, Plugin, Harness 개념을 정리했습니다. 이 글에서 하네스는 모델을 둘러싼 규칙 파일, Skill, Subagent, Hook 같은 실행 환경 전체를 가리킵니다. 이번 2편에서는 개념을 실제로 구현해 본 경험을 공유합니다.
먼저, 이 글은 성공 사례가 아닙니다. 의도대로 잘 돌아간 부분도 있고 그렇지 않은 부분도 있었습니다. 설계가 무거워졌다가 가벼워진 과정을 돌아보며, 하네스에서 어떤 부분이 남고 어떤 부분이 금방 레거시가 되었는지 정리해 보았습니다.
1. 우리가 FE 하네스를 만든 이유
네이티브 개발자의 FE 개발을 돕고 싶었습니다
저희 오프라인결제클라이언트 팀에는 FE, iOS, Android 개발자분들이 한 조직으로 함께 일하고 있습니다. AI를 활용한 개발 시대에 맞춰 플랫폼의 경계를 허물고 서로의 과제를 함께 맡아 보면 어떨까 생각했고, 이때 잘 다듬어 둔 하네스가 있으면 도움이 되지 않을까 싶었습니다.
FE 개발자들이 오래 다듬어 온 것들이 있습니다.
- 개발 방식과 작업 순서
- 개발 환경과 기술 스택
- 컨벤션과 규칙
- 디자인 시스템과 이벤트 로깅 규칙
이런 내용은 일부만 문서로 남아 있고, 대부분은 FE 개발자들의 머릿속에 있는 암묵지입니다. 네이티브 개발자가 FE를 처음 시작할 때 이 모든 걸 한꺼번에 익히기는 어렵습니다. 그래서 FE 개발자가 해 온 방식을 하네스에 담아, 누가 개발하더라도 같은 기준으로 작업하게 하는 것을 목표로 했습니다.
규칙 파일 하나로는 부족했습니다
규칙 파일을 길게 쓰면 Agent가 지시를 놓치기 쉽습니다. 사용하는 Agent 도구의 공식 문서도 프로젝트 지침 파일 하나는 200줄 미만으로 두고, 일부 경로에만 필요한 내용은 경로별 규칙으로 나누라고 안내합니다. 컨벤션, 룰, 사용 라이브러리, 특징을 한 문서에 모두 넣을 수 없었습니다. 그래서 문서를 역할별로 나누고, 역할이 정해진 Subagent(메인 세션이 일을 넘기는 별도의 Agent)와 Skill(작업 절차를 담은 문서)이 해당 문서만 참고하도록 하면 더 효율적으로 동작하지 않을까 생각했습니다.
팀 공용으로 관리하고 싶었습니다
자주 쓰고 좋은 것은 다 같이 나눠 쓰자는 의도도 있었습니다. 개인 환경에 흩어져 있는 Skill과 Subagent 등을 한곳에 모으고 싶었습니다.
1편의 개념으로 풀면 이렇습니다.
| 1편 개념 | 담고 싶은 것 |
|---|---|
| 규칙 파일 | 항상 지켜야 하는 프로젝트 규칙 |
| Skill | 디자인 구현, API 연동 같은 작업 절차 |
| Subagent | 작업별 전문 역할 |
| Hook, Harness | 어기면 안 되는 규칙의 강제 |
| Plugin, Marketplace | 위 요소를 묶어 팀에 배포 |
2. FE 하네스에 만든 것
도메인 지식을 어떻게 담았나
디자인 시스템 사용법, 이벤트 로깅 규칙, 상태 관리와 API 호출 방식 같은 FE 팀의 약속을 프리셋이라는 문서로 묶었습니다. 새 프로젝트에 플러그인을 설치하고 초기화 Skill을 실행하면 아래 순서로 동작합니다.
- 감지: 프로젝트의 의존성과 코드 패턴을 읽어 어떤 디자인 시스템과 라이브러리를 쓰는지 파악합니다.
- 합성: 감지 결과와 프리셋을 조합해 프로젝트에 맞는 규칙 파일을 만듭니다. 규칙은 경로별로 쪼개서, 해당 경로의 파일을 다룰 때만 읽히게 했습니다.
- 메타데이터 기록: 어떤 프리셋, 어떤 버전으로 초기화했는지 기록하고, 하네스가 만드는 임시 파일은 버전 관리에서 제외합니다.
- 검증: 생성된 규칙 파일이 제대로 만들어졌는지 확인합니다.
실제 프로젝트에서 초기화 Skill을 실행한 결과를 요약하면 아래와 같습니다. 사내 패키지와 경로 이름은 일반화하고, 일부 내용은 단순화했습니다.
> 프로젝트 초기화해줘
[1/4 감지]
디자인 시스템: 사내 디자인 시스템 패키지 사용 중
코드 패턴: export는 arrow, import alias는 @/*, 스타일은 scss-modules
[2/4 합성] 경로별 규칙 파일 4개 생성
react-conventions.md 적용 경로: **/*.tsx, **/*.ts
scss-conventions.md 적용 경로: **/*.scss
api-conventions.md 적용 경로: **/queries/**, **/mocks/**, **/services/**, **/api/**
event-log-conventions.md 적용 경로: 이벤트 로깅 디렉터리
[3/4 메타데이터]
preset.json 기록: 프리셋 버전, 신규/이전 디자인 시스템, 초기화 시각
[4/4 검증]
preset.json 필수 필드: 통과
규칙 파일 메타데이터: 통과
기존 AGENTS.md: 수정하지 않음
합성 단계에서 생성된 규칙 파일 중 하나를 열어 보면 아래와 같습니다. 파일 맨 위에는 적용 경로와 코드를 읽어 감지한 패턴이 기록되고, 이어서 반드시 지킬 규칙(Hard)이 나옵니다. 그 뒤에는 프로젝트 코드가 다르면 코드를 따를 권장 패턴(Soft)이 이어집니다.
규칙 파일 맨 위의 paths에 적은 경로의 파일을 다룰 때만 해당 규칙이 로드됩니다. 생성된 파일에는 paths 외에 감지한 패턴도 함께 기록하지만, 도구가 읽는 것은 paths뿐이어서 감지 결과는 사람이 참고하는 정보에 가깝습니다.
---
paths:
- "**/*.tsx"
- "**/*.ts"
---
1편에서 말씀드린 “상시 규칙은 규칙 파일에, 특정 작업 지식은 Skill에”를 그대로 적용한 구조입니다.
작업 절차를 어떻게 담았나
자주 반복되는 작업은 절차를 Skill로 만들었습니다.
- 디자인 시안을 FE 코드로 옮기는 작업
- API 명세를 읽고 연동 코드를 만드는 작업
- 이벤트 로깅 코드를 추가하는 작업
- 브라우저로 동작을 확인하는 작업
디자인 시안을 코드로 옮기는 Skill은 분석, 구현, 검증, 리뷰 네 단계로 나눴습니다. 분석 단계에서는 읽기 전용 Agent가 “이 화면을 어떤 컴포넌트 조합으로 만들고 어떤 색, 간격, 타이포 토큰을 쓸지” 매핑표만 만듭니다. 이 단계에서는 코드를 한 줄도 쓰지 않습니다. 구현 단계에서는 그 매핑표를 입력으로 받아 파일을 만듭니다. 검증 단계에서는 Agent에게 맡기지 않고 메인 세션이 타입 체크와 린트를 직접 실행하고, 리뷰 단계에서는 관점이 다른 Agent 세 개가 구현된 코드를 병렬로 검토합니다. 두 단계가 어떻게 동작하는지는 3절에서 자세히 설명합니다.
별도 오케스트레이터 Agent를 두지 않았습니다
여러 Agent를 지휘하는 방법은 두 가지가 있습니다. 별도 오케스트레이터 Agent를 하나 두는 방법과, 사용자가 대화 중인 메인 세션이 직접 지휘하는 방법입니다. 저희는 후자를 택했습니다. 별도 오케스트레이터가 있으면 Subagent를 호출하기 전에 한 단계가 더 생겨 핸드오프가 늘고, 그만큼 컨텍스트 손실과 토큰 소모가 늘 것으로 예상했기 때문입니다.
대신 메인 세션이 직접 파일을 읽고 고치기보다 Subagent를 호출하는 도구로 일을 넘기도록 Skill에 지시했습니다. 그리고 Subagent 호출이 정해진 흐름대로 이뤄지는지는 Hook 이벤트에 적용해 둔 스크립트로 검사했습니다. 이어지는 3절 내용입니다.
3. Agent에 컨벤션을 강제한 방법
이 하네스에서 가장 공을 들인 부분입니다. Agent에게 강제하는 시스템을 만들려고 했습니다. 문서로 관리되는 규칙 파일에 “반드시 지켜라”라고 적어도 Agent는 가끔 이를 어기기도 하고, AI는 사용하는 사람마다, 사용하는 모델마다 각기 다른 결과를 내놓습니다. 프롬프트로 내린 명령은 지켜지지 않을 확률이 있다고 판단했습니다. 그래서 1편에서 말한 대로, 지켜야 하는 규칙은 프롬프트가 아니라 Hook에서 실행될 스크립트로 강제했습니다.
Hook은 Agent가 일하는 동안 정해진 시점마다 스크립트를 실행할 수 있게 해 주는 기능입니다. 이 Hook들은 이름이 정해져 있는데요. 저희는 아래 네 가지 Hook 이벤트에 직접 구현한 스크립트 7개를 적용했습니다.
이 글의 Hook 이벤트 이름, 경로별 규칙 적용 방식, 플러그인 배포 방식은 현재(2026년 10월 기준) 사용 중인 Agent 도구의 규격을 기준으로 합니다. AI Agent 도구는 변화가 빠른 만큼 이 내용도 금방 레거시가 될 가능성이 높고, 같은 개념이라도 도구마다 이름과 입출력 형식이 다르므로, 사용하는 도구의 문서를 확인해 주세요.
| Hook 이벤트 | 실행 시점 | 하는 일 | 구현 스크립트 |
|---|---|---|---|
UserPromptSubmit | 사용자가 메시지를 보낸 직후, 모델이 읽기 전 | 컨텍스트 주입 | keyword-detector, fe-keyword-detector: “피그마 디자인을 참고하여 구현해줘” 같은 약속된 키워드를 감지해 해당 Skill로 연결 |
PreToolUse | 모델이 도구를 호출하기 직전 | 도구 호출 차단(deny), 컨텍스트 주입 | delegation-enforcer(잘못된 Agent로 호출하면 차단), phase-gate(이전 단계의 산출물이 없으면 차단), context-injector(프로젝트 규칙 파일을 프롬프트 뒤에 붙임) |
PostToolUse | 도구 실행이 끝난 직후 | 관찰과 기록 (이미 실행된 도구를 취소할 수는 없음) | evidence-recorder: 린트, 타입 체크 결과를 파일로 기록하고 실패하면 수정 단계로 전환 |
Stop | 모델이 응답을 끝내려는 순간 | 응답 종료 차단 | skill-stop-guard: 미완료 단계가 남아 있으면 종료를 차단하되, 컨텍스트 한계나 인증 오류에서는 예외로 허용 |
PreToolUse에 적용한 스크립트는 Subagent를 호출할 때만, PostToolUse에 적용한 스크립트는 셸 명령을 실행할 때만 동작하도록 범위를 좁혔습니다.
이 스크립트들로 만든 대표적인 강제 장치는 아래와 같습니다.
| 강제 장치 | 막으려던 문제 | 구현 방식 |
|---|---|---|
| 작업별 올바른 Agent로 위임 | 전문 Agent가 있는데도 범용 Agent가 대충 처리 | 요청의 키워드를 감지해 작업 종류를 판별하고, 잘못된 위임이면 거부하면서 이유를 알려 다시 시도하게 함 |
| 단계 건너뛰기 방지 | 분석 없이 바로 구현 | 각 단계가 남기는 산출물 파일을 확인하고, 이전 단계의 산출물이 없으면 다음 단계 호출을 차단. 파일이 있는지만 확인하므로 내용이 충분한지는 보장하지 않음 |
| 중간 종료 방지 | 절차가 남았는데 “완료”를 선언 | 작업 상태를 파일에 저장해 두고, 종료 시점에 미완료 단계가 있으면 종료를 막음 |
| 검증 결과 기록 | 실행하지 않은 검증을 통과했다고 보고 | lint, 타입 체크, 테스트 실행 결과를 도구 실행 직후에 기록하고, 실패하면 자동으로 수정 단계로 전환. Agent가 명령을 실행했을 때만 기록되고 종료 코드를 믿는 방식이라, 아래 사례 2처럼 종료 코드가 가려지면 틀릴 수 있음 |
이 밖에도 컨벤션 주입, 프리셋 변경 시 마이그레이션 강제(릴리스 차단), 브라우저 자동화 포트 격리 장치가 있었습니다.
호출, 종료, 릴리스 단계에서 검사할 수 있는 규칙은 “모델이 알아서 잘 하길 기대하는” 대신 “어기면 진행되지 않게” 스크립트로 제한하려 했습니다. 상태머신처럼 작업 단계와 산출물을 파일로 남기고, 스크립트가 그 파일을 검사하는 구조입니다.
관점이 다른 세 개의 리뷰어 Agent
마지막 리뷰 단계에는 세 개의 리뷰 Agent를 두었습니다. 같은 코드를 서로 다른 관점으로 바라보도록 했습니다.
- 유지보수 관점: 불필요한 추상화, 죽은 코드, 헷갈리는 이름
- 컨벤션 관점: 규칙 파일과 프로젝트 가이드를 지켰는지
- 정확성 관점: 로직 오류와 엣지 케이스
세 Agent가 같은 줄을 지적하면 우선 확인할 후보로 삼았습니다. 같은 모델이 같은 코드를 보기 때문에 합의만으로 문제를 확정하지는 않고, 실제 실패 조건이나 테스트로 확인하는 과정이 필요합니다. 리뷰어가 하나뿐이면 이런 교차 확인을 할 수 없습니다.
만들면서 겪은 문제들
처음부터 잘 동작하지는 않았습니다.
1. 위임을 강제하는 스크립트가 사실 아무것도 하지 않고 있었습니다. 요청에 “피그마 분석”이 들어 있는데 범용 Agent로 호출되면 바로잡아야 하는 장치였습니다. 이 스크립트는 PreToolUse Hook에 걸려 있습니다. PreToolUse는 모델이 도구를 호출하기 직전에 실행되는 Hook 이벤트로, 이 시점에 호출을 거부할 수도 있습니다. 그런데 처음 구현은 이 이벤트가 기대하는 형식과 다른 값을 출력하고 있었습니다. 단위 테스트도 통과해서 호출을 잘 걸러내고 있다고 믿었지만, 실제 Agent 세션에서 지켜보니 범용 Agent로 보낸 작업이 아무 제지 없이 그대로 통과되고 있었습니다. 이후 잘못된 호출이면 거부 사유와 함께 차단하도록 다시 만들었습니다. 모델은 사유를 읽고 올바른 Agent로 다시 시도합니다.
아래는 PreToolUse 이벤트에서 호출을 거부할 때의 출력 형식입니다.
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "요청에 '피그마 디자인 분석'이 포함되어 있습니다. 디자인 분석 전용 Agent로 호출해 주세요."
}
}
단위 테스트는 스크립트가 만든 출력의 모양만 확인했을 뿐, Agent 도구가 그 출력을 실제로 받아들이는지는 확인하지 못했습니다. 테스트가 통과해서 안심했던 만큼 발견도 늦었고, 도구가 읽는 출력은 실제 동작을 관찰해서 확인해야 한다는 점을 배웠습니다.
2. 린트가 실패했는데 통과로 기록되고 있었습니다. 검증 결과를 기록하는 스크립트는 린트나 타입 체크 명령이 끝난 뒤 그 명령의 종료 코드를 보고 통과 여부를 판단합니다. 종료 코드는 명령이 끝날 때 셸이 돌려주는 숫자로, 성공하면 0, 실패하면 0이 아닌 값입니다. 이 방식은 Agent가 명령을 있는 그대로 실행한다는 전제 위에서 성립합니다.
그런데 AI Agent는 작업을 처리하는 동안 도구가 돌려준 긴 출력을 컨텍스트에 모두 담지 않으려고, 명령 뒤에 | tail -20과 같은 명령을 추가로 붙여 결과를 잘라서 보는 경향이 있습니다. |(파이프)는 앞 명령의 출력을 뒤 명령으로 넘겨주는 연결이고, tail -20은 받은 출력의 마지막 20줄만 보여 주는 명령입니다. 저희는 처음에 Agent가 명령을 이렇게 가공할 수 있다는 점을 놓쳤습니다.
pnpm lint | tail -20 # 린트 결과의 마지막 20줄만 보기
echo $? # 방금 실행한 명령의 종료 코드. 린트가 실패해도 0이 나옵니다
이렇게 연결하면 셸은 린트가 아니라 마지막 명령인 tail의 종료 코드를 돌려줍니다(셸의 기본 설정 기준입니다). tail은 항상 성공하므로, 린트가 실패해도 기록 스크립트에는 “성공(0)“으로 전달되고 있었습니다.
그래서 검증 명령 뒤에 파이프가 붙어 있으면 결과를 믿을 수 없는 것으로 보고 실패로 기록하고, 파이프 없이 다시 실행하게 했습니다. 종료 코드처럼 하네스가 믿고 쓰는 값도 틀릴 수 있다는 걸 이 버그로 알게 됐습니다.
3. 다른 세션의 작업에 영향을 끼쳤습니다. 스킬을 실제 프로젝트에서 돌려 보던 중, Agent가 린트 오류가 내 변경 때문인지 원래 있던 오류인지 확인하려고 git stash && pnpm lint && git stash pop을 실행했습니다. git stash는 아직 커밋하지 않은 변경을 모두 별도 보관함(stash)으로 옮기는 명령입니다. 여러 세션이 같은 작업 폴더를 함께 쓰고 있으면 다른 세션이 작업하던 변경도 파일에서 사라집니다. 더구나 &&는 앞 명령이 성공해야 다음 명령을 실행하는 연결인데, 린트가 실패하면 stash pop(보관함에서 변경을 꺼내 되돌리는 명령)이 실행되지 않아 변경이 보관함에만 남은 채 복원되지 않습니다. 변경 자체는 보관함에 남아 복구할 수 있지만, 그 사실을 모르는 다른 세션은 작업이 사라진 상태로 이어서 작업하게 됩니다.
검증 단계 문서에 작업 중인 변경을 치우거나 되돌리는 git 명령(stash, restore, clean, reset --hard)을 쓰지 말라는 규칙을 넣었습니다. 대신 변경한 파일만 따로 린트해 원인을 분리하고, git diff --quiet는 변경 여부를 확인하는 데만 쓰도록 했습니다. “내 변경이 만든 오류”와 “원래 있던 환경 오류”를 구분하는 기준표도 같이 넣었습니다. 다만 이 규칙은 Skill 문서에 적은 지침이라, 앞서 말한 기준대로라면 Bash 호출을 검사하는 스크립트로 막는 쪽이 맞습니다. 아직은 Agent가 지키기를 기대하는 단계에 머물러 있습니다. 강제 장치를 만들 때는 허용할 행동의 범위도 함께 정해야 한다는 점을 배웠습니다.
세 가지 모두 하네스를 믿고 맡겼는데 의도와 다르게 동작하던 경우였습니다. Agent는 모델 제공사가 만든 시스템 안에서, 우리가 들여다볼 수 없는 블랙박스처럼 각종 명령을 고르고 실행합니다. Agent가 하는 일을 무조건 믿어서는 안 되고, 하네스에도 꼼꼼한 검증이 필요하다고 생각했습니다.
4. 팀 공용 플러그인으로 운영한 방법
개인이 만든 Skill, Hook, Subagent를 팀 공용으로 운영하기 위해 아래와 같은 규칙들을 정했습니다.
- 플러그인별 독립 버전 관리: 동료의 환경에서 플러그인 자동 업데이트가 켜져 있을 때, 업데이트가 일어났다는 사실을 알 수 있어야 했습니다. 새 Skill이나 Hook이 모르는 사이에 들어와 임의로 발동되는 상황을 줄이려는 것입니다. 다만 버전을 나눈다고 업데이트를 인지하거나 막을 수 있는 것은 아니어서, 아래 공유 규칙을 함께 뒀습니다.
- 변경되거나 추가된 내용 공유: 어떤 Skill과 Hook이 추가되고 무엇이 바뀌었는지 슬랙이나 PR에서 꼭 공유하여 동료들 모두가 인지하도록 했습니다.
- 로컬 검증 우선: 먼저 개인 로컬에서 직접 써 보고, 쓸 만하다는 확신이 들면 플러그인에 올리도록 정했습니다. 모든 기능이 하네스 플러그인에 들어갈 필요도 없고, 별도 Skill이나 Hook으로 올려도 됩니다.
공용 Skill을 하나의 큰 플러그인에 넣지 않고 별도 플러그인으로 나눈 이유도 같습니다. 사용하고 싶은 사람과 아닌 사람이 있을 수 있으니, 각자 필요한 것만 설치하고 켜게 하자는 의도였습니다.
개발은 이렇게 했습니다
하네스를 개발할 때는 터미널 멀티플렉서(tmux)로 창을 나눠 썼습니다. 한쪽에는 플러그인을 개발하는 Agent 세션을, 다른 쪽에는 그 플러그인을 사용해 볼 프로젝트의 Agent 세션을 띄웠습니다. 개발 쪽 Agent가 사용 쪽 세션에 프롬프트를 보내고 결과를 관찰하면서 서로 주고받는 방식입니다. 위임 강제 장치가 동작하지 않던 문제도 이렇게 실제 세션을 관찰하다가 발견했습니다.
5. 우리 하네스의 아쉬웠던 점과 앞으로의 숙제
운영하면서 아쉬웠고, 아직 풀지 못한 점이 네 가지 있습니다.
- Agent가 정상 케이스 위주로만 검증하고 “다 됐다”고 보고하는 경향이 있습니다. 스크립트를 만들고 테스트 코드도 짜고 실제 세션에서 검증해도, Agent는 스스로 만족스러운 검증을 마치고 “모든 케이스를 검증했다”고 보고합니다. 그런데 세션을 닫고 새 세션에서 다시 살펴보면 문제가 남아 있는 경우가 많았습니다. 강제 장치를 만든 사람도 결국 같은 Agent라는 점이 한계입니다.
- 반복되는 실수를 어떻게 막을지 정하지 못했습니다. 검증 명령에 파이프를 붙이는 실수처럼 규칙으로 검사할 수 있는 것은 스크립트로 막았습니다. 하지만 코드 스타일이나 설계 판단처럼 기계적으로 검사하기 어려운 실수는 새 세션에서 같은 실수가 반복됩니다. 이전 세션의 교훈을 메모로 남겨 다음 세션에 넘기는 방법을 생각했지만, 메모도 매 세션 컨텍스트에 실리는 비용이고 낡은 메모는 오히려 틀린 지시가 됩니다. 무엇을 남기고 언제 지울지 기준을 정하지 못했습니다.
- 워크플로우가 만드는 파일이 계속 쌓입니다. 분석 결과 같은 산출물은 버전 관리에서는 제외했지만 로컬에는 남습니다. 디버깅용이고 워크플로우당 수십 KB 수준이지만, 계속 쌓아 둬도 괜찮은지는 정하지 못했습니다.
- 개선이 실제로 나아진 것인지 판단할 정량 지표가 없었습니다. 하네스를 고칠 때마다 좋아졌다고 느꼈지만, 기준이 없어서 말로만 판단했습니다.
6. 모델이 발전하며 레거시가 된 하네스
하네스를 만드는 사이에 모델은 빠르게 좋아졌습니다. 초기(2026년 2월 무렵)에는 단계별로 쪼개서 지시하고 프롬프트로 반복 주입해야 안정적으로 동작했던 작업을, 2026년 10월 현재는 짧은 지시와 규칙 파일만으로도 잘 해내는 경우가 많아졌습니다. 정량 비교는 하지 못했고, 운영하면서 느낀 변화를 바탕으로 정리한 내용입니다.
그래서 하네스의 각 요소를 왜 만들었는가를 기준으로 정리해 보면 아래와 같습니다.
| 만든 장치 | 이 장치를 만든 이유 | 모델이 발전한 뒤에는 어떻게 되나 |
|---|---|---|
| 작업을 잘게 쪼갠 단계, 강한 어조의 지시문, 세분화된 역할 페르소나, 키워드로 Agent를 지정하는 라우팅 | 모델이 못하는 부분을 보완하려고 | 불필요해지거나 오히려 컨텍스트가 섞여 방해가 될 수 있음, 토큰 소비가 늘 수 있음 |
| 디자인 시스템 규칙, 이벤트 로깅 규칙, 컨벤션 문서 | 모델이 원래 모르는 팀의 지식을 알려주려고 | 코드만 봐서는 알 수 없는 사내 규칙은 계속 필요함. 다만 코드에서 알 수 있는 내용이나 분량이 많은 문서는 효과가 작고 비용만 늘 수 있음 |
| 검증 결과 기록, 마이그레이션 강제, 테스트와 릴리스 게이트 | 확률이 아니라 보장이 필요해서 | 모델이 좋아져도 자기 결과를 후하게 평가하거나 문서의 규칙을 놓치는 경향이 남아 있어 계속 필요함 |
| 단계 건너뛰기 방지, 위임 강제, 중간 종료 방지 | 모델이 단계를 건너뛰거나 일찍 끝내는 것을 막으려고 | 모델이 절차를 스스로 잘 따르게 되면 필요성이 줄어듦. 작업이 모델의 한계에 가까울 때만 효과가 큼 |
이 표는 1편의 마지막 문장과 이어집니다. “하네스는 실패를 자산으로 바꾸는 장치”라고 했는데, 제 하네스에는 자산이 된 부분과 부채가 된 부분이 섞여 있었습니다. 다만 부채인지 아닌지는 모델이 바뀔 때마다 다시 판단해야 합니다. 위와 비슷한 내용들은 모델 제공사의 글과 연구에도 있는데요.
- Anthropic은 하네스가 “모델이 혼자 하지 못하는 것”에 대한 가정을 담고 있고, 모델이 발전하면 그 가정이 더는 들어맞지 않게 된다고 설명합니다. 이전 모델은 컨텍스트 한계가 다가오면 작업을 서둘러 끝내려는 현상이 있어서 컨텍스트 초기화 장치를 넣었는데, 다음 모델에서는 그 현상이 사라져 장치가 불필요해졌다고 합니다.
- AGENTS.md 같은 컨텍스트 파일을 평가한 연구에서는 파일이 있어도 작업 성공률이 전반적으로 오르지 않았고 추론 비용은 평균 20% 이상 늘었습니다. 파일 속 지시는 잘 따랐지만 저장소 개요는 도움이 되지 않았고, 표준적이지 않은 코딩 관행을 알려 주는 데는 유용했다고 합니다.
- 문서에 적힌 제약을 실행 가능한 검사로 바꾼 연구에서는 SWE-bench Lite 300개 과제 기준으로 제약 준수율이 프롬프트만 쓸 때 67.0%, 스스로 되돌아보게 할 때 50.3%였고, 실행 가능한 검사를 쓰면 88.3%였습니다.
그래서 컨벤션 문서는 코드만 봐서는 알 수 없는 사내 규칙에 집중하고, 검증은 모델의 말이 아니라 실행 결과로 확인하는 쪽이 오래 간다고 생각합니다.
실제로 저희 하네스가 개발된 히스토리를 보면 위 연구 내용과 방향이 비슷합니다. 2026년 2월 말에는 Agent 21개, Skill 29개 규모였던 하네스가, 2026년 10월 현재는 Agent 11개, Skill 17개로 줄었습니다. 다른 도구와 겹치거나 쓰이지 않던 것을 정리한 결과도 있고, 모델이 좋아지면서 필요성이 줄어든 것도 있었습니다.
마치며
하네스를 개발하기 시작한 2026년 2월에는 Anthropic의 Opus 4.6, OpenAI의 GPT 5.3, 5.4 같은 모델이 최신 모델이었습니다. 지금은 Opus 5.5, GPT 6.1 Sol까지 출시되었는데요. 모델이 이렇게 빠르게 좋아지다 보니, 이제는 모델만으로 해결되는 일이 많아졌습니다. 그만큼 하네스의 상당 부분이 금세 레거시가 되었습니다.
처음 목표는 “네이티브 개발자가 FE를 쉽게 하게 만들기”였습니다. 이 목표가 실제로 얼마나 달성됐는지는 이 하네스를 활용한 결과와 함께 3편에서 이야기하려 합니다. 일부 장치는 금방 낡아버렸지만, 대신 하네스를 만들고 쓰는 과정에서 얻은 것은 분명합니다.
- 모델이 좋아져도 팀의 컨벤션 문서와 검증·릴리스 장치는 계속 쓰이고 있습니다. 새 모델이 나올 때마다 어떤 장치를 걷어낼지 다시 따져봐야 합니다.
- 강제 장치도 검증이 필요합니다. 테스트가 통과해도 실제 동작을 관찰해야 했습니다.
- 하네스에 단계와 지시를 더할수록 매 작업마다 Agent가 읽어야 하는 내용이 늘어 토큰 비용이 커집니다. 장치를 유지할 때는 이 비용도 함께 따져야 합니다.
- 개선했다고 느끼는 것과 개선된 것은 다릅니다. 정량적인 측정 기준이 없으면 하네스는 계속 쌓이기만 합니다.
1편에서는 “더 좋은 모델을 기다리는 것보다 지금 쓰는 도구의 실행 환경을 다듬는 쪽이 빠르다”고 썼습니다. 이 말은 지금도 맞다고 생각합니다. 다만 그 환경을 다듬을 때는 무엇을 남기고 무엇을 덜어낼지, 그리고 잘 다듬었는지를 어떻게 알 수 있을지를 함께 고민해야 한다는 점을 배웠습니다.
지금까지 읽어주셔서 감사합니다.