나는 AI 에이전트의 예산을 도서관처럼 관리한다 — 페이지, 책, 그리고 서가
요약
자율 에이전트 운영 시 발생하는 비용 관리 문제를 해결하기 위해, 직관적이지 않은 토큰 단위 대신 '페이지, 권, 서가'와 같은 독서 어휘를 활용한 예산 관리 체계를 제안합니다. 이를 통해 에이전트의 실행 비용을 인간이 이해하기 쉬운 단위로 설정하고 통제할 수 있습니다.
핵심 포인트
- 토큰 단위는 인간이 직관적으로 비용을 가늠하기 어려움
- 페이지(1k), 권(200p), 서가(20권) 단위의 새로운 예산 체계 도입
- 읽기 쉬운 예산 단위는 팀 간의 의사결정과 조정을 용이하게 함
- 에이전트 루프에 시간 및 토큰 기반의 강제적 상한선 설정 필요
자율 에이전트(autonomous agents)에 대해 내가 가졌던 가장 큰 두려움은 "이게 작동할까"가 아니었다.
그것은 바로 자리를 비우는 것이었다. 에이전트에게 목표를 부여하면, 그것은 루프(loop)를 돌기 시작한다 — 탐색(browse), 추출(extract), 저장(save), 판단(judge), 반복(repeat) — 그리고 노트북을 닫는 순간, 한 가지 질문이 머릿속을 괴롭히기 시작한다: 지금 이게 비용이 얼마나 들고 있는 거지?
나는 밤새 놀고 난 뒤 스마트폰을 확인하는 것처럼, 아침 7시에 API 대시보드를 확인하곤 했다. 초조하게 말이다.
해결책은 지루하게 들릴 것이다: 루프에 예산(budget)을 부여하는 것이다. 하지만 내가 실제로 그렇게 시도했을 때, 예상치 못한 문제에 부딪혔다. 그것은 기술적인 문제가 아니었다.
"이번 실행에는 600,000 토큰이 할당됩니다"라는 말은 아무런 의미가 없다
토큰(Tokens)은 LLM 지출의 자연스러운 단위이지만, 인간에게는 형편없는 단위이다. 빠르게 생각해 보자: 연구 작업에 600,000 토큰은 많은 양인가? 50,000 토큰은 인색한 편인가? 만약 동료가 "야간 작업의 한도를 200만 토큰으로 설정했어요"라고 말한다면, 당신은 이해해서 고개를 끄덕이는가, 아니면 그냥 고개를 끄덕이는 게 더 편해서 그러는가?
그 누구도 가공되지 않은 토큰 수에 대한 직관을 가지고 있지 않다. 이는 토큰 예산이 제대로 설정되지 않거나, 한 번 잘못 설정된 채 다시는 수정되지 않는다는 것을 의미한다.
rysh (에이전트 기반 터미널 멀티플렉서 — 모든 창이 셸(shell), 에이전트, 또는 채팅이 될 수 있음)를 구축하면서, 나는 에이전트 예산에 독서에서 빌려온 어휘를 부여하게 되었다:
- 1 페이지(page) = 1,000 토큰 — 솔직히 밀도 높은 텍스트 한 페이지 정도의 양이다.
- 1 권(book) = 200 페이지 (200k 토큰)
- 1 서가(shelf) = 20 권 (4M 토큰)
따라서 한 번의 실행에는 --budget-size 20p — 즉, 20 페이지가 할당된다. 나의 Instagram 탐색 자동화에는 세션당 3b — 즉, 3권이 할당된다. 본격적인 야간 작업에는 서가 하나가 할당될 수도 있다.
이 단위들은 강제성보다 대화의 방식을 더 많이 바꾸어 놓았다. "이번 실행에는 책 세 권이 할당됩니다"는 기획 회의에서 소리 내어 말할 수 있는 문장이며, 회의실에 있는 모든 사람이 동일한 대략적인 그림을 갖게 한다. 반면 "이번 실행에는 600,000 토큰이 할당됩니다"는 설정 파일에 붙여넣고 잊어버리는 숫자일 뿐이다. 읽기 쉬운 예산은 설정되고, 논의되며, 조정된다. 읽기 어려운 예산은 방치되어 썩어간다.
(그리고 맞다 — 상한선은 권고 사항이 아니라 강제 사항이다. 루프는 그 한도를 초과하여 지출할 수 없다.)
예산이 설정된 루프의 구조
rysh에서 자동화(automation)는 YAML 프론트매터(frontmatter)가 포함된 마크다운(markdown) 파일이며, .rysh/automations/ 아래에 저장됩니다. 따라서 전체 루프(loop)는 서비스하는 코드와 함께 git 내에 존재합니다. 제가 실제로 실행하는 실제 사례의 (축약된) 레시피는 다음과 같습니다. 이 루프는 특정 쇼를 위해 인스타그램에서 팟캐스트 게스트 후보를 탐색(scout)하며, 발견(discovery) 단계만 수행하고, 최종 후보 목록 파일을 저장합니다.
loop:
do: # 내부 루프 — 하나의 작업 세션
interval: 30
...
두 개의 루프, 두 개의 예산:
do는 하나의 작업 세션입니다. 이는 자체적인 토큰 상한선(3권의 책) 및 자체적인 실제 시간 제한(7분)을 가집니다. 둘 중 먼저 도달하는 제한이 적용됩니다.while은 전체 작업(job)을 감쌉니다. 이 예산(15권의 책)은 모든 세션에 걸쳐 해당 작업이 지출할 수 있는 모든 비용의 경계를 설정합니다. 목표가 달성되지 않더라도, 작업이 시작되기 전에 총 비용의 최악의 경우(worst case)를 알 수 있습니다.
마지막 문장이 핵심입니다. 리뷰 시점에 diff를 통해 "오늘 밤 이 작업에 비용이 얼마나 들 것인가?"라는 질문에 답할 수 있습니다.
인계 단계(The takeover leg) — 100%에서 멈추는 것 또한 실패이기 때문에
예산이 설정된 루프는 보통 다음 두 가지 기본 방식 중 하나로 실패합니다:
- 예산 없음 → 청구서가 당신을 놀라게 합니다.
- 강제 차단(hard cutoff) → 실행 도중 사고가 멈추고(mid-thought), 진행 중이던 작업이 유실됩니다.
둘 다 나쁜 상황이며, 두 번째 상황은 팀들이 은연중에 예산을 제거하도록 유도하여 결국 첫 번째 상황으로 되돌아가게 만듭니다.
따라서 예산에는 watch가 있습니다. takeover_when: 90은 다음과 같은 의미입니다: 상한선의 90%가 소진되면, 작업 자체의 프롬프트(prompt)가 제어권을 내려놓고 takeover_prompt가 제어권을 넘겨받습니다. 이때 남은 10%가 해당 프롬프트의 예산이 됩니다. 이 프롬프트의 임무는 진전을 만드는 것이 아닙니다. 임무는 비행기를 착륙시키는 것입니다: 존재하는 것을 저장하고, PARTIAL로 라벨을 붙이며, 누락된 것을 기록하고, 깔끔하게 종료하는 것입니다.
실행은 항상 저장되고 라벨이 붙은 출력물로 끝납니다. 절대 벽(wall)에 부딪히며 끝나지 않습니다.
재설정 및 재개 — 루프는 설계상 중단 가능합니다
do 세션이 종료되면 (목표에 근접하거나, 예산이 소진되었거나, 시간이 만료된 경우), LLM 심판(judge)이 파일에 기록되어 다른 모든 것과 마찬가지로 코드 리뷰를 통해 검토 가능한 중단 조건인 until: 텍스트와 대조하여 _저장된 출력물(saved output)_을 읽습니다.
- 목표 달성 (Goal met) → 루프가 종료됩니다.
- 미달성 (Not yet) → 내부 예산이 다시 새로운 3권으로 **재설정(resets)**되며, 다음 세션이 시작됩니다. 이때 마지막 세션이 저장한 최종 후보 목록을 시드(seed)로 사용합니다 (이것이
iterate_with프롬프트입니다). 이는 대화 기록(transcript)이 아니라 작업(work)을 재개하는 것입니다. 각 패스(pass)는 깨끗한 컨텍스트와 _아티팩트(artifact)_로 시작하며, 이는 200k 토큰의 히스토리를 계속 끌고 가는 것보다 비용이 저렴하고 노이즈가 적습니다.
또한 세션이 상태를 체크포인트(checkpoint)로 저장하기 때문에, 전체 과정을 중단할 수 있습니다:
##auto web stop scout # 일시 정지
##auto web continue scout # 마지막 체크포인트에서 재개, 예산 재장전
stop은 종료(kill)가 아닙니다. continue는 재시작(restart)이 아닙니다. 루프는 새로운 세션 예산을 가지고 중단된 지점부터 다시 시작합니다. 그런 다음 스케줄을 예약하고 잠자리에 들면 됩니다:
##cron add nightly-scout "0 7 * * *" ##auto web run --headless scout
내가 고수할 설계 결정 (그리고 확신이 덜 드는 부분)
가공되지 않은 토큰(raw tokens) 대신 인간 중심의 단위 사용. 위에서 다루었지만, 이것은 내가 끝까지 고수할 원칙입니다. 아무도 논리적으로 판단할 수 없는 예산은 아무도 관리하지 않는 예산입니다.
"정체 시 탐지" 대신 퍼센트 기반의 권한 인수(takeover). takeover_when은 자연어 술어가 아니라 숫자(10–99)입니다. "에이전트가 정체되었다"를 신뢰성 있게 탐지하는 것은 연구 과제이지만, "예산의 90%가 소진되었다"는 사실입니다. 평이한 언어로 된 가드레일("로그인 벽이 나타나면 중단")은 에이전트가 단계별로 적용하는 레시피 프롬프트 자체에 존재합니다.
대화 기록 재생(transcript replay) 대신 아티팩트 시드 재개(artifact-seeded resume). 저장된 파일로부터 재시작하면 각 패스의 비용을 저렴하게 유지할 수 있으며, 자동화 시스템이 "자신의 출력물"이 실제로 무엇인지 정의하도록 강제합니다. 이는 결과적으로 매우 훌륭한 규율(discipline)이 됩니다.
내가 덜 확신하는 부분: 판사(judge)입니다. until: 조건을 평가하는 LLM은 반복 횟수를 세는 것보다 훨씬 뛰어나지만, 여전히 LLM이 당신의 기준을 읽는 것이기에 — 모호한 목표는 모호한 판결을 가져옵니다. 명확한 until:을 작성하는 것이 기술입니다. 저의 경우, "중복 없는 강력한 후보 12명, 각 후보별 연락처 포함"이라는 문구가 편법(gameable)으로 이용되지 않게 만들기까지 세 번의 수정을 거쳤습니다.
솔직한 푸터 (Honest footer)
rysh는 저의 제품입니다. 현재 프라이빗 베타(private beta) 단계이며, Claude를 기반으로 구축되었습니다 (본인의 Anthropic 키를 사용하세요). 셀프 호스팅(self-hostable)이 가능합니다 — 즉, 당신의 자동화 프로세스는 제 데이터베이스의 행(row)이 아니라 당신의 리포지토리(repo)에 있는 파일로 존재합니다. 테이크오버(takeover)와 터널링(tunneling) 메커니즘을 나란히 비교하며 더 자세히 설명한 글은 여기에 있습니다: agents on a leash
만약 루프(loop) 내에서 에이전트를 실행하고 있으며, 초기 단계에서 이를 직접 테스트해보고 싶다면, 저희는 디자인 파트너(design partners)를 모집 중입니다: rysh.ai/design-partner — 혹은 페이지/책/서가(pages/books/shelves)라는 추상화(abstraction)가 왜 틀렸는지 저에게 알려주세요. 저도 전에는 틀린 적이 있었습니다; 그것이 바로 테이크오버(takeover) 단계가 존재하는 이유입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기