LLM 에이전트 장시간 작업 최적화: 기억 단절 해결과 하니스 설계 방법 (앤스로픽)
핵심 요약
여러 컨텍스트 윈도우를 넘나들며 오래 일하는 에이전트는 "기억 단절" 때문에 쉽게 길을 잃습니다. 이를 해결하려면 첫 실행에서 환경을 잘 설계하고, 이후 매 세션마다 작은 단위로 진전하고, 상태를 명확히 남기도록 하니스(운용 틀)를 짜야 합니다.
장시간 에이전트 문제의 본질
현재의 LLM 에이전트는 한 번의 세션(컨텍스트 창) 안에서는 꽤 잘 일하지만, 여러 번의 세션을 거쳐 며칠씩 일하게 하면 문제가 드러납니다.
모든 세션은 사실상 "기억 상실" 상태로 시작하며, 이전 세션의 상세한 작업 맥락을 그대로 가져오기는 어렵습니다.
사람으로 비유하면, 야간·주간 교대 근무를 하는 개발팀인데 교대할 때마다 전임자가 무슨 일을 했는지, 코드가 어떤 상태였는지 제대로 기록이 없는 상황과 같습니다.
컨텍스트 압축(compaction) 같은 기능이 있어도, "무엇을 했고, 무엇이 남았는지"를 명쾌하게 전달하지 못하면 새 세션의 에이전트는 추측에 많은 시간을 쓰게 됩니다.
이 문제를 해결하려면 "기억을 직접 늘리려는 접근"보다는, 인간 개발자가 팀 작업에서 사용하는 방법처럼, 작업 환경과 기록 구조를 잘 설계하는 것이 더 효과적입니다.
두 역할: 초기화 에이전트와 코딩 에이전트
Anthropic은 Claude Agent SDK로 실험하며, 역할을 둘로 쪼개는 방식이 효과적임을 확인했습니다.
첫 번째 역할은 초기화 에이전트입니다.
이 에이전트는 사용자 요청을 보고 전체 프로젝트의 뼈대를 설계하고, 나중에 들어올 에이전트들이 참고할 수 있는 환경과 기준을 만들어 둡니다.
두 번째 역할은 코딩 에이전트입니다.
이 에이전트는 이미 만들어진 환경과 기록을 읽고, 매 세션마다 하나의 작은 목표에 집중해 코드를 개선하며, 끝날 때마다 다음 세션을 위한 흔적을 정리해서 남깁니다.
두 에이전트는 사실 같은 모델·같은 도구를 쓸 수 있지만, "첫 세션에만 다른 프롬프트를 준다"는 점에서 실질적으로 다른 역할을 수행하게 됩니다.
초기화 에이전트가 준비해야 할 환경 요소
초기화 에이전트의 핵심 임무는 "향후 수많은 세션의 작업 효율을 높이는 기반"을 만드는 일입니다.
우선, 전체 요구사항을 세부 기능 목록으로 쪼개어 구조화된 파일로 저장합니다.
예를 들어 "claude.ai 비슷한 웹앱"이라는 추상적인 요구를 수백 개의 구체 기능으로 나눕니다.
"새 채팅 생성 버튼을 누르면 사이드바에 새 대화가 보인다" 같은 식의 세부 기능입니다.
이때 각 기능에는 간단한 시나리오와 함께 지금 통과 여부를 나타내는 플래그(예: passes: false)를 둡니다.
처음에는 전부 실패 상태로 두어 "무엇이 아직 안 됐는지"가 분명히 보이게 합니다.
또한, 작업 로그 역할을 하는 진행 상황 파일(예: claude-progress.txt)을 만들어, 이후 에이전트들이 세션별로 무엇을 했는지 기록하게 만듭니다.
마지막으로, git 저장소를 초기화하고 첫 커밋을 생성해 코드 상태를 기준점으로 남기면, 이후 되돌리기와 변경 추적이 쉬워집니다.
가능하다면 개발 서버를 실행하고 기본 검증을 수행하는 init.sh 스크립트도 만들어, 후속 세션의 "준비 작업"을 자동화할 수 있게 합니다.
기능 목록(Feature List)으로 작업 범위 고정하기
장시간 작업에서 자주 발생하는 문제 중 하나는 에이전트가 "앱을 한 번에 다 만들려고 하다가 실패"하거나, 반대로 "조금 돌아가는 것 같으니 완성으로 착각"하는 것입니다.
이를 막기 위해 초기화 단계에서 기능 목록을 매우 구체적으로 작성합니다.
각 항목에는 카테고리, 설명, 단계별 동작 방식, 통과 여부 같은 필드를 넣고, JSON처럼 구조가 엄격한 형식을 사용합니다.
에이전트에게는 "이 파일에서 바꿔도 되는 것은 passes 필드뿐"이라고 강하게 명시합니다.
내용을 지우거나 바꾸는 것은 금지하고, 새 기능을 마음대로 추가하는 것도 최대한 막습니다.
이렇게 하면:
프로젝트 범위가 고정되어 "조기 완성 선언"을 예방하고
매 세션마다 "무엇을 할지"를 기능 목록에서 뽑아 결정할 수 있으며
테스트 기준이 문서화되어, "어떻게 동작해야 하는지"에 대한 일관된 기준이 생깁니다.
사실상 JSON 기능 목록은 자동화된 "수동 테스트 시나리오 모음" 역할을 합니다.
한 번에 하나, 작은 단위로만 전진시키기
LLM에 복잡한 일을 시킬 때 자주 생기는 오류는 "욕심을 내서 너무 많은 기능을 한 번에 건드리는 것"입니다.
이렇게 되면 코드가 중간 상태에서 끝나고, 버그가 생기며, 다음 세션에 들어온 에이전트는 무엇이 어디까지 구현된 건지 파악하기가 매우 어려워집니다.
이를 방지하는 핵심 전략은 "각 세션에서 오직 하나의 기능(또는 매우 작은 단위)만 완성하는 것"입니다.
코딩 에이전트는 세션 시작 시 기능 목록을 읽고, 아직 passes가 false인 항목 중 우선순위가 높은 것을 하나 선택합니다.
그리고 그 기능을 구현·수정·테스트하는 데 집중합니다.
작업이 끝나면:
코드가 최소한 깨지지 않는 상태인지 확인하고
git에 의미 있는 커밋 메시지와 함께 커밋을 남기며
progress 파일에 "이번 세션에서 무엇을 했는지, 어떤 문제를 겪었는지, 다음에 무엇을 하면 좋은지"를 요약합니다.
이렇게 하면 각 세션이 "작은 스프린트"처럼 독립적으로 이해할 수 있는 단위가 되고, 이후 에이전트는 이전 세션의 흔적을 빠르게 따라갈 수 있습니다.
git과 진행 로그로 상태를 "외부 기억"으로 만들기
에이전트는 세션이 바뀔 때마다 내부 컨텍스트를 잃지만, 코드 저장소와 파일들은 그대로 남습니다.
여기에 git과 진행 로그를 체계적으로 활용하면, 사실상 "외부 기억 장치"를 만든 셈이 됩니다.
git 저장소는 다음과 같은 역할을 합니다.
어떤 파일이 언제, 왜 바뀌었는지 추적하는 타임라인
잘못된 변경을 되돌릴 수 있는 안전망
기능별 작업을 나눠 볼 수 있는 단위(commit)
진행 로그(claude-progress.txt 같은 파일)는 인간 개발자의 "작업 일지"에 가깝습니다.
여기에는:
이번 세션에서 선택한 기능
구현·디버깅 과정에서의 중요한 결정
남아 있는 문제와 TODO
환경 설정이나 실행 방법에서 발견한 이슈
같은 정보가 들어갑니다.
코딩 에이전트는 세션 시작 시 반드시 이 진행 로그와 git log를 읽고, 최근 작업 흐름을 빠르게 재구성합니다.
이 과정은 사람이 새 팀에 합류할 때, README와 커밋 기록을 읽으며 프로젝트를 이해하는 과정과 매우 비슷합니다.
테스트를 "사람처럼" 하도록 도구와 기준 제공하기
또 하나의 중요한 실패 패턴은 "테스트를 대충 하고 기능을 완료로 표시하는 것"입니다.
에이전트는 종종 코드 수정을 하고, 유닛 테스트나 간단한 curl 요청 정도는 실행하지만, 실제 사용 흐름 전체를 검증하지는 않습니다.
이를 개선하려면 두 가지가 필요합니다.
첫째, 명확한 기준입니다.
기능 목록 자체를 "엔드 투 엔드 시나리오" 형태로 작성하고, passes를 true로 바꾸기 전에 시나리오를 실제로 재현해 보도록 요구해야 합니다.
둘째, 적절한 도구입니다.
웹앱이라면 브라우저 자동화 도구(Puppeteer 등)를 통해 실제 사용자가 클릭·입력하는 행동을 에이전트가 재현할 수 있게 해야 합니다.
이를 통해 "버튼은 있지만, 실제로는 아무 동작도 하지 않는" 식의 겉보기 기능 완성 오판을 크게 줄일 수 있습니다.
물론 도구나 시각 인식의 한계 때문에 모든 버그를 잡을 수는 없습니다.
예를 들어 브라우저 기본 alert 창처럼 자동화 도구가 인식하지 못하는 UI 요소는 여전히 취약할 수 있습니다.
그럼에도, 도구를 제공하고 "사람처럼 끝까지 써 보라"고 명시하는 것만으로도 기능 완성도의 수준이 크게 올라갑니다.
새 세션의 "루틴"을 표준화하기
초기화 에이전트가 환경을 잘 준비했다면, 이후의 코딩 세션들은 일정한 루틴을 따르는 것이 좋습니다.
대표적인 루틴은 다음과 같은 흐름입니다.
현재 작업 디렉터리 확인 (어디서 작업 가능한지 파악)
git log와 진행 로그 읽기 (최근 작업 맥락 이해)
기능 목록에서 아직 완료되지 않은 기능 중 우선순위가 높은 것 선택
init.sh를 실행해 개발 서버를 띄우고, 기본 동작이 깨지지 않았는지 빠르게 점검
문제가 있다면 먼저 복구, 없다면 선택한 기능 구현
구현 후 브라우저 자동화 등으로 엔드 투 엔드 테스트
passes를 true로 변경, git 커밋, 진행 로그 업데이트
이 루틴을 프롬프트에 강하게 박아두면, 매번 "이번엔 어떻게 시작하지?"를 생각하는 데 쓰는 토큰과 시간을 줄일 수 있습니다.
또한 "먼저 기본 기능이 살아 있는지 확인"하게 만들어, 망가진 상태 위에 새 기능을 얹는 일을 막을 수 있습니다.
결과적으로 각 세션은 "현재 상태 파악 → 환경 점검 → 작은 기능 구현 → 깨끗한 마무리"라는 예측 가능한 구조를 갖게 되고, 프로젝트 품질과 속도가 동시에 좋아집니다.
인사이트
긴 시간 동안 스스로 일하는 에이전트를 잘 활용하려면, 모델의 능력을 키우는 것만큼이나 "일하는 방식"을 설계하는 것이 중요합니다.
핵심은 다음 네 가지로 요약할 수 있습니다.
첫 세션에서 환경을 꼼꼼히 설계하고, 기능 목록·진행 로그·init 스크립트·git을 준비한다.
각 세션은 하나의 기능에 집중해 작은 단위로만 전진하고, 항상 깨끗한 상태로 마무리한다.
진행 로그와 git을 "외부 기억"으로 활용해 세션 간 단절을 최소화한다.
사람처럼 사용하는 테스트(엔드 투 엔드)를 도구와 프롬프트로 강제해 "완료 착각"을 줄인다.
이 패턴은 웹앱 개발뿐 아니라, 연구 프로젝트, 데이터 파이프라인 구축, 금융 모델링처럼 여러 날에 걸쳐 점진적으로 개선하는 모든 작업에 응용할 수 있습니다.
실무에서 직접 적용해 보고 싶다면, 작은 프로젝트를 하나 정해:
기능 목록 JSON 작성
init 스크립트와 진행 로그 설계
"한 번에 하나의 기능만" 원칙을 프롬프트에 넣기
이 세 가지부터 시도해 보는 것을 추천합니다.
출처 및 참고 : Effective harnesses for long-running agents \ Anthropic
