
Amazon Bedrock AgentCore Gateway를 통해 Codex의 이용량과 Budget을 제어하기
요약
Amazon Bedrock AgentCore Gateway의 Interceptor를 활용하여 Codex의 이용량과 예산을 제어하는 방법을 다룹니다. 사용자별 토큰 사용량 및 비용을 기록하고, 설정된 일일/월간 예산을 초과할 경우 모델 호출을 차단하는 구현 사례를 검증합니다.
핵심 포인트
- Interceptor를 통한 요청 전후의 독자적 처리 가능
- JWT 기반 사용자 단위의 이용량 및 비용 기록
- Daily/Monthly Budget 상한 초과 시 모델 호출 차단
- CloudWatch와 DynamoDB를 활용한 사용 데이터 관리
※ 본 기사는 필자 개인의 검증 결과 및 견해를 바탕으로 하며, 소속 조직의 공식적인 견해나 방침을 나타내는 것이 아닙니다.
1. 서론
생성형 AI를 코딩 에이전트(Coding Agent)로부터 이용하는 케이스가 늘어남에 따라, 단순히 "모델을 호출할 수 있다"를 넘어, 누가 얼마나 이용했는지, 이용 금액이 일정액을 초과했을 때 중단할 수 있는지와 같은 비용 관리(Cost Management)도 중요해지고 있습니다.
Amazon Bedrock AgentCore Gateway에는 Gateway를 통과하는 요청(Request) 전후에 독자적인 처리를 끼워 넣을 수 있는 Interceptor가 있습니다.
Interceptor에는 크게 다음 두 가지가 있습니다.
- REQUEST Interceptor: 타겟(Target)을 호출하기 전에 처리를 실행
- RESPONSE Interceptor: 타겟으로부터 응답(Response)을 받은 후에 처리를 실행
이번에 AWS Samples에서 sample-agentcore-gateway-usage-interceptor가 공개되었기에, Amazon Linux 2023 EC2 상에 구축하여 Codex CLI를 통해 실제로 이용해 보았습니다.
이 샘플에서는 주로 다음 두 가지를 실현하고 있습니다.
- JWT의 사용자 정보를 사용한 사용자 단위의 이용량·비용 기록
- Daily / Monthly 상한을 초과한 사용자를 모델 호출 전에 차단하는 Budget 제어
본 기사에서는 실제로 다음 사항들을 확인합니다.
- Codex CLI를 통해 AgentCore Gateway를 경유하여 GPT-5.4를 호출할 수 있는가
- 이용 토큰과 추정 비용이 CloudWatch / DynamoDB에 기록되는가
- Daily Budget을 초과하면 요청이 차단(Block)되는가
- 차단된 요청으로 인해 이용 금액이 늘어나지 않는가
- Monthly Budget에서도 동일하게 차단되는가
2. sample-agentcore-gateway-usage-interceptor란
이번에 이용한 것은 AWS Samples의 다음 내용입니다.
이 샘플에서는 AgentCore Gateway의 추론 타겟(Inference Target)에 REQUEST / RESPONSE 두 가지 Interceptor를 통합하여, 사용자 단위의 비용 귀속과 Daily / Monthly Budget 제어를 수행합니다.
처리 흐름을 간략화하면 다음과 같습니다.
Codex CLI
|
| Bearer JWT
...
REQUEST Interceptor에서 Budget을 확인하고, 상한을 초과했다면 타겟을 호출하기 전에 요청을 거부할 수 있다는 점이 포인트입니다.
반면, 정상적으로 모델이 호출된 경우에는 RESPONSE Interceptor가 응답 내의 usage를 취득하여, 토큰 수나 추정 비용을 기록합니다.
3. 검증 환경
이번 검증 환경은 다음과 같습니다.
| 항목 | 내용 |
|---|---|
| 검증일 | 2026년 8월 7일 |
| ... |
이번에는 로컬 PC에서 EC2를 조작하며, Codex CLI 자체는 EC2 상에서 실행하고 있습니다.
Cognito의 최초 로그인만 로컬 PC의 브라우저를 이용하고, Session Manager의 Port Forwarding을 경유하여 EC2 상의 OAuth callback으로 되돌리는 구성으로 했습니다.
4. 샘플을 배포하기
먼저, EC2에 필요한 패키지를 설치합니다.
sudo dnf install -y \
git \
jq \
...
Codex CLI를 설치합니다.
sudo npm install -g @openai/codex
버전을 확인합니다.
codex --version
이번에 이용한 버전은 다음과 같습니다.
codex-cli 0.147.0
이어서 샘플을 clone 합니다.
cd ~
git clone \
...
검증 대상을 명확히 하기 위해, commit hash도 기록해 둡니다.
git rev-parse HEAD
이번에 이용한 commit은 다음과 같습니다.
d79bd57f6d5461b81f862630961b72c49967a4f9
CloudFormation 배포하기
환경 변수를 설정합니다.
export REG_ION=us-east-1
export STACK=agentcore-inference-sample
export ACCOUNT_ID=$(aws sts get-caller-identity \
...
CloudFormation용 S3 버킷을 생성합니다.
aws s3 mb \
"s3://${CFN_BUCKET}" \
--region "$REGION"
Stack을 배포합니다.
aws cloudformation deploy \
--region "$REGION" \
--stack-name "$STACK" \
...
정상적으로 완료되면 다음과 같이 표시됩니다.
Successfully created/updated stack - agentcore-inference-sample
CloudFormation의 Stack status도 확인합니다.
aws cloudformation describe-stacks \
--region "$REGION" \
--stack-name "$STACK" \
...
결과는 CREATE_COMPLETE가 되었습니다.
agentcore-inference-sample
CREATE_COMPLETE
5. Cognito를 통한 인증
Stack Outputs에서 인증 및 Gateway 연결에 필요한 값을 가져옵니다.
export DISCOVERY_URL=$(aws cloudformation describe-stacks \
--region "$REGION" \
--stack-name "$STACK" \
...
이번 검증에서는 Cognito 사용자로서 testuser01을 생성했습니다.
샘플에서는 Cognito Access Token의 username claim을 기본 사용자 ID로 사용합니다.
PKCE 인증 수행
인증 helper는 localhost에서 OAuth callback을 받습니다.
이번에 사용한 callback port는 8400이었습니다.
EC2 자체에는 브라우저를 설치하지 않고, 다음과 같은 구성으로 설정했습니다.
로컬 PC의 브라우저
|
| localhost:8400
...
로컬 PC의 PowerShell에서 Port Forwarding을 시작합니다.
aws ssm start-session --target <EC2_INSTANCE_ID> --region us-east-1 --document-name AWS-StartPortForwardingSession --parameters portNumber="8400",localPortNumber="8400"
EC2 측에서는 인증 helper를 실행합니다.
python3 auth-helper/oidc-token.py
표시된 URL을 로컬 PC의 브라우저에서 열고, testuser01로 로그인합니다.
인증에 성공하면 브라우저에는 다음과 같이 표시되었습니다.
Sign-in complete
You can close this tab.
EC2 측에는 token cache가 저장됩니다.
~/.config/agentcore-gateway/tokens.json
이후에는 helper가 이 cache를 이용하며, 필요에 따라 token을 갱신합니다.
6. Codex에서 AgentCore Gateway 호출하기
Codex의 설정 파일인 ~/.codex/config.toml을 생성합니다.
model = "openai.gpt-5.4"
model_provider = "agentcore-gateway"
[model_providers.agentcore-gateway]
...
연결 확인을 위해 다음 프롬프트를 실행했습니다.
codex exec "Reply with exactly: AGENTCORE_OK"
결과는 다음과 같습니다.
AGENTCORE_OK
이로써, 다음 경로를 통해 실제로 GPT-5.4를 호출할 수 있음을 확인했습니다.
Codex CLI
↓
AgentCore Gateway
...
7. 이용 토큰과 비용 확인하기
다음으로, RESPONSE Interceptor에서 이용량이 기록되고 있는지 확인합니다.
CloudWatch Logs를 확인합니다.
aws logs tail \"/aws/lambda/${STACK}-usage-record\" \--region "$REGION" \---
...
이번에 확인한 요청에서는 다음과 같은 값이 기록되어 있었습니다.
user: testuser01
model: openai.gpt-5.4
input_tokens: 11306
...
user, model, 입력·출력 토큰 수에 더해, cost_usd까지 기록되어 있습니다.
즉, 모델로부터 반환된 usage를 RESPONSE Interceptor가 취득하여, 추정 비용까지 산출할 수 있음을 알 수 있습니다.
DynamoDB에서 사용자별 이용 금액 확인하기
Access Token으로부터 username을 가져옵니다.
export ME=$(python3 -c "
import json, base64, pathlib
t = json.loads(
...
DynamoDB의 사용자 행을 가져옵니다.
aws dynamodb get-item \--region "$REGION" \--table-name "$SPEND_TABLE" \---
...
여러 번 요청한 시점에서는 다음과 같은 값이 기록되어 있었습니다.
{
"daily_spend_usd": "0.056924999999999994",
"monthly_spend_usd": "0.056924999999999994",
...

나아가 Codex를 여러 번 실행하자, 이용 금액은 다음과 같이 증가했습니다.
0.056925...
↓
0.090845...
USER#testuser01이라는 사용자 단위 레코드에 이용 금액이 누적되고 있음을 확인할 수 있습니다.
CloudWatch Metrics 확인하기
CloudWatch Metrics에는 AgentCore/InferenceUsage 네임스페이스 (namespace)가 생성되었습니다.
이번에 확인한 주요 메트릭 (metrics)은 다음과 같습니다.
InputTokens
OutputTokens
EstimatedCostUSD

CloudWatch에서는 토큰 수나 추정 비용을 시계열로 확인할 수 있으므로, DynamoDB의 현재 이용 금액과 함께 이용 상황을 파악할 수 있습니다.
8. Daily Budget 초과시켜 보기
여기서부터 Budget 제어를 확인합니다.
이 시점에서 testuser01의 이용 금액은 다음 값이었습니다.
daily_spend_usd = 0.090844999999999994
현재 이용 금액보다 충분히 작은 Daily Budget을 설정합니다.
aws dynamodb update-item \--region "$REGION" \--table-name "$SPEND_TABLE" \---
...
DynamoDB는 다음과 같은 상태가 됩니다.
daily_cap_usd = 0.0001
daily_spend_usd = 0.090845...
사용자 단위의 Budget override는 Lambda 내에서 일시적으로 캐시 (cache)되므로, 반영을 기다린 후 다시 실행합니다.
sleep 61
Codex를 실행합니다.
codex exec "hi"
이번에는 모델로부터 답변이 반환되지 않고, 다음과 같은 에러가 발생했습니다.
403 Forbidden:
Daily usage budget exceeded

Daily Budget을 초과한 사용자에 대해 모델 호출을 차단할 수 있음을 확인했습니다.
9. 차단된 요청으로 이용 금액이 늘어날까
Budget(예산) 초과 시 403을 반환할 수 있더라도, 해당 요청으로 인해 모델이 호출되어 비용이 발생한다면 Budget 제어로서 충분하지 않습니다.
그래서 차단(Block) 후에 다시 DynamoDB의 이용 금액을 확인했습니다.
aws dynamodb get-item \
--region "$REGION" \
--table-name "$SPEND_TABLE" \
...
결과는 다음과 같습니다.
| 타이밍 | daily_spend_usd |
|---|---|
| Budget 초과 전 | 0.090844999999999994 |
| 403으로 Block 후 | 0.090844999999999994 |
값은 변하지 않았습니다.
즉, 이번 검증에서는 Daily Budget을 초과한 요청은 모델 호출 전에 차단되며, 해당 요청으로 인한 이용 금액도 추가되지 않는다는 것을 확인할 수 있었습니다.
REQUEST Interceptor에서 Budget을 확인하는 구성의 효과를 잘 보여주는 결과입니다.
10. Monthly Budget도 확인하기
Daily Budget의 override를 삭제합니다.
aws dynamodb update-item \
--region "$REGION" \
--table-name "$SPEND_TABLE" \
...
이어서 Monthly Budget을 0.0001 USD로 설정합니다.
aws dynamodb update-item \
--region "$REGION" \
--table-name "$SPEND_TABLE" \
...
반영될 때까지 기다립니다.
sleep 61
다시 Codex를 실행합니다.
codex exec "hi"
결과는 다음과 같습니다.
403 Forbidden:
Monthly usage budget exceeded
Daily Budget뿐만 아니라 Monthly Budget에 대해서도 동일하게 모델 호출을 차단할 수 있음을 확인했습니다.
지금까지의 검증 결과를 정리하면 다음과 같습니다.
| 검증 내용 | 결과 |
|---|---|
| Codex → AgentCore Gateway → GPT-5.4 | 성공 |
| ... |
11. 이번에 확인하며 알게 된 점
이번에 특히 흥미로웠던 점은, AgentCore Gateway를 단순한 LLM Gateway로 이용할 뿐만 아니라, Interceptor를 비용 거버넌스(Cost Governance)의 포인트로 이용할 수 있다는 것입니다.
이번 샘플에서는 JWT를 통해 사용자를 식별하고, 다음 정보를 함께 다룰 수 있습니다.
누가 사용했는가
+
몇 토큰을 사용했는가
...
모델에 대한 액세스 자체는 Gateway의 실행 역할(Execution Role)을 통해 이루어지지만, Interceptor에서 JWT의 identity를 다시 가져옴으로써 USER#testuser01과 같은 사용자 단위의 이용 금액을 DynamoDB에 유지할 수 있습니다.
또한, 현재 이용 금액이 Budget을 초과한 상태에서는 REQUEST Interceptor에 의해 모델 호출 전에 403을 반환하며, 그 이후의 이용 금액도 늘어나지 않음을 실측할 수 있었습니다.
한편, 이번에 확인한 것은 이미 현재 이용 금액이 cap(한도)을 초과한 사용자의 다음 요청을 멈출 수 있다는 것입니다.
예를 들어 다음과 같은 케이스는 본 기사에서 아직 확인하지 않았습니다.
현재 이용 금액 $0.0900
Budget $0.1000
다음 1회 $0.0200
REQUEST Interceptor가 확인하는 시점에는 Budget 미만이지만, 다음 모델 호출에 의해 Budget을 초과할 가능성이 있습니다.
나아가 여러 요청을 병렬로 실행할 경우, 여러 개의 REQUEST Interceptor가 동일한 현재 이용 금액을 참조하여 동시에 통과할 가능성도 생각할 수 있습니다.
즉, "Budget을 초과한 사용자의 다음 호출을 멈추는 것"과 "설정한 Budget을 절대 초과하지 않는 것"은 같은 것인가라는 점은 조금 더 검증할 여지가 있습니다.
이 부분은 다음번에 경계값(Boundary Value)이나 병렬 실행을 사용하여 실측해 보도록 하겠습니다.
12. 요약
이번에는 AWS Samples에서 공개된 sample-agentcore-gateway-usage-interceptor를 Amazon Linux 2023 기반의 EC2 상에 구축하고, Codex CLI를 통해 실제로 사용해 보았습니다.
검증 결과, 다음과 같은 내용을 확인할 수 있었습니다.
- Cognito의 JWT identity를 기반으로 사용자 단위의 이용량을 식별할 수 있음
- RESPONSE Interceptor를 통해 입력/출력 토큰과 추정 비용을 기록할 수 있음
- DynamoDB에 일간(Daily) / 월간(Monthly) 이용 금액을 누적할 수 있음
- CloudWatch EMF로 토큰 수와 추정 비용을 시각화할 수 있음
- 일간 예산(Daily Budget) 초과 시 HTTP 403을 통해 모델 호출을 차단할 수 있음
- 차단(Block)된 요청에 대해서는 DynamoDB의 이용 금액이 증가하지 않음
- 월간 예산(Monthly Budget)에서도 동일하게 차단이 가능함
Agent형 코딩 도구에서는 사람이 API를 한 번씩 실행하는 경우와 비교하여, 수많은 모델 호출이 발생할 가능성이 있습니다.
따라서 단순히 "모델에 접근할 수 있는가"뿐만 아니라, 누가, 얼마나 사용하며, 어디에서 차단할 것인가를 설계하는 중요성이 앞으로 더욱 높아질 것으로 보입니다. 이번 샘플은 그 메커니즘을 AgentCore Gateway의 Interceptor로서 구현하는 구체적인 사례로서 참고가 되었습니다.
다음에는 한 단계 더 나아가 다음과 같은 사항들을 실측해 보고자 합니다.
- 사용자별로 예산(Budget)이 정말로 분리되는가
- 상한선 직전의 1개 요청에서 예산을 초과하지는 않는가
- 여러 요청을 병렬 실행하면 어떻게 되는가
- "Hard Budget"은 어디까지 엄격하게 적용되는가
참고 자료
Discussion

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