버짓
버짓 (Budget)
단일 실행이 돈, 토큰, 또는 작업 시간 중 무엇을 쓰든 상한을 설정해요.
출처: 문서
본문
개요 (Overview)
버짓은 실행에 상한(ceiling)을 설정해요. 상한을 넘으면 정확히 어떤 한도가 걸렸는지 이름을 밝히는 메시지와 함께 실행이 멈추고, TUI는 실행이 진행되는 동안 소비를 실시간으로 추적해요.
모든 한도는 선택 사항이고 설정되지 않은 한도는 무제한이므로, 돈, 토큰, 시간 중 원하는 조합으로 상한을 둘 수 있어요. 아예 버짓을 선언하지 않으면 실행이 버짓 없이 진행되는데, 이것이 기본값이에요.
선언하는 두 가지 방법이 있고, 그것들은 결합해요:
| Block | Scope |
|---|---|
budget |
모든 에이전트에 적용되는 실행 전체 상한 하나. |
budgets |
에이전트가 이름으로 선택하는 이름 있는 버짓들. |
실행 전체 버짓 (A run-wide budget)
agents:
root:
model: openai/gpt-4o-mini
description: An agent on a short leash.
instruction: You are a helpful assistant.
budget:
max_cost: 0.50
max_tokens: 100000
max_time: 10m
| Field | Type | Description |
|---|---|---|
max_cost |
number | 최대 지출, USD 기준. |
max_tokens |
integer | 최대 누적 입력+출력 토큰. |
max_time |
string | 에이전트가 작업하는 최대 시간, Go duration 형식(10m, 30s, 1h30m). |
이름 있는 버짓 (Named budgets)
최상위 budgets 키 아래에 이름으로 버짓을 정의한 뒤, 각 에이전트가 자신의 budgets 필드에 이름을 나열해 선택(opt in)해요. 필드는 같은 세 가지예요.
budgets:
shell-work:
max_cost: 0.03
max_tokens: 8000
research:
max_time: 1m
agents:
root:
model: openai/gpt-4o-mini
description: Does shell work.
instruction: You are a helpful assistant.
budgets: [shell-work]
researcher:
model: openai/gpt-4o-mini
description: Answers questions.
instruction: You answer questions concisely.
budgets: [shell-work, research]
에이전트는 여러 버짓을 나열할 수 있어요; 모두 적용되고, 첫 번째로 소진된 것이 실행을 멈춰요. 실행 전체 버짓은 어떤 이름 있는 버짓에도 더해져 적용되므로, 실제로 묶는 상한은 먼저 소진되는 쪽이에요.
정의되지 않은 버짓 이름을 참조하면 구성 오류로, 파싱 시점에 잡혀서 에이전트를 조용히 상한 없이 두지 않아요.
이름 하나는 공유 통 하나 (A name is one shared pot)
여러 에이전트가 같은 버짓 이름을 참조하면 각자 사본이 아니라 같은 상한에서 끌어와요. 위에서 root 와 researcher 는 shell-work 를 공유해서, 함께 $0.03 이상을 쓸 수 없어요.
이것은 의도적이며, 버짓이 가질 가치가 있는 바로 그 이유예요. 각 에이전트가 자신만의 수당을 갖는다면, N개의 하위 에이전트로 분산(fan out)하는 것만으로 실행이 max_cost × N 을 쓸 수 있고, 상한은 가장 필요로 하는 워크로드에 정확히 의미가 없어질 거예요.
독립적인 통을 원하면 에이전트에게 서로 다른 버짓 이름을 주세요.
실행 전체 버짓에도 같은 것이 적용돼요: 실행 안의 모든 하위 세션(전송된 작업, 하위 에이전트, 스킬)은 그 하나의 지갑에서 지출해요.
범위: 버짓은 세션에 걸친다 (Scope: a budget spans the session)
지출은 세션의 수명 동안, 보내는 모든 메시지에 걸쳐 누적돼요 — 엔터를 칠 때마다 리셋되지 않아요. 매 메시지마다 다시 쓸 수 있는 max_cost: 0.50 은 전혀 상한이 아니기 때문이에요. 새 세션을 시작하면 새 버짓이 시작돼요. 세션별 상한이지 세션을 가로지르는 평생 할당량이 아니에요.
Note
max_time은 에이전트가 실제로 작업하는 시간 — 턴 지속 시간의 합 — 을 측정하지, 세션이 열린 이후의 벽시계 시간을 측정하지 않아요. 버짓이 세션에 걸치고, 세션이 읽거나 타이핑하는 동안 유휴 상태로 있기 때문에, 벽시계는 커피브레이크 동안 버짓을 만료시킬 수 있어요: TUI를 10분 열어두면 다음 메시지가 에이전트가 아무것도 하기 전에max_time2분을 즉시 트리거할 수 있어요.
실행을 멈추는 것 (What stops a run)
어떤 한도든 — 실행 전체든 이름 있는 것이든 — 넘으면 실행이 멈추고 다음이 생성돼요:
- 한도와 금액을 이름 짓는 트랜스크립트의 어시스턴트 메시지
budget,limit,used,max,config_path를, 그리고stop_message아래에는 어시스턴트 stop 메시지 자체(에이전트 이름, 역할, 콘텐츠, 타임스탬프만)를 운반하는budget_exceeded이벤트- 경고 레벨의 notification 훅
budget_exceeded인 stream end 이유. 그래서 멈춘 실행이 완료된 것과 텔레메트리에서 구분돼요.
메시지는 올릴 정확한 YAML 경로를 이름 짓기 때문에, 여러 버짓 중 어느 것이 걸렸는지 모호함이 없어요:
Execution stopped after reaching the configured budgets.shell-work.max_cost
limit (used $0.0312 of $0.0300).
max_iterations 와 달리 버짓 중지는 종결적이에요 — 계속할 것인지 묻는 프롬프트가 없어요. 버짓은 의도적으로 설정하는 상한이므로, 올리려면 대화상자에 답하는 대신 구성을 편집해야 해요.
평가 출력에서의 버짓 중지 (Budget stops in evaluation output)
버짓이 있는 에이전트를 docker agent eval 로 실행하면 버짓 중지는 구조화된 종결로 기록돼요. 에러가 아니고, 일반적인 스트림 중지와도 구별돼요: 실행 출력 JSON이 해당 세션에서 선택적 eval_result.termination 객체로 노출해요.
"eval_result": {
"passed": true,
"termination": {
"reason": "budget_exceeded",
"budget": "run",
"limit": "max_cost",
"used": "$0.0312",
"max": "$0.0300",
"config_path": "budget.max_cost",
"message": "Execution stopped after reaching the configured budget.max_cost limit (used $0.0312 of $0.0300)."
}
}
reason은 항상budget_exceeded예요. 다른 필드는 선택 사항이며 런타임의budget_exceeded이벤트에서 허용 목록을 통해 복사돼요:budget,limit,used,max,config_path,message만 취하고, 각각 정제된(잘못된 UTF-8과 제어 문자 제거, 길이 제한) 뒤 없거나 사용할 수 없으면 생략돼요.- 저장된 세션(SQLite 데이터베이스와 sessions JSON)은 stop 마커를 시간순 위치에 유지하고, 이벤트에 내장된
stop_message에서 재구성된 어시스턴트 stop 메시지가 정확히 한 번 뒤따라요(역시 에이전트 이름, 역할, 콘텐츠, 타임스탬프만 취하고 같은 방식으로 정제). 이벤트가 사용 가능한stop_message를 운반하지 않으면 마커가 단독으로 서요;termination.message에서 아무것도 꾸며내지 않아요. - 종결은 정보성입니다:
passed,failures,error를 바꾸지 않아요. 정상 완료되거나 에러로 실패한 실행은 종결 필드가 없고, 필드가 생기기 전에 쓰인 이전 출력은 변경 없이 로드돼요.
TUI에서 지출 추적 (Tracking spend in the TUI)
사이드바의 Token Usage 패널은 선언된 각 상한에 대한 소비와 함께 모든 활성 버짓을 이름별로 나열해요:
run $0.12/$0.50 · 12.3K/100.0K · 2m14s/10m
shell-work $0.09/$0.10 · 4.3K/20.0K
구성한 상한만 나타나요. 각 수치는 사이드바의 공유 게이지 밴드로 색칠되는데 — 컨텍스트 게이지가 압축에 가까워지며 쓰는 것과 같은 것 — 그래서 버짓은 상한 한참 전에 호박색으로, 바로 직전에는 빨간색으로 변하고, 멈추려는 실행은 멈추기 전에 보여요.
누가 무엇을 썼는지 에이전트별 보기를 원하면 /settings → Appearance에서 Sidebar info mode를 Detailed로 설정하세요: 그러면 Agents 섹션이 각 에이전트의 effort와 컨텍스트 옆에 비용을 보고해요. 버짓 줄은 의도적으로 그 분석을 반복하지 않아요 — 같은 숫자를 두 번 보여주면 사이드바의 가장 좁은 열이 어수선해지기 때문이에요. 에이전트별 분할은 여전히 프로그램 소비자를 위해 budget_usage 이벤트에 실리고, /cost 에는 By Agent 섹션이 있어요.
한계와 주의 사항 (Limits and caveats)
가격이 없는 모델은 max_cost에 포함되지 않음 (Unpriced models do not count towards max_cost)
런타임이 가격을 매길 수 있는 응답만 max_cost 에 포함돼요. 가격 데이터가 없는 모델 — 알 수 없는 모델 ID, 또는 로컬·비공개 배포 같은 커스텀 엔드포인트 — 은 아무것도 기여하지 않아요, 더할 정직한 숫자가 없기 때문이에요.
그런 실행은 경고를 내고 TUI는 수치를 (unpriced spend) 로 표시해요, 지출이 보이지 않아서 조용히 낮게 읽히지 않게요. 커스텀 엔드포인트를 포함시키려면 모델 레벨 cost 블록으로 명시적으로 가격을 매겨요:
models:
local:
provider: openai
model: my-model
base_url: http://localhost:8000/v1
cost:
input: 0.15
output: 0.60
agents:
root:
model: local
description: A locally-served agent with real cost accounting.
instruction: You are a helpful assistant.
budget:
max_cost: 0.50
한도는 턴 경계에서 검사됨 (Limits are checked at turn boundaries)
실행은 턴 사이에 검사되므로, 이미 진행 중인 턴만큼만 초과할 수 있어요. 특히 max_time 은 이미 시작된 모델 호출이나 도구를 중단하지 않아요; 실행은 한도에 도달한 뒤 첫 경계에서 멈춰요.
이것은 max_iterations 와 같은 세분성이에요, 그리고 상한을 스트리밍 핫 경로에서 벗어나게 해요. 한도를 초과해선 안 되는 정확한 숫자보다 약간의 여유(headroom)를 두고 설정하세요.
여기서의 max_tokens는 모델의 max_tokens가 아님 (max_tokens here is not the model's max_tokens)
버짓의 max_tokens 는 전체 실행에 걸친 입력+출력 토큰의 누적 수예요. 단일 응답의 출력을 상한 짓는 제공자·모델 레벨 max_tokens 와는 무관해요.
또한 세션의 컨텍스트 길이도 아니에요: 압축은 그것을 리셋하지만 버짓은 계속 셉니다.
예제 (Examples)
돈만 상한 짓고 실행이 필요한 만큼 걸리게 두기:
agents:
root:
model: openai/gpt-4o
description: A cost-capped agent.
instruction: You are a helpful assistant.
budget:
max_cost: 5.00
무인 작업의 작업 시간 상한:
agents:
root:
model: openai/gpt-4o-mini
description: A time-boxed agent.
instruction: You are a helpful assistant.
toolsets:
- type: shell
budget:
max_time: 15m
실행 가능한 구성은 examples/budget.yaml 참고.