코딩 에이전트 바깥의 하니스 루프가 소프트웨어 엔지니어링, 유지보수, 책임, 그리고 이해 가능성을 어떻게 바꾸고 있는지에 대한 고찰.
written on 2026년 6월 23일
이제 나는 Claude에 직접 프롬프트하지 않는다. Claude에 프롬프트를 넣고 무엇을 할지 판단하는 루프들을 돌린다. 내 일은 루프를 작성하는 것이다.
— Boris Cherny
지난 몇 달 동안 나는 점점 더 많은 사람들이 단순히 코딩 에이전트를 사용하는 것과는 의미 있게 다른 무언가를 코딩 에이전트 위에 구축하는 모습을 지켜보았다. 그중 일부는 Pi 위에서 일어나고 있는데, 그건 분명 멋진 일이다! 하지만 패턴은 어디서나 같다. 작업이 어떤 종류의 큐에 들어가고, 기계가 그것을 집어 들어 시도하고, 멈추면, 어떤 하니스가 그것이 정말 끝인지 판단한다.
그렇지 않다면 하니스는 같은 세션을 계속하고, 다른 메시지를 주입하고, 수정된 컨텍스트로 새 세션을 시작하거나, 작업을 다른 기계로 보낸다. 작업은 모델이 스스로라면 보통 “끝났습니다.”라고 말했을 지점을 넘어서도 계속 살아 있다.
나는 인정하고 싶은 것보다 더 자주 그런 종류의 루프를 생각한다.
이미 모든 코딩 에이전트 내부에는 에이전트 루프가 있다. 모델은 도구를 호출하고, 그 결과를 반영하고, 다른 도구를 호출하고, 파일을 읽고, 파일을 수정하고, 테스트를 실행하고, 결국 어떤 답을 만들어 낸다. 그 루프는 우리가 아주 오랫동안 꽤 익숙하게 다뤄 온 것이다. 다른 루프는 하니스 수준의 루프다. 에이전트 루프 바깥의 루프다. 그 루프 역시 새로운 것은 아니다. 우리는 Claude Code 초창기부터 이런 식의 변형들을 해 왔지만, 그 루프는 점점 더 에이전트 기반 엔지니어링에서 두드러지고 있으며 최근 몇 주 사이에는 Twitter 담론을 지배하기 시작했다.
내 현재 상태를 말하자면, 내가 깊이 신경 쓰는 코드에 대해서는 이런 작업 방식으로 큰 성공을 거두지 못했다. 그리고 알고 보니 내가 깊이 신경 쓰는 코드는 꽤 많다.
그 일부는 취향의 문제이고 일부는 통제의 문제다. 나는 코드가 어떤 모습이어야 하는지에 대해 높은 기준을 세우려 하고, 내가 배포하는 코드를 이해하고 싶다. 압박 속에서든, 다른 인간과 토론하는 자리에서든, 먼저 덜컹거리는 기계에게 설명해 달라고 묻지 않고도 시스템이 무엇을 하는지 설명할 수 있기를 원한다. 물론 몇 년 뒤에도 내가 코드를 이해하고 싶어 할지에 대한 질문은 분명 있다. 하지만 지금으로서는 이해 가능성이 나에게 중요하다는 지점을 아직 지나지 못했다.
이런 바람을 고려하면, 내가 주의를 기울이지 않은 채 작성된 코드, 특히 루프에서 나온 코드에 대한 경험에는 뭔가 부족한 점이 있다. 현재의 모델들은 지나치게 방어적이고, 지나치게 복잡하며, 추론이 지나치게 국소적이다. 강한 불변식을 피한다. 나쁜 상태를 불가능하게 만드는 대신 폴백을 추가한다. 코드를 중복시키고, 형편없는 추상화를 발명하며, 불명확한 설계를 더 많은 장치로 덮어 버린다. 하지만 더 나쁜 점은, 이것이 개선되고 있다는 진전을 지금까지 거의 보지 못했다는 것이다. 오히려 그 측면에서는 잘못된 방향으로 가고 있는지도 모른다는 느낌마저 든다. 적어도 내 취향으로는, ultracode가 붙은 Claude Code 같은 현재의 핸즈오프 하니스들이 지난 가을 우리가 만들던 코드보다 더 나쁜 코드를 만들어 낸다. 예를 들어 Fable과 함께라면 Claude Code는 문제 하나를 30분 이상 끊김 없이 작업하는데, 예전에는 그 과정에 훨씬 더 인간이 개입해 있었다.
게다가 모델들이 어떤 국소적 실패를 관찰하고 국소적 방어를 추가하는 경향이 있다는 것은 잘 알려져 있다. Karpathy는 모델들이 “예외를 죽을 만큼 두려워한다”고 말했다. 중요한 불변식이 있는 시스템, 특히 영속화된 데이터 형식이나 핵심 인프라에서는 올바른 수정이 “모든 잘못된 경우를 처리하라”가 아니다. 올바른 수정은 애초에 잘못된 경우를 표현할 수 없게 만들거나 기록할 수 없게 만드는 것이다. 그런데 많은 수동 조향이 있더라도 그런 종류의 코드는 LLM에서 자연스럽게 나오지 않으며, 설령 그런 코드가 자연스럽게 나오더라도 여전히 이제는 불가능한 오류를 처리하려고 시도할 것이다.
그런 행동을 루프 뒤에 두면 대체로 그것이 증폭된다. 반복마다 또 하나의 작은 방어가 추가되면, 시스템은 겉보기에는 더 견고해 보이면서도 서서히 덜 이해 가능해진다. 손을 덜 댈수록 그런 현상은 더 심해진다. 또 이런 도구를 명확한 지침 없이 주니어들에게 주면 아주 나쁜 관행도 가르치게 된다. 왜냐하면 왜 그런 모든 것을 하고 있느냐고 물으면, 그들은 아주 그럴듯하게 자신의 논리를 펼칠 것이기 때문이다.
동시에, 루프 패턴이 작동하지 않는 척하는 것은 정직하지 못하다. 왜냐하면 어떤 영역에서는 이미 놀라울 정도로 잘 작동하고 있기 때문이다.
코드 포팅이 그중 하나다. 이미 대규모 자동 포팅 작업의 인상적인 사례들이 있고, Bun의 일부를 Zig에서 Rust로 옮기는 작업에 대한 보고도 포함된다. 나 역시 MiniJinja를 Go로 포팅하는 데 성공적으로 사용해 보았다. 성능 탐색 역시 이것이 아름답게 작동하는 또 다른 경우다. 기계는 실험을 시도하고, 벤치마크를 돌리고, 실패를 버리고, 계속 탐색할 수 있다. 보안 스캐닝도 자연스럽게 들어맞고, 거의 모든 유형의 연구도 마찬가지다. 시스템에게 복잡한 문제 공간을 탐색하게 하고, 반드시 오래 남을 코드를 커밋하지 않으면서 결과를 보고하게 하는 것이다. 이런 사례들 다수가 공유하는 한 가지는, 새 코드를 생성하지 않고 이미 존재하는 코드를 변환하거나, 의도적으로 오래 보존될 필요가 없는 코드를 만든다는 점이다. 이들은 개념 증명이나 아이디어를 만들고, 발견 사항을 드러내거나, 기계적 변환에 더 가깝다.
나는 장기 보존의 필요가 없는 산출물을 만들어 내는 루프나, 명확하게 검증 가능한 어떤 형태의 기계적 번역을 만들어 내는 루프가, 하니스가 목표를 기계적으로 측정하는 일반적 능력보다 더 중요하다고 믿는다. 루프의 많은 성공 사례는 또 다른 LLM을 판정자나 오케스트레이터로 사용한다. 기계적 번역의 경우는 이진 테스트 케이스로 검증할 수 있지만, LLM이 판정하도록 할 수도 있다!
예를 들어 Claude Code는 자신이 실행할 전체 실험 워크플로를 만들어 내는 데 점점 더 능숙해지고 있다. 물론 그것이 만들어 내는 코드는 엉망이지만, 그것은 하니스가 워크플로의 한 단계가 순 개선이나 완료로 이어졌는지를 판단하는 데 서툴러서라기보다 모델의 잘못에 더 가깝다.
하니스는 그저 계속 진행할 수 있게 해 주는 어떤 신호만 있으면 된다. 그것이 객관적이거나 이진적일 필요는 없고, 다음 반복을 이끌 만큼 충분히 유용하기만 하면 된다.
나는 이미 실험하고 측정하고 아이디어를 얻는 데서 내 하루의 지루한 부분을 덜어 주는 루프들을 정말 좋아한다.
반면 같은 루프 방법론을 오래 남을 코드를 작성하는 데 사용하는 것은 아직 내게 잘 맞지 않는다. 내가 자주 끌어오는 비유는 소프트웨어를 결정론적 기계로 보는 관점에서 유기체로 보는 관점으로 이동하는 것이다.
나는 기계를 이해하도록 장려받는 환경에서 소프트웨어 엔지니어가 되었다. 언제나 이해를 더 깊게 하기 위해 벗겨 낼 수 있는 층이 있었다. 결정론적이고 관찰 가능한 동작을 보이지 않는 기계들도 받아들여지긴 했지만, 대체로 정확히 최선이라고 여겨지지는 않았다. 소프트웨어 아키텍처 측면에서도 나는 덜 결정론적인 방향보다 더 결정론적인 방향으로 밀어붙이는 것을 바람직하다고 보았다. 마찬가지로 코드를 이해할 수 있는 능력은 부정할 수 없는 목표였다. 실제로는 항상 가능하지 않았지만, 우리는 영리한 아키텍처를 통해 새로운 엔지니어들조차 복잡한 코드베이스를 헤쳐 나갈 수 있도록 코드를 작성하는 데 자부심을 가졌다. 잘 설계된 시스템에는 언제나 불변식이 어디에 있는지, 어떤 부분이 하중을 지탱하는지, 어떤 변경이 안전한지를 아는 엔지니어들이 있었다. 이상적으로는 그 모든 것 역시 잘 문서화되어 있었다. 그런 이해가 부족한 곳에서는 일반적으로 그것이 개선해야 할 대상으로 여겨졌다.
물론 그런 이상은 늘 압박을 받아 왔다. 많은 소프트웨어 시스템, 특히 매우 성공적인 시스템들은 팀의 엔지니어들이 그것을 깔끔하게 유지할 수 있었던 시기를 지나왔다. 대형 소프트웨어 시스템은 드물지 않게 너무 크고, 너무 동적이며, 외부 서비스에 너무 의존적이어서 누구 한 사람의 머릿속에 다 들어가지 않는다. LLM이 없던 때조차도 우리는 이미 분산 시스템을 어느 정도 의사들처럼 진단한다. 증상을 관찰하고, 가설을 세우고, “추가 검사를 주문”하고, 몇 가지 처방을 시도하고, 다시 관찰한다.
그런데 LLM과 함께라면 우리는 그 방향으로 훨씬 더 멀리, 그리고 훨씬 더 빠르게 나아가고 있다. 우리는 그것들을 코드를 작성하는 데 사용하고, 진단과 처방에도 사용한다. 이미 프로덕션 이슈가 발생했을 때 첫 단계가 곧바로 덜컹거리는 기계에게 로그를 읽게 하고, 근본 원인을 제안하게 하고, 선제적으로 패치를 올리게 하는 세계에서 살아가는 엔지니어들이 많다. 그렇게 나온 패치는 종종 또 다른 기계가 검토하고, 때로는 인간의 감독 없이 그대로 main에 들어가기도 한다.
분명 그것은 강력하며, 매력적으로 들린다는 점도 부인할 수 없다. 하지만 그 생각을 받아들이는 것, 특히 인간의 감독이 점점 줄어드는 형태로 받아들이는 것은 우리가 더 이상 시스템 전체를 같은 방식으로 이해하지 못하게 될 수도 있음을 받아들이는 뜻이다. 우리는 그것을 치료하고, 모니터링하고, 안정화하지만, 반드시 이해하는 것은 아니다.
어떤 소프트웨어에 대해서는 그것이 괜찮다는 데 의심이 없다. 모든 코드 한 줄 한 줄이 인간의 저작을 받을 가치가 있는 것은 아니고, 과거에는 더 나쁜 코드가 쓰였을 수도 있다.
하지만 나는 모든 소프트웨어가 이런 식으로 작성되기를 원하는가?
매우 불편한 점은, 이렇게 완전히 기계 주도적인 미래에서 빠지는 것이 선택지가 아닐 수도 있다는 것이다.
오늘날 가장 분명한 사례는 보안이다. 당신이 소프트웨어를 만들 때 루프를 사용하지 않더라도, 다른 사람들은 당신의 소프트웨어를 상대로 루프를 사용할 것이다. 공격자들은 기계를 계속 돌릴 것이고, 설령 공격자가 아니더라도 보안 연구자들은 그렇게 할 것이다. 그런 자동화된 작업들 중 일부는 먼지만 일으키겠지만, 실제 문제도 찾아낼 것이다. 그리고 그 신호와 잡음이 엄청난 양으로 당신에게 밀려와서, 당신 스스로도 기계를 문제에 투입하지 않는 한 거의 감당할 수 없게 될 것이다.
Daniel Stenberg가 curl의 summer of bliss에 대해 쓴 글은 유지보수자들이 이미 받고 있는 압박의 좋은 예다. 내가 아는 한, 오늘날 AI는 curl의 핵심 개발에서 엄청난 역할을 하지는 않는다. 그런데도 유지보수자들은 보고에 압도되고 있으며, 그중 대부분은 이제 AI가 생성한 보고들이다.
공격자와 보고자들이 루프를 돌린다면, 방어자들도 결국 따라가기 위해 루프를 돌려야 할 것이다. 직접 패치를 작성하기 위해서가 아닐 수도 있고, 단지 분류하고 재현하기 위해서일 수도 있지만, 압박은 커질 것이다.
경쟁 측면에서도 마찬가지다. 어떤 팀들은 순수한 속도로 다른 팀들을 앞지를 것이다. 어떤 프로젝트들은 아주 작은 그룹이 기계를 효과적으로 오케스트레이션하는 법을 알아내면서 갑자기 더 빨리 움직이게 될 것이다. 어떤 스타트업은 예전에는 50명이 필요했던 일을 5명으로 해낼 것이다. 어떤 사람들은 문자 그대로 당신의 제품에 기계를 루프로 붙여 놓고 “저 다른 것처럼 만들어”라고 지시할지도 모른다. 그리고 그들의 사용자가 만족한다면, 그것이 정말 중요할까?
모든 소프트웨어가 똑같이 영향을 받지는 않을 것이다. 어떤 영역은 엉성함을 용납하지 않고 신뢰와 책임을 요구하겠지만, 많은 소프트웨어는 순수한 속도, 빠른 실험, 광범위한 커버리지가 엄청나게 중요한 세계에 살고 있다.
내게 가장 무서운 부분은 우리가 이런 새로운 기계들에 새로운 방식으로 의존하게 된다는 점이다. 소프트웨어는 언제나 도구에 의존해 왔다. 컴파일러에 돈을 내야 했던 시절도 나는 기억한다. 이런 새로운 도구들은 소프트웨어 제작에 실제 비용이 따르던 시절을 떠올리게 한다. 하지만 이제는 일회성 지불이 아니라 지속적인 의존성이다. 채워진 지갑에 대한 의존성일 뿐 아니라 인지적 의존성이기도 하다.
만약 어떤 코드베이스가 루프에 의해 생산되고, 루프에 의해 검토되고, 루프에 의해 패치되고, 루프에 의해 살아 유지된다면, 더 이상 같은 종류의 시스템에 접근할 수 없게 되었을 때 무슨 일이 일어날까? 어떤 무역 제한 때문에 가장 강력한 모델들에 대한 접근을 잃게 되면 어떻게 될까? 비용이 감당할 수 없을 정도가 되면 어떨까? 당신과 팀이 기계를 쓰지 않고는 코드를 이해하는 마지막 남은 능력마저 잃어버리면 어떨까?
우리는 인간이 유지보수하기 어렵기만 한 것이 아니라, 유지보수 모델의 일부로 기계의 참여를 전제하는 코드베이스를 만들어 낼 수도 있다. 이런 일은 이미 벌어지고 있다! 모든 곳에서 벌어지는 것은 아니고, 심지어 문제로 여겨지지 않는 방식으로 벌어지고 있을 수도 있지만, 우리는 점점 더 많은 사례를 보고 있다. 사람들은 점점 더 자신이 완전히 설명할 수 없는 코드를 병합한다. 사람들은 덜컹거리는 기계가 제공한 컨텍스트로 자신의 메시지를 보강하거나 다시 다듬지 않고서는 이슈 보고를 작성하거나 채팅에서 논의하는 능력을 잃어 간다. 너무 많은 사람들이 요약하거나 맥락을 부여하는 일을 점점 더 기계에 의존한다. 점점 더 자주 나는 LLM이라는 간접층을 통해 나와 대화하는 사람들을 만난다.
다시 말하지만, 어쩌면 그것이 틀린 방향은 아닐지도 모른다. 하지만 그것은 우리가 일을 해 오던 방식에 대한 엄청난 변화다.
나는 이것이 우리가 향하는 방향이라는 데 거의 의심이 없지만, 그 방향으로 가려면 코딩 에이전트만이 아니라 모든 곳의 도구를 손봐야 할 것이다.
그저 더 많은 루프를 오케스트레이션하는 것만으로는 충분하지 않을 것이다. 더 나은 변경 시각화나 오케스트레이션, 에이전트들이 우리의 이해를 되돌려 주지는 못할 것이다. 우리는 인간을 다시 루프 안으로 밀어 넣고 루프의 변경을 장기적으로 읽을 수 있게 만드는 영리한 방법을 찾아야 하거나, 아니면 점점 더 복잡해지는 이런 시스템들을 더 잘 조합하는 방법을 찾아야 한다.
이 지점에서 Pi의 역할에 대한 내 생각도 바뀌고 있다. Pi는 신중해 왔고, 나는 그 신중함이 좋다고 생각한다. 나는 내가 따라갈 수 없는 변화를 만들어 내는 통제되지 않은 기계 떼로 모든 상호작용이 바뀌는 미래를 원하지 않는다. 스스로 코드를 쓰는 소프트웨어를 향한 경쟁에서 이기기 위해 Pi가 유지보수 불가능한 혼란이 되는 것도 원하지 않고, Pi가 이런 유형의 엔지니어링을 장려하는 것도 원하지 않는다. 동시에 Pi는 하니스이고, 하니스는 사람들이 이런 새로운 유형의 실험을 수행하는 중심에 있다.
코딩 작업을 위한 태스크 큐, 에이전트와 서브에이전트의 오케스트레이션, 지속 가능한 세션은 점점 더 중요해질 것이다. 루프를 맹목적으로 받아들이지 않고 유보적인 태도를 가진 우리조차도 그런 실험을 시작해야 할 것이다. 우리는 그렇게 해야 한다. 왜냐하면 우리는 이 미래를 경계 안에 두고 살아남을 수 있게 만드는 방법을 이해해야 하기 때문이다.
이 글에서 읽을 수 있듯이, 나는 이 미래에 대해 매우 불편함을 느낀다. 두려움 때문이 아니라, 지금까지 이 기술과 함께한 경험이 주는 신중함 때문이다.
하니스 루프라는 개념을 받아들인다는 것은 작업이 끝났는지를 하니스가 결정한다는 뜻이다. 에이전트 루프에서는 모델이 결국 “완료”라고 말하고 내가 검토한다. 그 이전에도 나는 보통 중간중간 방향을 잡는다. 나는 개입하고, 그 과정에서 배우는 것을 즐긴다. 하지만 하니스가 운영하는 루프에서는 내 역할이 대체 무엇인지조차 확신이 없다. “완료” 신호조차 모든 의미를 잃고 그저 판정하는 또 다른 기계에게 전달될 뿐이다. 내 역할은 전달자에 불과한 것으로 축소된다.
오늘날 나는 그런 방식으로 구축된 시스템에서 나오는 코드 대부분을 좋아하지 않으며, AI assistence로 만들어진 소프트웨어 상당수와 상호작용하는 것도 즐겁지 않다. 루프는 강력하지만 점점 더 책임을 제거하고, 적어도 오늘날에는 우리가 기계에 굴복하도록 매우 강하게 부추긴다.
그럼에도 불구하고, 지금 내가 그것을 달가워하지 않는다는 사실과 별개로 이 루프의 미래가 우리의 미래가 될 것이라는 데는 의심이 없다. 나는 이미 놀라울 정도로 작은 팀들이 불가능한 속도로 무언가를 만들어 내는 모습을 보고 있고, 코드베이스가 점점 더 많은 기계로만 진단할 수 있는 불투명하고 혼란스러운 유기체로 변해 가는 것도 보고 있다. 그런 코드베이스들은 동시에 유용하고도 지저분하다.
그래서 내가 받아들이게 되는 것은, 문제는 우리가 루프를 돌릴 것인가가 아니라는 점인 것 같다. 분명 우리는 그럴 것이기 때문이다. 어쩌면 질문은 루프의 미래에서 어떻게 판단을 포기하지 않을 것인가, 어떻게 좋은 엔지니어링의 규칙을 유지할 것인가, 어떻게 책임 있는 인간이 계속 감독할 수 있게 할 것인가, 그리고 그 과정에서 제정신을 유지하기 위해 코드 아키텍처를 어떻게 다시 생각해야 하는가일지도 모른다.