승인은 불리언(Boolean)이 아니다: 에이전트가 재개될 때 여전히 유효해야 하는 것은 무엇인가?
요약
AI 에이전트의 승인 프로세스가 단순한 불리언(Boolean) 값이 아닌, 실행 시점의 비즈니스 맥락과 정책을 반영해야 함을 강조합니다. 비동기적 작업 환경에서 승인된 데이터가 실행 시점에 유효한지 검증하는 설계의 중요성을 다룹니다.
핵심 포인트
- 승인은 영구적인 권한이 아닌 특정 시점의 결정임
- 에이전트 작업은 긴 생명주기와 비동기적 경계를 가짐
- 실행 전 주문 상태, 정책, 권한 등을 재검증해야 함
- 승인 의도와 실행 조건을 분리하는 설계가 필수적임
인간의 승인은 특정 사실 관계 하에서의 단일 행동에 대한 결정입니다. 그것은 영구적인 허가 비트(permission bit)가 아닙니다.
AI 에이전트가 환불 요청을 준비하는 상황을 상상해 보십시오:
주문(Order): SO-1001
금액(Amount): CNY 199.00
사유(Reason): 중복 결제
런타임(Runtime)은 이 행동을 고위험(high risk)으로 분류하고, 작업을 일시 중지한 뒤, 인간에게 해당 요청을 승인할 것을 요청합니다.
오전 10:00에 승인자는 매개변수(parameters)를 검토하고 **승인(Approve)**을 클릭합니다.
작업은 즉시 실행되지 않습니다. 작업은 일시 중지된 상태로 유지되며, 큐(queue)에서 대기하고, 코디네이터(coordinator) 재시작 시에도 유지되며, 마침내 15:00에 디스패치(dispatch) 단계에 도달합니다.
그 5시간 동안 다음 중 어느 것이라도 변경될 수 있습니다:
- 주문이 이미 다른 채널을 통해 환불되었을 수 있음;
- 환불 정책에 추가적인 재무 검토(finance review)가 필요하게 되었을 수 있음;
- 승인자가 더 이상 필요한 역할(role)을 보유하고 있지 않을 수 있음;
- 실행 주체(acting subject)가 조직을 떠났을 수 있음;
- 작업 재구성(task reconstruction) 과정에서 금액이나 통화가 변동되었을 수 있음;
- 도구 구현(tool implementation)이 변경되었을 수 있음;
- 승인이 단 30분 동안만 유효했을 수 있음.
단순히 데이터베이스 행(row)에 approved = true라고 남아 있다는 이유만으로 시스템이 실행되어야 할까요?
아니요.
승인은 시대를 초월한 부여가 아니었습니다. 그것은 특정 주체에 의해, 특정 권한(capability)을 사용하여, 특정 인자(arguments)와 함께, 특정 정책 및 비즈니스 사실 관계 하에서 이루어진 특정 행동에 대한 결정이었습니다.
에이전트가 질문에 답하는 수준을 넘어 실제 비즈니스 결과(business consequences)를 만들어내기 시작할 때, 이러한 구분은 필수적이 됩니다.
1. 위험한 단순화: approval = true
전통적인 관리 소프트웨어에서 승인과 실행은 종종 밀접하게 붙어 있습니다. 사용자가 양식을 제출하면 관리자가 이를 승인하고, 시스템은 곧이어 행동을 수행합니다.
그러한 상호작용은 다음과 같은 단순화된 멘탈 모델(mental model)을 조장합니다:
approval = true
일단 그 값이 저장되면, 다운스트림(downstream) 코드에서는 해당 행동을 영구적으로 권한이 부여된 것으로 취급합니다.
에이전트 작업(Agent tasks)은 다릅니다. 단일 작업이 여러 비동기 경계(asynchronous boundaries)를 가로지를 수 있습니다.
의도 이해 (understand intent)
-> 기능 (capability) 선택
-> 인자 (arguments) 구성
...
생명주기(lifecycle)는 몇 분, 몇 시간, 또는 며칠 동안 지속될 수 있습니다. 프로세스가 재시작될 수 있고, 정책(Policies)이 재배포될 수 있으며, 비즈니스 객체(Business objects)가 다른 채널을 통해 변경될 수도 있습니다.
그러한 환경에서 "승인이 발생했다"는 것은 단지 과거의 사실일 뿐입니다. 그것이 해당 행동이 지금도 여전히 유효하다는 것을 증명하지는 않습니다.
프로덕션 설계는 최소한 다섯 가지 개념을 구분해야 합니다:
| 개념 | 답변하는 질문 |
|---|---|
| 승인 의도 (Approval intent) | 이러한 종류의 작업에 인간의 개입이 필요한가? |
| ... |
이 다섯 가지를 하나의 불리언(boolean)으로 통합하는 것은 가장 중요한 장애 모드(failure modes)를 숨기게 됩니다.
2. 승인은 모호한 의도가 아니라 행동에 결합되어야 한다
다음과 같은 승인 프롬프트만으로는 충분하지 않습니다:
환불을 승인하시겠습니까?
이는 승인자에게 다음 사항을 알려주지 않습니다:
- 어떤 주문이 변경될 것인지;
- 얼마의 금액이 이동할 것인지;
- 어떤 통화(currency)가 연관되어 있는지;
- 에이전트가 누구의 권한을 대리하는지;
- 어떤 기능(capability)이 실행될 것인지;
- 어떤 정책 버전(policy version)이 승인 요구사항을 생성했는지;
- 결정이 얼마나 오래 유효한지;
- 작업이 한 번 이상 실행될 수 있는지 여부.
유용한 승인 기록은 구체적인 실행 엔벨로프(execution envelope)에 결합되어야 합니다. 보증 수준(assurance level)에 따라 다음을 포함할 수 있습니다:
신뢰할 수 있는 주체 (trusted_subject)
기능 (capability)
표준 인자 (canonical_arguments)
...
더 높은 보증이 필요한 배포에서는 다음을 결합할 수도 있습니다:
테넌트 (tenant)
비즈니스 객체 버전 (business_object_version)
도구 또는 서버 아티팩트 (tool_or_server_artifact)
...
모든 구현이 동일한 표현 방식을 가질 필요는 없습니다. 어떤 것은 서명된 객체(signed object)를 사용하고, 어떤 것은 영구적인 데이터베이스 레코드(durable database record)를 사용하며, 어떤 것은 외부 승인 시스템을 사용할 수 있습니다. 형식보다 중요한 것은 불변량(invariant)입니다:
시스템은 곧 실행될 내용이 검토되었던 바로 그 행동임을 증명할 수 있어야 합니다.
3. 파라미터 해시(parameter hash)는 구조를 보호하며, 시간은 보호하지 않는다
일반적인 안전장치는 인자를 표준화(canonicalize)하고 해시를 저장하는 것입니다:
args_hash = SHA256(canonical_json(arguments))
디스패치(dispatch) 전, 런타임(runtime)은 해시를 다시 계산합니다. 만약 값이 다르다면, 이전의 승인을 재사용할 수 없습니다.
이는 위험한 유형의 드리프트(drift)를 방지합니다:
승인 시점:
order_id = SO-1001
amount = 199.00
...
하지만 동일한 파라미터 해시가 실행이 여전히 안전하다는 것을 증명하지는 않습니다.
다음과 같은 상황에서도 인자(arguments)는 변경되지 않았을 수 있습니다:
- 행위 주체(acting subject)가 권한을 상실한 경우;
- 승인이 만료된 경우;
- 적용 가능한 정책(policy)이 변경된 경우;
- 주문(order)이 이미 환불된 경우;
- 기능(capability)이 이제 다른 구현(implementation)을 가리키는 경우.
따라서 인자의 동일성은 승인 재사용을 위한 필요조건(necessary condition)이지, 충분조건(sufficient condition)은 아닙니다.
이것이 핵심적인 차이점입니다:
구조적 무결성 (Structural integrity):
이것이 동일한 요청인가?
...
견고한 시스템에는 두 가지 모두가 필요합니다.
4. 승인을 무효화할 수 있는 네 가지 유형의 드리프트
승인의 신선도(freshness)는 단일 체크 항목이 아닙니다. 이는 서로 다른 컴포넌트들이 소유한 체크 항목들의 집합입니다.
4.1 요청 드리프트 (Request drift)
기능(capability), 정규화된 인자(canonical arguments), 신뢰할 수 있는 주체(trusted subject), 테넌트(tenant), 또는 작업 ID(task identity)가 승인된 엔벨로프(envelope)와 더 이상 일치하지 않는 경우입니다.
예상 동작: 디스패치하지 마십시오. 동일한 내구적 작업(durable task)을 승인 필요(approval-required) 상태로 되돌리거나, 디스패치 전에 거부하십시오.
4.2 주체 및 권한 드리프트 (Subject and authority drift)
행위 주체(acting subject) 또는 승인자(approver)가 현재 정책에서 요구하는 역할(role), 멤버십(membership), 위임(delegation), 또는 권한(authority)을 더 이상 보유하지 않은 경우입니다.
예상 동작: 권한 있는 시스템(authoritative system)으로부터 신뢰할 수 있는 ID와 권한 부여(authorization)를 다시 확인(re-resolve)하십시오. 모델이 생성한 ID 필드를 절대 신뢰하지 마십시오.
4.3 정책 및 기능 드리프트 (Policy and capability drift)
작업이 일시 중지된 동안 리스크 정책(risk policy), 승인 임계값(approval threshold), 경로 허용 목록(route allowlist), 기능 선언(capability declaration), 또는 도구 구현(tool implementation)이 변경된 경우입니다.
예상 동작: 승인된 정책 및 기능 컨텍스트(context)를 현재 컨텍스트와 비교하십시오. 변경 사항이 실질적(material)이라면, 새로운 결정을 요구하십시오.
4.4 비즈니스 객체 드리프트 (Business object drift)
승인 후 주문(order), 송장(invoice), 계정(account), 재고 항목(inventory item), 배포 대상(deployment target), 또는 기타 비즈니스 객체가 변경된 경우입니다.
기대되는 동작 (Expected behavior): 비즈니스 시스템 또는 동일한 권위 있는 데이터 (authoritative data)를 기반으로 하는 새로운 사전 점검 (preflight) API가 현재 상태와 최종 권한을 다시 평가해야 합니다.
소유권 경계 (ownership boundary)는 다음과 같이 요약할 수 있습니다:
| 무엇이 변경되었을 수 있는가? | 현재 진실(truth)의 자연스러운 소유자 |
|---|---|
| 정형 인자 (Canonical arguments) 및 작업 식별자 (task identity) | 에이전트 런타임 (Agent runtime) 또는 공유 실행 제어 (shared execution control) |
| ... |
단일 승인 서비스가 이러한 모든 진실을 안전하게 생성할 수는 없습니다.
5. 디스패치(Dispatch)가 진정한 체크포인트이다
가장 중요한 검증 순간은 사람이 승인 (Approve) 버튼을 클릭할 때가 아닙니다. 비즈니스 액션이 디스패치(dispatch)되기 직전입니다.
보수적인 재개 경로 (resume path)는 다음과 같습니다:
1. 동일한 내구성이 있는 작업 식별자 (durable task identity)를 로드합니다.
2. 정형 실행 엔벨로프 (canonical execution envelope)를 재구성합니다.
3. 권한 (capability)과 인자 (arguments)가 여전히 승인 증거 (approval evidence)와 일치하는지 확인합니다.
...
만약 디스패치 전 바인딩 (pre-dispatch binding) 중 어느 하나라도 실패한다면, 작업은 조용히 계속 진행되어서는 안 됩니다.
올바른 결과는 보통 다음 중 하나여야 합니다:
awaiting_reapproval (재승인 대기 중)
rejected_pre_dispatch (디스패치 전 거부됨)
정확한 상태 이름은 구현 방식에 따라 다릅니다. 안전성 속성 (safety property)은 다음과 같은 것이 아닙니다:
"우리는 승인 기록을 가지고 있다."
그것은 다음과 같습니다:
"더 이상 유효하지 않은 승인 증거 하에서는 어떠한 비즈니스 디스패치도 발생하지 않는다."
6. 만료 (Expiry)는 재시도 가능한 전송 실패가 아니다
승인 만료는 일시적인 네트워크 오류처럼 처리되어서는 안 됩니다.
다음 시퀀스를 고려해 보십시오:
작업 T가 승인됨
-> 승인이 만료됨
-> 디스패처(dispatcher)가 T의 재개를 시도함
...
안전하지 않은 구현은 인자가 변경되지 않았다는 이유로 새로운 작업을 생성하거나, 자동으로 재시도하거나, 오래된 승인을 재사용할 수 있습니다.
이 세 가지 동작 모두 제어 경계 (control boundary)를 약화시킵니다.
더 안전한 규칙은 다음과 같습니다:
동일한 내구성이 있는 작업 (same durable task)
-> 만료된 승인 감지됨
-> 디스패치 없음
...
단순히 만료된 결정을 우회하기 위해 새로운 작업을 생성하는 것은 연속성 (continuity)을 파괴합니다. 만료를 전송 재시도 (transport retry)로 취급하는 것은 정책 실패 (policy failure)를 전달 실패 (delivery failure)와 혼동하는 것입니다. 오래된 결정을 재사용하는 것은 시간 제한이 있는 승인을 영구적인 권한으로 변질시킵니다.
작업의 정체성 (task identity)은 유지되어야 합니다. 실행에 대한 권한 (authorization)은 그렇지 않을 수 있습니다.
7. 정책 버전은 승인 컨텍스트의 일부입니다
승인 결정은 보통 특정 정책 버전 (policy version) 하에서 생성됩니다:
policy_version = refund-policy-2026-08-01
작업이 재개될 때, 런타임 (runtime)은 다음을 비교할 수 있어야 합니다:
approved_policy_version
current_policy_version
하지만 버전 불일치가 항상 동일한 응답을 요구하는 것은 아닙니다.
| 정책 변경 | 예시 | 가능한 응답 |
|---|---|---|
| 비중요 변경 (Non-material) | 문구 또는 UI 안내 변경 | 증거를 보존하며 계속 진행 |
| ... |
이식 가능한 계약 (portable contract)은 구현체가 관련 정책 컨텍스트 (policy context)를 보존하도록 요구할 수 있습니다. 모든 기업의 '중요한 정책 변경 (material policy change)'에 대한 정의를 표준화하려고 시도해서는 안 됩니다.
그 결정은 배포 정책 (deployment policy)과 해당 규칙을 소유한 권한의 영역입니다.
8. 승인의 신선도 (freshness)가 비즈니스 신선도를 대체할 수는 없습니다
완벽하게 유효한 승인 증거라 할지라도, 해당 주문이 여전히 환불 가능한 상태인지는 증명할 수 없습니다.
승인 계층 (approval layer)은 다음을 알 수 있습니다:
승인자가 SO-1001에 대해 CNY 199.00를 환불하는 것에 동의함
오직 비즈니스 도메인 (business domain)만이 다음을 확실히 알 수 있습니다:
SO-1001이 여전히 존재하는지
현재 테넌트 (tenant)에 속해 있는지
CNY 199.00가 여전히 환불 가능한 상태인지
...
이것이 에이전트 거버넌스 아키텍처 (agent governance architecture)가 최종적인 비즈니스 경계 (business boundary)를 반드시 보존해야 하는 이유입니다.
승인은 필요한 인간의 결정이 발생했다는 증거입니다. 이는 현재의 객체 수준 권한 부여 (object-level authorization), 트랜잭션 제약 조건 (transaction constraints), 테넌트 격리 (tenant isolation), 또는 도메인 불변성 (domain invariants)을 대체하는 것이 아닙니다.
요약하자면:
승인은 실행을 진행할 수 있는지 여부를 제어합니다.
비즈니스 시스템은 그 결과가 존재할 수 있는지 여부를 제어합니다.
9. 경계를 실행 가능하게 만드세요
아키텍처 다이어그램(Architecture diagrams)만으로는 충분하지 않습니다. 승인 유효성(Approval validity)은 서로 다른 구현체들이 실행할 수 있는 실패 시나리오(failure scenarios)로 표현되어야 합니다.
유용한 테스트 케이스 중 하나는 다음과 같습니다:
시나리오: 작업이 일시 중지된 동안 승인이 만료됨
Given:
...
테스트는 또한 다음과 같은 지름길(shortcuts)을 금지해야 합니다:
- 만료된 승인 하에 디스패칭(dispatching)하는 것;
- 만료를 재시도 가능한 전송 오류(retryable transport error)로 취급하는 것;
- 만료를 피하기 위해 새로운 내구적 작업(durable task)을 생성하는 것;
- 이전의 승인을 현재의 비즈니스 권한(business authority)으로 해석하는 것.
구현체는 서로 다른 시계(clocks), 임대(leases), TTL 형식, 상태 이름 및 워크플로 엔진(workflow engines)을 선택할 수 있습니다. 하지만 이들은 여전히 동일한 외부 관찰 가능 속성(externally observable property)을 증명할 수 있어야 합니다.
이것이 바로 "우리는 인간의 승인을 지원합니다"라고 말하는 것과, 실패 및 지연 상황에서도 승인이 여전히 유의미함을 입증하는 것 사이의 차이입니다.
10. 이식 가능한 계약(portable contract)에 포함되어야 할 것과 그렇지 않은 것
모든 런타임(runtime) 관련 사항을 기능 선언(capability declaration)에 추가하여 이 문제를 해결하고 싶은 유혹이 생길 수 있습니다:
approval:
required: true
ttl: 30m
...
이는 이식 가능한 선언을 순식간에 특정 조직 전용의 워크플로 언어로 변질시킵니다.
더 깔끔한 경계는 다음과 같습니다:
이식 가능한 기능 선언 (Portable capability declaration)
이는 특정 작업이 승인 의도(approval intent)와 기타 안정적인 거버넌스 의미론(governance semantics)을 수반함을 표현할 수 있습니다.
런타임 및 승인 권한 (Runtime and approval authority)
이들은 증거 바인딩(evidence binding), 유효성 메타데이터(validity metadata), 만료(expiry), 취소(revocation), 일시 중지 및 재개 동작(pause and resume behavior), 그리고 정책 버전 처리(policy-version handling)를 구현합니다.
비즈니스 시스템 (Business system)
결과(consequence)를 생성하기 직전에 현재 주체 권한(subject authority), 테넌트 경계(tenant boundaries), 객체 상태(object state), 도메인 불변성(domain invariants) 및 최종 권한을 다시 확인합니다.
표준은 가장 작은 단위의 이식 가능한 의미를 기술해야 합니다. 구현체는 운영상의 보장(operational guarantee)을 실질적으로 만들어내야 합니다. 비즈니스 시스템은 자신의 상태에 대한 권한을 유지해야 합니다.
이러한 구분은 의도적인 것입니다. 이는 하나의 스키마가 기업의 ID(identity), 승인 워크플로 또는 비즈니스 인가(business authorization)를 대체할 수 있는 것처럼 가장하지 않으면서도, 계약의 상호 운용성(interoperability)을 유지하게 해줍니다.
11. 실무 검토 체크리스트
에이전트 승인 경로(approval path)를 검토할 때, 다음 사항을 질문하십시오:
- 승인이 정확한 권한(capability) 및 정형 인자(canonical arguments)에 결합되어 있는가?
- 신뢰할 수 있는 주체(trusted subject)가 모델이 생성한 입력값 외부에서 가져와지는가?
- 승인이 유효성(validity) 또는 취소(revocation) 의미론(semantics)을 포함하는가?
- 적용 가능한 정책 버전(policy version)이 보존되는가?
- 실행(dispatch) 전에 중대한 정책 변경 사항이 감지되는가?
- 작업 재개(task resume) 시 하나의 지속적인 작업 식별자(durable task identity)가 유지되는가?
- 만료된 승인은 자동 재시도 대신 재승인 단계로 돌아가는가?
- 안정적인 멱등성 식별자(idempotency identity)가 비즈니스 경계(business boundary)까지 전달되는가?
- 비즈니스 시스템이 현재 객체 상태와 최종 권한(final authority)을 다시 확인하는가?
- 테스트를 통해 유효하지 않은 승인이 비즈니스 효과를 전혀 발생시키지 않음을 증명할 수 있는가?
시스템이 이러한 질문에 답할 수 없다면, approved = true는 거버넌스(governance)를 보장하지 않습니다. 그것은 단지 과거의 기록(historical flag)일 뿐입니다.
결론
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기