긴 시간 동안 실행되는 에이전트를 위한 효과적인 하니스

TMT

https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents

에이전트는 많은 컨텍스트 윈도우에서 작업할 때 여전히 어려움을 겪습니다. 우리는 장시간 실행되는 에이전트를 위한 더 효과적인 하니스를 만들기 위해 인간 엔지니어에게서 영감을 얻었습니다.

AI 에이전트가 더 강력해지면서, 개발자들은 점점 더 여러 시간, 심지어 며칠에 걸친 작업이 필요한 복잡한 과제를 맡기고 있습니다. 그러나 여러 컨텍스트 윈도우를 넘나들며 일관된 진행을 이루게 하는 것은 아직 해결되지 않은 문제입니다.

장시간 실행되는 에이전트의 핵심 과제는, 작업이 이산적인 세션으로 이루어지고 각 새로운 세션이 이전 세션의 기억 없이 시작한다는 점입니다. 마치 소프트웨어 프로젝트를 교대 근무 엔지니어로 운영하는데, 매번 새 엔지니어가 이전 근무 내용에 대한 기억 없이 도착하는 상황을 떠올려 보세요. 컨텍스트 윈도우는 제한되어 있고, 대부분의 복잡한 프로젝트는 하나의 윈도우에서 완료할 수 없기 때문에, 에이전트는 코딩 세션 사이의 간극을 메우는 방법이 필요합니다.

우리는 Claude Agent SDK가 여러 컨텍스트 윈도우에 걸쳐 효과적으로 작동하도록 하는 2단계 솔루션을 개발했습니다: 첫 실행에서 환경을 설정하는 이니셜라이저 에이전트와, 매 세션마다 점진적 진전을 이루고 다음 세션을 위한 명확한 산출물을 남기도록 하는 코딩 에이전트입니다. 코드 예시는 함께 제공된 퀵스타트에서 확인할 수 있습니다.

장시간 실행 에이전트 문제

Claude Agent SDK는 코딩뿐 아니라, 도구를 사용해 컨텍스트를 수집하고, 계획하고, 실행해야 하는 작업에 능한 강력한 범용 에이전트 하니스입니다. 이 SDK는 컴팩션(compaction) 같은 컨텍스트 관리 기능을 갖추고 있어, 에이전트가 컨텍스트 윈도우를 소모하지 않고 작업을 수행할 수 있게 해줍니다. 이론적으로 보면, 이러한 설정을 통해 에이전트가 임의로 긴 시간 동안 유용한 작업을 계속 수행하는 것이 가능해야 합니다.

하지만, 컴팩션만으로는 충분하지 않습니다. 기본 설정 상태에서, Opus 4.5 같은 프론티어 코딩 모델이 Claude Agent SDK 상에서 여러 컨텍스트 윈도우에 걸쳐 루프로 실행되더라도, “claude.ai 클론을 만들어라” 같은 상위 수준 프롬프트만 제공되면 프로덕션급 웹 앱을 만드는 데에는 미치지 못했습니다.

Claude의 실패는 두 가지 패턴으로 나타났습니다. 첫째, 에이전트가 한 번에 너무 많은 것을 하려는 경향이 있었습니다—사실상 앱을 원샷으로 구현하려는 시도입니다. 이는 종종 구현 도중 컨텍스트가 고갈되게 만들고, 다음 세션은 절반만 구현되고 문서화되지 않은 기능 상태에서 시작하게 됩니다. 그러면 에이전트는 무슨 일이 있었는지 추측해야 하고, 기본 앱을 다시 작동시키는 데 상당한 시간을 소모하게 됩니다. 이는 컴팩션이 있더라도, 다음 에이전트에게 완벽히 명확한 지시가 항상 전달되지는 않기 때문에 발생합니다.

둘째, 프로젝트 후반에 자주 나타나는 실패 모드가 있습니다. 일부 기능이 이미 구현된 후, 나중 세션의 에이전트 인스턴스가 살펴보고 진척이 있었다는 점을 보고 작업이 끝났다고 선언하는 경우입니다.

이 문제는 두 부분으로 분해됩니다. 첫째, 주어진 프롬프트가 요구하는 모든 기능의 기반을 마련하는 초기 환경을 설정해야 합니다. 이를 통해 에이전트가 단계별로, 기능별로 작업하도록 준비합니다. 둘째, 각 에이전트는 목표를 향해 점진적 진전을 이루도록 프롬프트되어야 하고, 동시에 세션 종료 시 환경을 깨끗한 상태로 남겨야 합니다. 여기서 “깨끗한 상태”란 메인 브랜치에 머지할 만한 코드를 의미합니다: 치명적 버그가 없고, 코드가 정돈되어 있으며 문서화가 잘 되어 있어, 개발자가 새로운 기능 작업을 쉽게 시작할 수 있고 관련 없는 문제를 먼저 정리할 필요가 없는 상태입니다.

내부 실험에서, 우리는 다음의 2단계 솔루션으로 이 문제를 해결했습니다:

  1. 이니셜라이저 에이전트: 첫 세션에서 특수화된 프롬프트로 모델에게 초기 환경 설정을 요청합니다. 여기에는 ⁠init.sh⁠ 스크립트, 에이전트가 수행한 작업 로그를 남기는 claude-progress.txt 파일, 그리고 추가된 파일이 무엇인지 보여주는 초기 git 커밋이 포함됩니다.

  2. 코딩 에이전트: 모든 이후 세션에서 모델에게 점진적 진전을 이루고, 구조화된 업데이트를 남기도록 요청합니다.1

여기에서의 핵심 통찰은, 새로운 컨텍스트 윈도우로 시작할 때 작업 상태를 빠르게 이해하게 만드는 방법을 찾는 것이었습니다. 이는 claude-progress.txt 파일과 git 히스토리를 함께 사용함으로써 달성되었습니다. 이러한 실천은 매일 효과적인 소프트웨어 엔지니어가 하는 일에서 영감을 받았습니다.

환경 관리

업데이트된 Claude 4 프롬팅 가이드에서, 우리는 멀티 컨텍스트 윈도우 워크플로우를 위한 모범 사례를 공유했으며, **“첫 번째 컨텍스트 윈도우에 다른 프롬프트를 사용”**하는 하니스 구조를 포함했습니다. 이 “다른 프롬프트”는 이니셜라이저 에이전트가 향후 코딩 에이전트가 효과적으로 작업하는 데 필요한 모든 컨텍스트로 환경을 설정하도록 요청합니다. 여기서는 이러한 환경의 핵심 구성 요소에 대해 더 깊이 살펴봅니다.

기능 목록

에이전트가 앱을 원샷으로 구현하거나 프로젝트를 너무 일찍 완료했다고 간주하는 문제를 해결하기 위해, 우리는 이니셜라이저 에이전트에게 사용자의 초기 프롬프트를 확장한 기능 요구사항의 포괄적 파일을 작성하도록 프롬프트했습니다. claude.ai 클론 예시에서는, “사용자가 새 채팅을 열고, 쿼리를 입력하고, 엔터를 누르면 AI 응답이 보인다” 같은 200개 이상의 기능이 포함되었습니다. 이러한 기능은 모두 초기에 “실패”로 표시되어, 이후 코딩 에이전트가 완전한 기능 구현의 윤곽을 명확하게 파악할 수 있도록 했습니다.

{
    "category": "functional",
    "description": "New chat button creates a fresh conversation",
    "steps": [
      "Navigate to main interface",
      "Click the 'New Chat' button",
      "Verify a new conversation is created",
      "Check that chat area shows welcome state",
      "Verify conversation appears in sidebar"
    ],
    "passes": false
}

우리는 코딩 에이전트가 이 파일을 passes 필드의 상태만 변경하는 방식으로 편집하도록 프롬프트하며, “테스트를 제거하거나 수정하는 것은 용납할 수 없다. 이는 누락되거나 버그가 있는 기능으로 이어질 수 있다” 같은 강력한 지침을 사용합니다. 여러 실험 끝에, 우리는 이를 Markdown 대신 JSON으로 관리하기로 했습니다. 모델이 JSON 파일을 부적절하게 변경하거나 덮어쓸 가능성이 더 낮기 때문입니다.

점진적 진전

이러한 초기 환경 스캐폴딩을 바탕으로, 다음 버전의 코딩 에이전트에게는 한 번에 하나의 기능만 작업하도록 요청했습니다. 이러한 점진적 접근법은 에이전트가 한 번에 너무 많은 것을 하려는 경향을 해결하는 데 결정적이었습니다.

점진적으로 작업하더라도, 모델이 코드 변경 후 환경을 깨끗한 상태로 남기는 것이 여전히 중요합니다. 우리의 실험에서, 이러한 행동을 가장 잘 이끌어낸 방법은 모델에게 설명적인 커밋 메시지와 함께 git에 진전을 커밋하고, 진전 요약을 progress 파일에 작성하도록 요청하는 것이었습니다. 이를 통해 모델은 git을 사용해 나쁜 코드 변경을 되돌리고, 코드베이스의 작동 상태를 복구할 수 있었습니다.

이러한 방식은 효율성도 높였습니다. 에이전트가 무슨 일이 있었는지 추측할 필요가 없어졌고, 기초 앱을 다시 작동시키는 데 시간을 낭비하지 않게 되었기 때문입니다.

테스트

마지막으로 관찰된 큰 실패 모드는 Claude가 적절한 테스트 없이 기능을 완료로 표시하는 경향이었습니다. 명시적 프롬프트가 없으면, Claude는 코드 변경을 하고, 유닛 테스트나 개발 서버에 대한 ⁠curl⁠ 명령으로 테스트를 수행하기도 했지만, 그 기능이 엔드 투 엔드로 작동하지 않는다는 사실을 인식하지 못하는 경우가 있었습니다.

웹 앱을 구축하는 경우, Claude는 브라우저 자동화 도구를 사용하고 사람 사용자처럼 모든 테스트를 수행하도록 명시적으로 프롬프트했을 때 엔드 투 엔드 기능 검증을 대부분 잘 수행했습니다.

Image

Claude가 claude.ai 클론을 테스트하면서 Puppeteer MCP 서버를 통해 찍은 스크린샷들.

Claude에게 이러한 테스트 도구를 제공하자 성능이 크게 개선되었습니다. 에이전트가 코드만으로는 명백하지 않은 버그를 식별하고 수정할 수 있었기 때문입니다.

여전히 남아 있는 이슈도 있습니다. 예를 들어, Claude의 비전 한계와 브라우저 자동화 도구의 제약은 모든 종류의 버그를 식별하는 것을 어렵게 만듭니다. 예시로, Claude는 Puppeteer MCP를 통해 브라우저 네이티브 alert 모달을 볼 수 없으며, 이 모달에 의존하는 기능은 그 결과 더 버그가 많아지는 경향이 있었습니다.

속도 높이기

위의 모든 요소가 갖춰진 상태에서, 모든 코딩 에이전트는 상황 파악을 위해 일련의 단계를 수행하도록 프롬프트됩니다. 일부는 아주 기본적이지만 여전히 유용합니다:

  1. 작업 중인 디렉토리를 확인하기 위해 ⁠pwd⁠를 실행합니다. 이 디렉토리의 파일만 편집할 수 있습니다.
  2. 최근에 작업된 내용을 파악하기 위해 git 로그와 progress 파일을 읽습니다.
  3. 기능 목록 파일을 읽고 아직 완료되지 않은 최우선 기능을 선택해 작업합니다.

이 접근법은 매 세션마다 토큰을 절약해 줍니다. 코드를 어떻게 테스트할지를 에이전트가 스스로 알아낼 필요가 없기 때문입니다. 또한, 이니셜라이저 에이전트에게 개발 서버를 실행할 수 있는 ⁠init.sh⁠ 스크립트를 작성하게 하고, 새 기능을 구현하기 전에 기본적인 엔드 투 엔드 테스트를 수행하게 하는 것이 도움이 됩니다.

claude.ai 클론의 경우, 이는 에이전트가 항상 로컬 개발 서버를 시작하고 Puppeteer MCP를 사용해 새 채팅을 시작하고, 메시지를 보내고, 응답을 받는다는 의미였습니다. 이를 통해 Claude는 앱이 깨진 상태로 방치되었는지 빠르게 식별하고, 존재하는 버그를 즉시 수정할 수 있었습니다. 만약 에이전트가 대신 새로운 기능 구현을 시작했다면, 문제를 악화시켰을 가능성이 큽니다.

이 모든 것을 고려하면, 전형적인 세션은 다음과 같은 어시스턴트 메시지로 시작합니다:

[Assistant] 프로젝트의 현재 상태를 파악하고 이해하는 것부터 시작하겠습니다.
[Tool Use] <bash - pwd>
[Tool Use] <read - claude-progress.txt>
[Tool Use] <read - feature_list.json>
[Assistant] 최근 작업을 확인하기 위해 git 로그를 살펴보겠습니다.
[Tool Use] <bash - git log –oneline -20>
[Assistant] 서버를 재시작할 init.sh 스크립트가 있는지 확인해 보겠습니다.
<개발 서버를 시작함>
[Assistant] 훌륭합니다! 이제 애플리케이션으로 이동해 몇 가지 기본적인 기능이 여전히 작동하는지 확인하겠습니다.
<기본 기능을 테스트함>
[Assistant] 검증 테스트를 기반으로 볼 때, 기본 기능은 잘 작동하고 있습니다. 코어 채팅 기능, 테마 전환, 대화 로딩, 에러 처리 모두 정상입니다. 이제 tests.json 파일을 더 면밀히 검토하여 다음에 구현해야 할 항목을 파악하겠습니다.
<새로운 기능 작업을 시작함>

에이전트 실패 모드와 해결책

문제이니셜라이저 에이전트 동작코딩 에이전트 동작
Claude가 프로젝트 전체를 너무 일찍 완료로 선언함피처 목록 파일 설정: 입력 명세를 바탕으로 엔드 투 엔드 피처 설명이 포함된 구조화된 JSON 파일을 설정세션 시작 시 피처 목록 파일을 읽고, 작업할 단일 피처를 선택
Claude가 버그가 있거나 문서화되지 않은 상태로 환경을 남김최초 git 저장소와 진행 노트 파일 작성세션을 진행 노트와 git 커밋 로그 읽기부터 시작하고, 개발 서버에서 기본 테스트를 실행해 문서화되지 않은 버그를 포착. 세션 종료 시 git 커밋과 진행 업데이트 작성
Claude가 기능을 너무 일찍 완료로 표시함피처 목록 파일 설정모든 기능을 자체 검증. 충분한 테스트 이후에만 “pass”로 표시
Claude가 앱 실행 방법 파악에 시간을 소모함개발 서버를 실행할 수 있는 init.sh 스크립트 작성세션 시작 시 init.sh 읽기

장시간 실행되는 AI 에이전트에서 흔한 네 가지 실패 모드와 해결책을 요약합니다.

향후 과제

이 연구는 여러 컨텍스트 윈도우에 걸쳐 점진적 진전을 가능하게 하는 장시간 에이전트 하니스에서의 한 가지 가능한 해결책을 보여줍니다. 그러나 여전히 열린 질문들이 존재합니다.

가장 주목할 점은, 단일 범용 코딩 에이전트가 다양한 컨텍스트에서 최상의 성능을 내는지, 아니면 멀티 에이전트 아키텍처를 통해 더 나은 성능을 달성할 수 있는지가 아직 명확하지 않다는 것입니다. 예컨대 테스팅 에이전트, 품질 보증 에이전트, 코드 정리 에이전트 같은 특화된 에이전트가 소프트웨어 개발 라이프사이클 전반의 서브 태스크에서 더 뛰어난 성과를 낼 수 있다는 점은 합리적으로 보입니다.

또한, 이 데모는 풀스택 웹 앱 개발에 최적화되어 있습니다. 향후 방향은 이러한 발견을 다른 분야로 일반화하는 것입니다. 예를 들어, 과학 연구나 금융 모델링 같이 장시간의 에이전틱 작업이 요구되는 분야에도, 이러한 교훈의 일부 또는 전부를 적용할 수 있을 가능성이 큽니다.

Footnotes

  1. 여기서 우리는 초기 사용자 프롬프트가 다르기 때문에 이를 별개의 에이전트로 지칭합니다. 시스템 프롬프트, 도구 세트, 전체 에이전트 하니스는 그 외에는 동일했습니다.

Edit this page

On this Page