하네스 엔지니어링, 결국 에이전트의 고삐를 누가 쥐느냐의 문제다

프롬프트 엔지니어링 얘기는 이제 좀 오래된 느낌이 난다. 한때는 그게 전부인 것처럼 말하던 시기가 있었다. 질문을 어떻게 쓰느냐, 역할을 어떻게 부여하느냐, 예시를 몇 개 넣느냐. 그 조합 하나로 결과가 꽤 달라졌으니까 그럴 만도 했다. 실제로 2023년, 2024년에는 그게 맞았다. 같은 모델을 써도 프롬프트를 잘 짠 사람이 더 나은 결과를 뽑았다.

그런데 2025년쯤부터 이상한 일이 생겼다. 프롬프트를 아무리 잘 써도 안 풀리는 문제가 눈에 들어오기 시작한 거다. 모델은 분명 좋아졌고, CLI 기반 도구나 에이전트형 인터페이스도 계속 나왔는데, 막상 실제 작업을 시켜보면 엉뚱한 데서 무너졌다. 구현은 시작하는데 끝을 못 보고, 파일은 만지는데 상태를 잃고, 스스로 테스트까지 하라고 하면 이상할 정도로 낙관적이 됐다. “잘했다”고 말하는데 결과물은 별로인 상황. 이게 반복되다 보니, 문제의 중심이 프롬프트가 아니라는 게 보였다.

그다음에 나온 말이 컨텍스트 엔지니어링이었다. 이건 꽤 설득력이 있었다. 결국 모델이 똑똑하게 일하려면 질문을 잘 쓰는 것보다 뭘 보여주느냐가 더 중요하다는 얘기였으니까. RAG, MCP, 메모리 시스템, 히스토리 관리, 각종 검색 레이어가 전부 그 흐름 위에 있었다. 나도 한동안은 여기서 정리가 끝나는 줄 알았다.

근데 올해 들어서는 그것도 부족하다는 쪽으로 생각이 바뀌었다.

왜냐하면 에이전트를 실제로 오래 굴려보면, 컨텍스트조차 전체의 일부일 뿐이기 때문이다. 어떤 파일에 접근할 수 있는지, 코드를 어디서 실행하는지, 실패했을 때 무엇으로 검증하는지, 상태를 어디에 남기는지, 언제 멈추게 할지, 어느 지점에서 사람에게 넘길지. 이건 “무엇을 보여줄까”보다 더 바깥의 문제다. 말 그대로 환경이다.

그리고 이 환경을 설계하는 일을 가리키는 이름으로, 이제는 하네스 엔지니어링이라는 표현이 꽤 정확해 보인다.

하네스라는 단어부터가 좋다. 말에게 씌우는 마구. 고삐, 안장, 등자. 말의 힘을 없애는 장비가 아니라, 그 힘이 엉뚱한 데로 새지 않게 방향을 주는 장비다. AI 에이전트도 비슷하다. 모델이 강력해질수록 더 그렇다. 힘이 세다고 좋은 게 아니라, 어디에 그 힘을 전달하게 만들지 설계해야 한다. 그러니까 하네스 엔지니어링은 “모델을 더 똑똑하게 만드는 일”이 아니라 “모델이 일할 수 있는 외부 환경을 설계하는 일”에 가깝다.

이걸 가장 짧게 쓰면 이렇게 된다.

Agent = Model + Harness

이 공식이 왜 중요한지 생각해보면 금방 감이 온다. 모델이 아닌 나머지 전부가 하네스다. 시스템 프롬프트, 도구 정의, 샌드박스, 실행 환경, 오케스트레이션 로직, 파일 시스템, 메모리 관리, 훅, 미들웨어, 피드백 루프. 그러니까 하네스 엔지니어링은 프롬프트 엔지니어링의 후속편이 아니라, 훨씬 바깥쪽 레이어다. 프롬프트와 컨텍스트를 품고 그 위에서 굴러가는 전체 시스템.

여기서 중요한 건 “왜 지금 이게 중요해졌는가”다. 그냥 이름만 새로 붙인 유행어면 금방 사라진다. 그런데 이건 좀 다르다. 모델만으로는 해결이 안 되는 문제가 이미 너무 분명하게 드러났기 때문이다.

LLM은 세션이 끝나면 상태를 잃는다. 코드를 직접 실행하지 못한다. 실시간 정보에 자동으로 접근하지 못한다. 자기 결과물을 자기 기준으로 검증하는 데도 한계가 크다. 우리가 ChatGPT와 대화할 때조차 사실은 원시적인 형태의 하네스를 쓰는 셈이다. 이전 메시지를 이어붙이고, 툴을 부르고, 조건이 맞으면 다시 모델을 호출하는 루프. 이건 그냥 대화 UI가 아니라 아주 기초적인 하네스다.

문제는 에이전트 작업이 길어질수록, 이 기초적인 하네스로는 버티기 어렵다는 점이다.

Anthropic 사례가 그래서 흥미롭다. Claude에게 “claude.ai의 클론을 만들어라” 같은 고수준 작업을 맡겼을 때 나타난 패턴을 보면, 모델 자체가 멍청해서가 아니라 환경이 부족해서 무너진다는 게 꽤 노골적으로 드러난다. 컨텍스트가 길어질수록 작업을 끝내지 못하고, 컨텍스트 한계에 가까워지면 이상하게 조급해지면서 덜 된 결과를 마감하려 하고, 자기 작업을 평가하라고 시키면 형편없는 상태에서도 스스로 만족해버린다. 이건 모델을 조롱할 일이 아니라, 사실 사람한테도 비슷한 조건을 주면 똑같이 벌어질 일이다. 진행 상황 보드도 없고, 테스트도 없고, 기록도 없고, 상태 인수인계도 없는데 복잡한 프로젝트를 끝내라고 하면 누가 잘하겠나.

그래서 프롬프트, 컨텍스트, 하네스를 한 줄에 놓고 보면 층위가 다르다.

프롬프트 엔지니어링은 “무엇을 물어볼까”의 문제다.
컨텍스트 엔지니어링은 “무엇을 보여줄까”의 문제다.
하네스 엔지니어링은 “이 전체 환경을 어떻게 설계할까”의 문제다.

나는 이 셋을 대체 관계로 보지 않는다. 포함 관계에 가깝다. 프롬프트는 아직도 필요하고, 컨텍스트도 여전히 중요하다. 다만 지금의 에이전트 시스템에서는 그 둘만 잘한다고 해결되지 않는 영역이 너무 커졌다. 그래서 관심의 중심이 바깥으로 이동한 거다.

이 흐름을 시간축으로 보면 더 분명하다. 2022년부터 2024년까지는 프롬프트가 주인공이었다. 질문을 어떻게 구성하느냐가 거의 모든 담론을 잡아먹었다. 2025년 중반부터는 컨텍스트가 올라왔다. RAG니 MCP니 메모리니, 결국 모델에 어떤 토큰을 어떤 타이밍에 주입하느냐가 핵심이라는 얘기가 많아졌다. 그러다 2026년에 와서는, 아예 에이전트를 둘러싼 외부 시스템 전체를 건드리는 얘기가 전면으로 튀어나온다. Mitchell Hashimoto가 하네스 엔지니어링이라는 표현을 블로그에서 꺼내고, OpenAI나 Anthropic 쪽 사례도 “모델이 좋아서”보다 “환경을 잘 짜서” 성능을 끌어올린 쪽으로 읽히기 시작했다. 흐름이 확실히 바뀌었다.

이쯤 되면 하네스를 구성하는 요소를 좀 더 구체적으로 봐야 한다. 막연하게 “환경”이라고만 하면 금방 또 공허해진다.

가장 밑바닥에는 파일 시스템과 지속적 저장소가 있다. 이건 단순해 보여도 엄청 중요하다. LLM은 대화창이 끊기면 잊어버린다. 그런데 파일은 남는다. 이 차이가 크다. 세션이 끝나도 작업 상태를 텍스트 파일 하나에 남겨두면, 다음 세션이 그걸 읽고 이어서 일할 수 있다. 예를 들어 claude-progress.txt 같은 파일에 “어제 어디까지 했고, 어떤 파일을 건드렸고, 다음엔 뭘 해야 하는지”를 적어둔다. 별거 아닌 것 같지만, 이게 없으면 매 세션이 기억상실에서 시작한다. Git까지 붙이면 더 강력해진다. 이전 상태로 롤백할 수 있고, 실험 브랜치를 나눌 수 있고, 여러 에이전트가 같은 저장소를 두고 협업하는 것도 가능해진다. 결국 파일 시스템은 에이전트의 장기 기억 장치다.

그 다음은 코드 실행과 샌드박스다. 이건 에이전트의 손과 발에 가깝다. 툴 호출이 여기에 해당한다. 문제는 모든 행동을 사전에 툴로 정의할 수 없다는 데 있다. 그래서 범용 도구가 필요하다. bash, 파일 읽기/쓰기, 코드 실행, 테스트 실행. 그런데 이렇게 범용성을 열어주면 바로 보안 문제가 따라온다. 생성한 코드를 아무 생각 없이 돌리면 위험하다. 그래서 샌드박스가 필요하다. 격리된 환경에서, 허용된 명령만, 네트워크 제약을 두고, 필요할 때만 잠깐 생성해서 쓰고 버리는 구조. Anthropic이 Brain과 Hands를 분리하는 식으로 설명한 것도 이 맥락이다. 생각하는 쪽과 실행하는 쪽을 분리하면 공격 표면이 줄어든다. 예전엔 신뢰할 수 없는 코드가 자격 증명이 든 같은 컨테이너에서 뛰는 경우가 있었는데, 이건 진짜 찝찝하다. 프롬프트 인젝션 한 번 잘못 맞으면 환경 변수부터 털릴 수 있으니까.

세 번째는 컨텍스트 관리다. 정확히는 컨텍스트 부패를 어떻게 막을 것인가의 문제다. 긴 컨텍스트가 무조건 좋은 게 아니라는 건 이제 다들 안다. 관련 없는 정보가 계속 쌓이면, 모델은 바늘 대신 건초더미를 더 많이 받는 셈이다. 컨텍스트 윈도우가 크다고 해서 바늘 찾기가 쉬워지는 건 아니다. 오히려 의미적으로 덜 맞는 정보가 늘어나면 추론이 흐릿해진다. 그래서 하네스는 이걸 제어해야 한다. 오래된 히스토리를 압축해서 요약하는 컴팩션, 도구 출력 전체를 대화창에 밀어넣지 않고 파일로 빼두는 오프로딩, 필요할 때만 지침을 로드하는 스킬 기반 노출, 통과한 테스트는 조용히 넘기고 실패한 테스트만 보고하는 백프레셔형 설계. 이런 사소해 보이는 결정이 실제론 엄청 크게 작용한다. 예전에 테스트 통과 로그 4천 줄을 매번 컨텍스트에 넣었다가, 실패한 테스트만 남기도록 바꿨더니 에이전트 성능이 체감될 정도로 좋아졌다는 얘기가 괜히 나오는 게 아니다.

네 번째는 서브 에이전트다. 이걸 역할 분담 도구 정도로만 보면 절반만 본 셈이다. 프론트엔드 담당, 백엔드 담당, 리서치 담당… 물론 그렇게도 쓸 수 있다. 하지만 더 중요한 역할은 컨텍스트 격리다. 상위 에이전트가 모든 조사 흔적, 시도 실패, 중간 노이즈를 다 떠안으면 금방 오염된다. 서브 에이전트가 하위 작업을 처리하고, 상위에는 결과만 요약해서 올려주면 그 자체가 컨텍스트 방화벽이 된다. 그리고 이 구조는 비용 제어에도 유리하다. 메인 세션은 비싼 모델로 두고, 범위가 좁은 하위 작업은 더 싼 모델로 돌릴 수 있으니까. 결국 필요한 건 무한한 컨텍스트가 아니라, 더 나은 분리다.

다섯 번째는 훅과 백프레셔 메커니즘이다. 이건 진짜 “하네스 냄새”가 나는 부분이다. 특정 이벤트에서 자동으로 개입하는 장치. 파일 수정 후 타입 체크를 돌리거나, 특정 파일은 수정 전에 승인 훅을 걸거나, git commit --no-verify를 막거나, 세션 시작 시 필요한 상태 파일을 자동으로 읽게 만들 수 있다. 말하자면 에이전트가 일하는 과정 곳곳에 규율을 심는 방식이다. 그리고 백프레셔는 여기서 더 중요하다. 에이전트가 자기 작업을 스스로 확인하게 만드는 장치. 테스트, 커버리지, 브라우저 자동화, 타입 체크, 스모크 테스트. 이게 있느냐 없느냐가 결과물을 완전히 다르게 만든다. “완료”라고 말하기 전에 실제 사용자처럼 눌러보게 하는 것. 이건 단순한 QA가 아니라, 에이전트에게 현실을 되돌려주는 장치다.

이쯤 되면 “그래서 이게 정말 그렇게 차이를 만드나?”라는 질문이 나온다. 나도 처음엔 약간 회의적이었다. 도구 인터페이스 하나 바꿨다고 점수가 그렇게 뛰나 싶었으니까. 그런데 실험 사례들을 보면 생각보다 크다. LangChain Terminal Bench 2.0에서는 모델은 그대로 두고 하네스만 개선했는데 점수가 52.8에서 66.5로 올랐고, 순위도 30위권에서 5위권까지 뛰었다. 모델 가중치 한 바이트 안 바꿨다. 시스템 프롬프트, 도구, 미들웨어, 피드백 루프만 바꿨다. 이건 꽤 충격적이다. 하네스가 모델 위에 얹는 얇은 래퍼가 아니라는 뜻이니까.

Hashline 파일 편집 실험도 비슷하다. 파일 편집 인터페이스를 바꿨을 뿐인데, 줄마다 해시를 붙여 위치 참조를 안정화하자 성능이 6.7%에서 68.3%로 튄 사례가 나왔다. 평균 출력 토큰은 오히려 줄었다. 이건 모델이 갑자기 천재가 된 게 아니다. 일이 잘 풀리도록 손잡이를 바꿔준 결과다. 사용자가 도구를 이해하기 쉽게 만든 게 아니라, 모델이 도구를 덜 헷갈리게 만든 것이다.

Anthropic의 3-에이전트 하네스 사례는 더 노골적이다. 같은 고수준 요구사항으로 단일 에이전트와 다중 에이전트를 비교했을 때, 단일 에이전트가 20분, 9달러 안팎으로 데모용 결과물을 만든 반면, 3-에이전트 하네스는 6시간 넘게, 200달러 가까이 쓰면서 훨씬 완성도 높은 결과를 냈다. 겉으로만 보면 9달러짜리가 더 효율적으로 보일 수도 있다. 근데 그런 결과물은 데모 화면에선 멀쩡해도 실제로 쓰면 금방 무너진다. 반대로 오래 걸리고 비싼 쪽은 진짜로 버틸 수 있는 수준에 가까워진다. 이 차이는 모델 IQ 차이보다, 작업을 어떻게 분할하고 검증하고 이어붙였느냐의 차이다.

여기서 하나 더 흥미로운 역설이 있다. 프론티어 코딩 모델들은 대개 자기 하네스 안에서 훈련된다. Claude는 Claude Code 하네스, Codex는 Codex 하네스 같은 식이다. 이게 무슨 뜻이냐면, 모델이 기본 하네스에 과적합될 수 있다는 뜻이다. 실제로 어떤 벤치에서는 Claude가 자기 친숙한 하네스에선 오히려 상대적으로 덜 좋고, 다른 하네스에서 더 잘 나오는 경우도 있었다. 아이러니하지만 자연스러운 결과다. 기본값이 언제나 최적은 아니라는 얘기다. 결국 에이전트를 잘 쓰려면 “어느 모델을 고를까”만큼이나 “어떤 하네스를 얹을까”를 봐야 한다.

이쯤 오면 엔지니어 역할도 바뀔 수밖에 없다. 예전엔 좋은 엔지니어를 “코드를 정확히 쓰는 사람”으로 상상했다. 물론 지금도 그 능력은 중요하다. 그런데 에이전트 시대에는 그 엄밀함이 조금 다른 자리로 이동한다. 한 줄 한 줄 직접 타이핑하는 정밀함이 아니라, 에이전트가 제대로 일할 수 있는 환경을 설계하는 정밀함. 어떤 도구를 연결할지, 어떤 파일을 상태 저장소로 삼을지, 어떤 테스트를 매 단계에서 강제할지, 실패했을 때 어디서 되돌릴지, 어떤 수준에서 사람에게 에스컬레이션할지. Chad Fowler가 말한 “엄밀함의 재배치”라는 표현이 여기서 꽤 잘 맞는다. 손이 아니라 환경으로 엄밀함이 이동한다.

그렇다고 모델이 더 좋아지면 하네스가 덜 중요해질까? 나는 오히려 반대로 본다. 프롬프트 엔지니어링이 아직도 완전히 사라지지 않은 것처럼, 하네스도 모델이 좋아질수록 더 중요해질 가능성이 크다. 왜냐하면 더 강한 모델일수록 더 넓은 자유도를 가지기 때문이다. 자유도가 커질수록 고삐의 역할이 중요해진다. 힘이 약한 말은 멀리 못 가지만, 힘이 센 말은 방향이 틀리면 더 크게 사고를 낸다.

결국 이 얘기는 굉장히 현실적인 조언으로 돌아온다. 코딩 에이전트가 기대만큼 작동하지 않을 때, 모델부터 탓하지 말라는 것. 물론 모델 차이도 있다. 하지만 꽤 자주 문제는 다른 데 있다. 상태 파일이 없고, 툴 인터페이스가 거칠고, 검증 루프가 없고, 실패를 걸러줄 훅이 없고, 컨텍스트가 이미 썩어가는데 계속 그 위에 로그를 쌓고 있는 경우. 그럴 때 답은 모델 업그레이드보다 하네스 손질에서 나오는 경우가 많다.

한마디로 줄이면 이렇다.

모델은 생각보다 괜찮다.
자주 문제인 건, 그 모델을 일하게 만든 환경 쪽이다.

그리고 이제는 그 환경을 설계하는 사람이 실력을 갖는 시대가 온 것 같다. 코드를 잘 쓰는 사람에서 끝나지 않고, AI가 코드를 잘 쓰게 만드는 사람. 하네스 엔지니어링은 아마 그 전환을 설명하는 꽤 정확한 이름일 것이다.