본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 05. 20:23

Token Budgets 논문: Affine-Typed 예산 소유권

요약

Token Budgets 논문은 멀티 에이전트 환경에서 발생하는 비용 초과 문제를 해결하기 위해 Affine-typed 리소스 모델링을 제안합니다. Rust 크레이트를 통해 토큰 예산을 컴파일 타임에 추적함으로써, 런타임 에러 대신 정적 소유권 개념으로 예산 초과를 방지합니다.

핵심 포인트

  • 멀티 에이전트 위임 시 발생하는 비용 초과 문제 분석
  • Affine typing을 통한 컴파일 타임 예산 검증
  • 런타임 가드 대비 안전한 예산 관리 방식 제안
  • Rust 기반의 토큰 예산 추적 크레이트 제공

무엇인가: Token Budgets 논문은 63건의 실제 LLM 에이전트 비용 초과 사례를 분류하고, 토큰/비용 예산을 컴파일러가 추적하는 affine-typed (최대 한 번만 사용 가능) 리소스로 모델링하는 Rust 크레이트(crate)를 제공합니다.

이유: 비용은 프로덕션 환경에서의 실패 모드이며, 논문은 비용 초과를 유발하는 원인이 단일 에이전트가 아닌 멀티 에이전트 위임 (multi-agent delegation) 임을 발견했습니다. 즉, 작업을 병렬 서브 에이전트들에게 분산(fan out)할 때, 각 에이전트가 아무도 차감하지 않는 상한선에 대해 조용히 예산을 예약해 버리는 것이 문제입니다.

기존 방식 대비: 토큰이 이미 사용된 후 지출 시점에 실행되는 assert와 같은 런타임 예산 가드 (runtime budget guard) 와 달리, affine typing은 예산 초과를 컴파일 타임 (compile-time) 에러로 만듭니다. 따라서 안전하지 않은 코드 경로가 애초에 배포될 수 없습니다.

다음과 같이 생각해보세요

식사 자리에서 그룹이 나누어 쓰는 하나의 선불 기프트 카드와 같습니다.

                  1,000달러짜리 기프트 카드 하나
                          │
          ┌───────────────┴───────────────┐
...
  • 토큰 예산 (token budget) = 카드의 잔액 ($1,000)
  • 서브 에이전트 (sub-agent) = 돈을 쓰고 싶어 하는 친구
  • 정적 예약 (static reservation) = 모두가 카드를 복사하여 전체 잔액이 그대로 있다고 가정함
  • 초과 지출 (overshoot) = 네 명의 복사본이 각각 $350를 사용함 — $1,000 카드에서 청구액이 $1,400에 달함
  • affine 소유권 (affine ownership) = 카드를 선불 서브 카드로 나눔 — 돈이 이동하며, 복사할 수 없음

빠른 용어 정리

토큰 / 비용 예산 (Token / cost budget) — 하나의 에이전트 작업이 사용할 수 있는 토큰(따라서 달러)의 엄격한 상한선입니다. 프로덕션 에이전트가 가장 먼저 고려해야 할 사항은 바로 이 토큰이 어디로 가느냐 하는 것입니다.

Affine 타입 (Affine type)최대 한 번만 사용될 수 있는 타입입니다. 컴파일러가 값의 소유권(ownership)을 추적하므로, 값을 이동(move) 하거나 분할(split) 할 수는 있지만 절대 복사(copy) 할 수는 없습니다. 이는 예산에 정확히 필요한 속성입니다.

위임 팬아웃 (Delegation fan-out) — 오케스트레이터(orchestrator)가 작업을 병렬로 실행되는 여러 서브 에이전트에게 전달할 때 발생합니다. 각 자식 에이전트는 일정량의 예산이 필요하며, 문제는 누가 공유된 총액을 정직하게 유지하느냐 하는 것입니다.

정적 vs 적응형 예약 (Static vs adaptive reservation) — 정적 예약 (Static reservation)은 처음에 고정된 할당량을 가져가며 4~6배를 초과 할당 (over-provisions) 합니다. 반면 적응형 예약 (adaptive reservation)은 호출마다 재추정하며 2.11배를 초과 할당합니다. 낭비되는 토큰은 더 적지만, 여전히 런타임 (runtime) 상의 회계적 트릭에 불과합니다.

컴파일 타임 vs 런타임 체크 (Compile-time vs runtime check) — 런타임 체크는 에이전트가 실행되는 동안 예산을 테스트합니다 (이미 소비된 후에는 되돌릴 수 없습니다). 컴파일 타임 체크는 프로그램이 실행되기도 전에 안전하지 않은 프로그램을 거부합니다. 어파인 타입 (Affine typing)은 이 상한선 설정을 두 번째 범주로 이동시킵니다.

코헨 카파 (Cohen's kappa) — 평가자 간 일치도 점수 (1.0 = 완벽). 이 논문의 8개 카테고리 실패 분류 체계(failure taxonomy)는 0.837에 도달했습니다. 즉, 두 명의 독립적인 검토자가 사건들을 거의 동일하게 분류했다는 의미입니다.

뉴스. 2026년 6월 2일, Token Budgets 논문이 발표되었습니다. 이 논문은 2023년부터 2026년까지의 21개 오케스트레이션 (orchestration) 프레임워크를 검토하여 추출한, LLM 에이전트 시스템에서의 **63가지 운영 비용 초과 사례 (production cost-overrun incidents)**를 정리한 실증적 카탈로그입니다. 이 사례들은 8개 카테고리의 실패 분류 체계로 클러스터링되었습니다 (평가자 간 코헨 카파 0.837). 완화책으로서 저자들은 어파인 타입 소유권 (affine-type ownership)을 사용하여 예산 위반을 컴파일 타임 에러 (compile-time errors)로 전환하는 1,180라인 규모의 Rust 크레이트 (crate)를 출시했습니다. 통제된 테스트에서 단일 에이전트 실행은 예산을 초과하지 않았으나 (0/30), 멀티 에이전트 asyncio 위임 (asyncio delegation)은 매번 예산을 초과했습니다 (30/30). 이후 완화책을 적용한 실행은 160개의 라이브 API 테스트 전반에 걸쳐 상한선 위반이 0건으로 기록되었습니다. 논문 읽기 →

단체 저녁 식사 장면을 상상해 보세요. 1,000달러가 충전된 기프트 카드 한 장이 있고, 음식을 주문하려는 친구 네 명이 있습니다. 저렴하고 게으른 방식은 모두가 카드를 복사하여 각자 전체 잔액을 가지고 있다고 가정하는 것입니다. 즉, 네 개의 복사본이 생기고 네 명의 사람이 각각 즐겁게 350달러씩 사용하면, 원래 1,000달러만 들어있던 카드에 대해 1,400달러의 청구서가 날아오게 됩니다. 사람들이 돈을 쓸 때 카드가 _차감(debited)_되지 않았기 때문에, 청구서가 나오기 전까지는 초과 지출을 막을 수 있는 것이 아무것도 없었습니다. **Affine-typed 예산 소유권 (Affine-typed budget ownership)**은 이와 정반대의 규칙입니다. 카드는 정확히 단 한 장만 존재하며, 유일하게 허용되는 합법적인 작업은 이를 선불 하위 카드(sub-cards)로 나누는 것뿐입니다. 즉, 돈은 물리적으로 원본 카드에서 빠져나가야 하며, 단순히 복사본을 만드는 것은 허용되지 않습니다.

에이전트 시스템(agent system)에서 이 "복사" 버그는 위임 팬아웃(delegation fan-out) 현상으로 나타납니다. 오케스트레이터(orchestrator)가 병렬적인 하위 에이전트(sub-agents)들을 생성하면, 각 에이전트는 단일 소유자가 차감하지 않는 상한선(cap)을 기준으로 토큰 예산의 일부를 예약합니다. 이 논문의 핵심 수치는 이러한 패턴이 30번의 실행 중 30번 모두에서 예산을 초과한 반면, 하나의 실행 총계(running total)를 기준으로 사용하는 단일 에이전트는 30번 중 0번의 초과도 발생하지 않았다는 것입니다. 해결책은 예산을 어파인 (affine) 값으로 만드는 것입니다. Rust 컴파일러는 이를 '최대 한 번만 사용(use-at-most-once)'되는 것으로 추적하므로, 두 하위 에이전트가 동일한 예산을 동시에 보유할 수 있는 코드 경로는 타입 체크(type-check)에 실패하게 됩니다. 상한선은 토큰이 이미 다 써버린 후에 발생하는 assert에 의해 강제되는 것이 아니라, 구조적으로 (by construction) 강제됩니다. 이는 조용히 재청구되는 재시도 루프(retry loop)와 아예 실행조차 불가능한 루프를 구분 짓는, 런타임(runtime)에서 컴파일 타임(compile-time)으로의 전환과 동일한 원리입니다.

예산이 실제로 가는 곳

간단한 계산을 통한 과정 살펴보기 (예시용 상한선 및 슬라이스 크기이며, 초과 및 과다 예약 횟수는 논문의 수치를 따름). 공유 상한선(shared cap)이 1,000 토큰이고 오케스트레이터(orchestrator)가 4개의 하위 에이전트(sub-agents)로 팬아웃(fan-out)한다고 가정해 봅시다. 정적 예약(static reservation) 방식에서는 각 자식 에이전트가 350개씩 고정적으로 가져가며, 예약이 사실상 복사본이기 때문에 총 청구량은 4 × 350 = 1,400이 됩니다. 이는 지출이 발생하기 전까지는 아무도 거부하지 않는 **400 토큰(40%)의 초과(overshoot)**를 발생시킵니다. 예산을 아핀(affine) 방식으로 설정하면 동일한 1,000 토큰이 소유된 슬라이스(owned slices)로 나뉩니다. 예를 들어 300 + 220 + 260 + 220 = 1,000과 같이 나누어지며, 이 경우 네 번째 청구는 앞선 세 개가 남긴 것만 가져갈 수 있습니다. 합계는 구조적으로 상한선 내로 제한되며, 이는 해당 논문의 Rust 크레이트(crate)가 강제하는 속성입니다. 이 크레이트는 160개의 라이브 API 테스트를 통해 상한선 위반 0건을 기록했으며, 경계가 없는 멀티 에이전트 위임(multi-agent delegation)은 30번의 실행 모두에서 초과가 발생했습니다. 정적 예약 방식이 필요한 예산의 4~6배를 가져가는 습관(적응형 트리밍(adaptive trims)을 적용해도 2.11배)은 반대 측면에서 보았을 때 동일한 낭비입니다.

방식상한선 체크 시점멀티 에이전트 초과과다 예약 (Over-reservation)
런타임 예산 가드 (Runtime budget guard)지출 시점 — 토큰이 커밋된 후가능 (기본적인 실패 사례)
...

문제는 이것이 타입 시스템(type system)에서 소유권(ownership)을 표현할 수 있는 곳에서만 안전성을 보장한다는 점입니다. Rust 크레이트는 이를 무료로 얻지만, asyncio.gather를 기반으로 구축된 Python 오케스트레이터는 그렇지 못하며, 이것이 바로 논문에서 언급된 30/30 초과가 발생한 정확한 지점입니다. 하지만 이 교훈은 언어를 넘어 일반화됩니다. 멀티 에이전트 팀에서 예산은 공유 자원이며, _누가 이를 보유할 수 있는지, 그리고 그것을 복사할 수 있는지_는 설계 결정 사항이지, 청구서가 도착했을 때 발견하게 되는 것이 아닙니다.

더 자세한 내용: Agent Engineering → Cost & Latency Engineering → Where the tokens go

관련 설명 (Related explainers)

  • StreamMA — Streaming inter-agent reasoning — 또 다른 형태의 멀티 에이전트 (multi-agent) 비용 문제: 토큰을 제한하는 대신 파이프라이닝 (pipelining)을 통해 직렬 핸드오프 (serial handoffs)로 인한 실제 시간 (wall-clock) 지연 시간을 줄임
  • Maestro — RL orchestrator over frozen experts — 이러한 팬아웃 (fan-out) 예산 문제가 발생하는 서브 에이전트 상위의 오케스트레이터 (orchestrator-over-sub-agents) 토폴로지 (topology)
  • EFC — feedback-quality scaling law — 에이전트 하네스 (agent-harness)의 성공을 실제로 예측하는 요소이자, "예산을 잘 사용하는 것"의 나머지 절반

FAQ

Affine-typed 예산 소유권이란 무엇인가요?

이는 에이전트의 토큰 또는 비용 예산을 affine-typed 값으로 모델링하는 것을 의미합니다. 이는 컴파일러가 최대 한 번만 사용할 수 있도록 허용하는 값입니다. 예산을 더 작은 소유 슬라이스 (owned slices)로 나누거나 서브 에이전트 (sub-agent)로 이동할 수는 있지만, 복사할 수는 없습니다. 따라서 시스템의 두 부분이 동일한 한도 (cap)를 동시에 사용할 수는 없습니다. Token Budgets 논문은 이를 Rust 크레이트 (crate)로 구현하였으며, 160개의 라이브 API 테스트 전반에서 한도 위반 (cap violations)이 0건임을 보고했습니다.

왜 멀티 에이전트 시스템은 토큰 예산을 초과하나요?

위임 (delegation) 과정에서 작업을 병렬 서브 에이전트 (parallel sub-agents)로 팬아웃 (fan-out)하기 때문입니다. 이때 각 에이전트는 단일 소유자가 차감하지 않는 한도를 기준으로 예산을 예약 (reserve)합니다. 이러한 예약은 복사본처럼 동작하므로, 그 합계가 실제 제한을 초과할 수 있습니다. 논문의 통제된 테스트에서, 단일 에이전트(하나의 실행 총액을 기준으로 지출)는 30회 실행 중 초과 사례가 0건이었던 반면, 멀티 에이전트 asyncio 위임은 30회 실행 중 30회 모두 초과했습니다.

컴파일 타임 (compile-time) 예산 체크는 런타임 (runtime) 가드와 어떻게 다른가요?

런타임 가드 (runtime guard, assert 또는 limiter)는 에이전트가 실행되는 동안 예산을 확인하며, 이는 이미 소비된 토큰을 되돌리기에는 너무 늦습니다. 컴파일 타임 체크 (compile-time check)는 프로그램이 실행되기 전에 안전하지 않은 프로그램을 거부합니다. 어파인 타이핑 (affine typing)을 사용하면, 두 개의 서브 에이전트 (sub-agents)가 동일한 예산을 보유할 수 있는 코드 경로는 단순히 타입 체크 (type-check) 단계에서 실패하게 됩니다. 따라서 상한선 (cap)은 가드가 제때 작동하기를 기대하는 방식이 아니라, 구조적으로 (by construction) 강제됩니다.

원문은 Learn AI Visually에 게시되었습니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0