Skip to main content

AI 하네스: 요구사항부터 검증까지 같은 흐름으로 일하기

· 17 min read
Engineering Team

AI를 개발 업무에 쓰는 사람은 늘었지만, 결과의 품질은 사람마다 달라지기 쉬웠습니다. 그래서 저희는 더 좋은 프롬프트를 찾기보다, AI가 매번 같은 순서로 일하고 같은 기준으로 멈추게 만드는 팀의 작업 장치를 먼저 만들었습니다. 이 글에서는 그 장치를 AI 하네스라고 부르겠습니다.

왜 하네스를 만들었나

처음에는 각자 AI를 꽤 잘 쓰고 있다고 생각했습니다. 누군가는 티켓을 먼저 정리했고, 누군가는 바로 구현을 시작했습니다. 누군가는 테스트까지 챙겼고, 누군가는 "동작할 것 같다"는 설명만 듣고 다음 단계로 넘어갔습니다. 문제는 AI 사용 여부가 아니라, AI를 쓰는 방식의 편차였습니다.

AI 하네스를 만든 이유

특히 반복해서 보였던 문제는 네 가지였습니다.

  • 사람마다 요구사항을 정리하는 깊이가 달랐습니다.
  • 애매한 티켓을 AI가 임의로 채우는 경우가 있었습니다.
  • 완료라고 했지만 컴파일, 단위 테스트, 브라우저 확인, API smoke 중 필요한 검증이 빠진 적이 있었습니다.
  • 코드는 올라갔지만 JIRA 상태, MR 본문, 검증 결과가 비어 있어 다음 사람이 다시 확인해야 했습니다.

그래서 목표를 바꿨습니다. "AI가 더 똑똑하게 답하게 하자"가 아니라 "AI가 팀의 작업 방식 안에서만 움직이게 하자"로요.

하네스의 구조

하네스는 별도의 거대한 플랫폼이 아닙니다. 저희는 FE와 BE가 같은 모노레포에 있기 때문에, 하네스도 repository 안에 함께 둡니다. repo를 열면 원칙, 도메인 지식, 템플릿, 스킬을 같은 위치에서 읽고 실행할 수 있게 만드는 방식입니다.

대표 구조는 다음과 같습니다.

.agents/                     # 도구 중립 지식 베이스
├── domain/ # 주문, 배차, 정산 등 도메인 지식
├── patterns/ # 아키텍처와 구현 패턴
├── guides/ # TDD, workflow 등 작업 가이드
├── templates/ # spec, plan 등 산출물 템플릿
├── skills/ # 반복 판단을 실행 단위로 만든 스킬
├── roles/
├── scripts/
└── scratch/

.claude/ # Claude Code 전용 설정
├── settings.json # 모델, env, hook
├── rules/ # glob 기반 자동 로드 규칙
├── agents/ # 역할별 agent
├── hooks/ # 자동 검증 hook
└── skills -> ../.agents/skills

핵심은 .agents를 도구 중립의 단일 진실원으로 두는 것입니다. Claude, Codex, Gemini처럼 사용하는 도구가 달라도 같은 도메인 지식과 같은 스킬을 읽게 만들면, 도구별 프롬프트를 각각 관리하는 부담을 줄일 수 있습니다.

일하는 흐름: 입력, 하네스, 출력

하네스가 하는 일은 간단히 말해 입력을 정리하고, 정해진 단계로 처리하고, 결과를 기록하게 만드는 것입니다.

단계내용예시
Input무엇을 보고 시작할지 정합니다.JIRA 티켓, Figma, Confluence, 코드베이스, 팀 규칙
Process어떤 순서와 기준으로 일할지 정합니다.feature-startfeature-specfeature-planfeature-implementfeature-test
Output결과를 어디에 남길지 정합니다.코드, 테스트, 커밋, MR, JIRA 코멘트

이 흐름에서 가장 중요한 스킬은 feature-workflow입니다. 이 스킬은 지휘자 역할을 합니다. 티켓을 받아 작업 경로를 고르고, 각 phase 스킬을 호출하고, 단계 전환을 통제합니다.

각 phase는 자기 산출물과 통과 조건만 책임집니다.

Phase역할통과 조건
feature-start작업 공간, 브랜치, JIRA 맥락 준비시작 상태가 고정되어야 spec 진입
feature-specJIRA, Figma, Confluence를 구현 가능한 요구사항으로 정리모호함이 남아 있으면 plan 차단
feature-planAPI, 데이터, 화면, 테스트 설계로 번역구현 가능 수준의 계획이 있어야 implement 진입
feature-implementplan을 task로 쪼개 구현하고 빌드타임 검증plan 밖 구현이나 빌드 실패 시 test 차단
feature-test실제 실행 검증과 커밋 게이트 담당테스트 실패 시 커밋과 MR 차단

이렇게 나누면 AI가 "이제 구현할게요"라고 성급하게 넘어가기 어렵습니다. spec에서 질문이 남으면 plan으로 가지 못하고, test에서 실패하면 commit으로 가지 못합니다.

실제 사례: TMS-8103

예를 들어 [FE] Admin 동기화 현황 상세 페이지 데이터 덮어쓰기 및 외부 재전송 API 연동 작업이 있었습니다.

그냥 시작했다면 API를 붙이고 "동작함"으로 끝났을 가능성이 컸습니다. 하지만 하네스는 구현 전에 먼저 다음을 잡았습니다.

  • Acceptance Criteria
  • 에러 매트릭스
  • 기존 drawer/service 패턴
  • 검증 범위

그 결과 작업은 다음 순서로 정리됐습니다.

  1. spec: 요구사항을 구현 단위로 바꾸기 전에 AC, edge case, 에러 매트릭스를 확정했습니다.
  2. plan: 변경 파일, API 계약, 테스트 범위를 정하고 기존 구현 패턴을 확인했습니다.
  3. code: forceUpdateFailedSyncOrder, forceResendDispatch를 기존 service/component 흐름 안에 연결했습니다.
  4. test: type-check, unit, 브라우저 검증 결과를 커밋 전 게이트로 남겼습니다.

최종 산출물은 코드 변경뿐 아니라 테스트, MR/JIRA 요약까지 포함했습니다. "무엇을 바꿨는지"보다 "무엇을 확인했는지"가 같이 남는 것이 중요했습니다.

AI 결과는 말이 아니라 실행으로 믿습니다

AI가 설명을 잘했다고 해서 믿지 않습니다. 실행 결과로 믿습니다.

FE 작업에서는 보통 다음을 봅니다.

  • Playwright로 실제 화면, viewport, 주요 interaction 확인
  • Vitest 단위 테스트
  • 확인한 화면, 조건, 미검증 영역을 report로 기록

BE 작업에서는 다음을 봅니다.

  • 서버를 띄우고 변경된 endpoint를 직접 호출하는 API smoke
  • OpenAPI 요청/응답 계약 확인
  • Kotest BehaviorSpec 등 단위 테스트
  • Kotlin/Gradle compile 검증

feature-test는 state의 마지막 단계가 implement가 아니면 시작하지 않습니다. 필요한 smoke나 browser 검증이 실패하면 커밋과 MR 단계로 넘어가지 못합니다. 실패를 사용자가 명시적으로 승인하지 않는 한, AI가 완료로 포장하지 못하게 막습니다.

사람이 까먹어도 시스템이 강제하게 만들기

스킬은 능력이고, hook은 강제입니다. 사람이 기억하면 좋겠지만, 반복되는 품질 게이트는 사람이 기억하지 않아도 실행되어야 합니다.

저희가 실제로 설정한 hook 예시는 두 가지입니다.

Hook역할효과
PostToolUse스킬 호출 시마다 스킬명, 시각, 성공 여부, args를 기록실제 쓰이는 스킬과 안 쓰이는 스킬을 구분
StopAI가 턴을 끝내려 할 때 수정된 Kotlin 파일에 ktlint/test 실행위반 시 종료 차단, AI가 고쳐야만 끝낼 수 있음

이 방식은 작은 차이를 만듭니다. "테스트 했나요?"라고 사람이 묻는 대신, 테스트를 통과하지 못하면 다음 단계로 가지 못합니다.

처음부터 잘 된 것은 아니었습니다

하네스는 처음부터 완성품이 아니었습니다. 오히려 실패를 하나씩 줄이면서 만들어졌습니다.

실패바꾼 점
AI가 완료라고 했는데 실제로 안 돌아감feature-test 게이트를 추가해 실행 검증 후에만 완료 선언
문서의 포트가 실제 vite.config와 다름코드가 진실이라는 원칙을 세우고 문서를 최신화
FE 구현은 끝났지만 Figma와 레이아웃이 미묘하게 다름browser-test로 viewport, Figma, 브라우저 비교 절차와 report 강제
만든 스킬이 실제 작업에서 호출되지 않음사용량을 추적하고 trigger와 내용을 수정하거나 제거

여기서 얻은 교훈은 단순합니다. 하네스도 운영 대상입니다. 완료 여부, 화면 일치, 스킬 유용성을 말로 믿지 않고 근거로 확인해야 합니다.

AI와 사람의 책임 경계

AI가 검증까지 도와주더라도 최종 책임은 개발자에게 있습니다. 그래서 역할을 분명히 나눕니다.

AI와 사람의 책임 경계

AI가 주로 하는 일은 다음과 같습니다.

  • spec 초안 작성
  • JIRA, Figma, Confluence 맥락 병합
  • 모호한 요구사항 질문 목록화
  • plan/tasks 분해
  • 코드 변경 제안
  • 테스트 작성
  • 기존 패턴 탐색
  • 검증 gate 실행
  • MR/JIRA 업데이트 초안 작성

개발자가 책임지는 일은 다음과 같습니다.

  • spec 최종 확정
  • 질문 답변과 범위 결정
  • AI 코드리뷰 확인과 최종 판단
  • 필요한 코드 수정
  • 테스트 케이스 검증
  • 아키텍처 판단
  • gate 통과 또는 재작업 결정
  • MR 최종 승인과 머지

AI는 작업의 속도를 올리고 빈틈을 드러내는 도구입니다. 하지만 무엇을 만들지, 어떤 위험을 받아들일지, 최종적으로 머지해도 되는지는 사람이 판단합니다.

보안: 사람이 지키고, 시스템이 막는 것

보안도 같은 방식으로 나눴습니다. 민감 데이터 입력은 사람이 지키는 원칙이고, secret 유출은 하네스 게이트가 막아야 하는 영역입니다.

AI에 입력하지 않는 정보는 명확히 정합니다.

  • 고객, 기사 개인정보
  • 사업자번호, 계좌 정보
  • Keycloak과 운영 인증 정보
  • 주문, 정산 실데이터

반대로 공유 가능한 정보도 정합니다.

  • 공개 문서
  • 코드 구조
  • 값이 제거된 스키마
  • 마스킹된 데이터
  • 테스트 데이터

시스템 쪽에서는 skill-quality-reviewer가 스킬과 스크립트의 plaintext secret을 blocker로 보고, Gitleaks나 패턴 스캔으로 merge를 차단합니다. 테스트에도 inline DB 자격증명이나 계정을 넣지 않고, 등록된 reference만 사용하도록 강제합니다.

반복 업무는 n8n으로 확장

AI 하네스가 개발 작업 안쪽의 판단과 검증 기준을 만든다면, n8n은 정해진 시간과 이벤트에 맞춰 팀 운영 업무를 흘려보내는 장치입니다.

예를 들면 다음과 같은 흐름을 자동화할 수 있습니다.

  • Datadog 알림이 울리면 원인 분석과 해결 후보 정리
  • 2주 누적 FE 에러를 분석해 대응 필요 항목 리포트
  • MR 이벤트를 받아 리뷰 포인트와 확인 필요 항목 정리
  • 배포 알림, 슬래시 커맨드, 스프린트 대시보드, 데일리 스크럼 요약

하네스와 n8n은 같은 방향을 봅니다. 사람의 기억에 맡기던 반복 업무를 팀 시스템으로 옮기는 것입니다.

마치며

AI 하네스는 스킬을 많이 만드는 일이 아닙니다. 같은 품질을 더 적은 맥락과 비용으로 반복하게 만드는 일입니다.

저희가 특히 중요하게 본 원칙은 네 가지였습니다.

  • FE와 BE가 함께 쓰는 하나의 workflow를 둡니다.
  • 요구사항이 애매하면 구현하지 않고 질문합니다.
  • spec, plan, tasks, report를 산출물로 남깁니다.
  • 컨텍스트 비용을 줄이기 위해 필요한 맥락만 넘기고, state를 handoff 가능한 형태로 유지합니다.

AI를 팀에 도입할 때 중요한 질문은 "어떤 모델을 쓸 것인가"에서 끝나지 않습니다. "어떤 순서로 일하게 할 것인가", "무엇을 통과해야 완료라고 볼 것인가", "사람은 어디서 판단할 것인가"까지 정해야 합니다.

저희 팀의 답은 하네스였습니다. 앞으로도 실패 사례와 운영 경험을 바탕으로 이 하네스를 계속 다듬어갈 예정입니다.

댓글