코딩 에이전트의 결과에 대한 신뢰를 높이기 위해 가이드와 센서를 조합하는 하니스 엔지니어링의 정신 모델을 설명한다.
코딩 에이전트가 더 적은 감독으로 작업할 수 있게 하려면, 그 결과에 대한 우리의 신뢰를 높이는 방법이 필요하다. 소프트웨어 엔지니어로서 우리는 AI가 생성한 코드에 대해 자연스러운 신뢰 장벽을 가지고 있다. LLM은 비결정적이고, 우리의 맥락을 모르며, 코드를 진정으로 이해하지도 않고 토큰 단위로 사고한다. 이 글은 그 신뢰를 구축하기 위해 컨텍스트 엔지니어링과 하니스 엔지니어링에서 떠오르는 개념들을 하나로 묶는 정신 모델을 탐구한다.
2026년 04월 02일
Birgitta는 Thoughtworks의 Distinguished Engineer이자 AI 보조 딜리버리 전문가이다. 그녀는 소프트웨어 개발자, 아키텍트, 기술 리더로서 20년이 넘는 경험을 가지고 있다.
이 글은 하니스 엔지니어링에 대한 나의 첫인상을 정리했던 이전 메모를 업데이트한 것이다.
하니스라는 용어는 모델 자체를 제외한 AI 에이전트의 모든 것을 뜻하는 축약어로 떠올랐다 - Agent = Model + Harness. 이것은 매우 넓은 정의이므로, 일반적인 에이전트 범주에 대해서는 더 좁혀볼 가치가 있다. 여기서는 코딩 에이전트를 사용하는 제한된 맥락 안에서 그 의미를 정의해 보려고 한다. 코딩 에이전트에서는 하니스의 일부가 이미 내장되어 있다(예: 시스템 프롬프트, 선택된 코드 검색 메커니즘, 혹은 정교한 오케스트레이션 시스템을 통해서). 하지만 코딩 에이전트는 또한 사용자에게, 우리의 사용 사례와 시스템에 맞춘 외부 하니스를 구축할 수 있는 많은 기능을 제공한다.
누군가는 하니스 위에 다시 하니스를 감싼다는 것은 말이 되지 않는다고 지적했다. “개 몸 안쪽에 하니스를 씌워본 적이 있나요?” 그래서 이것은 다소 은유를 무리하게 확장하는 셈이지만, 이 단어의 사용을 탐색하는 데 도움이 된다면 나는 기꺼이 받아들일 생각이다.
Figure 1: “하니스”라는 용어는 제한된 맥락에 따라 다른 의미를 갖는다.
잘 구축된 외부 하니스는 두 가지 목표를 가진다. 첫째, 에이전트가 처음부터 올바르게 해낼 확률을 높인다. 둘째, 사람이 보기 전에 가능한 한 많은 문제를 스스로 교정할 수 있도록 피드백 루프를 제공한다. 궁극적으로는 검토에 드는 수고를 줄이고 시스템 품질을 높여야 하며, 그 과정에서 낭비되는 토큰이 줄어드는 부수적 이점도 있다.
![Image 4: 제목은 "코딩 에이전트 사용자를 위한 하니스 엔지니어링". 가이드의 개요(예시는 [추론적] principles, CfRs, Rules, Ref Docs, How-tos; [계산적] Language Servers, CLIs, scripts, codemods)가 코딩 에이전트로 피드포워드된다. 그리고 피드백 센서(예시는 [추론적] review agents; [계산적] static analysis, logs, browser)가 있다. 피드백 센서는 코딩 에이전트를 가리키며, 그 자체 교정 루프의 입력으로도 들어간다. 전체의 왼쪽에는 가이드와 센서를 모두 조향하는 인간이 있는 상자가 보인다.](https://martinfowler.com/articles/harness-engineering/harness-overview.png)
코딩 에이전트를 하니스로 다룬다는 것은, 원치 않는 출력을 미리 예상하고 방지하려 노력하는 동시에, 에이전트가 스스로 교정할 수 있도록 센서를 배치하는 것을 의미한다.
둘 중 하나만 따로 두면, 같은 실수를 계속 반복하는 에이전트(피드백만 있는 경우) 혹은 규칙은 인코딩했지만 그것이 효과가 있었는지 결코 알지 못하는 에이전트(피드포워드만 있는 경우)를 얻게 된다.
가이드와 센서에는 두 가지 실행 유형이 있다.
계산적 가이드는 결정적 도구를 통해 좋은 결과의 확률을 높인다. 계산적 센서는 충분히 저렴하고 빨라서 모든 변경마다 에이전트와 함께 실행할 수 있다. 추론적 제어는 물론 더 비싸고 비결정적이지만, 풍부한 안내를 제공하고 추가적인 의미적 판단을 더할 수 있게 해준다. 비결정적이라는 점에도 불구하고, 추론적 센서는 강력한 모델, 혹은 수행하려는 작업에 적합한 모델과 함께 사용할 때 특히 우리의 신뢰를 높일 수 있다.
예시
| 방향 | 계산적 / 추론적 | 예시 구현 | |
|---|---|---|---|
| 코딩 규약 | 피드포워드 | 추론적 | AGENTS.md, Skills |
| 새 프로젝트를 부트스트랩하는 방법에 대한 지침 | 피드포워드 | 둘 다 | 지침이 담긴 Skill과 부트스트랩 스크립트 |
| 코드 모드 | 피드포워드 | 계산적 | OpenRewrite 레시피에 접근할 수 있는 도구 |
| 구조 테스트 | 피드백 | 계산적 | 모듈 경계 위반을 검사하는 ArchUnit 테스트를 실행하는 pre-commit(또는 코딩 에이전트) 훅 |
| 리뷰 방법에 대한 지침 | 피드백 | 추론적 | Skills |
컨텍스트 엔지니어링은 가이드와 센서를 에이전트가 이용할 수 있게 만드는 수단을 제공한다. 코딩 에이전트를 위한 사용자 하니스를 엔지니어링하는 것은 컨텍스트 엔지니어링의 한 가지 구체적 형태다.
여기에서 인간의 역할은 하니스를 반복적으로 개선함으로써 에이전트를 조향하는 것이다. 어떤 문제가 여러 번 발생한다면, 그 문제가 미래에 발생할 가능성을 낮추거나 아예 막을 수 있도록 피드포워드와 피드백 제어를 개선해야 한다.
조향 루프에서는 물론 하니스 자체를 개선하는 데에도 AI를 사용할 수 있다. 오늘날의 코딩 에이전트는 더 많은 커스텀 제어와 더 많은 커스텀 정적 분석을 훨씬 저렴하게 구축하게 해준다. 에이전트는 구조 테스트 작성, 관찰된 패턴에서 초안 규칙 생성, 커스텀 린터의 골격 마련, 혹은 코드베이스 고고학을 통해 how-to 가이드 만들기를 도울 수 있다.
지속적 통합을 수행하는 팀은 항상 테스트, 점검, 인간 리뷰를 개발 타임라인 전반에 걸쳐 비용, 속도, 중요도에 따라 배치해야 하는 과제에 직면해 왔다. 지속적 딜리버리를 지향한다면, 이상적으로는 모든 커밋 상태가 배포 가능하기를 원한다. 문제를 더 일찍 발견할수록 수정 비용이 더 저렴하므로, 가능한 한 생산 경로의 왼쪽에 점검을 배치하고 싶다. 새로운 추론적 센서를 포함한 피드백 센서는 그에 맞추어 생애주기 전반에 분산되어야 한다.
변경 생애주기에서의 피드포워드와 피드백

지속적 드리프트와 헬스 센서

에이전트 하니스는 사이버네틱스적 조속기처럼 작동하여, 피드포워드와 피드백을 결합해 코드베이스를 원하는 상태로 규제한다. 그 원하는 상태를, 하니스가 무엇을 규제해야 하는지에 따라 여러 차원으로 구분해 보는 것이 유용하다. 이 범주들을 구별하는 것이 도움이 되는 이유는, 범주마다 하니스 가능성과 복잡성이 다르기 때문이며, 이 단어에 수식어를 붙이면 원래 매우 일반적인 용어인 하니스에 대해 더 정확한 언어를 얻을 수 있기 때문이다.
현재로서는 다음 세 가지 범주가 유용해 보인다.
이 글에서 내가 드는 예시의 거의 전부는 내부 코드 품질과 유지보수성을 규제하는 것에 관한 것이다. 현재 시점에서 이것이 가장 쉬운 종류의 하니스인데, 우리가 활용할 수 있는 기존 도구가 많이 있기 때문이다.
이러한 유지보수성 하니스 아이디어가 에이전트에 대한 나의 신뢰를 얼마나 높여주는지 돌아보기 위해, 나는 이전에 정리한 코딩 에이전트의 일반적인 실패 모드를 그것과 매핑해 보았다.
계산적 센서는 구조적인 문제를 신뢰성 있게 잡아낸다. 중복 코드, 순환 복잡도, 누락된 테스트 커버리지, 아키텍처 드리프트, 스타일 위반 등이 그렇다. 이들은 저렴하고, 검증되었으며, 결정적이다.
LLM은 의미적 판단이 필요한 문제, 예를 들어 의미적으로 중복된 코드, 중복 테스트, 무식한 방식의 수정, 과도하게 공들인 해결책 등을 부분적으로 다룰 수 있지만, 비용이 많이 들고 확률적이다. 매 커밋마다 실행하기는 어렵다.
그러나 어느 쪽도 더 큰 영향을 미치는 몇몇 문제는 신뢰성 있게 잡아내지 못한다. 문제를 잘못 진단하는 것, 과도한 설계와 불필요한 기능, 잘못 이해한 지시 등이 그렇다. 가끔은 잡아내지만, 감독을 줄일 만큼 충분히 신뢰할 수는 없다. 인간이 애초에 무엇을 원하는지 명확히 지정하지 않았다면, 정합성은 어떤 센서의 책임 범위에도 들어가지 않는다.
이 범주는 애플리케이션의 아키텍처 특성을 정의하고 점검하는 가이드와 센서를 묶는다. 기본적으로는 적합성 함수다.
예시:
이것이 바로 가장 큰 문제다. 애플리케이션이 우리가 필요로 하는 방식으로 기능적으로 동작하는지를 어떻게 가이드하고 감지할 것인가? 현재로서는, 코딩 에이전트에 높은 자율성을 부여하는 대부분의 사람들이 이렇게 하는 것으로 보인다.
이 접근법은 AI가 생성한 테스트에 많은 믿음을 둔다. 하지만 아직은 그것만으로 충분하지 않다. 내 동료들 중 일부는 approved fixtures 패턴으로 좋은 결과를 보고 있지만, 어떤 영역에는 적용하기 쉽고 어떤 영역에는 그렇지 않다. 그들은 이것이 맞는 곳에 선택적으로 사용하지, 테스트 품질 문제 전체에 대한 일괄적인 해답으로 보지는 않는다.
그래서 전반적으로, 감독과 수동 테스트를 줄일 만큼 우리의 신뢰를 충분히 높여주는 기능적 행동 하니스를 찾아내기 위해 아직도 해야 할 일이 많다.

모든 코드베이스가 똑같이 하니스 적용에 적합한 것은 아니다. 강한 타입 언어로 작성된 코드베이스는 자연스럽게 타입 체킹을 센서로 가진다. 명확하게 정의 가능한 모듈 경계는 아키텍처 제약 규칙을 가능하게 한다. Spring 같은 프레임워크는 에이전트가 아예 신경 쓸 필요조차 없는 세부사항을 추상화해 주며, 따라서 암묵적으로 에이전트의 성공 가능성을 높인다. 이런 성질이 없다면, 그런 제어를 구축할 수 없다.
내 동료 Ned Letcher는 환경 자체의 성질 중 에이전트가 더 잘 하니스될 수 있게 만드는 것을 “주변적 어포던스”라고 부른다. “에이전트가 그 안에서 작동할 때 환경을 더 읽기 쉽고, 탐색 가능하고, 다루기 쉽게 만드는 환경 자체의 구조적 성질”이라는 뜻이다.
이것은 그린필드와 레거시에서 서로 다르게 나타난다. 그린필드 팀은 첫날부터 하니스 가능성을 내장할 수 있다. 기술 선택과 아키텍처 선택이 코드베이스를 얼마나 잘 통제할 수 있는지를 결정하기 때문이다. 반면 레거시 팀, 특히 기술 부채가 많이 쌓인 애플리케이션을 다루는 팀은 더 어려운 문제에 직면한다. 하니스가 가장 필요한 곳이, 바로 그것을 구축하기 가장 어려운 곳이기 때문이다.
대부분의 기업은 자신들이 필요로 하는 것의 80%를 커버하는 몇 가지 공통 서비스 토폴로지를 가지고 있다. API를 통해 데이터를 노출하는 비즈니스 서비스, 이벤트 처리 서비스, 데이터 대시보드 같은 것들이다. 많은 성숙한 엔지니어링 조직에서는 이런 토폴로지가 이미 서비스 템플릿으로 성문화되어 있다. 앞으로는 이것들이 하니스 템플릿으로 발전할 수도 있다. 즉, 특정 토폴로지의 구조, 규약, 기술 스택에 코딩 에이전트를 묶어두는 가이드와 센서의 묶음이 되는 것이다. 팀은 자신들에게 이미 어떤 하니스가 제공되는지를 기준으로 부분적으로 기술 스택과 구조를 선택하기 시작할 수도 있다.

애슈비의 필요 다양성 법칙은 이러한 사전 정의된 토폴로지에 대해 또 다른 흥미로운 논거를 제공한다. 이 법칙은 규제자가 자신이 다스리는 시스템만큼은 다양한 상태를 다룰 수 있어야 하며, 자신이 모델을 가진 것만 규제할 수 있다고 말한다. LLM 기반 코딩 에이전트는 거의 무엇이든 만들어낼 수 있지만, 토폴로지에 헌신하면 그 공간이 좁아져 포괄적인 하니스를 구축하기가 더 쉬워진다. 토폴로지를 정의하는 것은 다양성을 줄이는 행위다.
물론 우리는 서비스 템플릿과 유사한 과제에 직면하게 될 것이다. 팀이 그것을 인스턴스화하는 순간, 상위의 개선 사항과 동기화가 어긋나기 시작한다. 하니스 템플릿도 동일한 버전 관리와 기여 문제에 직면할 것이며, 아마도 테스트하기 더 어려운 비결정적 가이드와 센서 때문에 더 심각할 수도 있다.
인간 개발자로서 우리는 우리의 기술과 경험을 암묵적 하니스로서 모든 코드베이스에 가져간다. 우리는 규약과 좋은 관행을 체화했고, 복잡성이 주는 인지적 고통을 경험했으며, 커밋에 우리의 이름이 남는다는 사실을 안다. 또한 우리는 조직적 정렬도 가지고 있다. 팀이 무엇을 달성하려 하는지, 어떤 기술 부채가 비즈니스 이유로 용인되는지, 그리고 이 특정 맥락에서 “좋음”이 무엇을 의미하는지에 대한 인식이다. 우리는 작은 단계로, 인간의 속도에 맞춰 작업하고, 그 덕분에 이러한 경험이 자극되고 적용될 사고 공간이 생긴다.
코딩 에이전트는 이 중 어느 것도 없다. 사회적 책임감도 없고, 300줄짜리 함수에 대한 미적 혐오도 없으며, “여기서는 그렇게 하지 않는다”는 직관도 없고, 조직의 기억도 없다. 어떤 규약이 구조적으로 중요한지, 무엇이 단지 습관인지, 혹은 기술적으로 맞는 해결책이 팀이 하려는 일에 부합하는지도 알지 못한다.
하니스는 인간 개발자의 경험이 가져오는 것을 외부화하고 명시적으로 만들려는 시도이지만, 거기에도 한계가 있다. 가이드, 센서, 자체 교정 루프로 이루어진 일관된 시스템을 구축하는 일은 비용이 많이 들기 때문에, 우리는 명확한 목표를 가지고 우선순위를 정해야 한다. 좋은 하니스는 인간의 입력을 완전히 제거하는 것을 목표로 하기보다는, 우리의 입력이 가장 중요한 곳으로 그것을 유도하는 것을 목표로 해야 한다.
여기서 내가 제시한 정신 모델은 이미 실제로 일어나고 있는 기법들을 설명하고, 우리가 아직 무엇을 해결해야 하는지에 대한 논의를 틀지어 준다. 그 목표는 대화를 기능 수준 위로 끌어올리는 데 있다. Skills와 MCP 서버에서, 에이전트가 만들어내는 것에 대해 진정한 신뢰를 주는 제어 시스템을 우리가 어떻게 전략적으로 설계할 것인가로 논의를 옮기는 것이다.
현재 논의에서 볼 수 있는 하니스 관련 사례 몇 가지는 다음과 같다.
아직 해결해야 할 일은 많이 남아 있다. 이미 언급한 행동 하니스만이 아니다. 가이드와 센서가 서로 동기화되고, 서로 모순되지 않으면서, 하니스가 성장함에 따라 어떻게 일관성을 유지할 수 있을까? 지침과 피드백 신호가 서로 다른 방향을 가리킬 때, 에이전트가 합리적인 절충을 할 것이라고 어디까지 신뢰할 수 있을까? 센서가 전혀 발화하지 않는다면, 그것은 높은 품질의 신호일까, 아니면 탐지 메커니즘이 부적절하다는 신호일까? 우리는 테스트에 대해 코드 커버리지와 뮤테이션 테스팅이 해주는 것과 유사하게, 하니스의 커버리지와 품질을 평가할 방법이 필요하다. 피드포워드와 피드백 제어는 현재 딜리버리 단계 전반에 흩어져 있는데, 이를 하나의 시스템으로 설정하고 동기화하고 추론할 수 있게 돕는 도구에는 분명한 가능성이 있다. 이 외부 하니스를 구축하는 일은 일회성 설정이 아니라 지속적인 엔지니어링 실천으로 떠오르고 있다.
지난 기술 레이더 미팅에서 흥미로운 토론을 나눠준 Doppler 팀에 큰 감사를 전한다. 특히 사이버네틱스를 언급해 준 Kief Morris에게 감사한다. 하니스가 도대체 무엇인지에 대한 대화를 함께 나눈 Ned Letcher, Chris Ford, Ben O'Mahoney에게도 감사하고, 행동 하니스에 대한 통찰을 준 Matteo Vaccari에게도 감사한다. 그리고 초안을 읽고 많은 귀중한 피드백을 제공해 준 모든 분들께 감사한다: Christoph Burgmer, Jörn Dinkla, Michael Feathers, Karrtik Iyer, Swapnil Phulse, Paul Sobocinski, Zhenjia Zhou
연구, 기존 메모에서 관련 아이디어를 끌어오기, 그리고 문장을 다듬는 데 GenAI(Claude와 Claude Code)를 사용했다.
나는 2월 초에 쓴 메모에서 Harness Engineering이라는 용어가 처음 등장했을 때의 초기 생각을 정리했다. 그 글은 많은 트래픽을 끌어모았다. 이 글이 그 메모를 대체하므로, 독자들에게는 이 페이지가 더 나은 자료라고 판단해 원래 메모 URL을 이 페이지로 리디렉션했다.
중요한 수정 사항 2026년 04월 02일: 가이드, 센서, 계산적 요소와 추론적 요소, 하니스 템플릿을 포함한 전체 글 게시
2026년 02월 17일: Harness Engineering에 대한 초기 메모 게시
© Martin Fowler | 공개 정보