Daily AI Digest
오늘의 AI 글: 코딩 에이전트의 진짜 엔진은 모델이 아니라 하네스다
Codex CLI와 Claude Code류 코딩 에이전트가 대화, 컨텍스트, 도구 실행, 승인, 샌드박스를 어떻게 엮어 실제 작업 능력을 만드는지 해설한다.
왜 이 글인가
요즘 코딩 에이전트를 이야기할 때 사람들은 대개 모델 이름부터 묻는다. “Claude가 더 잘하나?”, “GPT 계열이 더 빠른가?”, “추론 강도를 높이면 버그가 줄어드나?” 같은 질문이다. 물론 모델 성능은 중요하다. 하지만 실제로 Claude Code, Codex CLI, Cursor, OpenClaw 같은 도구를 매일 써보면 금방 다른 층위의 문제가 보인다. 같은 모델을 붙여도 어떤 도구는 믿고 맡길 수 있고, 어떤 도구는 몇 번 명령하다가 사람이 계속 수습해야 한다. 차이는 모델 하나가 아니라, 모델을 감싸고 있는 실행 환경, 즉 에이전트 하네스에서 나온다.
오늘 고른 글은 바로 그 하네스를 해부한다. Jonathan Fulton의 글은 Codex CLI 코드베이스 분석을 바탕으로, 코딩 에이전트가 내부적으로 어떤 루프를 돌고, 무엇을 모델에 보내며, 모델이 요청한 도구 호출을 어떻게 실제 셸 명령·파일 편집·컨텍스트 갱신으로 바꾸는지 설명한다. 겉으로 보면 에이전트는 “생각하고 실행하는 똑똑한 개발자”처럼 보이지만, 속을 들여다보면 훨씬 단순하면서도 훨씬 까다로운 시스템이다. 단순한 부분은 모델 호출 루프이고, 까다로운 부분은 컨텍스트 관리, 권한 정책, 샌드박스, 출력 정리, 승인 흐름, 병렬 실행, 플러그인 연결이다.
이 글이 오늘 특히 읽을 가치가 있는 이유는 코딩 에이전트의 경쟁이 이제 “채팅창에서 답을 잘하는가”를 넘어섰기 때문이다. 실무에서 중요한 질문은 “이 에이전트가 내 저장소를 얼마나 정확히 이해하는가”, “긴 작업 중 맥락을 잃지 않는가”, “위험한 명령을 실행하기 전에 멈추는가”, “출력 5천 줄짜리 테스트 로그를 모델이 읽을 수 있게 줄여주는가”, “여러 독립 작업을 병렬로 돌리면서도 결과 순서를 보존하는가”다. 이런 것들은 모델 벤치마크 점수만으로는 잘 드러나지 않는다. 하네스 설계가 제품의 체감 품질을 결정한다.
또 하나 중요한 점은 안전이다. 코딩 에이전트는 일반 챗봇과 달리 실제 부작용을 만든다. 파일을 고치고, 명령을 실행하고, 네트워크에 접근하고, Git 기록을 바꾸고, 배포를 트리거할 수 있다. 그래서 “모델이 똑똑하면 알아서 조심하겠지”라는 접근은 부족하다. 하네스는 모델의 제안을 그대로 실행하는 파이프가 아니라, 실행 전 검증하고, 권한을 확인하고, 샌드박스 안에 가두고, 결과를 구조화해서 다시 모델에 돌려주는 안전 장치여야 한다. 이 글은 그 구조를 비교적 짧지만 알차게 보여준다.
핵심 요약
-
코딩 에이전트의 핵심 루프는 생각보다 단순하다. 대화 기록과 도구 정의를 모델에 보내고, 모델이 도구 호출을 요청하면 실행한 뒤 결과를 다시 대화 기록에 넣는다. 모델이 더 이상 도구를 요청하지 않고 최종 텍스트를 반환하면 한 턴이 끝난다. “에이전트적 행동”은 별도의 신비한 엔진이라기보다, 이 반복 루프가 컨텍스트와 도구 실행을 누적하면서 나타나는 효과에 가깝다.
-
단순한 루프만으로는 제품이 되지 않는다. 진짜 어려운 부분은 모델 주변의 인프라다. 어떤 시스템 지시를 넣을지, 사용자 지시와 프로젝트 지시를 어떻게 계층화할지, 이전 도구 호출과 출력의 인과관계를 어떻게 보존할지, 긴 로그를 어떻게 줄일지, 위험한 명령을 어떻게 판단할지, 권한 밖 파일 쓰기를 어떻게 막을지가 품질을 좌우한다.
-
모델에 전달되는 입력은 그냥 텍스트 덩어리가 아니다. 사용자 메시지, 이전 assistant 응답, 함수 호출, 함수 호출 결과가 구조화된 항목으로 들어간다. 특히 도구 호출과 그 결과는 연결된 식별자를 통해 “이 명령의 결과가 이것”이라는 관계를 유지한다. 이 구조가 없으면 모델은 긴 작업 중 무엇이 왜 실패했는지 쉽게 헷갈린다.
-
도구 정의는 JSON 스키마 같은 명확한 계약으로 제공된다. 셸 실행 도구라면 명령 배열, 작업 디렉터리, 타임아웃 같은 인자를 정의하고, 모델은 그 형식에 맞춰 호출을 만든다. 하네스는 모델이 준 인자를 검증하고, 정책에 맞는지 확인하고, 실행 가능한 형태로 바꾼다. 이 단계가 느슨하면 모델의 애매한 출력이 곧 운영 사고로 이어질 수 있다.
-
컨텍스트 관리는 에이전트의 숨은 핵심이다. 작업이 길어지면 대화 기록, 파일 내용, 테스트 로그, 명령 결과가 빠르게 불어난다. Codex류 하네스는 토큰 수를 추정하고, 한계에 가까워지면 이전 대화를 요약해 압축하거나, 바뀐 부분만 다시 주입하는 식으로 비용과 맥락 보존 사이의 균형을 잡는다. 이것이 없으면 에이전트는 몇 번 명령을 실행한 뒤 금방 기억을 잃는다.
-
도구 출력은 모델이 이해할 수 있도록 정리되어야 한다. 단순히 stdout 전체를 붙이는 방식은 비효율적이고 위험하다. 종료 코드, 실행 시간, stderr, 전체 줄 수, 생략 위치, 앞부분과 뒷부분의 보존 같은 메타데이터가 있어야 모델이 “성공했는지”, “어디서 실패했는지”, “중간 로그가 생략되었는지”를 판단할 수 있다.
-
승인과 샌드박스는 선택 기능이 아니라 필수 기반이다. 파일 읽기는 허용하더라도 쓰기, 네트워크, 워크스페이스 밖 접근, 민감한 명령은 정책에 따라 막거나 사용자 승인을 받아야 한다. 좋은 하네스는 모델의 선의를 믿는 대신, 실행 경계를 기술적으로 강제한다.
-
병렬 도구 실행과 하위 에이전트는 생산성을 높이지만 조율 비용도 만든다. 독립적인 검색이나 테스트는 병렬화할 수 있지만, 앞선 결과에 의존하는 명령까지 무작정 동시에 실행하면 상태가 꼬인다. 하네스는 어떤 호출이 독립적인지 판단하고, 결과를 순서 있게 다시 모델에 돌려줘야 한다.
-
MCP 같은 프로토콜은 에이전트 확장의 접점이 된다. 데이터베이스, 사내 API, 문서 검색, 배포 도구를 별도 서버가 노출하고, 하네스가 이를 모델 도구로 변환하면 에이전트는 훨씬 넓은 업무를 다룰 수 있다. 동시에 권한과 감사 로그의 중요성도 커진다.
글의 논지를 단계별로 풀어보기
원문은 먼저 코딩 에이전트의 마법을 벗겨낸다. 사용자가 “이 버그 고쳐줘”라고 입력하면 에이전트가 갑자기 독립적인 개발자처럼 움직이는 것처럼 보인다. 하지만 내부적으로는 대화 기록을 모아 모델에 보내고, 모델이 “파일을 읽어야겠다” 또는 “테스트를 실행해야겠다”는 도구 호출을 만들면, 하네스가 그 요청을 실제 환경에서 실행한다. 실행 결과는 다시 대화의 일부가 되고, 모델은 그 결과를 보고 다음 행동을 정한다. 즉 에이전트의 지능은 모델 하나에만 있지 않고, 모델 호출과 도구 실행을 반복해서 연결하는 루프에 있다.
두 번째 단계는 “무엇을 모델에 보내는가”다. 하네스는 기본 시스템 지시, 사용자 지시, 프로젝트별 규칙, 동적으로 감지된 스킬이나 도구 설명을 층층이 쌓는다. 여기에 과거 대화, 이전 명령, 명령 결과가 구조화되어 들어간다. 이 설계가 중요한 이유는 모델이 현재 작업의 맥락을 재구성하는 방식이 입력 구조에 크게 좌우되기 때문이다. 단순히 모든 것을 문자열로 이어 붙이면 모델은 무엇이 사용자 요구이고 무엇이 도구 출력인지 혼동할 수 있다. 반대로 역할과 관계가 명확하면, 모델은 “이 테스트 실패는 내가 방금 실행한 명령에서 나온 결과”라고 더 잘 추론한다.
세 번째 단계는 도구 호출의 현실화다. 모델은 JSON 형태의 인자를 만들어 “셸 명령을 실행해 달라”고 요청할 수 있지만, 모델 출력은 곧바로 믿을 수 있는 운영 명령이 아니다. 하네스는 인자 형식이 맞는지 확인하고, 작업 디렉터리가 적절한지 보고, 타임아웃을 적용하고, 명령이 정책상 허용되는지 판단한다. 필요하면 사용자에게 승인을 요청하고, 샌드박스 안에서 실행한다. 이 과정이 바로 에이전트 도구의 안전성과 신뢰성을 만든다.
네 번째 단계는 결과를 다시 모델이 읽을 수 있게 바꾸는 일이다. 사람 개발자는 긴 로그를 스크롤하면서 감으로 핵심을 찾지만, 모델에게 무제한 로그를 던질 수는 없다. 그래서 하네스는 앞부분과 뒷부분을 보존하고 중간을 생략하거나, 종료 코드와 실행 시간 같은 요약 정보를 붙인다. 특히 실패 로그에서는 마지막 수십 줄이 결정적인 경우가 많고, 빌드 시작부의 환경 정보도 중요할 수 있다. 좋은 출력 포맷은 모델이 다음 행동을 더 정확히 고르게 만든다.
다섯 번째 단계는 긴 작업에서 맥락을 유지하는 일이다. 에이전트가 저장소를 읽고, 파일 여러 개를 고치고, 테스트를 반복하면 컨텍스트 창은 빠르게 차오른다. 이때 하네스는 오래된 대화를 요약하거나, 핵심 결정만 남기거나, 변경된 컨텍스트만 다시 넣는다. 이 압축은 단순 비용 절감이 아니다. 압축이 잘못되면 모델은 이미 내린 결정, 사용자가 금지한 방식, 실패했던 접근을 잊고 같은 실수를 반복한다. 반대로 압축이 잘되면 긴 작업도 한 사람의 연속된 사고처럼 이어진다.
마지막 단계는 확장과 조율이다. Responses API의 병렬 도구 호출, 추론 강도, 프롬프트 캐시 키, 구조화된 스트리밍 이벤트 같은 기능은 모두 에이전트 하네스를 염두에 둔 요소다. 여기에 하위 에이전트나 MCP 도구까지 붙으면, 하나의 모델 호출을 넘어 여러 작업 흐름을 조율하는 시스템이 된다. 하지만 확장성이 커질수록 승인, 격리, 로그, 실패 복구가 더 중요해진다. 원문이 말하는 “루프는 단순하지만 인프라가 전부”라는 결론이 여기서 나온다.
일반 독자에게 중요한 포인트
-
코딩 에이전트의 품질을 볼 때 모델 이름만 보지 말아야 한다. 같은 모델이라도 하네스가 대화 기록을 어떻게 관리하고, 도구 결과를 어떻게 전달하고, 권한을 어떻게 제한하느냐에 따라 실사용 경험이 크게 달라진다. 에이전트 제품을 고를 때는 “어떤 모델을 쓰는가”와 함께 “어떤 실행 경계를 제공하는가”를 봐야 한다.
-
“AI가 내 컴퓨터에서 명령을 실행한다”는 말은 꽤 무거운 말이다. 일반 챗봇의 틀린 답변은 대개 사람이 무시하면 끝나지만, 코딩 에이전트의 잘못된 명령은 파일 삭제, 잘못된 커밋, 의도치 않은 네트워크 전송, 배포 실패로 이어질 수 있다. 그래서 승인 버튼, 샌드박스, 워크스페이스 제한은 귀찮은 장식이 아니라 안전벨트다.
-
긴 작업에서 에이전트가 갑자기 멍청해지는 이유는 종종 모델 지능 부족이 아니라 컨텍스트 관리 실패다. 앞서 본 로그가 잘렸거나, 사용자의 중요한 제약이 요약 과정에서 빠졌거나, 도구 결과가 애매하게 전달되면 모델은 방향을 잃는다. “왜 아까 말한 걸 잊었지?”라는 느낌의 상당 부분은 하네스 설계와 관련된다.
-
에이전트가 잘 작동하려면 프로젝트의 규칙을 명시적으로 적어두는 습관이 중요하다. 빌드 명령, 테스트 명령, 금지된 라이브러리, 코드 스타일, 배포 절차, 위험한 디렉터리 같은 정보를 README나 AGENTS/CLAUDE류 지시 파일에 정리하면 하네스가 그 정보를 모델에 넣기 쉬워진다. 사람끼리는 암묵지로 통하던 것도 에이전트에게는 입력으로 존재해야 한다.
-
앞으로의 경쟁은 “더 똑똑한 답변”뿐 아니라 “더 좋은 작업 운영체제” 쪽으로 갈 가능성이 크다. 모델, 도구, 권한, 메모리, 승인, 감사 로그, 플러그인 생태계가 합쳐져야 실무 에이전트가 된다. 이 글은 그 방향을 이해하는 데 좋은 입문 지도다.
개발자에게 중요한 포인트
개발자라면 이 글을 읽고 자신이 쓰는 에이전트의 하네스 품질을 점검해볼 만하다. 먼저 도구 호출 결과가 충분히 구조화되어 있는지 보자. 테스트가 실패했을 때 에이전트가 종료 코드와 실패 위치를 제대로 이해하는가, 아니면 긴 로그 속에서 아무 줄이나 붙잡고 헛수정하는가. 후자라면 모델만 탓할 일이 아니다. 실행 결과를 모델에게 전달하는 포맷이 나쁠 수 있다.
둘째, 프로젝트별 지시와 사용자 지시의 계층이 분명해야 한다. 전역 규칙, 저장소 규칙, 현재 작업 지시가 뒤섞이면 모델은 우선순위를 헷갈린다. “이 프로젝트에서는 pnpm만 쓴다”, “마이그레이션 파일은 직접 수정하지 않는다”, “외부 네트워크 호출은 승인 없이 하지 않는다” 같은 규칙은 문서화하고, 에이전트가 읽을 수 있는 위치에 둬야 한다.
셋째, 자동 승인 범위를 작게 시작해야 한다. 반복적인 npm test, git diff, 타입체크처럼 되돌리기 쉽고 범위가 명확한 명령은 자동화해도 된다. 반면 rm, 홈 디렉터리 접근, 토큰 파일 읽기, 배포, 네트워크 전송, 의존성 설치, 데이터베이스 변경은 기본적으로 사람이 끊어보는 편이 안전하다. 생산성은 경계를 없애서 얻는 것이 아니라, 안전한 루틴을 식별해 자동화할 때 가장 오래 간다.
넷째, 장시간 작업은 중간 요약과 검증 지점을 설계해야 한다. 에이전트에게 큰 기능을 통째로 맡길 때도 “먼저 계획을 세우고”, “파일 변경 후 테스트를 실행하고”, “마지막에 diff를 요약하라”는 식의 체크포인트를 두면 컨텍스트 압축 과정에서 중요한 결정이 사라질 가능성이 줄어든다. 좋은 하네스는 이런 체크포인트를 자동으로 돕지만, 사용자도 작업 단위를 적절히 나눠야 한다.
적용 아이디어
-
현재 쓰는 코딩 에이전트에서 자동 승인되는 명령 목록을 확인한다. 읽기, 테스트, 빌드, 포맷팅처럼 안전한 명령과 네트워크, 삭제, 배포, 홈 디렉터리 수정처럼 위험한 명령을 분리한다.
-
저장소 루트에 에이전트용 작업 규칙 파일을 둔다. 빌드 명령, 테스트 명령, 패키지 매니저, 코딩 스타일, 금지 작업, 배포 전 확인 사항을 짧고 명확하게 적는다. 사람에게 당연한 것을 모델에게도 당연하게 만들어야 한다.
-
긴 로그를 다루는 방식을 점검한다. CI 실패 로그나 테스트 출력이 너무 길다면, 에이전트가 볼 요약 명령을 따로 만든다. 예를 들어 실패 테스트만 출력하거나, 마지막 200줄과 에러 패턴을 추출하는 스크립트를 둘 수 있다.
-
낯선 저장소나 외부 PR을 에이전트로 분석할 때는 네트워크와 쓰기 권한을 제한한다. 먼저 읽기 전용 분석을 시키고, 수정이 필요할 때 별도 승인으로 넘어가는 흐름이 좋다.
-
에이전트가 반복해서 같은 실수를 한다면 “모델이 별로다”라고 결론내리기 전에 컨텍스트가 어떻게 전달되는지 본다. 중요한 프로젝트 규칙이 프롬프트에 들어갔는지, 이전 실패가 요약에 남았는지, 도구 출력이 잘린 위치가 적절한지 확인한다.
-
큰 작업을 맡길 때는 독립 가능한 하위 작업을 분리한다. 문서 조사, 타입 오류 분류, 테스트 실패 원인 조사처럼 서로 독립적인 일은 병렬화할 수 있지만, 같은 파일을 동시에 고치는 작업은 충돌 위험이 크다.
-
MCP나 외부 도구를 붙일 때는 기능보다 권한 모델을 먼저 본다. 데이터베이스 조회 도구가 쓰기도 가능한지, API 토큰이 어떤 범위를 갖는지, 호출 로그가 남는지, 실패 시 재시도 정책이 있는지 확인한다.
-
팀에서 에이전트를 도입한다면 “좋은 프롬프트 모음”보다 “좋은 운영 규칙”을 먼저 만든다. 어떤 작업을 자동화할지, 어떤 작업은 승인할지, 어떤 경로는 절대 건드리지 않을지, 결과는 어떻게 리뷰할지 합의해야 한다.
읽기 우선순위
이 글은 코딩 에이전트를 단순한 자동완성 도구가 아니라 실제 개발 작업자처럼 쓰기 시작한 사람에게 우선순위가 높다. 특히 Claude Code, Codex CLI, Cursor, OpenClaw 같은 도구로 파일 수정과 테스트 실행을 맡기고 있다면 원문을 읽어볼 만하다. 내부 구현을 아주 깊게 파고드는 논문식 글은 아니지만, “에이전트 하네스가 무엇을 책임지는가”를 빠르게 잡아준다.
추천하는 읽기 방식은 먼저 이 요약으로 큰 구조를 잡고, 원문에서는 도구 호출, 컨텍스트 관리, 승인 시스템 부분을 자세히 보는 것이다. 직접 에이전트를 만들고 있다면 원문이 언급한 Codex CLI 코드베이스까지 이어서 보는 편이 좋다. 반대로 단순히 제품을 쓰는 입장이라면 결론만 가져가도 충분하다. 좋은 코딩 에이전트는 좋은 모델 하나가 아니라, 모델이 안전하고 일관되게 일하도록 만드는 하네스 전체의 결과물이다.