Amazon Bedrock의 토크노믹스(Tokenomics) 실습: requestMetadata와 Model Invocation
요약
본 글은 생성형 AI 애플리케이션 운영 시 비용 관리의 핵심인 '이용 주체 및 용도 추적' 문제를 다룹니다. Amazon Bedrock에서 IAM Role 단위로만 추적이 가능한 한계를 극복하기 위해, `requestMetadata`를 활용하여 사용자 ID나 업무 용도 같은 세부 정보를 Model Invocation Logs에 기록하고 검증하는 방법을 설명합니다.
핵심 포인트
- IAM Principal ≠ 실제 Application User이므로, 비용 관리에 한계가 있다.
- AWS는 AI 이용 비용 관리를 See(가시화) → Save(최적화) → Run(거버넌스) 단계로 제시했다.
- `requestMetadata`를 사용하면 사용자 ID나 업무 용도 등 세부 정보를 추적할 수 있다.
- 이를 통해 '누가, 어떤 용도로, 몇 Token을 사용했는지'를 정밀하게 파악 가능하다.
본 내용은 작성 시점의 정보를 기반으로 합니다.
이 글은 Claude와 함께 작성했지만, 최종 조정 및 확인은 사람이 진행했습니다.
생성형 AI 애플리케이션을 운영해 나가는 과정에서,
'누가・무엇에・얼마나 이용하고 있는지'를 파악하는 것은 비용 관리의 첫걸음입니다.
Amazon Bedrock에서는 IAM Principal 단위로 이용 주체를 추적할 수 있습니다.
하지만, 복수의 사용자가 동일한 Lambda 등을 경유하여 Bedrock을 이용하는 구성에서는,
Bedrock에서 보이는 실행 주체는 동일한 IAM Role이 됩니다.
즉 문제는 'IAM Principal를 얻을 수 없다'가 아니라,
IAM Principal
≠
실제 Application User
라는 점입니다.
사내에서 복수 인원・복수 용도(요약, FAQ, 분류 등)가 동일한 API를 공유하고 있다면,
IAM Principal 단위의 정보만으로는 세부 내역을 파악하기 어렵습니다.
2026년 9월, AWS는 'AWS Tokenomics Strategy'라는 블로그에서,
생성형 AI 이용의 비용 관리를 다음 4단계로 정리했습니다.
See → Visibility & Attribution (가시화・귀속)
Save → Optimization (최적화)
Run → Governance (거버넌스)
...
이 중 첫 번째 단계인 See에서는,
- IAM Principal Allocation (CUR 2.0으로 Bedrock의 모델 추론 비용을 IAM Principal 단위에 귀속)
- Application Inference Profiles / Bedrock Projects / Bedrock Workspaces에서의 태깅
- Model Invocation Logging (프롬프트, 응답, Token 수, 모델, 계정, IAM Role을 기록)
이 소개되었습니다.
IAM Principal Allocation이나 Application Inference Profiles 등을 사용하면,
IAM Principal・팀・애플리케이션・프로젝트 단위로 비용을 귀속할 수 있습니다.
또한, Model Invocation Logging에서는 추론 요청 단위로 Token 수나 모델,
IAM Principal 등을 자동으로 기록할 수 있습니다.
반면, 복수의 최종 사용자나 복수 용도가 동일한 Lambda / IAM Role을 공유하는 경우,
해당 요청이 '어떤 최종 사용자에 의한 것인지', '어떤 업무 용도인지'와 같은
애플리케이션 고유의 정보까지는 자동으로 부여되지 않습니다.
본 기사에서는 이 격차를 requestMetadata
로 보완할 수 있는지 검증했습니다.
Amazon Bedrock 공식 문서에 따르면,
requestMetadata는 토크노믹스(Tokenomics) 글 자체에서는 명시적으로 다루어지지 않았지만,
team / application / environment / experiment처럼 요청마다 변화하는
속성을 Model Invocation Logs에 부여하기 위한 메커니즘으로서,
Converse / ConverseStream / InvokeModel / InvokeModelWithResponseStream
의 4가지 작업으로 이용할 수 있습니다 (요청당 최대 16개, 키・값 각각 최대 256자).
즉,
누가・어떤 용도로・몇 Token을 사용했는지
를 정말 추적할 수 있는지 실제로 구현하여 검증했습니다.
누가?
↓
어떤 용도로?
...
최종적으로, 다음과 같은 세밀한 단위로 이용 상황을 볼 수 있는 것을 목표로 했습니다.
| user_id | use_case | model | input_tokens | output_tokens |
|---|---|---|---|---|
| user-001 | summary | Claude Haiku 4.5 | 172 | 103 |
| ... | ||||
| 간단한 구성도 예시는 다음과 같으며, |
API Gateway + Lambda: 서버 관리가 필요 없는 최소 구성 -
Bedrock Converse API: 이번에는 모델 차이를 흡수하기 쉽고, 응답에서 Token Usage도 얻기 쉬우므로 Converse API를 채택했습니다 (requestMetadata
자체는 InvokeModel 계열 API에서도 헤더를 통해 이용 가능) -
Model Invocation Logging: Bedrock 호출 단위의 상세 로그를 CloudWatch Logs에 출력하는 기능
IaC(Infrastructure as Code)는 AWS CDK로 관리하고 있습니다.
| 항목 | 획득원 |
|---|---|
| 누가? | IAM Principal (Lambda 실행 역할, 고정) + requestMetadata.user_id (애플리케이션 측의 최종 사용자 식별자) |
| 어떤 용도로? | requestMetadata.use_case (summary / faq / classification) |
| 몇 토큰? | Bedrock Converse API 응답의 usage, 및 Model Invocation Logging에 기록되는 토큰 수 |
핵심은 requestMetadata입니다.
Lambda에서 Converse를 호출할 때, 다음과 같이 애플리케이션 측의 컨텍스트를 삽입합니다.
bedrock_response = bedrock_runtime.converse(
modelId=BEDROCK_MODEL_ID,
system=[{"text": system_prompt}],
...
이것만으로 Model Invocation Logging 출력에 requestMetadata가 그대로 담깁니다.
AWS IAM의 관점에서 볼 때, Bedrock을 호출하는 Principal(실행 주체)은 항상 하나입니다.
user-001이 API를 호출하든
user-002가 API를 호출하든
IAM 상으로는 동일한 "InvokeFunctionRole" (Lambda 실행 역할)
API Gateway와 Lambda를 공유하는 구성에서는 CloudTrail이나 IAM의 접근 기록을 봐도 'user-001이 호출했다'는 정보는 전혀 나오지 않습니다. IAM이 기록하는 것은 'InvokeFunctionRole이라는 역할이 Bedrock을 호출했다'는 사실뿐입니다.
실제로 Model Invocation Logging 로그를 보면 이것이 그대로 확인됩니다 (계정 ID와 역할명 일부는 가림 처리했습니다).
{
"requestMetadata": {
"use_case": "summary",
...
user_id가 user-001든 user-002든, identity.arn (IAM Principal)는 완전히 동일했습니다.
즉,
Infrastructure Principal (IAM Principal)
→ Lambda 실행 역할. AWS 리소스에 대한 접근 제어/인가의 단위
Application User
...
라는 두 '누구'는 구조적으로 명확히 분리되어 있습니다.
requestMetadata.user_id는 Lambda 코드 내에서 자유롭게 설정할 수 있는 값이며, IAM을 통한 인증/검증을 거친 것이 아닙니다.
실제 운영 환경에서는 Cognito・OIDC・사내 IdP・JWT 등 인증된 Identity로부터 requestMetadata에 전달해야 합니다.
획득한 user_id만
또한, requestMetadata는 Model Invocation Logs에 저장되므로, 운영 환경에서는 실명이나 이메일 주소 같은 개인 정보를 직접 저장하지 않고 분석용 내부 ID 등을 활용하는 것이 안전합니다.
이번 경우는 API Gateway에 인증을 설정하지 않았고, user_id도 리퀘스트 바디에서 직접 받는 검증용 간이 구현입니다. 실제로 로그에서 user_id / use_case별 토큰 사용량을 추출했습니다.
LambdaExecutionRole (IAM 상으로는 항상 동일)
│
├ user-001
...
IAM 상으로는 identity.arn이 항상 동일한 Lambda 실행 역할인 반면, requestMetadata를 통해서는 사용자/용도 단위의 내역을 깔끔하게 가져올 수 있습니다.
Tokenomics의 'See'가 잘 구현되고 있네요.
1건씩 로그를 육안으로 확인하는 것뿐만 아니라, CloudWatch Logs Insights를 사용하면 user_id}
× use_case
단위로 토큰 사용량을 집계할 수 있습니다.
본 검증에서 실제로 출력된 로그의 필드 구조는 다음과 같습니다.
(requestMetadata.user_id, input.inputTokenCount 등)에 맞춰 쿼리는 아래와 같습니다.
fields requestMetadata.user_id, requestMetadata.use_case,
input.inputTokenCount, output.outputTokenCount
| stats count(*) as requests,
...
※ 대상 로그 그룹은 /aws/bedrock/tokenomics-poc (Model Invocation Logging의 전송지)
실제로 aws logs start-query / get-query-results로 실행해 본 결과, 아래와 같이 user_id × use_case 단위로 집계된 결과가 반환되었습니다.
| user_id | use_case | requests | inputTokens | outputTokens |
|---|---|---|---|---|
| user-001 | summary | 2 | 172 | 103 |
| ... | ||||
마지막 행 (user_id / use_case가 공백)은 동작 확인 과정에서 Bedrock 콘솔의 Playground에서 직접 호출한 분입니다. |
Playground를 경유한 요청만 requestMetadata가 비게 된 것을 통해, 메타데이터를 부착하는 의미도 실제 데이터 상에서 확인할 수 있었습니다.
공식 문서에도
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기