하네스 엔지니어링은 AI 코딩 에이전트가 사용하는 맥락·도구·권한과 결과 검증·작업 인계 과정을 설계하는 일입니다. 작업을 맡기는 문장부터 변경을 받아들이는 근거까지 연결하는 것이 핵심입니다.
가상의 문의 폼 사례를 보겠습니다. AI가 폼을 만들고 “검사까지 마쳤습니다”라고 답했습니다. 이름과 내용을 입력하고 전송하니 완료 안내도 나옵니다. 그런데 버튼을 빠르게 두 번 누르면 같은 문의가 두 개 접수됩니다. 저장이 실패했을 때는 입력한 내용이 사라집니다.
‘검사했다’는 말은 맞을 수도 있습니다. 정상 전송 한 번만 확인했다면 그 검사는 통과했을 테니까요. 문제는 무엇을 확인해야 완료인지, 실패하면 어떻게 멈추고 고칠지가 작업 과정에 들어 있지 않다는 데 있습니다.
검사 도구를 잘 연결해도, 무엇을 만들지와 어떤 구조를 유지할지가 불명확하면 좋은 PR을 기대하기 어렵습니다. 문의 폼 하나에서 설계와 검토가 어디에 들어가야 하는지 살펴보겠습니다. 아래 앱 동작과 검사 결과는 구조를 설명하기 위한 가상 사례입니다.
하네스 엔지니어링이란: 지침·도구·검증의 역할
‘하네스’는 문맥에 따라 범위가 달라집니다. 테스트 하네스는 준비된 입력으로 코드를 실행하고 결과를 확인하는 장치를 뜻할 수 있습니다. AI 에이전트 하네스는 모델 호출, 도구 실행, 작업 상태와 맥락 관리까지 포함하는 더 넓은 실행 환경을 가리킵니다.
이 글에서 다루는 것은 AI 코딩 작업을 맡기고, 확인하고, 이어 가는 프로젝트의 운영 구조입니다. 특정 파일 이름이나 제품 하나를 뜻하지 않습니다. 기존 코딩 에이전트 위에 작업 지침과 검사 명령, 리뷰 절차를 정리하는 것부터 시작할 수 있습니다. 자체 에이전트 실행기를 새로 개발해야만 하네스를 갖추는 것은 아닙니다.
Anthropic의 장기 실행 에이전트 하네스 사례는 기능을 조금씩 구현하고, 동작을 확인하고, 다음 세션이 이어받을 기록을 남기는 방식을 설명합니다. 이 사례가 모든 프로젝트의 정답은 아니지만, 하네스를 검사 스크립트 하나보다 넓게 봐야 하는 이유를 보여 줍니다.
문의 폼 작업이라면 하네스가 답해야 하는 질문은 이렇습니다. AI는 어떤 요구사항을 읽고 시작하는가, 어느 파일을 고쳐도 되는가, 문의가 제대로 접수됐다는 사실을 무엇으로 확인하는가, 실패 로그를 보고 무엇을 다시 검사하는가, 마지막에 누가 변경을 받아들이는가.
프롬프트·컨텍스트 엔지니어링과의 차이
프롬프트 엔지니어링은 모델에게 전달할 지시를 작성하고 구성하는 데 초점을 둡니다. 컨텍스트 엔지니어링은 지시와 함께 제공할 코드·문서·도구 정보·이전 대화 등 필요한 맥락을 고르고 관리합니다. Anthropic도 두 개념을 지시 작성과 전체 맥락 관리로 구분합니다. 프롬프트와 컨텍스트의 역할
이 글에서 다루는 하네스는 그 지시와 맥락을 실제 작업에 연결하고, 도구를 실행하고, 결과를 검사하며, 실패 뒤 작업을 이어 가는 구조입니다. 문의 폼에서는 “중복 접수를 막아 주세요”가 지시이고, 기존 접수 코드와 응답 규약이 맥락이며, 시험용 요청·검사 명령·실패 처리·리뷰 기록을 연결하는 것이 하네스 구성입니다. 개념의 범위는 겹칠 수 있으며, 하나의 지침 파일만으로 전체 실행 구조가 갖춰지는 것은 아닙니다.
각 구성 요소가 맡는 역할을 나누면 다음과 같습니다.
| 구분 | 역할 | 설명 | 예시 |
|---|---|---|---|
| 작업 지침 | 무엇을 만들지 전달 | 목적·제약·완료 기준을 AI에게 알려 줍니다. 문장만으로 권한이 제한되지는 않습니다. | 문의 폼만 수정하고 실제 고객에게 메일을 보내지 않습니다. |
| 검사 도구 | 동작의 근거 수집 | 입력에 따른 결과를 비교하고 실패 위치와 기록을 남깁니다. | 중복 클릭 뒤 시험용 접수함에 문의가 하나인지 확인합니다. |
| 실행·통제 | 언제 실행하고 멈출지 결정 | 도구 권한, 검사 실패 처리, 리뷰와 승인 조건을 연결합니다. | 필수 검사 실패 상태에서는 다음 병합 단계로 진행하지 않습니다. |
| 상태 기록 | 다음 작업으로 이어 주기 | 현재 코드와 검사 근거, 미해결 문제를 남깁니다. | 전송은 확인했지만 저장 실패 처리는 아직 미검증이라고 기록합니다. |
이 요소들은 역할을 나눠 맡습니다. AGENTS.md 같은 지침 파일에 “검사 실패를 무시하지 마세요”라고 적는 것은 유용합니다. 실제로 실패 시 명령을 중단하거나 병합을 막는 설정까지 연결하면 그 약속을 실행 과정에서도 확인할 수 있습니다.
신뢰성·효율·보안·추적 가능성으로 점검하기
TRAE 개발자 커뮤니티의 Xianyu가 쓴 하네스 엔지니어링 설명 글은 신뢰성·효율·보안·추적 가능성을 네 가지 목표로 묶습니다. 업계 공통 표준으로 받아들이기보다는, 하네스에서 빠진 운영 질문을 찾는 틀로 쓸 수 있습니다.
문의 폼 작업이라면 다음을 확인합니다. 중단 후 같은 시험 요청을 다시 보내도 중복 저장을 피할 수 있는가, 검토를 반복할 때 시간과 호출 비용을 제한할 수 있는가, 시험용 데이터만 다루도록 실제 권한을 제한했는가, 어느 코드에서 어떤 검사를 실행했는지 찾을 수 있는가. 화면 하나가 동작하는 것과 운영 가능한 작업 과정이 갖춰진 것은 이렇게 구분할 수 있습니다.
다만 하네스를 붙였다고 같은 실패가 영원히 사라지거나 모델의 판단 전체가 일정해지지는 않습니다. 로그도 내부 사고를 완벽하게 복원하는 기록은 아닙니다. 추적할 대상은 작업 입력, 도구 호출, 변경 내용, 실행 결과, 승인처럼 확인 가능한 사건입니다. 비밀값과 실제 문의 내용을 통째로 남기는 것은 피해야 합니다.
하네스만으로 좋은 코드가 보장될까
Dex Horthy는 AI Engineer 발표에서 하네스만으로는 충분하지 않다고 주장합니다. 사람의 코드 검토를 없앤 운영 경험을 바탕으로, 유지보수성 판단과 구현 전 설계의 필요성을 강조합니다. 여기서 ‘lights-off’는 시스템 종료가 아니라 사람의 코드 작성·검토를 배제한 무인 운영을 뜻합니다. 발표 영상과 발표자의 확장 원문을 함께 읽을 수 있습니다.
이 주장은 경험에 기반한 견해로 읽어야 합니다. 한 조직의 실패로 모든 모델의 한계를 확정할 수는 없습니다. 반대로 하네스의 효과를 무시할 이유도 없습니다. Anthropic의 SWE-bench 평가 설명은 모델과 도구·실행 구성을 함께 평가하며, 실행 구성이 결과에 영향을 준다고 설명합니다. 과제 해결 성능이 높아지는 것과 실제 프로젝트의 장기 유지보수성이 보장되는 것은 구분해야 합니다.
문의 폼으로 돌아가 보겠습니다. 정상 접수와 저장 실패 검사가 모두 통과해도 입력 검증 규칙을 화면·접수 처리·관리자 도구에 각각 복사해 뒀을 수 있습니다. 오늘은 세 곳이 같으니 동작합니다. 다음에 문의 유형을 추가하면서 한 곳만 수정하면 경로마다 허용하는 값이 달라집니다. 기존 테스트가 새 요구를 다루지 않는다면 이 차이도 지나칠 수 있습니다.
이때 필요한 질문은 “검사를 더 실행했는가”에서 한 단계 더 나아갑니다. 이 규칙의 기준은 어디에 있고, 다음 변경 때 누가 무엇을 함께 고쳐야 하는가? 하네스에는 이런 설계 근거를 전달하고 검토를 요청하는 절차를 넣을 수 있습니다. 그러나 그 절차를 실행했다는 사실만으로 설계 판단이 옳아지는 것은 아닙니다.
모델이 좋아지면 하네스는 덜 필요할까
새 모델에서 계획·도구 선택·자기 점검이 좋아졌다면, 예전에 필요했던 세세한 보조 절차를 줄일 여지는 있습니다. 다만 ‘직접 만든 하네스를 덜 쓴다’와 ‘하네스 없이 작업한다’는 다릅니다. 코딩 에이전트에서 모델을 선택해 쓰는 동안에도 제품이 제공하는 도구 실행, 맥락 관리, 권한 설정은 계속 작동할 수 있습니다. 체감 향상에는 모델뿐 아니라 이런 제품 구성의 변화도 영향을 줍니다.
개선 방향은 공식 설명에서도 확인할 수 있습니다. OpenAI는 GPT-6 Astra가 이전 모델보다 지시를 잘 따르고 작업 경계를 존중한다고 설명합니다. Anthropic은 Opus 5.5가 자사 행동 평가에서 되돌리기 어려운 행동이나 주어진 범위를 벗어나는 행동을 덜 보였다고 보고합니다. SpaceXAI는 Grok 4.7의 자기 검증과 긴 맥락 관리 개선을 설명하며, Grok Bot 하네스를 이해하도록 학습했다고도 밝힙니다. 이는 각 개발사의 평가와 제품 설명입니다. 세 모델을 동일한 조건에서 비교해 외부 통제가 불필요해졌다고 입증한 결과는 아닙니다.
줄일 수 있는 보조 절차
이 변화는 최근 세대에만 나타난 현상은 아닙니다. Anthropic의 장기 앱 개발 하네스 사례에서는 Opus 4.5에서 4.6으로 바꾸며 작업을 짧은 구간으로 강제 분할하던 장치를 없앴습니다. 계획·평가 역할은 유지하되 평가 시점을 조정했고, 모델이 혼자 처리하기 어려운 작업에서는 평가가 여전히 도움이 됐다고 설명합니다. 특정 실험의 결과지만, 하네스의 구성 요소를 하나씩 줄이며 영향을 확인한다는 접근은 참고할 수 있습니다.
문의 폼에서도 매 단계마다 같은 계획을 다시 쓰게 하거나, 쉬운 문구 수정까지 여러 리뷰 에이전트가 반복 확인하게 했다면 필요성을 재검토할 수 있습니다. 새 모델이 잘하는 일을 이미 낡은 절차로 반복시키면 시간과 비용이 늘 수 있습니다. 그렇다고 모델명만 보고 규칙을 일괄 삭제할 근거가 생기는 것은 아닙니다.
계속 관리해야 하는 기준과 권한
모델이 ‘실제 고객에게 메일을 보내면 안 된다’는 지시를 잘 이해하는 것과, 시험 계정에 실제 발송 권한이 없는 것은 별개의 통제입니다. 전자는 행동에 대한 지시이고, 후자는 실행 환경의 접근 제한입니다. OpenAI의 에이전트 승인·보안 문서도 안전 모니터링이 샌드박스·권한·결과 검토를 대체하지 않는다고 설명합니다. 샌드박스는 실행 가능한 파일·네트워크 등의 범위를 제한하는 환경입니다.
따라서 모델을 바꿀 때는 다음처럼 나누어 점검해 볼 수 있습니다. 아래는 문의 폼 프로젝트에 적용한 판단 예시입니다.
| 구분 | 역할 | 설명 | 예시 |
|---|---|---|---|
| 간소화 후보 | 모델 약점을 보완하던 반복 | 고정된 짧은 작업 분할, 같은 계획의 반복 작성, 효과가 불분명한 중복 AI 리뷰를 하나씩 줄여 봅니다. | 문구 수정의 반복 리뷰를 줄인 뒤 누락·오류·재작업이 늘었는지 비교합니다. |
| 계속 전달할 기준 | 프로젝트의 목표와 약속 | 완료의 의미, 기존 데이터 호환성, 담당 범위는 모델이 좋아져도 작업에 맞게 알려 줘야 합니다. | ‘접수 완료’가 저장 성공을 뜻하고 실제 메일 도착을 뜻하지 않는다는 약속을 남깁니다. |
| 환경에서 관리할 통제 | 권한·한도·필수 검사 | 데이터 접근과 배포 권한, 실행 한도, 병합 조건은 위험에 맞춰 따로 설정하고 검증합니다. | 시험 계정에 운영 발송 권한을 주지 않고, 필수 검사가 실패하면 병합을 막습니다. |
지시를 더 잘 따르는 모델일수록 오래된 지시도 더 충실하게 적용할 수 있다는 점도 생각해야 합니다. OpenAI는 GPT-6 Astra에 접근 가능한 스킬과 AGENTS.md의 지시를 점검하도록 권고합니다. 예전에 넣은 ‘항상 다시 승인받기’나 중복 검사 규칙이 지금의 작업 의도와 맞는지 살펴보고, 목표·완료 조건·필수 경계는 분명히 남깁니다. GPT-6 지시 따르기 안내
이 글에서 권하는 기준은 모델이 발전할수록 하네스의 보조 절차를 재평가하되, 프로젝트의 기준과 외부 통제는 위험에 맞춰 유지하는 것입니다. 어느 모델부터 하네스가 덜 중요해졌다고 선을 긋기보다는, 현재 과제에서 각 장치가 무엇을 막고 어떤 비용을 만드는지 확인하는 편이 정확합니다.
하네스 설계의 시작: 완료 기준과 작업 범위
문의 폼을 만들기 전에 ‘완료 안내가 보이면 성공’이라는 모호한 기준을 나눠 봅니다. 화면이 바뀌는 것과 저장이 끝나는 것은 다른 사건입니다. 메일 발송까지 있는 서비스라면 접수와 메일 도착도 구분해야 합니다.
이 예시에서는 문의를 시험용 저장소에 접수하는 것까지만 구현합니다. 실제 메일 발송은 범위에 넣지 않습니다. 완료 기준은 다음처럼 행동과 확인 대상을 짝지어 적습니다.
- 정상 입력: 이름과 내용을 보내면 문의가 하나 저장되고 접수 완료 안내가 보입니다.
- 빈 입력: 내용이 비어 있으면 저장을 시도하지 않고 어떤 항목이 필요한지 알려 줍니다.
- 중복 클릭: 같은 제출을 연속으로 눌러도 이 예시의 요구사항상 하나만 접수됩니다.
- 저장 실패: 저장이 실패한 상황에서는 성공 안내를 보여 주지 않고 입력 내용을 남깁니다.
- 기존 기능: 문의 목록을 읽는 기존 동작이 그대로 작동합니다.
여기서 ‘중복 제출을 어디까지 같은 요청으로 볼 것인가’도 결정해야 합니다. 버튼을 잠깐 비활성화하면 빠른 연속 클릭은 줄일 수 있지만, 새로고침 뒤 재전송이나 여러 창의 요청까지 막는다는 보장은 없습니다. 그런 상황까지 요구한다면 서버가 같은 제출을 구분하는 기준과 저장 방식도 필요합니다. 화면에서 막을 범위와 서버에서 보장할 범위를 먼저 합의해야 테스트도 정확해집니다.
작업 범위에는 파일뿐 아니라 실행 환경과 권한을 적습니다. 이 예시에서는 문의 화면·접수 처리·관련 테스트를 수정 대상으로 삼고, 운영 데이터와 실제 고객 메일에는 접근하지 않습니다. 저장 실패를 재현할 시험용 대상을 준비해야 실패 검사를 하다가 실제 문의를 망가뜨리는 일을 피할 수 있습니다.
AI가 알아야 할 기존 구조도 함께 지정합니다. 화면이 어떤 응답을 성공으로 해석하는지, 입력 검증과 저장을 어디서 하는지, 검사 명령은 무엇인지가 여기에 해당합니다. 모든 문서를 한꺼번에 넣기보다 필요한 근거를 찾을 위치와 우선 읽을 자료를 알려 주는 편이 관리하기 쉽습니다. Anthropic의 컨텍스트 설계 설명도 모델에 제공하는 정보의 구성을 별도 설계 문제로 다룹니다.
구현 전에 확인할 네 가지 결정
문의 폼의 계획은 “프런트엔드 구현, 서버 구현, 테스트 작성”이라는 작업 목록보다 구체적이어야 합니다. 같은 문장을 읽은 두 작업자가 서로 다른 성공 상태를 만들지 않도록, 아래 결정을 먼저 남겨 봅니다. 다음은 이 글의 가상 프로젝트에 적용한 설계 예시입니다.
- 사용자에게 약속할 결과문의가 저장되면 ‘접수 완료’라고 알립니다. 메일이 도착했다는 뜻으로 표시하지 않습니다.
- 화면과 서버의 연결화면은 접수 API를 부르고, 서버는 입력을 확인한 뒤 저장합니다. 성공·실패 응답을 양쪽이 함께 정합니다.
- 코드의 책임접수 규칙은 접수 처리 함수에 모읍니다. 화면은 응답에 맞게 안내하고, 실패하면 입력을 남깁니다.
- 처음 확인할 작은 흐름시험용 문의 한 건이 화면에서 저장소까지 도달하는 흐름부터 연결하고, 빈 입력과 중복·실패 상황을 보완합니다.
‘코드의 책임’은 큰 구성도보다 한 단계 세밀한 결정입니다. 예를 들어 접수 함수가 성공 시 접수 번호와 상태를 돌려주고 실패 시 오류를 전달한다면, 화면이 어느 결과에서 입력을 지울지 정할 수 있습니다. AI에게 주요 함수의 입력·출력과 호출 순서를 먼저 적게 하고, 기존 함수로 처리할 수 있는지도 확인합니다. 이 단계에서 이름까지 전부 고정할 필요는 없습니다. 데이터 저장과 성공 판정이 어디서 이뤄지는지는 서로 이해해야 합니다.
화면에서 저장까지 이어지는 작은 기능을 **수직 분할(vertical slice)**이라고 부릅니다. 여러 기술 계층을 지나더라도 사용자 동작 하나를 연결해 검증하는 방식입니다. 초기 흐름은 시험 환경에서 확인하고, 사용자에게 노출하기 전에는 합의한 오류 처리와 완료 기준까지 충족합니다. 정상 경로를 먼저 만들었다는 이유로 실패 처리가 빠진 코드를 바로 배포하는 것은 아닙니다.
계획의 분량은 불확실성에 맞춥니다. 문구 수정이나 원인이 명확한 작은 버그는 짧은 설명으로 충분할 수 있습니다. 저장 형식·권한·여러 서비스의 약속이 바뀌면 구현 전에 검토할 항목이 늘어납니다. 구현 중 새 제약을 발견했다면 기존 계획을 억지로 따르기보다 변경 이유를 기록하고 영향을 다시 확인합니다.
테스트 설계: 정상·경계·실패 상황 나누기
가장 먼저 할 일은 변경 전 기준 상태를 확인하는 것입니다. 기존 검사가 이미 실패하는지 모른 채 구현하면, 나중에 발견한 오류가 새 변경 때문인지 판단하기 어렵습니다. 원래 있던 실패는 별도로 기록하고 이번 작업에서 해결할지 결정합니다. 기존 실패가 있다는 이유로 새 실패까지 통째로 무시하지 않습니다.
검사에는 서로 다른 역할이 있습니다. 정적 검사는 코드를 실행하기 전에 문법·타입·규칙 위반을 찾습니다. 단위 테스트는 입력 검증 함수처럼 작은 조각을 확인합니다. 통합 테스트는 접수 처리와 저장소처럼 연결된 부분을 봅니다. 종단 간 테스트는 사용자가 폼을 열고 전송한 뒤 결과를 확인하는 흐름을 끝까지 실행합니다.
어느 하나만 늘린다고 나머지가 자동으로 충족되지는 않습니다. 입력 검증 함수가 맞아도 화면이 다른 함수를 부를 수 있고, 서버 저장이 성공해도 화면이 응답을 잘못 읽을 수 있습니다. 문의 폼에서는 ‘전송 버튼이 눌렸다’와 ‘시험용 접수함에 저장됐다’를 함께 확인하는 검사가 필요합니다.
실패 검사는 발생 조건을 통제해야 합니다. 우연히 네트워크가 끊기기를 기다리기보다 시험용 저장소가 의도적으로 오류를 반환하도록 만들어 기대 동작을 확인합니다. 다만 가짜 저장소로 검사한 범위와 실제 저장소를 연결해 검사한 범위는 기록에서 구분합니다. 가짜 응답으로만 통과했다면 실제 연결의 인증·형식·시간 제한까지 확인한 것은 아닙니다.
테스트 자체의 품질도 리뷰 대상입니다. “전송 함수를 한 번 호출했다”만 확인하는 테스트는 접수 누락을 놓칠 수 있습니다. “문의가 하나 저장되고, 성공 안내가 나오며, 실패 시 입력이 남는다”처럼 사용자와 데이터의 결과에 연결해야 합니다. 버그를 고친 뒤에는 그 버그가 있을 때 실패하고 수정하면 통과하는 검사를 남기면 같은 문제가 돌아왔을 때 발견하기 쉽습니다.
AI 코드 리뷰 자동화: 입력과 결과 형식 정하기
리뷰어에게 diff만 던져 주면 바뀐 줄의 문법에는 의견을 낼 수 있어도, 왜 그 변경이 필요한지나 빠진 요구사항은 모를 수 있습니다. 하네스는 검토할 맥락과 증거를 같은 변경에 묶어 전달하는 일까지 맡아야 합니다.
문의 폼의 리뷰 묶음에는 목적과 완료 기준, 비교 기준이 되는 코드 버전, 변경 파일, 관련 저장 구조, 검사 결과, 알려진 한계가 들어갑니다. 아직 확인하지 못한 저장 실패 처리가 있다면 “미검증”으로 표시합니다. “모든 검사 통과”라는 AI 요약보다 실제 검사 이름과 로그 위치가 중요합니다.
AI 리뷰어의 역할은 우선 문제를 찾고 근거를 남기는 쪽으로 좁혀 볼 수 있습니다. 코드 수정까지 동시에 맡기면 리뷰하던 대상을 바꿔 버리고, 지적과 수정이 뒤섞이기 쉽습니다. 검토를 먼저 끝낸 뒤 작성자가 수정하고, 바뀐 코드로 다시 확인하는 순서가 추적에 유리합니다. 도구가 권한 설정을 지원한다면 리뷰 역할에는 필요한 읽기 권한부터 주고, 별도 시험 환경에서 실행할 검사만 허용합니다. “읽기 전용으로 일하세요”라는 지시만으로 실제 쓰기 권한이 사라지지는 않습니다.
리뷰 의견에는 아래 정보가 이어져야 합니다.
문제: 저장이 거절돼도 입력을 지웁니다.
위치: 전송 버튼 처리에서 저장 결과를 확인하기 전에 폼 초기화를 호출하는 부분입니다.
발생 조건: 이름과 내용을 입력하고 시험용 저장소가 오류를 반환하도록 한 뒤 전송합니다.
영향: 문의는 접수되지 않았고 사용자는 같은 내용을 다시 작성해야 합니다.
확인할 결과: 저장 실패 안내가 보이고 기존 입력이 유지돼야 합니다. 정상 저장 시에만 합의한 시점에 입력을 정리합니다.
이것은 가상의 지적 형식입니다. 실제 리뷰라면 파일과 줄 위치, 사용한 입력, 확인한 실행 결과를 붙입니다. 추정만 했다면 재현했다고 적지 않습니다. 지적이 틀렸을 때는 기존 처리 위치나 반례를 근거로 기각할 수 있어야 합니다.
AI의 지적이 하나도 없다는 결과도 완전한 안전 증명은 아닙니다. GitHub는 Copilot 에이전트의 용도와 한계에서 리뷰가 잘못된 지적을 만들거나 문제를 놓칠 수 있음을 설명합니다. 다른 모델에 다시 맡겨도 둘 다 같은 요구사항을 받지 못했다면 같은 문제를 놓칠 수 있습니다. 사람은 요구사항 자체의 적절성, 확인되지 않은 위험, 사용자 경험을 판단해야 합니다.
지금의 동작과 다음 변경을 함께 리뷰하기
동작 확인 뒤에는 가까운 후속 요구 하나를 대입해 봅니다. 문의에 ‘유형’을 추가한다면 화면, 서버의 입력 검증, 저장 형식이 바뀌는 것은 자연스럽습니다. 문제는 서로 떨어진 여러 함수에 같은 허용값 목록이 복사돼 있어 모두 찾아 고쳐야 하는 경우입니다. 변경 파일 수만 세기보다 같은 규칙을 여러 번 수정해야 하는 이유를 봅니다.
리뷰에서 “중복이 있으니 추상화하세요”라고만 적으면 방향이 모호합니다. “문의 유형의 허용값이 접수와 관리자 수정 경로에 따로 있어 한쪽만 바꾸면 서로 다른 데이터를 허용합니다. 공통 기준을 참조하도록 하고, 두 진입 경로가 같은 값을 처리하는지 확인해 주세요”처럼 다음 변경의 위험과 검증 방법을 연결해야 합니다.
모든 닮은 코드를 한 함수로 합칠 필요는 없습니다. 화면 안내와 서버의 권한 검사는 책임이 다릅니다. 아직 없는 여러 전송 채널을 가정해 복잡한 공통 프레임워크를 만드는 것도 재검토 대상입니다. 실제로 함께 바뀌어야 할 규칙과 독립적으로 달라질 동작을 구분하는 것이 기준입니다.
합의한 설계 중 일부는 도구로 확인할 수 있습니다. 화면이 저장소를 직접 불러오지 못하게 의존 관계를 검사하거나, 서버 응답과 화면이 사용하는 형식을 함께 검증할 수 있습니다. 이런 검사는 정한 경계를 반복해서 지키는 데 도움이 됩니다. 그 경계 자체가 적절한지는 설계 리뷰에서 판단합니다.
PR 설명과 피드백의 기본 형식은 AI PR 작성법: 코드 리뷰와 기능별 분할에서 연결해 볼 수 있습니다. 여기서는 그 리뷰가 필요한 근거를 매번 받을 수 있도록 실행 체계에 넣는 것이 다음 단계입니다.
로컬 검사와 CI를 같은 기준에 연결하기
로컬에서 빨리 확인하는 검사와 PR에서 반복 실행하는 검사는 서로 보완합니다. Husky 같은 도구는 Git 훅에 검사 명령을 연결합니다. CI는 코드 변경을 받아 정해진 환경에서 검사와 빌드 등을 실행하는 자동화 과정입니다. 둘 중 어디에서 실행됐는지만으로 검증 범위가 정해지지는 않으며, 어느 코드와 환경에서 무엇을 검사했는지를 봐야 합니다.
검사 명령은 한곳에서 관리하는 편이 좋습니다. 예를 들어 빠른 정적 검사를 묶은 명령, 문의 기능 검사 명령, 병합 전 전체 검사 명령을 프로젝트에 정의합니다. 로컬 훅과 CI가 같은 검사 진입점을 호출하도록 하면 검사 목록이 달라지는 실수를 줄일 수 있습니다. quick, feature, full 같은 이름을 붙일 수 있지만 이것은 예시일 뿐이며, 이름보다 실제 실행 항목과 실패 처리의 일치가 중요합니다.
명령은 실패를 성공처럼 감추면 안 됩니다. 실행이 실패했는데도 종료 상태를 성공으로 바꾸거나, 필요한 검사가 실행되지 않았는데 통과로 요약하는 설정은 병합 판단을 흐립니다. 그렇다고 모든 검사를 커밋 때마다 실행할 필요도 없습니다. 빠른 검사로 자주 피드백을 받고, 저장소 연결이나 긴 브라우저 검사는 PR 단계에서 실행하는 식으로 비용을 나눌 수 있습니다.
Husky의 로컬 훅은 끌 수 있으므로 강제 검증의 마지막 경계로 삼을 수 없습니다. Husky의 훅 비활성화 설명을 고려해 CI는 로컬 훅 실행 여부와 무관하게 필요한 검사를 직접 실행해야 합니다. 폴더 분리, 담당 범위 검사와 CI 보완의 구체적인 연결은 Git worktree와 Husky로 AI 병렬 코딩 충돌 줄이기에 정리돼 있습니다.
또한 CI 실행과 병합 차단을 따로 설정해야 합니다. GitHub에서는 필요한 상태 검사와 리뷰 승인을 보호 브랜치의 조건으로 둘 수 있습니다. 새 커밋이 들어왔을 때 이전 승인을 어떻게 처리할지도 정합니다. 기능 제공 범위는 저장소와 플랜에 따라 다릅니다. 보호 브랜치와 필수 검사
검사 코드나 워크플로가 바뀌는 PR은 특히 주의해서 봅니다. 구현을 고치는 대신 실패하던 테스트를 삭제하거나 기대값을 바꾸면 초록색 결과를 만들 수 있습니다. 요구사항이 실제로 바뀌어 기대값을 고칠 수도 있지만, 그 이유와 영향을 별도로 검토해야 합니다. 검사 도구를 바꿀 권한과 그 기준을 승인하는 역할을 구분하는 것이 도움이 됩니다.
Git 충돌 없이 병합해도 통합 검사가 필요한 이유
두 작업이 같은 줄을 고치면 Git이 텍스트 충돌을 알려 줄 수 있습니다. 하지만 서로 다른 파일을 고쳤어도 동작의 약속이 어긋날 수 있습니다. 이 문제는 Git이 자동으로 찾아 주는 충돌 표시와 구분해서 봐야 합니다.
문의 폼의 서버 담당은 문의를 저장한 뒤 상태값으로 queued를 돌려주도록 바꿨다고 가정하겠습니다. 이는 ‘처리 대기 상태로 접수됐다’는 뜻입니다. 화면 담당은 sent일 때만 성공으로 표시하도록 만들었습니다. 이 예시에서 sent는 화면이 기대하는 성공 상태 이름입니다. 두 값은 표준으로 정해진 이름이 아니라 팀이 합의해야 할 응답의 일부입니다.
서버 테스트는 queued가 나오는지 확인하니 통과합니다. 화면 테스트는 가짜 sent 응답을 주니 통과합니다. 둘을 연결하면 문의는 저장됐는데 화면에는 실패라고 나옵니다. 사용자는 다시 전송할 수 있습니다.
이때는 화면 문구만 고치기 전에 성공의 의미부터 맞춰야 합니다. 접수 완료와 실제 메일 발송 완료가 다르다면 화면에도 그 구분이 드러나야 합니다. 합의한 응답 구조를 바탕으로 양쪽 테스트를 맞추고, 실제 접수 처리와 화면을 연결한 테스트를 추가합니다. 가짜 응답을 계속 쓸 경우에도 실제 서버의 약속과 어긋나지 않는지 검사할 장치가 필요합니다.
PR이 여럿이라면 검사 대상 버전도 중요합니다. 예전 기준 브랜치에서 통과한 결과만으로 나중에 합쳐질 상태가 맞는지는 알 수 없습니다. 최신 기준 변경을 포함해 검사하거나, PR이 자주 합쳐지는 저장소라면 merge queue를 검토할 수 있습니다. GitHub의 merge queue는 대상 브랜치와 앞선 PR을 포함한 조합에 필수 검사를 적용합니다. 사용 가능한 저장소 조건이 있으며, Actions를 쓴다면 merge_group 이벤트도 검사 실행에 연결해야 합니다. merge queue의 동작과 CI 연결
하네스는 결국 각자의 검사가 끝나는 지점과 함께 검증하는 지점을 모두 갖춰야 합니다. worktree로 폴더를 나눴다는 사실이나 충돌 없이 병합됐다는 결과만으로 이 과정을 대신할 수는 없습니다.
실패했을 때 멈추는 규칙과 재시작 기록
자동화가 실패할 때마다 같은 작업을 반복하면 시간과 비용만 늘어날 수 있습니다. 오류를 읽고 다음 행동을 바꾸는 규칙이 필요합니다. 실패를 적어도 세 종류로 구분해 볼 수 있습니다.
구현이 요구사항과 다른 경우에는 그 차이를 고친 뒤 관련 검사를 다시 실행합니다. 입력이 사라지는 버그가 여기에 해당합니다. 환경 문제라면 시험용 저장소의 실행 여부나 권한부터 확인합니다. 환경이 준비되지 않아 실행하지 못한 검사는 ‘통과’가 아니라 ‘미실행’으로 남깁니다. 요구사항이 모호한 경우에는 성공 응답의 의미처럼 필요한 결정을 요청하고, 그 결정에 의존하는 구현을 잠시 멈춥니다.
재시도 자체가 부작용을 만들 수도 있습니다. 접수는 됐는데 응답만 늦게 도착한 상황에서 무조건 다시 보내면 문의가 중복될 수 있습니다. 이 경우에는 이미 처리됐는지 확인하거나 같은 요청을 구분하는 설계가 필요합니다. 하네스가 재시도 횟수만 관리해서 해결할 문제는 아닙니다.
시간·비용 한도도 시작 전에 정합니다. 같은 실패가 원인 설명 없이 반복되거나, 필요한 권한이 없거나, 다음 행동이 운영 데이터 변경·배포처럼 맡긴 범위를 넘으면 기록을 남기고 판단을 넘기도록 합니다. 모두에게 맞는 재시도 횟수는 없으므로 변경 위험과 실행 비용에 맞춰 정합니다.
- 시작 상태 확인현재 코드와 이전 기록을 읽고 기본 검사가 작동하는지 확인합니다.
- 한 범위 구현합의한 완료 기준 중 하나의 검토 가능한 작업을 진행합니다.
- 검사와 리뷰실행 결과와 diff를 함께 보고 실패·미검증 항목을 분류합니다.
- 수정 또는 중단고칠 수 있는 원인을 수정하고, 결정·권한이 필요한 일은 멈춰 알립니다.
- 상태 인계현재 코드, 확인 근거, 남은 문제와 다음 행동을 기록합니다.
작업 세션이 끊기기 전에는 인계 기록을 남깁니다. 예를 들면 ‘문의 화면 구현 완료, 정상 접수 확인, 저장 실패 시 입력 보존 미완료, 다음에는 실패 시 초기화 호출을 검토’처럼 적습니다. 여기에 현재 커밋 식별자, 아직 커밋하지 않은 변경, 검사 로그 위치, 시험 환경을 연결합니다. 커밋 식별자는 어떤 코드의 결과인지 가리키는 이름이며, 검사 뒤 파일이 바뀌었다면 그 기록은 현재 코드의 통과 증거가 아닙니다.
다음 세션은 요약만 믿고 곧바로 코드를 더 쓰기보다 실제 작업 폴더와 변경 상태를 먼저 확인합니다. 요약이 가리키는 코드가 달라졌거나 로그가 없으면 필요한 검사를 다시 해야 합니다. 인계 기록은 이전 추론을 모두 복사하는 문서보다 다음 작업자가 현재 상태를 확인할 수 있는 안내에 가까워야 합니다.
하네스 구축 방법: 작은 프로젝트의 최소 구성
처음부터 복잡한 자동화 플랫폼을 만들 필요는 없습니다. 문의 폼 하나에 다음 산출물을 붙이는 것부터 시작할 수 있습니다. 아래 파일명은 구조를 설명하는 예시이며, 사용 중인 도구가 자동으로 인식하는 공통 규격은 아닙니다.
- 작업 약속:
docs/tasks/contact-form.md같은 위치에 목적, 범위, 완료 기준, 제외할 기능을 적습니다. 도구가 실제로 읽도록 작업 지침에서 경로를 연결합니다. - 반복 가능한 검사 진입점: 기존 검사 명령을
package.json의 스크립트나 프로젝트 실행 도구에 정리합니다. 시험 환경 준비와 정리, 실패 전달 방식까지 설명합니다. 설치와 실행 명령은 프로젝트의 기술과 운영체제에 맞춰야 합니다. - 검사 근거: 자동 검사 로그에는 코드 버전, 실행 환경, 검사 이름, 결과와 실패 내용을 남깁니다. 화면 증거가 필요한 동작만 캡처하고, 비밀값이나 실제 문의 내용은 기록에 넣지 않습니다.
- 리뷰와 병합 조건: PR 설명에 완료 기준별 근거를 연결하고, 필수 검사와 필요한 승인이 충족돼야 합칠 수 있게 설정합니다. 결과가 바뀌면 검토 근거도 갱신합니다.
- 인계 기록: 완료·미완료·미검증과 다음 행동을 구분합니다. 같은 정보를 여러 문서에 복제하기보다 권위 있는 기록 한곳을 정합니다.
첫 자동화는 사람이 실행하는 동일한 검사 명령으로 시작해도 됩니다. 그다음 로컬 훅, CI, AI 리뷰를 붙이고, 실패 처리까지 안정적으로 확인된 부분의 자동화 범위를 넓힙니다. 검사할 대상이 없는데 실행기부터 복잡하게 만들면 무엇이 개선됐는지 알기 어렵습니다.
검사 환경의 권한은 용도에 맞춰 제한합니다. 외부 PR의 코드나 설명을 신뢰한 지시로 받아들이지 않고, 검토용 작업에 운영 배포 권한을 섞지 않습니다. 문서에 금지 문장을 적는 것에 더해 실행 계정과 도구 권한으로 제한해야 합니다. GitHub의 Actions 보안 지침은 최소 권한과 신뢰할 수 없는 입력·코드 취급을 설명합니다.
하네스가 좋아졌는지 확인하는 방법
하네스 파일이 늘었거나 AI가 오래 자율적으로 움직였다는 사실만으로 개선을 판단하기는 어렵습니다. 문의 폼에서 실제로 발견한 실패를 고정된 예시로 남기고, 작업 지침이나 도구 구성을 바꿨을 때 같은 실패를 찾아내는지 확인해 보세요.
정상 접수, 빈 입력, 중복 클릭, 저장 실패, 응답 이름 불일치를 같은 조건으로 비교할 수 있습니다. 그 과정에서 어떤 문제를 놓쳤는지, 근거 없는 지적 때문에 사람이 얼마나 재검토했는지, 검사에 어느 정도 시간과 비용이 들었는지도 봅니다. 작은 예시 묶음의 성공을 모든 작업의 품질 보장으로 확대하지는 않습니다.
한 번 완성한 결과에 새 요구를 순서대로 붙여 보는 평가도 필요합니다. SlopCodeBench는 에이전트가 자신이 만든 코드를 이후 요구에 맞춰 계속 확장하도록 평가합니다. 연구팀도 이를 완결된 품질 판정 기준이 아닌 발전 중인 평가 도구로 소개합니다. 특정 벤치마크의 성공률만으로 내 서비스의 유지보수성을 확정하기는 어렵습니다.
이 문의 폼에서는 ‘기본 접수 → 문의 유형 추가 → 같은 제출의 재시도 처리 → 저장소 교체’를 후속 과제로 정할 수 있습니다. 첫 구현을 매번 버리고 새로 만들지 않고 이전 결과를 이어서 수정합니다. 각 단계에서 기존 동작이 유지되는지, 같은 규칙을 여러 곳에서 고쳐야 하는지, 관련 없는 코드를 얼마나 건드렸는지, 사람이 설명과 수정을 얼마나 보탰는지를 기록합니다. 이는 평가 구성의 제안이며 실제 비교 결과는 아닙니다.
하네스 변경 전후를 비교할 때는 모델·도구 버전, 시작 코드, 요구사항, 시간·토큰 예산과 실행 환경을 맞추고 바뀐 조건을 기록합니다. 사람이 계획을 검토하는 시간을 포함해야 전체 비용을 볼 수 있습니다. PR 생성 수나 첫 코드가 나온 시간만으로 속도를 평가하면 리뷰 대기와 재작업이 빠집니다. 요구를 정한 시점부터 검증된 변경을 받아들일 때까지의 시간을 함께 보세요.
모델 교체와 하네스 간소화는 한 번에 섞지 않는 편이 원인을 파악하기 쉽습니다. 먼저 같은 하네스에서 새 모델의 결과를 확인합니다. 그다음 새 모델을 유지한 채 반복 계획이나 중복 리뷰 같은 보조 요소를 하나씩 줄입니다. 여러 대표 작업에서 완료 기준 누락, 잘못된 변경, 사람의 재작업, 시간·비용을 비교하고, 실패가 늘면 해당 요소를 복구합니다. 안전 경계를 해제한 운영 실험 대신 격리된 시험 환경에서 보조 절차의 효과를 비교합니다.
검사를 늘리는 것이 항상 답은 아닙니다. 같은 실패를 중복 검사하는 항목은 줄이고, 중요한데 빠진 동작을 보완합니다. 자주 불규칙하게 실패하는 검사는 무작정 재실행해 초록색으로 만들기보다 원인을 기록하고 고칩니다. 일시적으로 필수 검사에서 제외해야 한다면 책임자와 복구 조건을 정해 검증 공백이 잊히지 않도록 합니다.
다음 AI 작업에서는 아래처럼 설계부터 요청해 볼 수 있습니다.
문의 폼을 구현하기 전에 작업 하네스를 설계해 주세요. 기존 검사 명령과 저장 구조를 먼저 확인하고, 성공의 의미·화면과 서버의 응답 약속·주요 함수의 책임·첫 PR 범위를 제안해 주세요. 모호한 요구나 구조 변경이 필요한 부분은 구현 전에 검토할 수 있게 표시해 주세요. 정상 접수·빈 입력·중복 클릭·저장 실패를 어떤 입력과 결과로 확인할지 제안해 주세요. 수정 가능한 범위와 시험 환경, 리뷰에 전달할 근거, 실패 시 중단 조건, 다음 세션에 남길 기록을 정리해 주세요. 새 도구를 추가하기 전에 현재 도구로 가능한 구성을 우선 검토해 주세요. 실제 메일 발송과 운영 데이터 변경은 이번 범위에 포함하지 않습니다.
좋은 하네스는 어떤 상태에서 작업을 시작했고, 무엇을 바꿨고, 무엇으로 확인했으며, 어디에서 사람이 결정해야 하는지 알 수 있게 하는 구조입니다. 완료 조건을 합의하고, 작은 동작을 연결하고, 다음 변경의 부담까지 검토하는 데서 시작해 보세요. 하네스 엔지니어링의 실용적인 목표는 이런 판단과 근거가 작업마다 빠지지 않도록 만드는 것입니다. 모델이 더 잘하는 일에 대한 보조 절차는 줄이고, 프로젝트가 요구하는 기준과 통제는 필요한 만큼 유지하세요.
VIEW—


