에이전트 루프를 5분 동안 휴면(sleep)시키지 마세요
요약
에이전트 루프 설계 시 Anthropic의 프롬프트 캐시 유지 시간(약 5분)을 고려하지 않으면 불필요한 비용이 발생합니다. 캐시가 만료되는 경계 시간인 5분 근처의 휴면 시간은 비용 효율성을 최악으로 만드는 '데드 존'이 됩니다.
핵심 포인트
- Anthropic 프롬프트 캐시는 약 5분간 컨텍스트를 유지함
- 5분 근처의 휴면은 캐시 미스 비용과 짧은 대기 시간의 단점을 모두 가짐
- 캐시를 유지하려면 5분 미만으로 짧게 휴면하거나, 아예 길게 휴면해야 함
- 루프 설계 시 캐시 윈도우를 기준으로 전략적 휴면 시간 설정 필요
저는 몇 분마다 깨어나 장기 실행 중인 작업을 확인하는 에이전트(agent)를 출시했습니다.
첫 시도에 바로 작동했습니다. 하지만 제 청구서가 이해되지 않았습니다.
루프(Loop) 로직은 정확했습니다. 모델(Model) 선택도 괜찮았습니다. 비용은 제가 전혀 생각지도 못한 곳, 즉 두 턴(turn) 사이의 간극, 즉 휴면(sleep) 상태에 숨어 있었습니다.
여기에 아무도 제품 상자에 인쇄하지 않는 부분이 있습니다. 당신의 에이전트 유휴 타이머(idle timer)는 프롬프트 캐시(prompt cache)와 상호작용하며, 대부분의 루프는 마치 그렇지 않은 것처럼 작성됩니다.
당신의 휴면은 캐시와 대화합니다
루프 내의 에이전트가 깨어날 때마다, 무언가를 하기 전에 전체 컨텍스트(context)를 다시 읽습니다.
Anthropic의 프롬프트 캐시(prompt cache)는 마지막 사용 후 약 5분 동안 해당 컨텍스트를 유지합니다. 이 시간 범위 내에서는 다음 턴이 캐시된 컨텍스트를 읽습니다. 저렴하고 빠릅니다. 이 시간이 지나면 캐시는 차가워지고(cold), 다음 턴은 처음부터 모든 것을 다시 읽기 위해 전체 비용을 지불해야 합니다.
따라서 휴면(sleep) 길이는 간단하게 말해 당신의 비용을 제어합니다.
4분 동안 낮잠을 자면 캐시를 따뜻하게(warm) 유지하여 재개 비용이 거의 들지 않습니다. 6분 동안 낮잠을 자면 그 따뜻한 컨텍스트를 버리고 매 사이클마다 영원히 처음부터 다시 구축해야 합니다.
대부분의 루프는 감에 의존해 휴면 시간을 정합니다. 5분은 깔끔해 보입니다. 10분은 안전해 보입니다. 아무도 실제로 비용을 청구하고 있는 단 하나의 시계와 그 숫자를 대조해 보지 않습니다.
5분은 최악의 선택입니다
제가 고수할 의견은 다음과 같습니다. 루프를 정확히 5분 동안 휴면시키는 것은 가능한 선택지 중 단연 최악의 선택입니다.
당신이 무엇을 구매하게 되는지 살펴보십시오. 약 4분 30초 동안 낮잠을 자면 시간 범위 안에 들어오게 됩니다. 재개(Resume)는 따뜻하며(warm), 비용이 거의 들지 않습니다. 20분 동안 낮잠을 자면, 네, 차가운 캐시(cold cache)를 감수해야 하지만, 그 한 번의 손실로 20분이라는 실제 아무것도 하지 않는 시간을 벌었습니다. 페널티가 길고 진정으로 유휴 상태인 대기 시간 동안 얇게 분산됩니다.
이제 정확히 5분 동안 낮잠을 잔다고 가정해 봅시다. 당신은 바로 경계선에 앉아 있습니다. 당신은 전체 차가운 캐시(cold-cache) 페널티를 지불하면서, 동시에 다음 턴이 실행되기 전까지 단 5분만을 벌게 됩니다. 비싼 옵션이며, 보상은 짧습니다.
매 사이클마다, 최악의 두 가지 상황을 모두 겪게 되는 것입니다.
딱 떨어지는 숫자(Round numbers)가 함정입니다. 5분은 인간의 단위이며, 시계 위의 깔끔한 눈금입니다. 캐시 로직(Cache logic)은 그것이 깔끔해 보이는지에는 전혀 관심이 없습니다.
캐시 윈도우(cache windows) 관점에서 생각하기
이러한 관점의 전환이 제 루프(loops)를 고쳤습니다.
두 가지 정직한 체제(regimes)가 있고, 그 사이에는 데드 존(dead zone)이 존재합니다.
- 윈도우 미만(Under the window): 캐시를 따뜻하게(warm) 유지하는 짧은 낮잠입니다. 변화 시점을 알려줄 수 없는 빠르게 움직이는 무언가를 지켜보고 있을 때, 즉 CI 실행, 배포(deploy), 원격 큐(remote queue) 상황 등입니다.
- 윈도우를 훨씬 초과(Well past the window): 실제 대기 시간 동안 한 번의 콜드 리드(cold read)를 분산시키는 긴 낮잠입니다. 더 빨리 확인할 필요가 전혀 없는 상황입니다.
- 데드 존(Dead zone): 5분 선 근처에 머무는 그 어떤 것이든 해당합니다. 대기 시간의 이득은 얻지 못한 채 캐시 미스(miss) 비용만 지불하게 됩니다.
이런 방식으로 바라보면 질문의 형태가 바뀝니다. "얼마나 오래 자야 할까"가 아니라 "내가 실제로 무엇을 기다리고 있는가"로 변합니다.
숫자를 정하기 전 세 가지 질문
타이머 코드는 의도적으로 공개하지 않겠습니다. 중요한 것은 어떤 숫자를 선택하기 전에 세 가지 질문을 던지는 습관입니다.
첫째. 시스템이 대신 나에게 알림(notify)을 줄 수 있는가? 내가 기다리는 작업이 상태가 변했을 때 루프 자체를 깨울 수 있다면, 폴링(polling)을 아예 하지 말아야 합니다. 타이머는 다른 어떤 것도 변화를 알려줄 수 없을 때에만 찾는 최후의 수단입니다.
둘째. 내가 지켜보는 대상이 실제로 얼마나 빨리 변하는가? 8분 만에 끝나는 빌드(build)는 60초마다 확인할 필요가 없습니다. 그렇게 자주 폴링하면 빌드가 끝나기도 전에 캐시를 8번이나 태워버리게 됩니다. 비용은 훨씬 적게 들면서, 인내심 있는 두 번의 확인이 불안해하며 수행하는 여덟 번의 확인보다 낫습니다.
셋째. 오래 기다려야 한다면, 그것을 확정(committing)했는가? 긴 휴면(sleep)은 의도적으로 유휴(idle) 상태가 되겠다는 결정입니다. 윈도우 근처의 숫자로 어설프게 결정하면, 절약은 얻지 못한 채 기다림의 페널티만 받게 됩니다. 다시 말하지만, 최악의 상황이 겹치는 것입니다.
따라서 이 모든 습관은 한 호흡에 정리됩니다. 가능하다면 알림을 받으세요. 확인 주기(check rate)를 대상이 움직이는 속도에 맞추세요. 기다려야 한다면, 콜드 캐시(cold cache) 비용이 아깝지 않을 만큼 충분히 길게 기다리세요.
깔끔한 숫자를 버렸을 때 변한 것
제 루프는 느려지지 않으면서도 더 저렴해졌습니다.
그 이유는 확인하기 전까지 저를 놀라게 했습니다. 느려짐(Slowness)은 턴(turn) 사이의 간극, 즉 작업(work)이 아닌 시계(clock)에 맞춰 설정된 일정에 따라 버려지는 따뜻한 컨텍스트(warm context) 속에 존재했습니다.
더 깊은 교훈이 더 강렬하게 남았습니다. 대부분의 에이전트 비용은 프롬프트(prompt)나 선택한 모델(model)에 들어있지 않습니다. 비용은 우리가 배관(plumbing) 정도로 치부하며 측정조차 하지 않는, 턴 사이의 이음새(seams)에 숨어 있습니다. 캐시 타이밍(Cache timing)이 바로 그러한 이음새 중 하나입니다. 다른 이음새들도 존재하며, 그것들은 모두 동일한 조치를 취했을 때 보상을 줍니다.
비용을 발생시키는 것을 측정하세요. 그저 깔끔해 보이는 것은 무시하세요.
여러분의 차례
여러분의 에이전트 루프(agent loop)는 얼마 동안 휴면(sleep)하나요? 그리고 그 수치를 작업(work)을 위해 선택했나요, 아니면 시계(clock)를 위해 선택했나요?
이 내용이 유용했다면
저는 성공과 정체(freezes)를 모두 포함하여 이 과정을 공개적으로 진행하고 있으며, 주로 LinkedIn과 YouTube에서 활동합니다. 공개적으로 빌드(building in the open)하는 실제 과정이 여러분에게 유용하다면, 그곳에서 확인하실 수 있습니다. X, GitHub에서 저를 찾으실 수 있으며, 작업물은 next8n.com에서 보실 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기