AI 에이전트가 카드를 결제하기 전에 승인 절차를 거치는 방법
요약
AI 에이전트의 자율적 지출 과정에서 발생할 수 있는 금융 위험을 방지하기 위한 승인 프로세스 설계 방법을 다룹니다. 결제 금액의 수정 불가능성 유지와 멱등성 설정 등 안전한 에이전트 결제를 위한 기술적 가이드를 제공합니다.
핵심 포인트
- 에이전트 결제 시 인간의 최종 승인 단계를 포함하여 환각 및 오류 방지
- 결제 데이터(금액, 판매자 등)는 검토자가 수정할 수 없도록 설정 필수
- 재시도 시 중복 결제 위험을 알리기 위해 비멱등성(non-idempotent) 표시 활용
- TypeScript SDK 및 API를 활용한 결제 게이트 구현 방법 제시
AI 에이전트가 카드를 결제하기 전에 승인하세요 — 사람이 '예'라고 말하지 않고는 어떤 결제도 실행되지 않도록 판매자, 금액, 등록된 카드를 검토해야 합니다.
자율적 지출 (autonomous spend)의 문제점
광고 예산을 관리하거나, 클라우드 크레딧을 충전하거나, 판매자 구독을 갱신하는 에이전트는 결국 돈을 움직여야 합니다. 이는 이메일을 보내거나 트윗을 게시하는 것과는 다른 위험 등급에 속합니다. 잘못되거나 중복된 이메일은 당혹스러운 일이지만, 잘못되거나 중복된 결제는 차지백 (chargeback), 고객 지원 티켓, 그리고 잠재적으로 컴플라이언스 (compliance) 문제를 야기합니다. 만약 에이전트가 카드를 결제하기 위한 유일한 경로가 먼저 인간의 결정을 거치는 것이라면, 환각 (hallucination)된 금액이나 잘못 파싱된 인보이스 (invoice)는 결제 제공업체에 아예 도달하지 않을 것입니다.
이 패턴은 다른 모든 작업에서 사용되는 '푸시(push), 폴링(poll), 실행(execute)'의 3단계 게이트 (gate)와 동일하지만, 결제에는 두 가지 조정 사항이 필요합니다. 첫째, 금액은 검토자가 수정할 수 없어야 하며, 둘째, 해당 작업은 재시도가 안전하지 않음을 승인 카드에 시각적으로 경고하도록 표시되어야 합니다.
TypeScript SDK로 게이트 연결하기
일일 예산이 하한선 아래로 떨어질 때 광고 계정을 충전하는 지출 에이전트의 예시:
import { ImpriClient, ImpriRejected, ImpriTimeout } from '@impri/sdk'
const impri = new ImpriClient({ apiKey: process.env.IMPRI_API_KEY! })
...
chargeCard는 awaitDecision이 해결(resolve)된 후 try 블록 내부에 위치합니다. 거절(rejection)되거나 타임아웃(timeout)이 발생했을 때는 해당 코드에 도달하는 분기가 없습니다.
결제 승인이 수정 불가능해야 하는 이유
작성 중인 이메일이나 소셜 게시물의 경우, 검토자가 승인하기 전에 문구를 수정할 수 있게 하는 것이 핵심입니다. 하지만 결제의 경우는 정반대입니다. 만약 검토자가 preview.body를 편집하여 숫자를 변경할 수 있다면, 그들은 정산 (reconciliation) 및 멱등성 (idempotency) 로직이 예상하는 것과 다른 트랜잭션을 승인하게 됩니다. 카드, 판매자, 그리고 금액은 에이전트가 실제로 제출한 것과 일치해야 합니다. 결제 작업에 editable: []를 설정하세요. 검토자의 역할은 이진적(binary)입니다: '정확히 이 결제를 승인할 것인가, 아니면 거절할 것인가'입니다.
결제를 비멱등적 (non-idempotent)으로 표시하기
POST /v1/actions는 승인 카드에 직접 표시되는 idempotent (멱등성) 힌트와 undo (취소) 설명을 허용합니다. 결제(charge)의 경우, 두 가지 모두 설정할 가치가 있습니다:
curl -X POST https://api.impri.dev/v1/actions \
-H "Authorization: Bearer $IMPRI_API_KEY" \
-H "Content-Type: application/json" \
...
idempotent: false를 설정하면 카드에 "재시도 시 이 작업이 중복될 수 있음"이라는 배지가 표시됩니다. 이는 에이전트의 재시도 루프(retry loop)로 인해 동일한 결제가 두 번 실행되었을 경우 유용한 문맥(context)을 제공합니다. undo는 검토자에게 무언가 잘못된 후에가 아니라, 승인하기 전에 미리 탈출구(escape hatch)를 알려줍니다.
사람이 필요 없는 항목 자동 승인하기
모든 결제에 사람이 검토할 필요는 없습니다. Impri의 규칙 엔진 (rules engine)은 사용자가 보내는 payload 필드에 대해 payload_conditions를 평가하므로, 소액의 정기 충전은 대기열을 건너뛸 수 있는 반면 더 큰 금액은 여전히 사람의 승인을 기다리게 할 수 있습니다:
{
"name": "소액 광고 충전 자동 승인",
"kind_pattern": "payment.*",
...
더 큰 금액에 대해 기본 알림 대신 특정 Slack 또는 Telegram 채널로 라우팅하고 싶다면, rule_action: "escalate"를 사용하여 두 번째 규칙을 설정하세요.
거절, 타임아웃 또는 만료 시 발생하는 일
ImpriRejected 및 ImpriTimeout은 오류가 아닌 정상적인 결과입니다. 충전이 거절되었다는 것은 사람이 수동으로 충전하거나 다음 시도를 승인할 때까지 캠페인이 일시 중지된 상태로 유지됨을 의미할 뿐입니다. Impri는 결제가 좋은 아이디어인지 여부를 결코 결정하지 않습니다. Impri는 제안된 결제를 저장하고, 누군가에게 알리고, 결정을 보류합니다. 연간 갱신을 위한 $1,200가 적절한지에 대한 판단은 전적으로 승인을 누르는 사람에게 달려 있으며, 감사 로그 (audit log)는 정확히 누가 어떤 결제를 언제 승인했는지에 대한 기록을 유지합니다.
다음 단계: 이 예제에서 사용하는 전체 createAction/awaitDecision/reportResult API에 대한 TypeScript SDK 레퍼런스 (TypeScript SDK reference).
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기