Skip to content
Go back

AI 에이전트 하네스 개발기 #5 — 실제 프로젝트에 적용해보니

#1에서 스캐폴더, #2에서 Hook, #3에서 학습 시스템, #4에서 워크플로우를 만들었다. 이론적으로는 완성이다. 근데 진짜 프로젝트에 붙여봐야 의미가 있다. 테스트 프로젝트를 새로 만들어서 /start <이슈번호>로 로그인 페이지를 구현해봤다.

테스트 프로젝트 세팅

npx @frontend-playground/agent-harness-starter로 모노레포를 만들었다.

프로젝트: test
구조: 모노레포 (Turborepo)
FE: Next.js App Router (FSD, styled-components, Jest)
BE: Java Spring Boot (Layered, Maven, PostgreSQL)
Blockchain: Solidity Hardhat
에이전트: Claude Code
이슈 트래커: Jira

/start <이슈번호> — 로그인 페이지 구현

Jira 티켓 <이슈번호>: “로그인(/login) 페이지 UI 컴포넌트 개발”

Jira 조회 성공

이슈 제목, 설명, 타입을 가져왔다. Figma 링크도 두 개 추출됐다 — 기획(와이어프레임)과 디자인(시안).

Figma 분석

기획 Figma에서 와이어프레임을 읽었다. 페이지 정보(Screen ID, 경로)부터 각 컴포넌트의 크기, 비즈니스 로직(이메일 유효성, 비밀번호 마스킹, 로그인 오류 팝업)까지 추출됐다.

디자인 Figma에서는 실제 시안을 읽었다. 1920×900 캔버스, 480px 폼 영역, 로고(191×40), 입력 필드(480×85), 버튼(480×60) 등 컴포넌트 구조와 크기가 나왔다.

구현 결과

에이전트가 FSD 구조로 파일을 생성했다.

apps/web/src/
├── shared/ui/
│   ├── button.tsx          — Button (primary/secondary)
│   ├── input.tsx           — Input (label, error, 눈 아이콘)
│   ├── button.test.tsx     — 4 tests
│   └── input.test.tsx      — 5 tests
├── features/auth/
│   └── ui/loginForm.tsx    — 로그인 폼 (formik, 유효성 검사)
├── pages/login/
│   └── ui/loginPage.tsx    — 페이지 레이아웃
└── app/login/page.tsx      — Next.js 라우트

4 suites, 18 tests 전부 통과.

터진 것들

styled-components를 골랐는데 CSS Module로 만든다

에이전트가 input.module.css, button.module.css를 만들었다. styled-components를 선택했는데 왜?

harness.config.jsondevelopment.styling이 빈 문자열이었다. 모노레포에서 FE 스택의 style 값이 공통 config에 전달되지 않는 버그. 그리고 룰 파일에 “CSS Module, Tailwind, styled-components 등을 사용한다”로만 적혀있어서 에이전트가 Next.js 기본값으로 판단했다.

→ config에서 FE 스택 style을 fallback으로 가져오고, 룰에 {{STYLING}} 플레이스홀더를 넣어서 해결.

Jest가 ts-node 없어서 안 돌아간다

jest.config.ts를 읽으려면 ts-node이 필요한데 devDependencies에 없었다. 그리고 setupFilesAfterSetup이라는 존재하지 않는 키를 쓰고 있었다. 정답은 setupFilesAfterEnv.

→ 스캐폴더에서 ts-node + setupFilesAfterEnv 자동 추가.

Go 테스트 파일이 kebab-case로 강제된다

inquiry-service-test.go가 생성됐는데, Go 테스트 파일은 반드시 _test.go여야 한다. scaffold-guard가 kebab-case를 강제하면서 언더스코어를 거부한 것.

→ 언어 규약으로 강제되는 파일명 패턴(*_test.go, test_*.py, mod.rs 등)은 scaffold-guard 스킵.

stop-review가 계속 에러를 뱉는다

“Stop hook error: Failed with non-blocking status code” 메시지가 끝없이 떴다. 새로 만든 프로젝트인데도. agent hook 문제인 줄 알고 수정하고, 제거까지 했는데 계속 뜬다.

진짜 원인: 초기 커밋이 없는 상태에서 git diff HEAD가 exit 128로 죽는 것. set -euo pipefail 때문에 스크립트가 즉시 종료. 이걸 찾는 데 시간을 꽤 썼다.

에러코드가 비어있다

metrics.jsonl"codes":[]로 기록됐다. biome 에러코드 추출 정규식이 biome 출력 포맷을 못 잡고 있었다. 그리고 biome의 check ━━━━━━━ 요약 줄에서 구분선이 에러코드로 같이 들어가는 문제도 있었다.

→ linter별 포맷에 맞게 직접 파싱 + 파일 확장자 필터 추가.

구현 계획 제시 후 바로 구현에 들어간다

/start에서 “진행할까요?”라고 물어보면서 동시에 구현을 시작했다. stop hook이 걸려서 adversarial review가 2분+ 돌아가는 것까지 겹쳤다.

→ stop-review에 “파일 변경 없으면 스킵” 추가. agent hook은 결국 제거.

메트릭 결과

테스트 프로젝트에서 /start → 구현 → /done 한 사이클을 돌린 후:

post-write 실행: 26회
  clean (에러 없음): 15회
  error (에러 발견): 11회
    → organizeImports: 8회
    → lint/a11y/noSvgWithoutTitle: 1회
    → codingStandards 위반: 2회
self-heal: 에러 후 clean으로 전환 11/11 (100%)
first-pass: 15/26 (58%)

에이전트가 에러를 만들긴 하지만, 전부 self-heal로 수정했다. first-pass 58%는 개선 여지가 있다 — import 정렬을 자동 format으로 처리하면 organizeImports 8건이 사라진다.

하네스가 실제로 막아준 것들

항목막은 횟수예시
scope-guard 차단3회harness.config.json 밖 파일 수정 시도
scaffold-guard 차단1회Go _test.go 네이밍 규칙 충돌
post-write 에러 감지11회import 정렬, 타입 에러, codingStandards
self-heal 자동 수정11회에이전트가 알아서 고침

hook 없이 에이전트를 돌렸으면 이 11건의 에러가 코드에 그대로 남았을 것이다.

아직 남은 것들

스캐폴더(#1) → Hook(#2) → 학습(#3) → 워크플로우(#4) → 실전(#5)까지 왔다. 에이전트가 룰을 안 지켜도 “부탁”밖에 못 하던 상태에서, 물리적으로 “안 하면 못 넘어가게” 강제하는 시스템이 됐다. 완벽하진 않지만, 에이전트 없이 코딩하던 때로 돌아가긴 힘들 것 같다.


Share this post on:

Comments


Previous Post
Chrome 페이지 번역이 Next.js 다국어 사이트를 망가뜨리는 이유
Next Post
AI 에이전트 하네스 개발기 #4 — Jira 이슈 하나로 Figma 분석부터 MR까지