AI 에이전트가 호출당 API 비용을 지불하게 만드는 방법 (HTTP 402 경로)
요약
자율 에이전트가 API를 호출할 때 발생하는 비용 문제를 해결하기 위해 HTTP 402(Payment Required) 상태 코드를 활용하는 설계 방식을 제안합니다. 에이전트가 예산 제한이 있는 토큰을 사용하여 안전하게 결제하고 서비스를 이용할 수 있는 게이트웨이 패턴을 설명합니다.
핵심 포인트
- HTTP 402 상태 코드를 활용한 에이전트 전용 결제 흐름 설계
- 예산 제한(Budget cap)을 통한 에이전트의 무분별한 지출 방지
- JWT 기반의 결제 토큰 검증 및 게이트웨이 프록시 패턴 적용
- x402 스펙 준수를 통한 에이전트 프레임워크와의 호환성 확보
만약 여러분이 MCP 서버나 실행 시 비용이 발생하는 API(LLM 호출, 유료 데이터 소스, 컴퓨팅 등)를 구축했다면, 아마 저와 같은 벽에 부딪혔을 것입니다:
호출자가 신용카드 양식을 가진 사람이 아니라 AI 에이전트일 때, 어떻게 호출당 비용을 받을 수 있을까요?
사람은 가입하고, 카드를 입력하고, API 키를 받을 수 있습니다. 하지만 자율 에이전트(Autonomous agent)는 작업 도중에 Stripe 결제 양식을 채울 수 없습니다. 그렇다고 에이전트에게 지출 한도가 없는 생(raw) API 키를 넘겨줄 수도 없습니다. 제어되지 않는 루프가 한 번이라도 돌면 청구 금액이 폭발할 테니까요.
이 포스트에서는 제가 최종적으로 도달한 설계 방식을 설명합니다. 이것이 유일한 방법은 아니지만, 여러분만의 방식을 구축하더라도 이 구성 요소들은 재사용할 수 있습니다.
핵심 아이디어: HTTP 402
402 Payment Required는 초기부터 예약된 HTTP 상태 코드였지만, 기본적으로 사용되지 않았습니다. 그런데 이것이 바로 우리에게 필요한 원시적인 도구(primitive)임이 밝혀졌습니다.
흐름:
- 에이전트가 결제 없이 여러분의 엔드포인트를 호출합니다.
- 여러분은 결제 방법(가격, 충전 위치, 허용되는 토큰 형식)을 설명하는 작은 JSON 본문과 함께 402 응답을 보냅니다.
- 에이전트(또는 소유자)가 한 번 충전하여 예산 제한이 있는 토큰을 받습니다.
- 에이전트가 Authorization 헤더에 해당 토큰을 넣어 재시도합니다. 이제 작동하며, 예산이 소진될 때까지 계속 작동하다가 다시 402를 받게 됩니다.
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"accepts": [
{
"scheme": "lemoncake-pay-token",
"price": "0.01",
"currency": "USD",
"mintUrl": "https://.../buy/",
"gatewayUrl": "https://.../g/"
}
]
}
이것이 x402 스펙이 표준화하는 형태입니다. 이를 구현하기 위해 반드시 스펙을 따를 필요는 없지만, 스펙을 준수하면 이미 402를 이해하고 있는 에이전트 프레임워크들이 별도의 커스텀 글루(glue) 코드 없이도 여러분에게 결제할 수 있습니다.
예산 제한(Budget cap)이 중요한 부분입니다.
{
"budget": 5.00,
"spent": 0.06,
"max_calls": 50,
"calls_used": 6,
"expires_at": "2026-07-01T00:00:00Z"
}
게이트웨이(Gateway)는 업스트림(upstream)으로 전달하기 전 매 호출마다 이 값들을 확인합니다. 예산 소진(Budget exhausted) → 402. 속도 제한(Rate limit) 도달 → 429. 만료(Expired) → 402. 에이전트가 통제 불능 상태가 되더라도, 토큰이 허용하는 것보다 더 많은 비용을 지출할 수는 없습니다.
저는 토큰을 서명된 JWT (HS256)로 인코딩하여, 게이트웨이가 핫 패스(hot path)에서 DB 왕복(round-trip) 없이도 이를 검증할 수 있게 한 뒤, Postgres에서 실시간 지출 카운터를 확인합니다. JWT에는 토큰 ID, 엔드포인트(endpoint) ID, 소유자(owner) ID가 포함되며, 변경 가능한 예산 정보는 DB에 저장됩니다.
게이트웨이 패턴 (The gateway pattern)
핵심적인 아키텍처 설계: 실제 엔드포인트 앞에 프록시(proxy)를 두는 것입니다. 에이전트는 여러분의 업스트림을 직접 호출하지 않습니다. 대신 /g/와 같은 게이트웨이 URL을 호출합니다. 게이트웨이는 다음을 수행합니다:
- 결제 토큰을 검증합니다.
- 예산 / 속도 제한 / 만료 여부를 확인합니다.
- 실제 업스트림으로 요청을 전달합니다 (서버 측에서 여러분의 업스트림 인증을 부착하므로, 에이전트는 여러분의 실제 키를 절대 볼 수 없습니다).
- 호출 및 비용을 원장(ledger)에 기록합니다.
- 업스트림의 응답을 반환합니다.
agent ──► /g/ (gateway)
├─ 토큰 검증 (verify token)
├─ 예산 확인 (check budget)
├─ 전달 (forward) ──► 실제 API (여러분의 비밀 키 포함)
├─ 사용량 + 비용 기록 (record usage + cost)
└─ 응답 반환 (return response)
이 방식은 보통 뒤엉켜 있는 두 가지 요소, 즉 '누가 호출할 수 있는가(에이전트의 결제 토큰)'와 '업스트림 인증을 어떻게 하는가(절대 노출되지 않는 여러분의 비밀 키)'를 분리(decouple)합니다. 또한, 기존 API의 코드를 수정하지 않고도 모든 엔드포인트에 개별 가격을 책정할 수 있음을 의미합니다.
정산 (Settling the money)
예산 제한이 있는 토큰을 발행(minting)한다는 것은 누군가가 선불로 결제했음을 의미합니다. 저는 제공자의 연결된 계정(Stripe Connect)에 직접 결제(Direct Charge)하는 방식으로 Stripe Checkout을 사용합니다. 따라서 돈은 제공자의 잔액으로 들어가고, 플랫폼은 호출당이 아닌 결제 시점에 단 한 번 소액의 애플리케이션 수수료(application fee)를 가져갑니다. 호출당 비용은 단지 선불 예산을 차감하는 원장상의 수치일 뿐입니다.
이것이 중요한 이유는, 모든 미세한 호출마다 수수료를 부과하면 Stripe의 거래당 최소 수수료에 의해 수익이 잠식될 수 있기 때문입니다. 선불 번들(Prepaid bundle)과 원장 차감(ledger drawdown) 방식은 이 문제를 완전히 우회합니다.
직접 구축하기 전에 제가 드리고 싶은 말씀:
저를 힘들게 했던 몇 가지 사항들입니다:
- 호출마다 수수료를 부과하지 마세요. Stripe의 최소 결제 금액 때문에 호출당 1센트 미만의 과금은 불가능합니다. 예산을 선불로 결제(Prepay)하게 하고, 자체 원장(ledger)에서 차감하는 방식을 사용하세요.
- 토큰은 다시 표시될 수 있어야 합니다. 에이전트는 컨텍스트(context)를 잃어버립니다. 구매자는 동일한 토큰을 복구할 수 있는 방법이 필요합니다. (저는 Stripe 세션 ID를 기준으로 성공 페이지의 키를 생성하는데, 이는 단회용이며 추측이 불가능합니다).
- 토큰의 범위를 하나의 엔드포인트(endpoint)로 제한하세요. 엔드포인트 A를 위해 발행된 토큰은 엔드포인트 B에서 거부되어야 합니다. 그렇지 않으면 유출된 토큰은 백지수표와 다름없습니다.
- 상위(upstream) 인증 정보는 서버 측에서만 전달하세요. 에이전트는 실제 상위 키를 절대 읽을 수 없어야 합니다. 게이트웨이가 인증 후에 이를 부착합니다.
결과물
저는 이 내용을 LemonCake라는 프로젝트로 패키징했습니다. 어떤 API/MCP 엔드포인트든 감싸고, 호출당 가격을 설정하면, 에이전트가 자율적으로 결제할 수 있는 게이트웨이 URL을 얻을 수 있습니다. 402 → 충전(top-up) → 호출 루프가 처음부터 끝까지 실행되는 것을 보고 싶다면 (가입 없이 이용 가능한) 라이브 데모가 있습니다: https://www.lemoncake.xyz/demo
하지만 솔직히 말해서, 설령 이 프로젝트를 사용하지 않더라도 이 패턴 자체는 독립적인 가치가 있습니다:
가격을 알리기 위한 402 → 예산 제한이 있는 토큰 → 검증, 전달 및 미터링(metering)을 수행하는 게이트웨이.
자율적인 호출당 결제가 오늘날 에이전트 빌더들에게 당장 필요한 것인지, 아니면 제가 1~2년 정도 앞서가고 있는 것인지는 여전히 확신할 수 없습니다. 만약 여러분이 반대편 입장에서 "에이전트에게 어떻게 비용을 청구할 것인가"라는 문제에 직면했다면, 어떻게 해결하셨는지 꼭 듣고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기