긴 작업은 기억력이 아니라 구조로 버틴다
AI 에이전트에게 몇 시간짜리 일을 맡기면 처음에는 잘 진행되는 것처럼 보인다. 요구사항을 읽고, 계획을 세우고, 파일을 수정하고, 테스트도 실행한다. 그러나 시간이 길어질수록 문제가 드러난다. 초기에 내린 결정이 희미해지고, 완료된 일과 남은 일이 섞이며, 작은 실패가 누적된다. 마지막에는 에이전트가 많은 일을 한 것 같지만 실제 제품은 불안정한 상태로 남는다.
장시간 작업의 핵심은 더 긴 프롬프트가 아니다. 큰 일을 작은 단위로 나누고, 각 단위의 상태를 명확히 기록하며, 다음 실행자가 이어받을 수 있는 형태로 남기는 것이다. 하네스는 여기서 작업 기억을 외부화한다. 모델의 컨텍스트 안에만 있던 계획, 결정, 검증 결과를 파일, 이슈, 체크리스트, 로그, 평가 리포트로 꺼내어 관리한다.
좋은 오케스트레이션은 하나의 똑똑한 에이전트에게 모든 것을 맡기지 않는다. 계획하는 에이전트, 구현하는 에이전트, 평가하는 에이전트를 분리한다. 각 에이전트는 다른 책임을 가진다. 그리고 서로 대화만 하는 것이 아니라 구조화된 산출물을 주고받는다. 이것이 장시간 작업을 안정적으로 만드는 기본 원리다.

초기화 에이전트: 요구사항을 실행 가능한 작업으로 바꾸기
복잡한 작업의 첫 단계는 구현이 아니라 초기화다. 초기화 에이전트는 제품 요구사항 문서, 기존 코드 구조, 제약 조건, 품질 기준을 읽고 실행 계획을 만든다. 이 역할은 프로젝트 매니저와 기술 리드의 중간에 가깝다.
초기화 에이전트의 출력은 막연한 계획이 아니어야 한다. 다음과 같은 구조를 갖춘 작업 목록이어야 한다.
작업 ID와 짧은 설명
작업의 목적과 완료 조건
선행 작업과 의존성
수정이 예상되는 파일 또는 모듈
필요한 테스트와 검증 명령
위험 요소와 롤백 방법
사람이 승인해야 하는 지점
예를 들어 결제 화면에 쿠폰 기능을 추가한다고 하자. 나쁜 계획은 '쿠폰 기능 구현' 하나로 끝난다. 좋은 계획은 요구사항 분석, 데이터 모델 변경, API 계약 정의, 프론트엔드 입력 흐름, 가격 계산 로직, 실패 케이스 처리, 테스트 추가, 문서 갱신으로 나뉜다. 각 작업은 독립적으로 검토될 수 있어야 한다.
초기화 에이전트가 특히 잘해야 하는 일은 숨은 의존성을 드러내는 것이다. 어떤 기능은 UI만 바꾸는 것처럼 보이지만 실제로는 권한 정책, 로깅, 캐시, 마이그레이션, 결제 정산에 영향을 준다. 초기화 단계에서 이를 발견하지 못하면 뒤에서 작업하는 코딩 에이전트는 잘못된 범위를 기준으로 움직인다.
따라서 초기화 에이전트의 산출물은 단순한 할 일 목록이 아니라 작업 그래프에 가까워야 한다. 작업 그래프는 어떤 일이 먼저 끝나야 다음 일이 가능한지 보여준다. 하네스는 이 그래프를 기준으로 작업을 큐에 넣고, 병렬 실행 가능한 항목과 순차 실행해야 하는 항목을 구분한다.
작업 상태는 대화가 아니라 문서에 남긴다
장시간 작업에서 가장 위험한 문장은 '앞에서 말했듯이'다. 에이전트의 이전 세션이 종료되면 그 말은 사라질 수 있다. 같은 에이전트가 이어서 실행되더라도 컨텍스트가 압축되거나 일부만 전달되면 세부 결정은 쉽게 손실된다.
그래서 하네스는 작업 상태를 명시적인 저장소에 남겨야 한다. 가장 단순한 방식은 tasks.md 같은 파일이다. 더 큰 시스템에서는 이슈 트래커, 데이터베이스, 오케스트레이션 서버를 사용할 수 있다. 중요한 것은 형식이다.
각 작업은 최소한 다음 상태를 가져야 한다.
pending: 아직 시작하지 않음in_progress: 특정 에이전트가 작업 중blocked: 외부 결정이나 선행 작업을 기다림review_ready: 구현은 끝났고 평가 대기 중accepted: 평가를 통과함rework: 수정이 필요함abandoned: 더 이상 진행하지 않음
상태가 명확하면 에이전트는 다음 행동을 추측하지 않는다. 무엇을 이어받아야 하는지, 무엇을 건드리면 안 되는지, 무엇을 사람에게 물어야 하는지 알 수 있다. 특히 여러 에이전트가 동시에 움직일 때 상태 관리가 없으면 같은 파일을 서로 다르게 수정하거나, 이미 실패한 접근을 반복하는 일이 생긴다.
상태 문서는 에이전트의 기억을 대신한다. 좋은 상태 문서는 현재 위치만 알려주지 않는다. 왜 이 위치에 왔는지도 알려준다. 어떤 대안을 버렸는지, 어떤 테스트가 실패했는지, 어떤 위험을 감수했는지 기록해야 한다. 이 기록이 다음 세션의 출발점이 된다.
코딩 에이전트는 기능 단위로 일하고 핸드오프를 남긴다
코딩 에이전트에게 가장 나쁜 지시는 '이 기능을 전부 완성해줘'다. 범위가 크면 에이전트는 많은 파일을 동시에 수정하고, 중간 검증 없이 진행하며, 마지막에 실패 원인을 찾기 어려운 상태를 만든다.
좋은 방식은 기능을 작고 닫힌 단위로 나누는 것이다. 닫힌 단위란 시작과 끝이 분명하고, 자체 검증이 가능한 작업을 말한다. 예를 들어 '쿠폰 코드 입력 UI 추가', '할인 계산 함수 구현', '유효하지 않은 쿠폰 오류 처리', '가격 표시 테스트 추가'는 각각 작은 단위가 될 수 있다.
각 코딩 세션은 하나 또는 소수의 작업만 맡아야 한다. 세션이 끝나면 반드시 핸드오프 문서를 남긴다. 핸드오프 문서는 다음 에이전트나 다음 세션의 자신에게 넘기는 인수인계서다.
좋은 핸드오프 문서에는 다음 내용이 들어간다.
수행한 작업 요약
변경한 파일 목록
중요한 설계 결정과 이유
실행한 검증 명령과 결과
아직 남은 작업
알려진 문제와 의심 지점
되돌릴 때 필요한 정보
이 문서는 길 필요가 없다. 그러나 모호하면 안 된다. '테스트 일부 실패'라고 쓰는 대신 어떤 테스트가 왜 실패했는지 적어야 한다. '리팩터링 필요'라고 쓰는 대신 어느 함수가 어떤 이유로 위험한지 적어야 한다.
핸드오프의 목적은 다음 에이전트가 다시 추리하지 않게 만드는 것이다. 추리는 비용이 크고 오류가 많다. 앞 세션의 의도를 코드만 보고 복원하려 하면 같은 실수를 반복한다. 반대로 인수인계가 잘 되어 있으면 다음 에이전트는 빠르게 작업 맥락을 회복하고 남은 문제에 집중할 수 있다.
계획자, 생성자, 평가자: 3에이전트 아키텍처
다중 에이전트 구조의 기본형은 계획자, 생성자, 평가자다. 이 셋은 같은 모델을 쓸 수도 있고 서로 다른 모델을 쓸 수도 있다. 중요한 것은 역할과 권한을 분리하는 것이다.
계획자는 문제를 나눈다. 요구사항을 읽고 작업 목록, 의존성, 위험, 완료 기준을 만든다. 계획자는 코드를 많이 수정하지 않는다. 대신 전체 범위와 순서를 책임진다. 계획자가 흔들리면 생성자는 잘못된 일을 열심히 하게 된다.
생성자는 산출물을 만든다. 코드, 문서, 디자인 시안, 테스트, 설정 파일을 작성한다. 생성자는 계획자가 정한 범위 안에서 움직인다. 범위를 벗어난 문제가 보이면 임의로 큰 결정을 내리기보다 작업 상태를 blocked로 바꾸거나 별도 이슈를 만든다.
평가자는 산출물을 검증한다. 테스트를 실행하고, 요구사항과 비교하고, 품질 기준을 적용한다. 평가자는 생성자의 설명을 그대로 믿지 않는다. 실제 산출물과 실행 결과를 기준으로 판단한다. 평가 결과는 통과, 수정 필요, 차단으로 나뉘며 반드시 근거를 포함해야 한다.
이 구조에서 핵심은 에이전트 간의 통신 방식이다. 자유 대화만으로 연결하면 판단 근거가 사라진다. 대신 작업 명세, 변경 요약, 테스트 결과, 평가 리포트 같은 구조화된 문서를 주고받아야 한다. 하네스는 이 문서들을 저장하고 다음 실행의 입력으로 사용한다.
3에이전트 아키텍처는 단순해 보이지만 강력하다. 계획자는 넓게 보고, 생성자는 깊게 만들고, 평가자는 차갑게 판단한다. 한 에이전트가 이 세 역할을 모두 수행하면 빠르지만 쉽게 자기합리화에 빠진다. 역할 분리는 속도를 조금 희생하는 대신 안정성을 얻는 방법이다.
자기 평가는 왜 관대해지는가
작업을 수행한 에이전트에게 스스로 평가까지 맡기면 종종 문제가 생긴다. 에이전트는 자신이 만든 결과를 좋게 해석하려는 경향을 보인다. 실패한 테스트를 환경 문제로 돌리거나, 요구사항의 빠진 부분을 사소한 누락으로 취급하거나, 애매한 품질을 '충분히 괜찮다'고 판단할 수 있다.
이것은 모델이 인간처럼 자존심을 가진다는 뜻이 아니다. 같은 컨텍스트 안에서 계획, 구현, 평가가 이어지면 앞선 결정이 평가 기준에 영향을 주기 쉽다는 뜻이다. 이미 어떤 접근을 선택한 상태에서는 그 접근을 부정하는 근거를 덜 민감하게 본다. 또한 생성 단계에서 사용한 가정이 평가 단계에도 그대로 남아 있어, 잘못된 가정을 다시 확인하지 못한다.
따라서 중요한 작업에서는 수행 에이전트와 평가 에이전트를 분리해야 한다. 평가 에이전트는 생성 과정의 세부 대화를 몰라도 된다. 오히려 모르는 편이 나을 때가 많다. 평가자는 요구사항, 산출물, 테스트 명령, 품질 기준만 보고 판단해야 한다.
평가 에이전트에는 별도의 프롬프트가 필요하다. 이 프롬프트는 친절한 조언자가 아니라 엄격한 검수자에 가깝게 설계한다. '좋은 점을 찾아라'보다 '계약 위반, 누락, 회귀, 위험한 추정을 찾아라'가 더 적절하다. 평가자는 수정 방법을 제안할 수 있지만, 평가와 구현을 동시에 맡아서는 안 된다. 수정은 다시 생성자에게 돌아가야 한다.
주관적 품질은 기준을 먼저 만든다
코드 테스트처럼 명확한 기준이 있는 작업도 있지만, 디자인, UX 문구, 브랜드 톤, 문서 품질처럼 주관적 판단이 중요한 작업도 있다. 이런 작업에서 단순히 '더 좋게 만들어라'라고 지시하면 반복은 길어지고 결과는 흔들린다.
주관적 품질을 다룰 때는 먼저 평가 기준을 만들어야 한다. 기준은 추상적인 단어만 나열해서는 안 된다. '깔끔함', '전문성', '친근함' 같은 단어는 사람마다 다르게 해석한다. 하네스는 이를 관찰 가능한 항목으로 바꿔야 한다.
예를 들어 디자인 평가 기준은 다음처럼 만들 수 있다.
정보 위계가 명확한가
주요 행동 버튼이 즉시 보이는가
색상과 간격이 기존 디자인 시스템과 맞는가
오류 상태와 빈 상태가 고려되었는가
모바일 화면에서 핵심 흐름이 유지되는가
문서 품질이라면 기준은 달라진다.
첫 문단에서 독자가 얻을 가치를 알 수 있는가
전문 용어를 사용할 때 간단한 설명이 있는가
같은 주장을 반복하지 않는가
예시가 개념을 실제 상황으로 연결하는가
독자가 다음 행동을 알 수 있는가
점수는 1점부터 5점까지 줄 수 있다. 그러나 점수만으로는 부족하다. 3점과 4점의 차이가 무엇인지 예시가 있어야 한다. 이를 앵커라고 부른다. 앵커는 기준 점수의 기준점 역할을 한다. 예를 들어 5점 디자인은 '주요 행동이 첫 화면에서 명확하고, 예외 상태까지 디자인되어 있으며, 기존 컴포넌트를 일관되게 사용한다'처럼 설명한다.
평가자는 처음부터 완벽하지 않다. 그래서 점수 보정이 필요하다. 사람이 몇 개의 결과물을 직접 평가하고, 평가 에이전트의 점수와 비교한다. 평가자가 지나치게 후하거나 박하면 프롬프트와 기준을 조정한다. 중요한 것은 평가 에이전트의 점수를 절대값으로 믿지 않는 것이다. 점수는 의사결정을 돕는 신호이지 최종 진실이 아니다.
반복 개선 루프는 작고 단단해야 한다
다중 에이전트 오케스트레이션은 반복 루프로 완성된다. 계획자가 작업을 만든다. 생성자가 산출물을 만든다. 평가자가 검토한다. 통과하면 다음 작업으로 넘어간다. 실패하면 평가 리포트를 바탕으로 수정 작업이 생성된다.
이 루프에서 피해야 할 것은 큰 재작업이다. 평가자가 '전체적으로 개선 필요'라고만 말하면 생성자는 다시 넓은 범위를 건드린다. 그러면 새로운 문제가 생긴다. 평가 결과는 가능한 한 구체적인 수정 작업으로 바뀌어야 한다.
예를 들어 'UI가 별로다'는 좋은 평가가 아니다. '모바일 360px 화면에서 가격 요약이 접히며 결제 버튼이 첫 화면에서 사라진다. 결제 버튼을 고정 하단 영역으로 이동하고 가격 요약은 접이식으로 바꿔라'가 좋은 평가다. 생성자는 이 지시를 작은 작업으로 수행할 수 있다.
하네스는 반복 횟수에도 제한을 두어야 한다. 같은 문제가 세 번 이상 반복되면 단순히 다시 시도할 일이 아니다. 요구사항이 모호하거나, 평가 기준이 잘못되었거나, 에이전트가 필요한 도구를 갖고 있지 않을 수 있다. 이때는 사람의 개입, 계획 수정, 기준 재정의가 필요하다.
좋은 반복 루프는 다음 질문에 답할 수 있어야 한다.
무엇이 실패했는가
실패를 어떻게 재현할 수 있는가
어떤 기준을 만족하지 못했는가
다음 수정 범위는 어디까지인가
다시 실패하면 누구에게 넘길 것인가
이 질문들이 문서화되어 있으면 장시간 작업도 흐트러지지 않는다.
병렬 실행에는 잠금과 병합 규칙이 필요하다
여러 에이전트를 동시에 실행하면 속도는 빨라질 수 있다. 하지만 충돌 위험도 커진다. 두 에이전트가 같은 파일을 수정하거나, 한 에이전트가 바꾼 인터페이스를 다른 에이전트가 모른 채 작업하면 통합 단계에서 문제가 폭발한다.
따라서 병렬 실행에는 잠금과 병합 규칙이 필요하다. 작업을 시작할 때 에이전트는 자신이 수정할 파일이나 모듈을 선언한다. 하네스는 겹치는 범위가 있으면 동시에 실행하지 않거나, 한쪽을 읽기 전용으로 제한한다. 데이터베이스 스키마, 공통 타입, 핵심 설정 파일처럼 영향 범위가 큰 파일은 별도 승인 없이 병렬 수정하지 못하게 할 수 있다.
병합 규칙도 명확해야 한다. 생성자가 코드를 작성했다고 바로 통합 브랜치에 합치면 안 된다. 최소한 로컬 검증, 자동 테스트, 평가자 리뷰, 충돌 확인을 거쳐야 한다. 중요한 제품에서는 제한 배포나 기능 플래그까지 연결한다. 다중 에이전트의 속도는 품질 게이트를 우회하기 위한 것이 아니라, 작은 단위를 더 자주 검증하기 위한 것이다.
큰일을 잘하는 에이전트의 조건
큰일을 잘하는 에이전트 시스템은 거대한 모델 하나로 만들어지지 않는다. 잘 나뉜 작업, 명확한 상태, 엄격한 평가자, 안정적인 핸드오프가 필요하다. 모델의 추론 능력은 중요하지만, 추론이 머무를 구조가 없으면 긴 작업에서 쉽게 흩어진다.
하네스 엔지니어링의 관점에서 장시간 작업은 다음 원칙으로 설계한다.
먼저 작업을 분해하고 의존성을 드러낸다.
각 작업은 완료 조건과 검증 방법을 가진다.
세션이 끝날 때마다 핸드오프 문서를 남긴다.
계획자, 생성자, 평가자의 역할을 분리한다.
자기 평가에 의존하지 않고 독립 평가자를 둔다.
주관적 품질도 기준과 앵커로 평가한다.
반복은 구체적인 수정 작업으로 닫는다.
병렬 실행에는 잠금, 권한, 병합 게이트를 둔다.
오케스트레이션의 목적은 에이전트를 많이 쓰는 것이 아니다. 한 번에 실패하기 쉬운 큰 일을 실패해도 복구 가능한 작은 흐름으로 바꾸는 것이다. 이 구조가 있으면 작업은 몇 시간, 며칠, 여러 세션에 걸쳐 이어질 수 있다. 그리고 각 단계는 추측이 아니라 기록과 평가를 바탕으로 다음 단계로 넘어간다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.