AI 에이전트의 지출 한도를 5분 만에 설정하는 방법 (PATCH 호출 하나로)
요약
AI 에이전트의 지출 한도를 서버 측에서 관리하는 방법을 설명합니다. 단 하나의 `PATCH` 호출만으로 월별 및 결제당 예산을 변경할 수 있으며, 이는 시스템 프롬프트에 의존하지 않아 우회 방지 효과가 뛰어납니다.
핵심 포인트
- 서버 측 API를 통해 에이전트의 지출 한도를 설정합니다.
- 단일 `PATCH` 호출로 월별/건당 예산 설정을 변경할 수 있습니다.
- 시스템 프롬프트는 제한 사항을 우회하기 쉽습니다.
하나의 PATCH 호출만으로 AI 에이전트의 예산을 월 $4,000에서 $5,000로 변경할 수 있었으며, 재배포나 코드 수정은 전혀 필요하지 않았습니다. 게다가 에이전트는 이 사실을 알지 못했습니다. 왜냐하면 애초에 그 숫자를 인지하고 있지 못했기 때문입니다.
공개 고지: 저는 PinkWallet의 Pink Agentic AI Payments 팀에서 근무하고 있습니다.
요약: 무료 샌드박스 워크스페이스를 설정하고, 이 하나의 PATCH 호출로 에이전트의 월별 예산과 결제당 한도를 설정한 다음, MCP(Messaging/Communication Protocol)를 통해 에이전트를 연결하면 됩니다. 제한 사항은 에이전트의 시스템 프롬프트가 아닌 서버에 존재하므로, 에이전트가 말만으로 이 제한을 우회할 수 없습니다. 아래에는 오늘 실행된 실제 응답과 함께 라이브 샌드박스에서 가져온 정확한 호출 내용이 있습니다.
왜 제한 사항은 프롬프트 안에 있을 수 없는가
시스템 프롬프트에 "월 $500 이상 쓰지 마세요"라고 적는 것은 모델이 결정하기 전에 읽어보는 단순한 제안일 뿐입니다. 긴 컨텍스트 창을 가진 에이전트, 혼란스러운 재시도 루프(retry loop)를 가진 에이전트, 또는 정교하게 조작된 도구 응답을 받은 에이전트는 이 지침을 벗어나 작동할 수 있으며, 어차피 다음 도구 호출은 아무것도 막지 못합니다. Pink Agentic AI Payments는 AI 에이전트가 요청하는 모든 결제 건에 대해 실행하기 전에 서버 측에서 에이전트별 규칙과 비교 검사합니다. 에이전트가 도구를 호출하면; 서버가 결정하고; 에이전트는 자신이 선택하지 않은 세 가지 결과 중 하나를 받게 됩니다.
1단계: 샌드박스 워크스페이스 생성하기
회원가입이나 사전 키 교환 과정 없이 바로 가능합니다:
curl -s -X POST "https://agentic-sandbox.pinkwallet.com/v1/sandbox/workspaces?utm_source=devto&utm_medium=article&utm_campaign=spending-limit-5min" \
-H 'content-type: application/json' \
-d '{"company":"Acme Robotics","email":"[email protected]","template":"coffee"}'
이 호출은 admin_key와 네 개의 에이전트 키(각 역할별 하나씩)를 반환하며, 워크스페이스는 이미 8개의 수취인과 11개의 규칙으로 초기화되어 있습니다. 이 기사에 사용된 실행의 실제 응답을 간추린 내용입니다:
{
"workspace_id": "u21i7shilt",
"admin_key": "pk_sandbox_admin_u21i7shilt...cee8",
...
관리자 키(admin key)와 구매 AI 에이전트 키(Purchasing AI agent key)를 환경 변수($ADMIN, $PURCH)로 저장하여 나머지 과정에서 사용합니다.
2단계: 에이전트의 월별 예산 및 결제당 한도 설정하기
관리자 경로(admin route)에 대한 단 한 번의 PATCH 호출만으로 하나의 에이전트에 대해 월별 및 건당 지출 한도를 모두 변경할 수 있으며, 재배포나 코드 수정가 필요 없습니다:
curl -s -X PATCH "https://agentic-sandbox.pinkwallet.com/v1/admin/agents/a_purch" \
-H "authorization: Bearer $ADMIN" -H 'content-type: application/json' \
-d '{"monthly":5000,"perPay":600}'
실제 응답(Real response):
{
"id": "a_purch", "name": "Purchasing AI", "dept": "Kitchen",
"monthly": 5000, "perPay": 600, "spentMonth": 2260, "spentToday": 0,
...
monthly는 현재 월 동안 해당 에이전트의 최대 지출 한도(hard ceiling)이며, perPay는 월별 총액에 관계없이 단일 결제 건당 상한선을 설정합니다. 이 두 가지 모두 결제가 생성되기 전에 강제되며, 나중에 확인하는 방식이 아닙니다. 또한 템플릿은 워크스페이스 내 모든 에이전트에 대해 회사 전체의 일일 지출 한도(company-wide daily ceiling)를 제공하며, 이는 GET /v1/budget에서 company_daily_ceiling으로 확인할 수 있습니다.
3단계: 요청 규칙(ask rule)과 차단 규칙(block rule)은 이미 구현되어 있음
커피 템플릿의 규칙 세트에는 직접 언급할 만한 두 가지 규칙이 포함되어 있으며, 이들은 순서대로 평가되고 첫 번째 일치하는 규칙이 적용됩니다:
r5"대량 공급 주문: 매장 관리자 확인": 승인된 수취인(payee)에게 $500에서 $2,000 사이의 결제를 요청하여 이름이 지정된 사람, 즉 "Luis Ortega (매장 관리자)"에게 전달하고 실행하지 않습니다. 이는ask규칙입니다.r11"절대: 기프트 카드, 현금성 자산, 암호화폐": 인간의 경로가 전혀 없는block규칙입니다. 이 규칙은 모든ask규칙보다 먼저 실행되므로, 기프트 카드 구매는 승인을 위해 누구에게도 도달하지 않습니다.
사용자는 PUT /v1/admin/rules를 사용하여 자체 수취인 기반, 카테고리 기반 또는 금액 기반 규칙을 추가할 수 있습니다(본문: `{
어떤 경우든 에이전트는 7개의 도구(tool)를 얻게 됩니다: pink.get_budget, pink.list_payees, pink.list_rules, pink.check_policy, pink.request_payment, pink.get_credential, pink.report_receipt.
5단계: 세 번의 결제를 시도하고, 세 가지 결과를 얻기
동일한 에이전트 키(agent key)와 동일한 규칙(rules)을 사용하지만, 금액과 수취인(payees)은 세 가지로 다릅니다. 이 기사에서는 샌드박스(sandbox) 실행을 통해 실제 처리된 응답입니다:
허용됨 (Allowed) ($150, 결제당 $600 한도 및 규칙 r4의 $500 상한액 미만):
curl -s -X POST "https://agentic-sandbox.pinkwallet.com/v1/payments" -H "authorization: Bearer $PURCH" \
-H 'content-type: application/json' -d '{"payee_id":"p_cc","amount":150,"purpose":"5kg espresso beans"}'
{
"decision": "allowed", "rule": "Small supply orders go through",
"credential": { "type": "bank_transfer", "max_amount": 150, "locked_to": "Counter Culture Coffee", "single_use": true, "expires_at": "2026-10-17T11:48:02.100Z" }
...
pending_human ($600, r5의 $500–$2,000 범위 내):
curl -s -X POST "https://agentic-sandbox.pinkwallet.com/v1/payments" -H "authorization: Bearer $PURCH" \
-H 'content-type: application/json' -d '{"payee_id":"p_uline","amount":600,"purpose":"bulk cup and lid order"}'
{
"decision": "pending_human", "rule": "Bigger supply orders: store manager checks",
"hold_id": "pay_b2c92cc5d182", "who": "Luis Ortega (Store manager)",
...
차단됨 (Blocked) (금액에 관계없이 기프트 카드):
curl -s -X POST "https://agentic-sandbox.pinkwallet.com/v1/payments" -H "authorization: Bearer $PURCH" \
-H 'content-type: application/json' -d '{"payee_name":"giftcards.com","amount":50,"purpose":"staff prize gift cards"}'
{ "decision": "blocked", "rule": "Never: gift cards, cash-like, crypto", "credential": null, "why": "matched · block" }
블록의 필드 이름은 reason이 아니라 why라는 점에 유의하십시오. 주입된 것처럼 보이는 목적 텍스트("직원 경품 상품권")는 어느 쪽을 사용하든 아무런 변화를 주지 않습니다. 규칙은 무료 텍스트 목적 필드를 파싱하는 것이 아니라 수취인 카테고리(payee category)에서 일치하기 때문에, 프롬프트로 주입된 목적만으로는 엔진이 다른 결정을 내리도록 속일 수 없습니다.
병렬 호출 시 발생하는 일
서버가 누적 총액을 업데이트하기 전에 열 개의 병렬 도구 호출(tool calls) 각각이 통과할 수 있다면, 명시된 단일 한도는 아무 의미가 없습니다. 우리는 이를 직접 테스트했습니다: 하루 $200 규칙을 가진 에이전트(agent)를 대상으로 40개의 병렬 $7 결제를 시도했습니다. 각 워크스페이스는 하나의 Cloudflare Durable Object로 실행되며, 요청 핸들러는 그 사이에 다른 작업 없이 로드하고, 평가하고, 지출하고, 저장합니다. 따라서 40개의 요청은 한 번에 도착하더라도 하나씩 평가됩니다.
오늘 실행 결과 (sandbox-examples 리포지토리의 race_test.sh 스크립트로 재현 가능, 예시 08-race-test):
Allowed: 28 Blocked: 12
Allowed spend: $196
GET /v1/budget -> "spent_today": 196
$200/일 한도에 도달하기 전에 28개의 결제가 승인되었고, 배치(batch) 내의 29번째 요청과 그 이후 모든 요청은 차단되었습니다. 총 지출액은 $196에 머물렀으며, 아무리 많은 요청이 같은 순간에 도착하더라도 $200을 초과하지 않았습니다. 이는 이 샌드박스에서 기록된 두 번의 이전 독립 실행 결과와 동일하기 때문에 일회성 현상이 아닙니다.
이 샌드박스의 한계점 (솔직하게 밝히는 바)
이 곳은 샌드박스입니다: 테스트 자금, 테스트 카드(4111 1111... BINs)를 사용하며, 아직 프로덕션 배포는 아닙니다 (현재 접근 경로는 얼리 액세스가 프로덕션으로 가는 길입니다). 규칙 엔진은 금액(amount), 지급처(payee), 카테고리(category), 시간 범위(time window), 그리고 짧은 증거 플래그 목록을 확인합니다. 에이전트가 첨부하는 증거를 독립적으로 검증하지는 않습니다 (명시된 인보이스 번호나 PO는 자체 주장일 뿐, 회계 시스템과 교차 확인되지 않습니다). 오늘날 이 엔진에는 카운트 기반 규칙(예: "하루 최대 N건 결제 제한")은 없으며, 금액 및 시간 범위 기반의 규칙만 있습니다. 그리고 이 샌드박스는 다른 공급업체의 자체 결제 도구를 감싸지 않습니다. 독립적인 MCP/REST 서버입니다.
사용해 보기
샌드박스는 무료이며 작업 공간을 생성하는 데 계정이 필요하지 않습니다: agentic-sandbox.pinkwallet.com. 전체 API 레퍼런스: pinkwallet.com/agentic/developers. 수동으로 JSON을 작성하는 대신 일반 언어 답변으로부터 시작 규칙 세트를 생성하고 싶다면: the policy generator.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기