'AI에게 더 잘 부탁하는 법'을 고민하다 보면 어느 순간 한계에 부딪힌다. 프롬프트를 아무리 정교하게 다듬어도, 다음 날 새 대화창을 열면 어제의 규칙은 사라져 있고, 같은 실수를 다시 교정하고 있는 자신을 발견하게 된다. 최근 벨로그에서 소개된 하네스 엔지니어링(Harness Engineering) 은 바로 이 지점에서 출발한다. 문제의 원인이 프롬프트 기술 부족이 아니라, '하나의 대화창 안에서 모든 것을 해결하려는 구조 자체'에 있다는 인식 전환이 핵심이다.
하네스 엔지니어링의 본질은 간단하다. LLM 모델을 바꾸거나 조작하는 것이 아니라, 모델이 일하는 작업장을 설계하는 것이다. AI에게 자유를 주는 대신 제약과 구조를 부여하고, 그 결과로 예측 가능하고 재사용 가능한 시스템을 만든다. 기존 방식이 매 대화마다 사람이 품질 게이트 역할을 떠맡는 구조였다면, 하네스는 그 책임을 파일과 워크플로우로 외부화한다.
구체적으로 어떤 문제들이 해결되는지 살펴보면 패턴이 보인다. 크게 다섯 가지 고통 지점이 있다. ① 새 대화마다 프로젝트 배경을 반복 입력하는 비용, ② AI가 설계 단계를 건너뛰고 바로 구현으로 점프하는 버릇, ③ 누락된 케이스와 컨벤션 위반을 사람이 매번 교정해야 하는 부담, ④ 대화창에서만 언급한 규칙이 다음 날 사라지는 휘발성, ⑤ 대화가 길어질수록 초반 설계 의도가 오염되는 컨텍스트 드리프트. 이 다섯 문제의 공통점은 '지식과 규칙이 사람의 머릿속과 대화창에만 존재한다'는 것이다.
하네스의 해법은 dev-harness/라는 디렉터리 하나로 수렴된다. 구조는 이렇다. CLAUDE.md와 memory/ 폴더가 프로젝트 배경과 팀 규칙을 영속화해 매 대화에 자동 주입한다. skills/ 폴더 안의 슬래시 커맨드들이 워크플로우를 고정하고—특히 /implement는 설계 문서 없이 호출하면 실행 자체를 거부하는 가드를 포함한다. agents/ 폴더는 planner, implementer, reviewer를 격리된 컨텍스트로 분리해 컨텍스트 오염을 원천 차단한다. 핵심 통찰은 이것이다. "프롬프트로 '계획부터 세워줘'라고 부탁하는 것과, 파일이 없으면 실행을 거부하는 것은 완전히 다르다." 전자는 모델의 선의에 기대고, 후자는 하네스가 강제한다.
이 방법론이 흥미로운 이유는 AI 도구를 둘러싼 논의의 방향을 바꾸기 때문이다. 지금까지 대부분의 'AI 잘 쓰는 법' 담론은 더 나은 프롬프트, 더 강력한 모델, 더 정교한 컨텍스트 윈도우에 집중해왔다. 하네스 엔지니어링은 반대 방향을 제안한다. 모델을 더 잘 다루려 하지 말고, 모델 바깥의 환경을 설계하라는 것이다. 이는 소프트웨어 엔지니어링의 오래된 원칙—사람의 실수를 줄이려면 개인의 주의력이 아니라 시스템의 구조를 바꿔야 한다—을 AI 워크플로우에 그대로 적용한 셈이다.
실전 적용 사례로, 또 다른 차원의 '조용한 품질 실패'를 함께 살펴볼 필요가 있다. dev.to에 게재된 Next.js JSON-LD 디버깅 사례는 하네스 엔지니어링이 해결하려는 문제와 구조적으로 닮아 있다. 개발자가 블로그의 구조화 데이터를 세 개의 <script type="application/ld+json"> 태그로 분리 작성했는데, Google Rich Results Test에서는 모두 통과했지만 Search Console에서는 Article 스키마만 인식되고 나머지 두 개는 무시됐다. 3시간의 디버깅 끝에 발견한 원인은 단순했다. Google은 여러 JSON-LD 블록을 파싱할 때 크롤 예산 제약으로 첫 번째만 처리하는 경우가 있으며, 공식 문서에서도 @graph를 통한 단일 문서 구조를 '권장'한다고 명시하고 있었다.
@graph로 전환하면 세 스키마가 하나의 JSON 문서로 통합되고, 스키마 간 @id 참조도 가능해진다. Next.js App Router에서의 구현은 어렵지 않다. Server Component에서 @graph 객체를 빌드하고 단일 <script> 태그로 렌더링하면 된다. 여기서 놓치기 쉬운 디테일이 하나 있다. dangerouslySetInnerHTML에 JSON 문자열을 직접 주입할 때 XSS 처리가 필요하다. 포스트 제목에 </script>가 포함되면 브라우저가 이를 실제 태그로 해석해 페이지가 깨질 수 있다. JSON.stringify(graph).split("</").join("<\\/") 처리가 정석이며, \/는 JSON 스펙상 유효한 이스케이프다. 스키마 타입이 많아지면 validateSchema() 같은 런타임 검증 함수를 추가하는 것도 고려할 만하다—TypeScript는 필드 타입 오류는 잡지만 Google이 요구하는 필수 필드 누락은 잡지 못하기 때문이다.
두 사례를 나란히 놓으면 공통된 설계 원칙이 드러난다. 검증은 빠를수록 좋고, 규칙은 코드 바깥에 있어야 오래 살아남는다. 하네스의 /review 체크리스트가 사람의 암묵지를 파일로 외부화하듯, JSON-LD의 validateSchema()는 Google의 크롤 결과를 기다리지 않고 렌더링 전에 스키마 오류를 잡아낸다. 두 접근 모두 '나중에 알아차리는 것'을 '미리 막는 것'으로 전환하는 구조적 선택이다.
시작점은 거창할 필요가 없다. 하네스 엔지니어링 원문에서 제안하는 순서가 현실적이다. memory/stack.md부터 만들어 반복 입력을 없애고, 같은 지적이 두 번 반복될 때마다 team-rules.md에 한 줄씩 추가하고, 설계 없이 구현으로 점프하는 상황이 불편해질 때 /plan 스킬을 추가하는 식이다. JSON-LD라면 기존 분리 태그를 @graph 단일 구조로 통합하는 것 하나만으로도 Search Console 가시성이 달라진다. 둘 다 '완벽한 시스템을 처음부터 구축'하는 것이 아니라, 경험이 누적될수록 점점 더 잘 작동하는 살아있는 레이어를 만드는 일이다.
결국 하네스 엔지니어링이 제시하는 방향은 AI 도구를 대하는 태도의 전환이다. AI를 더 잘 설득하려는 노력에서, AI가 일할 환경을 더 잘 설계하는 노력으로. 프롬프트 기술자에서 워크플로우 아키텍트로. 이 전환이 자리 잡는 팀과 그렇지 않은 팀 사이의 격차는, AI 도구의 도입 속도가 빨라질수록 더 선명하게 벌어질 것이다.