에이전트 부작용을 위한 자동 롤백
에이전트 부작용 자동 롤백으로는 모든 외부 작업을 되돌릴 수 없습니다. 스냅샷의 한계와 승인 또는 보상이 필요한 시점을 알아보세요.

에이전트 롤백은 코드, 구성 또는 일부 애플리케이션 데이터를 복원할 수 있습니다. 하지만 다른 조직에 요청을 잊으라고 하거나, 받은편지함에 도착한 이메일을 꺼내 오거나, 카드 청구가 결제 처리업체에 도달하지 않았던 것처럼 만들 수는 없습니다. 이런 작업을 전부 «롤백»이라고 부르는 팀은 결과가 중요한 순간에 정확히 실패하는 안심용 통제 장치를 만들게 됩니다.
안전한 설계는 네 가지 메커니즘을 구분합니다. 애플리케이션 스냅샷, Git 되돌리기, 데이터베이스 복구, 보상 작업입니다. 각각의 경계는 다릅니다. 애플리케이션 경계를 넘는 모든 작업은 에이전트가 실행하기 전에 별도의 승인, 증거, 재시도 규칙, 복구 경로가 필요합니다. 누구도 그 경로를 한 문장으로 설명할 수 없다면, 그 작업은 무인 실행을 맡길 준비가 되지 않은 것입니다.
롤백에는 서로 다른 네 가지 의미가 있습니다
팀이 복원할 상태와 건드릴 수 없는 상태를 분명히 할 때만 롤백은 유용합니다. 이 단어는 보통 보장 수준이 크게 다른 네 가지 메커니즘을 감춥니다.
스냅샷은 캡처한 애플리케이션 또는 작업 공간의 버전을 복원합니다. 제품에 따라 스냅샷에는 생성된 코드, 구성, 선택한 관리 대상 상태가 포함될 수 있습니다. 스냅샷 계약에 명시적으로 포함되지 않는 한 외부 서비스에 대해서는 아무것도 보장하지 않습니다.
Git revert는 이전 커밋의 변경을 반대로 적용하는 새 커밋을 기록합니다. 이력은 삭제하지 않고 소스 이력을 복구합니다. 이전 코드가 실행 중 호출했던 서비스에는 연락하지 않습니다.
데이터베이스 복구는 데이터베이스가 보유한 레코드를 변경합니다. 트랜잭션 롤백은 하나의 트랜잭션에서 커밋되지 않은 쓰기를 버립니다. 백업 복원이나 특정 시점 복구는 데이터베이스 클러스터를 이전 상태 쪽으로 옮기는 훨씬 큰 작업입니다. 어느 쪽도 그 데이터베이스 밖의 시스템을 자동으로 조정하지는 않습니다.
보상 작업은 과거 효과를 상쇄하려는 새 효과를 만듭니다. 환불은 완료된 결제를 보상합니다. 취소 요청은 주문을 보상합니다. 정정 이메일은 잘못 보낸 이메일의 피해를 줄일 수 있지만 첫 메시지를 제거하지는 못합니다. 보상은 원래 작업이 실제로 일어났다는 불편한 사실을 남깁니다.
저는 설계 검토에서 효과 소유권 표를 사용합니다. 정확한 답을 강제하기 때문입니다.
| 변경 | 복구 책임자 | 일반적인 메커니즘 | 원래 효과를 지울 수 있나요? |
|---|---|---|---|
| 생성된 소스 | 애플리케이션 또는 저장소 | 스냅샷 복원 또는 Git 되돌리기 | 보통 앞으로의 실행에 대해서는 가능 |
| 커밋된 행 | 데이터베이스 운영자 | 논리적 정정 또는 복구 | 로컬에서는 경우에 따라 가능 |
| 전달된 이메일 | 메일 제공업체와 수신자 | 후속 메시지 또는 대기 중인 메일 발송 억제 | 불가능 |
| 완료된 결제 | 결제 처리업체 | 무효 처리 또는 환불 | 불가능 |
| 외부 API 요청 | 수신 서비스 | 제공업체별 취소 또는 보상 | 대개 불가능 |
마지막 열이 가장 중요합니다. 반대 작업이 있다고 해서 원래 효과가 사라졌다는 증거는 아닙니다. 감사 기록, 수신자 사본, 정산 기록, webhook, 물리적 작업은 그대로 남을 수 있습니다.
코드 되돌리기는 프로그램을 바꾸지만 과거는 바꾸지 않습니다
코드 되돌리기는 앞으로의 동작을 막거나 바꿉니다. 이전 버전이 이미 일으킨 동작을 되돌리지는 않습니다. 팀이 Git, 플랫폼 스냅샷, 배포 롤백 중 무엇을 쓰든 마찬가지입니다.
Git 문서는 git revert를 이전 커밋이 도입한 변경을 반대로 적용하는 커밋을 기록하는 명령으로 설명합니다. 이 표현은 정확합니다. Git은 저장소 내용에 반대 패치를 적용합니다. 되돌린 커밋이 실행될 때 만들어진 이메일, 결제, 클라우드 리소스, 지원 티켓 또는 파트너 API에 대해서는 알지 못합니다.
에이전트가 청구 함수를 수정하고 배포한 뒤, 모니터링이 결함을 발견하기 전에 두 번 호출했다고 가정해 보겠습니다. 커밋을 되돌리면 잘못된 함수가 다시 실행되는 일은 막을 수 있습니다. 그러나 결제 처리업체에는 두 건의 결제 시도가 남아 있습니다. 로컬 데이터베이스가 한 번의 시도만 기록했다면, 두 번째 응답을 이해하던 코드 경로가 사라져 조사 자체가 더 어려워질 수도 있습니다.
배포 롤백도 같은 경계를 가집니다. 트래픽을 이전 빌드로 돌리면 실행 가능한 동작은 복원됩니다. 교체된 빌드가 이미 수락한 요청의 결과는 남습니다. 대기열 작업도 배포를 지나 살아남아, 복원된 버전에 오래된 전제를 적용할 수 있습니다.
되돌리기 전에 이전 빌드가 만든 운영 증거를 보존하세요.
- 배포 식별자와 소스 커밋
- 에이전트 실행 및 의도 식별자
- 큐 메시지 식별자와 임대 상태
- 외부 요청 식별자
- 제공업체 응답과 타임스탬프
그런 다음 새 실행을 멈추고, 미완료 작업을 조정한 뒤, 코드를 복원하세요. 먼저 되돌리고 나중에 질문하면 어떤 효과가 외부로 빠져나갔는지 파악할 가장 쉬운 단서를 자주 잃습니다.
스냅샷은 Git 커밋보다 넓은 범위를 가질 수 있지만 같은 원칙이 적용됩니다. 스냅샷 계약은 포함하는 리소스를 정확히 밝혀야 합니다. 코드와 구성을 담는다면 코드 및 구성 복구 메커니즘이라고 부르세요. 인터페이스의 희망적인 표현으로 만능 실행 취소처럼 포장하지 마세요.
데이터베이스 복구의 역할은 사람들이 생각하는 것보다 좁습니다
데이터베이스 복구는 트랜잭션 참여자 전체의 비즈니스 현실이 아니라 데이터베이스 상태를 복원합니다. 하나의 데이터베이스 안에서는 트랜잭션이 원자적일 수 있지만, 그 주변 작업은 여러 시스템에 걸쳐 나뉜 채로 남습니다.
다음 순서를 생각해 보겠습니다.
- 에이전트가 인보이스 행을 삽입합니다.
- 결제 API를 호출합니다.
- 처리업체가 청구를 수락합니다.
- 데이터베이스 커밋이 실패합니다.
로컬 롤백은 인보이스 행을 제거합니다. 청구는 그대로 존재합니다. 조정 없이 전체 작업을 재시도하면 고객에게 다시 청구할 수 있습니다. 이는 고전적인 이중 쓰기 실패입니다. 애플리케이션이 트랜잭션 코디네이터를 공유하지 않는 시스템들에 걸친 하나의 비즈니스 작업을 원자적으로 만들려 했기 때문입니다.
순서를 뒤집어도 해결되지 않습니다. 애플리케이션이 먼저 인보이스를 커밋하고 이후 결제 호출이 실패하면, 데이터베이스에는 미납 인보이스가 남습니다. 이 상태는 조사하기 더 쉽지만, 애플리케이션에는 여전히 payment_pending, payment_confirmed, payment_failed, payment_unknown를 구분하는 상태 머신이 필요합니다.
PostgreSQL 문서는 특정 시점 복구를 기본 백업을 복원한 뒤 선택한 복구 대상까지 write ahead log 레코드를 재생하는 과정으로 설명합니다. 이는 데이터베이스 클러스터를 복구하기 위한 운영자 절차입니다. 에이전트 한 번의 실행만 골라 되돌리는 기능도 아니고, 결제 처리업체나 메일 서비스에 같은 시점으로 돌아가 달라고 요청할 수도 없습니다.
데이터베이스를 과거로 되돌리면 두 번째 불일치가 생길 수 있습니다. 장애 후 10:00으로 복원한다고 해 보겠습니다. 제공업체는 10:07까지 요청을 수락했지만, 복원된 데이터베이스에는 그 기록이 더 이상 없습니다. «누락된» 행을 발견한 에이전트는 7분 동안의 작업을 전부 다시 만들 수 있습니다. 따라서 작업자를 재개하기 전에 외부 조정 단계가 필요합니다.
아웃박스 패턴은 위험한 빈틈 하나를 줄입니다. 애플리케이션은 비즈니스 변경과 효과 의도를 같은 로컬 트랜잭션으로 커밋합니다.
BEGIN;
INSERT INTO invoices (invoice_id, customer_id, status)
VALUES ('inv_2048', 'cust_91', 'payment_pending');
INSERT INTO effect_intents
(intent_id, operation, subject_id, status)
VALUES
('eff_7f31', 'capture_payment', 'inv_2048', 'pending');
COMMIT;
이후 작업자가 eff_7f31을 가져와 안정적인 멱등성 값으로 제공업체를 호출하고 결과를 기록합니다. 아웃박스가 외부 호출을 원자적으로 만들지는 않습니다. 다만 작업 의도가 있었다는 오래 남는 증거를 제공해 재시도와 조정을 가능하게 합니다.
외부 작업에는 보상이 필요하며, 보상이 없는 경우도 있습니다
외부 부작용에는 제공업체별 보상이 필요하거나, 의미 있는 보상이 없다는 명시적 설명이 필요합니다. 모든 작업을 되돌릴 수 있는 것처럼 다루는 일은, 어떤 작업에는 승인이 필요하다고 인정하는 것보다 더 위험합니다.
이메일이 가장 간단한 예입니다. 제공업체가 메시지를 수락하기 전에는 애플리케이션이 대기 중인 작업을 취소할 수 있습니다. 수락 후 제공업체는 짧은 내부 처리 단계에서는 취소를 허용할 수 있지만, 수신자와 메일 시스템 전체를 아우르는 일반적인 회수 보장은 없습니다. 한 번 전달되면 두 번째 메시지로 기록을 바로잡을 수는 있어도 첫 메시지를 지울 수는 없습니다. 민감한 데이터, 법적 고지, 평판상 피해는 이미 노출된 상태입니다.
결제에는 팀이 흔히 «청구됨»으로 뭉뚱그리는 여러 상태가 있습니다. 승인은 지출 가능 한도를 예약합니다. 청구는 그 승인에 따라 자금 이동을 요청합니다. 무효 처리는 아직 정산되지 않은 승인을 해제할 수 있습니다. 환불은 청구 후 돈을 돌려주는 후속 금융 기록을 만듭니다. 이 작업들은 시점, 수수료, 권한, 고객 영향이 서로 다릅니다. 일반적인 undo_payment 도구는 에이전트가 안전하게 행동하는 데 필요한 정보를 가립니다.
다른 API는 더 협조적이지 않을 수 있습니다. 요청은 재고를 주문하거나, 인프라를 프로비저닝하거나, 콘텐츠를 게시하거나, 접근 권한을 부여하거나, 소포를 보내거나, 사람이 일을 시작하게 할 수 있습니다. DELETE 엔드포인트가 있다고 해서 되돌릴 수 있다는 뜻은 아닙니다. 리소스를 삭제해도 감사 로그, 복사된 데이터, 알림, 종속 리소스 또는 물리적 결과가 남을 수 있습니다.
보상은 실제로 달성할 수 있는 일을 기준으로 분류하세요.
- 정확한 로컬 역연산은 제어하는 상태를 이전 값으로 되돌립니다.
- 제공업체 취소는 아직 완료되지 않은 작업을 멈춥니다.
- 금융 보상은 환불 또는 크레딧을 만듭니다.
- 정정 안내는 첫 메시지가 계속 보인다는 사실을 인정합니다.
- 수동 복구는 상황을 안전한 자동 규칙에 담을 수 없는 효과를 처리합니다.
보상도 실패할 수 있습니다. 환불 엔드포인트가 타임아웃될 수 있고, 취소 가능 시간이 지나갈 수 있으며, 수신자 주소가 정정 메시지를 거부할 수 있습니다. 에이전트가 쓰는 계정에 권한이 없을 수도 있습니다. 그래서 시스템은 보상도 자체 의도 식별자, 상태, 시도, 증거, 승인 정책을 갖춘 또 하나의 작업으로 추적해야 합니다.
«롤백을 롤백하는» 재귀 기능을 만들지 마세요. 이력은 작업 원장으로 모델링하세요. 보상으로 새 오류가 생기면 현재 상태를 검토한 뒤 또 다른 명시적 작업을 실행하세요. 이력은 길어지지만, 장애 중에도 이해할 수 있습니다.
멱등성은 반복을 막지만 성공을 되돌리지는 않습니다
멱등성은 재시도가 중복된 의도 효과를 만들지 않도록 보호하지만, 첫 번째 성공 효과를 실행 취소하지는 않습니다. 팀은 이 둘을 자주 혼동하다가 타임아웃이 난 뒤 차이를 발견합니다.
RFC 9110은 여러 개의 동일한 요청이 의도한 효과가 그중 하나의 요청과 같을 때 요청 메서드를 멱등적이라고 정의합니다. 프로토콜 의미론 수준에서 PUT, DELETE, 안전한 메서드를 멱등적이라고 봅니다. POST는 일반적으로 멱등적이지 않지만, API가 자체 계약으로 멱등성 동작을 추가할 수 있습니다.
이 단서가 중요합니다. 멱등적인 DELETE도 실행할 때마다 새 로그 기록, 메트릭 또는 응답을 만들 수 있습니다. 제공업체의 멱등성 구현은 기록을 만료시키거나, 식별자를 한 계정으로 한정하거나, 변경된 매개변수를 거부하거나, 일부 결과만 캐시할 수도 있습니다. HTTP 동사만 보고 보장을 추측하지 말고 제공업체 계약을 읽으세요.
모든 효과 의도에는 첫 시도 전에 안정적인 멱등성 값 하나를 부여해야 합니다. 같은 의도에 대한 재시도에는 그 값을 재사용합니다. 새 비즈니스 의도에는 새 값을 부여합니다. 고객, 금액, 날짜처럼 바뀔 수 있는 매개변수만으로 값을 만들면 안 됩니다. 정상적인 두 구매가 같은 값을 가질 수 있기 때문입니다.
타임아웃은 실패가 아니라 결과를 알 수 없는 상태입니다. 다음 순서를 따르세요.
- 시도를
outcome_unknown으로 표시하고, 대체 의도를 만들지 않습니다. - 멱등성 값 또는 작업 참조값으로 제공업체에 조회합니다.
- 제공업체가 성공을 확인하면 그 성공을 로컬에 기록합니다.
- 작업이 없었다고 확인하면 같은 값으로 재시도합니다.
- 답할 수 없다면 조정 또는 사람의 검토를 위해 작업을 보류합니다.
다음 응답 형태는 에이전트가 수락과 전송 불확실성을 구분하기에 충분한 정보를 제공합니다.
{
"intent_id": "eff_7f31",
"attempt": 2,
"idempotency_key": "eff_7f31",
"transport_status": "timeout",
"provider_status": "unknown",
"provider_reference": null,
"next_action": "reconcile"
}
지원되는 경우 멱등성 값은 로그, 큐 메시지, API 헤더, 제공업체 메타데이터를 통해 전달되어야 합니다. 운영자가 경계 양쪽에서 그 값으로 검색할 수 없다면 복구 중 추측하게 됩니다.
승인은 효과 경계에서 이뤄져야 합니다
승인은 에이전트가 정확한 외부 작업을 구성한 뒤, 첫 번째 되돌릴 수 없는 요청이 시스템을 떠나기 전에 이뤄져야 합니다. 광범위한 작업의 시작 단계에서 승인을 받으면, 이후 에이전트가 수신자, 금액, 범위 또는 도구를 바꿀 여지가 너무 커집니다.
«이 고객의 계정을 처리해»는 카드에 청구하거나 모든 사용자에게 이메일을 보내는 데 충분한 승인이 아닙니다. 유효한 승인은 구체적인 작업을 설명합니다. 수신자, 금액과 통화, 메시지 또는 페이로드 다이제스트, 대상 계정, 도구, 만료 시각, 허용 시도 횟수입니다. 승인된 필드가 하나라도 바뀌면 승인은 더 이상 맞지 않습니다.
유용한 정책은 어느 에이전트나 모델이 요청했는지가 아니라 결과를 기준으로 효과를 분류합니다. 읽기 접근도 개인 데이터를 노출할 수 있지만, 외부로 나가는 작업과 같은 복구 문제를 만들지는 않습니다. 이메일 초안 작성은 로컬에서 되돌릴 수 있습니다. 발송은 경계를 넘습니다. 결제 제안 작성은 로컬 작업입니다. 자금 청구는 경계를 넘습니다.
다음 작업에는 명시적 승인을 요구하세요.
- 돈을 옮기거나 금융 의무를 만드는 작업
- 개인이나 외부 조직에 정보를 보내는 작업
- 제어되는 저장소 밖에서 데이터를 게시, 삭제 또는 공개하는 작업
- 신원, 접근 권한, 소유권 또는 보안 설정을 바꾸는 작업
- 안정적으로 회수할 수 없는 물리적 작업이나 다른 프로세스를 시작하는 작업
결과가 작고 반복적인 작업에는 범위가 제한된 상시 승인을 쓸 수 있습니다. 제한에는 최대 금액, 수신자 집합, 허용 도구, 만료 시각, 비율, 총 작업 횟수가 들어가야 합니다. «청구 승인됨»에는 강제할 수 있는 경계가 없습니다.
승인은 재사용 공격도 막아야 합니다. 변경 불가능한 작업 다이제스트에 연결하고, 정책이 한 번의 실행만 허용하면 사용 완료로 표시하세요. 실행 결과가 알 수 없는 상태가 되었다고 새 승인을 받고 두 번째 의도를 만들면 안 됩니다. 먼저 승인된 의도를 조정하세요.
승인 화면에는 복구의 현실을 쉬운 말로 알려야 합니다. «이 메시지는 전달 후 회수할 수 없습니다»는 유용합니다. 실제 복구가 시간이 걸리고 금융 명세서에 남을 수 있는 환불인데 «이 작업은 되돌릴 수 있습니다»라고 하는 것은 오해를 부릅니다.
도구 계약은 효과의 전체 생명 주기를 드러내야 합니다
에이전트 도구 계약은 의도, 실행, 관찰, 보상을 별도 작업으로 설명해야 합니다. 효과를 수행하고 success: true를 반환하는 단일 함수만으로는 재시도, 승인, 장애 대응에 필요한 증거가 부족합니다.
다음 정책 조각은 강제하기에 충분히 작고 검토하기에 충분히 구체적입니다.
tools:
send_email:
effect: irreversible
approval: required
idempotency_field: intent_id
evidence_field: provider_message_id
compensation: null
capture_payment:
effect: compensatable
approval: required
idempotency_field: intent_id
evidence_field: provider_payment_id
compensation: refund_payment
update_draft:
effect: local_reversible
approval: none
compensation: restore_version
effect는 계획 수립기에 어떤 복구 분류가 적용되는지 알려 줍니다. approval은 정확한 인수가 승인될 때까지 실행을 막습니다. 멱등성 필드는 재시도에서 하나의 식별자를 재사용하게 합니다. 증거 필드는 운영자가 보존해야 할 것을 알려 줍니다. 보상 필드는 원래 호출을 거꾸로 실행할 수 있는 것처럼 가장하는 대신 별도 도구를 가리킵니다.
실행은 변경 불가능한 봉투를 받아야 합니다.
{
"intent_id": "eff_7f31",
"operation": "capture_payment",
"arguments": {
"invoice_id": "inv_2048",
"amount_minor": 12900,
"currency": "USD"
},
"approval": {
"approval_id": "apr_662",
"scope_hash": "sha256:8b4f...",
"expires_at": "2026-07-27T18:00:00Z"
}
}
실행기는 작업 다이제스트를 계산하고, scope_hash와 비교하며, 만료 여부를 확인하고, 의도를 예약한 뒤에만 제공업체에 연락합니다. 호출 전에는 요청 메타데이터를 저장하고, 호출 뒤에는 응답을 저장합니다. 이 기록 사이에 중단되더라도 오래 남는 의도는 조정을 위해 계속 사용할 수 있습니다.
실행기는 즉흥적으로 처리하지 말고 네 가지 조건을 거부해야 합니다. 변경된 인수, 만료된 승인, 다른 작업에 의도를 재사용하는 경우, 성공 완료가 확인되지 않은 효과를 보상하려는 시도입니다. 에이전트는 그럴듯한 다음 단계를 잘 찾아냅니다. 금융과 커뮤니케이션 통제는 그럴듯한 추측보다 분명한 중단을 택해야 합니다.
get_payment_status(intent_id) 같은 관찰 전용 도구를 별도로 제공하세요. 관찰은 효과를 만들면 안 됩니다. 이를 분리하면 에이전트는 원래 작업을 재시도할 권한을 받지 않고도 모호한 결과를 해결할 수 있습니다.
한 번의 실패한 실행도 모든 복구 경계를 넘을 수 있습니다
에이전트 한 번의 실행으로 코드, 데이터베이스 레코드, 외부 시스템이 서로 다른 시점에 남을 수 있습니다. 출시 전에 이런 실패를 따라가 보면 일반적인 롤백 제어가 감추는 빈틈이 드러납니다.
에이전트가 회원 가입 애플리케이션을 만들고, 변경을 배포하고, 고객 목록을 가져오고, 연회비를 청구하고, 환영 이메일을 보낸다고 가정해 보겠습니다. 하나의 작업처럼 들리지만 최소 네 가지 복구 경계를 넘습니다.
14:00에 에이전트는 잘못된 열에서 연회비를 계산하는 코드를 배포합니다. 14:02에 결제 의도 40건과 이메일 초안을 데이터베이스에 씁니다. 14:03에 작업자가 여러 결제를 청구합니다. 14:04에 메일 제공업체는 잘못된 회비가 담긴 환영 메시지를 수락합니다. 14:05에 모니터링이 작업자를 멈춥니다. 일부 결제 호출은 처리업체에 도달한 뒤 타임아웃되어, 로컬 상태만으로는 성공 여부를 알 수 없습니다.
13:59 코드 스냅샷을 복원하면 이후 실행에서 잘못된 계산을 멈출 수 있습니다. Git 커밋을 되돌려도 소스 수정 내역을 남길 뿐 같은 한계가 있습니다.
데이터베이스를 13:59로 복원하면 제공업체 참조값과 멱등성 값을 담은 로컬 의도 기록이 사라집니다. 외부 불일치가 더 심해집니다. 더 나은 데이터베이스 조치는 논리적 정정입니다. 의도를 보존하고, 불확실한 작업을 조정 대상으로 표시하며, 제공업체 상태를 대조한 뒤에만 행을 정정합니다.
이후 대응 팀은 효과 분류에 따라 진행해야 합니다. 안정적인 작업 식별자로 모든 불확실한 결제를 조회합니다. 확인된 청구는 환불 검토로 옮기고, 실패한 시도는 재시도 없이 종료하며, 해결되지 않은 시도는 차단된 상태로 둡니다. 이미 전달된 이메일에는 신중하게 승인된 정정 메시지를 보냅니다. 아직 제공업체에 도달하지 않은 대기 메시지는 취소합니다. 각 보상에는 원래 작업에 연결된 새 의도를 부여합니다.
이 예시는 자동 보상이 위험한 이유도 보여 줍니다. 시스템이 로컬 payment_unknown 기록을 즉시 모두 환불하면 존재하지 않았던 청구에 환불을 내거나 잘못된 참조값으로 환불 엔드포인트를 호출할 수 있습니다. 데이터베이스 복구 뒤 누락된 이메일을 모두 다시 보내면 수신자에게 중복 메시지가 갈 수 있습니다. 로컬 상태와 제공업체 상태가 다를 때는 보상보다 조정이 먼저여야 합니다.
모든 의도가 succeeded, confirmed_failed, compensated, manual_exception 같은 최종 상태에 도달해야 실행이 완료됩니다. «애플리케이션을 롤백했다»는 말은 장애 대응의 첫 부분만 설명합니다.
증거가 남아야 복구할 수 있습니다
롤백이 무슨 일이 일어났는지 판단하는 데 필요한 기록까지 지우면 복구 통제는 실패합니다. 일반적인 스냅샷이나 복원으로 교체되지 않는 애플리케이션 상태 밖에 추가 전용 효과 원장을 저장하고, 각 작업을 조정할 수 있는 충분한 제공업체 증거를 보존하세요.
원장에는 의도 생성, 인수 다이제스트, 승인, 실행 임대, 시도, 전송 결과, 제공업체 참조값, 관찰한 제공업체 상태, 보상 연결을 기록해야 합니다. 에이전트가 이전 항목을 덮어쓰게 두지 말고 상태 전환만 허용하세요. 정정은 이력을 고치는 대신 새 이벤트를 추가해야 합니다.
명시적인 오류뿐 아니라 해결되지 않은 상태도 모니터링하세요. 10분 동안 그대로인 outcome_unknown은 운영자가 수동으로 재시도할 수 있으므로 명확한 거부보다 더 위험할 수 있습니다. 실행 중 승인이 만료되거나, 멱등성 값이 다른 인수 다이제스트와 함께 나타나거나, 보상이 실패할 때도 알림을 보내세요.
불편한 실패 지점을 의도적으로 넣어 복구 훈련을 하세요. 제공업체가 요청을 수락한 뒤 로컬 성공 기록 전에 작업자를 종료합니다. 효과 원장은 보존한 채 애플리케이션 데이터를 이전 스냅샷에서 복원합니다. 계획과 실행 사이에 승인을 만료시킵니다. 관찰 API를 사용할 수 없게 만듭니다. 시스템이 멈추고, 조정하며, 효과를 중복하지 않고 해결되지 않은 결정을 드러낼 때 훈련은 통과입니다.
Koder.ai를 사용할 때는 그 스냅샷과 롤백을 애플리케이션 복구 계층으로 다루고, 데이터베이스 이력과 애플리케이션이 일으킬 수 있는 모든 외부 작업에는 별도의 통제를 설계하세요. 소스 내보내기, 배포 통제, 롤백은 소프트웨어 복구에 도움이 되지만, 애플리케이션의 도구 계약은 승인과 보상을 계속 책임져야 합니다.
롤백 버튼 옆에는 그 경계를 표시해야 합니다. 코드, 구성, 관리 데이터 또는 외부 효과입니다. 인터페이스가 그 문장을 정확히 쓸 수 없다면 롤백을 약속해서는 안 됩니다. 정직한 통제는 덜 마법처럼 보일 수 있지만, 새벽 2시에 대응 팀이 필요한 한 가지를 제공합니다. 무엇이 바뀌었고, 무엇이 외부로 나갔으며, 다음에 어떤 작업을 해도 안전한지에 대한 믿을 수 있는 설명입니다.
자주 묻는 질문
AI 에이전트를 롤백하면 이메일 발송을 취소할 수 있나요?
아니요. 이메일 요청 전의 코드나 애플리케이션 스냅샷은 복원할 수 있지만, 메일 제공업체가 이미 수락한 메시지를 회수할 수는 없습니다. 시스템은 발송 전에 승인을 받고, 제공업체 응답을 오래 보관해야 합니다.
자동 롤백으로 신용카드 결제를 되돌릴 수 있나요?
대체로 불가능합니다. 롤백으로 결제 처리업체 기록에서 이미 정산된 결제를 지울 수는 없으며, 시스템은 새 금융 거래로 환불을 처리해야 합니다. 아직 청구되지 않은 승인 금액은 취소할 수 있을지 모르지만, 이 역시 코드 롤백이 아니라 명시적인 결제 작업입니다.
Git revert는 실제로 무엇을 되돌리나요?
Git revert는 이전 코드 변경의 반대 내용을 적용하는 새 커밋을 만듭니다. 데이터베이스 행을 복원하거나, API 요청을 취소하거나, 이미 도착한 메시지를 삭제하거나, 결제를 환불하지는 않습니다. 소스 이력 복구 수단으로만 다루세요.
데이터베이스 롤백은 외부 API 호출도 취소하나요?
데이터베이스 트랜잭션은 아직 커밋되지 않은 로컬 쓰기를 롤백할 수 있습니다. 커밋 후에는 복구 과정에서 데이터베이스를 이전 상태로 되돌릴 수 있지만, 이 과정은 관계없는 유효한 쓰기까지 제거할 수 있고 외부 시스템의 작업은 되돌릴 수 없습니다. 만능 실행 취소 버튼이 아니라 복구 절차로 사용하세요.
멱등성 키는 롤백과 같은 것인가요?
아니요. 멱등성 키는 제공업체가 올바르게 구현했을 때 반복 시도가 중복 효과를 만들지 않도록 합니다. 첫 번째 성공 요청을 취소하지도 않고, 같은 식별자를 쓴 다른 요청이 안전하다는 보장도 하지 않습니다.
어떤 에이전트 작업에 사람의 승인이 필요한가요?
애플리케이션 밖에서 법적, 금전적, 개인정보, 평판 또는 운영상 결과를 만들 수 있는 작업에는 승인이 필요합니다. 메시지 발송, 결제 승인, 데이터 게시, 접근 권한 변경, 주문, 물리적 작업을 시작하는 API 호출 등이 여기에 해당합니다. 읽기 작업과 로컬 초안에는 보통 같은 수준의 통제가 필요하지 않습니다.
외부 API를 호출하기 전에 에이전트는 무엇을 기록해야 하나요?
의도 식별자, 정확한 인수, 권한 부여, 승인 범위, 멱등성 값, 시도 번호, 제공업체 참조값, 응답 상태, 보상 상태를 기록하세요. 실행 전 기록을 저장하고 매 시도 후 갱신해야 합니다. 조사 중인 롤백 과정에서 애플리케이션 로그만으로는 기록을 너무 쉽게 잃을 수 있습니다.
에이전트가 타임아웃된 요청을 안전하게 재시도하려면 어떻게 해야 하나요?
작업이 실제로 멱등적이거나 수신 서비스가 안정적인 멱등성 값을 인식할 때만 재시도가 안전합니다. 호출자가 응답을 받지 못했어도 첫 요청은 성공했을 수 있으므로 타임아웃 결과는 모호합니다. 가능하면 새 요청을 보내기 전에 같은 작업 식별자로 제공업체에 조회하세요.
보상 작업은 언제 자동으로 실행해야 하나요?
외부 작업에 의미 있는 반대 작업이 있고 정책이 허용할 때 보상을 사용하세요. 환불, 취소 요청, 정정 메시지는 기존 이력을 지우는 대신 새 이력을 추가하므로 보상에 해당합니다. 또 다른 청구, 메시지, 권한 변경 또는 법적 약속을 만들 수 있다면 무조건 자동화해서는 안 됩니다.
에이전트 도구의 롤백 안전성은 어떻게 테스트하나요?
제공업체가 요청을 수락한 뒤 에이전트가 성공을 기록하기 전에 타임아웃이 나도록 스테이징 환경에서 훈련하세요. 시스템이 작업 식별자로 상태를 조정하고, 중복을 피하며, 모든 보상을 기록하는지 확인합니다. 만료된 승인, 변경된 인수, 제공업체의 부분 장애, 애플리케이션 데이터 복원 후의 복구도 테스트하세요.