AI 처리 중 재시도(Retry)가 안전한가? - Idempotency와 Crash Recovery 실험
요약
본 글은 AI가 요청한 작업을 외부 API로 전송했을 때, 응답이 지연되거나 끊겼을 경우 발생하는 재시도(Retry)의 안전성을 다룹니다. 네트워크 문제 등으로 인해 '결과를 알 수 없음' 상태일 때, 실제 처리가 성공했는지 실패했는지 구분하는 것이 중요하며, 이 문제를 Idempotency와 Crash Recovery 관점에서 접근해야 합니다.
핵심 포인트
- 재시도는 불가피하므로, 안전한 설계가 핵심입니다.
- Timeout은 '처리 실패'를 의미하지 않습니다. 결과 알 수 없음과 처리가 실패함은 다릅니다.
- 같은 작업을 여러 번 실행해도 문제가 없도록 Idempotency를 확보해야 합니다.
- AI의 추론 정확도와 재시도의 안전성은 별개의 문제입니다.
서론
지난 글에서는 AI에게 여러 작업을 맡길 경우, Transaction이나 Atomicity가 중요하다는 것을 실험했습니다.
AI가
A를 실행한다
B를 실행한다
C를 실행한다
와 같은 여러 작업을 요구했을 때, 도중에 C가 실패했다고 해서 A와 B만 실행된 상태를 그대로 남겨도 되는 것은 아닙니다.
따라서,
- Validation
- Authorization
- Access Control
- Transaction
- Atomicity
등을 통해 처리 전체를 안전하게 관리해야 합니다.
하지만 여기서 또 다른 문제가 발생합니다.
예를 들어, AI가 요구한 작업을 외부 API로 전송했지만 응답이 돌아오지 않았다고 가정해 봅시다.
애플리케이션은
"처리에 실패한 것이 아닐까?"
라고 판단하여 같은 작업을 다시 실행할 수 있습니다. (재시도, Retry)
그런데 실제로는 외부 API에서 이미 처리가 성공했을 수도 있습니다.
그렇게 되면,
1회차 → 성공
2회차 → Retry
이 되어 같은 작업이 두 번 실행될 가능성이 생깁니다.
이번 글에서는 이 문제를 Idempotency, Race Condition, Crash Recovery라는 관점에서 실험해 보겠습니다.
이번 질문
이번의 질문은,
처리 결과가 알 수 없을 때, 그 처리를 재시도해도 안전한가?
더 나아가 실험을 진행하면 다음과 같은 질문들이 생겨납니다.
- 같은 작업을 2번 실행해도 안전할까?
- Idempotency Key만으로 중복 실행을 막을 수 있을까?
- 동시에 재시도되면 어떻게 될까?
- 처리 도중에 애플리케이션이 Crash하면 어떻게 될까?
- 외부 시스템에서는 성공했지만, 애플리케이션 측에 기록이 남아있지 않으면 어떻게 할까?
여기서는 단순히 "재시도를 금지하는" 것이 아니라,
재시도되는 것을 전제로, 처리를 안전하게 설계할 수 있는지
를 생각합니다.
'응답 없음'과 '처리 실패'는 같지 않다
먼저 매우 중요한 점이 있습니다.
Timeout
이 발생했다고 해도,
Operation failed
을 의미하는 것은 아닙니다.
예를 들어,
Application
│
│ Request
...
와 같은 상황을 생각해 봅시다.
애플리케이션의 관점에서는
"응답이 돌아오지 않았다"
라는 사실밖에 알 수 없습니다.
하지만 External API 측에서는 이미 처리가 완료되었을 가능성이 있습니다.
즉,
「결과를 알 수 없음」
것과,
「처리가 실패함」
은 별개입니다.
이 차이를 생각하지 않고,
Timeout
↓
실패
...
로 처리해 버리면, 같은 작업을 두 번 실행할 가능성이 생깁니다.
PI-036: 재시도로 인한 중복 실행
PI-036에서는 이 상황을 단순화하여 실험했습니다.
예를 들어, 알림을 보내는 처리(Send notification)가 있었다고 가정해 봅시다.
Application
│
│ Send notification
...
애플리케이션은 응답을 받을 수 없기 때문에,
"실패한 것이 아닐까?"
라고 판단합니다.
그리고 재시도(Retry)를 합니다.
그 결과,
1회차 → 알림 성공
2회차 → 알림 성공
이 되어,
알림이 2번 전송될
가능성이 생깁니다.
여기서 중요한 것은, AI가 틀린 것이 아니라는 점입니다.
AI가 처음에 올바른 작업을 판단했더라도,
- 네트워크 장애
- Timeout
- Response loss
- 외부 서비스 장애
등에 의해 재시도는 발생합니다.
즉, 이것은 AI의 추론 정확도와는 별개의 문제입니다.
AI가 관련되어도, 재시도의 안전성은 애플리케이션 측에서 고려해야 한다
여기까지 오면, AI와 애플리케이션의 책임 범위를 명확히 분리할 필요가 있습니다.
예를 들어,
AI
↓
「후보자 123에게 알림을 보내라」
라는 판단을 AI가 했다고 가정해 봅시다.
AI의 역할은,
어떤 작업을 수행해야 할지 판단하고 제안하는 것입니다.
반면,
Application
↓
Notification API
와 같은 실제 처리를 안전하게 실행할 책임은 애플리케이션 측에 있습니다.
따라서,
AI
│
│ Action Request
...
이러한 역할 분담이 이루어집니다.
여기서도,
AI가 요청한 것과, Application이 안전하게 실행할 수 있는 것은 별개라는 점을
지금까지의 기사에서 확인했던 사고방식이 다시 등장합니다.
AI가 Retry 할 가능성이 있다고 해서, AI에게 Idempotency를 기대하는 것이 아닙니다.
Application 측에서, Retry 되어도 안전한 메커니즘을 구현해야 합니다.
PI-037: Idempotency Key
여기서 등장하는 것이 Idempotency입니다.
동일한 논리적 작업에 대해,
idempotency_key = abc123
와 같은 고유 식별자를 부여합니다.
첫 번째 요청에서는,
abc123
↓
처리 실행
...
으로 진행됩니다.
그 후, 동일한 작업이 Retry 되었을 경우에는,
abc123
↓
이미 처리됨
...
으로 진행합니다.
개념적으로는,
Request
│
▼
...
와 같은 메커니즘입니다.
이를 통해,
Retry
그 자체를 금지하는 것이 아니라,
Retry 되어도 동일한 작업을 이중으로 실행하지 않도록 하는 설계가 가능해집니다.
'Retry하지 않기'보다 'Retry되어도 망가지지 않기'
여기는 이번 실험에서 특히 중요한 포인트입니다.
AI 에이전트를 사용한 시스템에서는,
AI에게 Retry를 시키지 않는다
라는 규칙만으로 안전성을 확보하기는 어려울 것입니다.
AI뿐만 아니라, Application이나 네트워크, 외부 서비스에서도 Retry가 발생할 수 있기 때문입니다.
따라서,
Retry를 완전히 막는다
가 아니라,
Retry되어도 안전하다
라는 설계를 고려해야 합니다.
이는 AI에만 국한된 생각이 아닙니다. 오히려, 기존의 분산 시스템에서 축적되어 온 사고방식을 AI 에이전트의 실행계에도 적용하고 있다고 볼 수 있습니다.
PI-038: Idempotency에도 Race Condition이 있다
하지만, Idempotency Key를 도입한다고 해서 그것만으로 안전해지는 것은 아닙니다.
예를 들어, 다음과 같은 구현을 생각해 보겠습니다.
if not exists(idempotency_key):
execute()
register(idempotency_key)
언뜻 보기에는 문제가 없어 보입니다. 하지만, 동시에 2개의 요청이 온 경우,
Request A Request B
│ │
├─ Check │
...
가 될 가능성이 있습니다.
결과적으로,
동일한 작업이 2번 실행된다
가능성이 생깁니다. 이것은 Race Condition입니다.
즉,
'처리 여부를 확인하는 것'
과,
'처리를 등록하는 것'
사이의 사이에 다른 처리가 끼어들 수 있다는 점이 문제입니다.
Idempotency를 구현할 때도, 상태를 안전하게 업데이트할 수 있는 메커니즘이 필요합니다.
PI-039: Lock으로 경쟁을 막는다
PI-039에서는 이 경쟁을 막기 위한 Lock을 다룹니다.
개념적으로는,
Request A
│
▼
...
와 같은 처리를 합니다. 이 사이에 Request B가 온 경우,
Request B
│
▼
...
이 됩니다.
A의 처리가 끝난 후에 B가 확인하면,
Already processed
라고 판단할 수 있으므로, 이중 실행을 막을 수 있습니다.
여기서부터는,
Idempotency를 실현하기 위해서도, 상태를 안전하게 관리해야 한다는 점을 알 수 있습니다.
PI-040: Crash하면 더욱 어려워진다
더 어려운 케이스를 생각해 보겠습니다.
예를 들어,
Check
↓
Register Idempotency Key
...
순서였던 경우입니다. Idempotency Key는 등록되어 있습니다.
하지만, External Operation은 실행되지 않았습니다.
그렇게 재부팅된 후,
'이미 처리됨'
이라고 판단하여, 원래 실행되어야 할 작업이 실행되지 않을 가능성이 있습니다.
역의 케이스도 있습니다.
External Operation
↓
성공
...
이 경우,
External Operation → 성공
Idempotency Record → 없음
이 경우, 재시도(Retry)를 하면,
External Operation
↓
다시 실행하기
가 되어 이중 실행으로 이어질 가능성이 있습니다.
여기서 단순한 Idempotency Key만으로는 문제를 충분히 표현할 수 없다는 것을 알 수 있습니다.
PI-041: Idempotency 상태 관리
이 문제에 대응하기 위해서는,
Key가 존재하는지
뿐만 아니라,
해당 처리가 현재 어떤 상태인지
를 관리해야 합니다.
예를 들어,
PENDING
SUCCESS
FAILED
와 같은 상태를 생각할 수 있습니다.
┌─────────┐
│ PENDING │
└────┬────┘
...
이처럼 상태를 가짐으로써,
'Key가 있다'
만으로는 알 수 없는,
'실제로 처리가 완료되었는지'
라는 정보를 다룰 수 있게 됩니다.
물론 실제 시스템에서는 상태 설계나 이상 케이스 처리는 훨씬 복잡해집니다.
중요한 것은,
Idempotency는 단순한 중복 체크가 아니라, 실행 상태를 관리하는 메커니즘이라는 점입니다.
PI-042: 외부 처리 후 Crash Recovery
나아가서,
External Operation
↓
SUCCESS
...
와 같은 케이스를 생각해 볼 수 있습니다.
External System에서는 처리가 성공했지만, Application 측에서는 그 결과를 기록하지 못했을 가능성이 있습니다.
이 상태에서 복구하려면,
지난 실행 상태
↓
External System의 상태
...
를 판단해야 합니다.
즉,
Retry = 일단 다시 실행한다
가 아닙니다.
실제로는,
현재 상태를 확인한 후, 필요하다면 재실행한다는
Recovery 처리
이 필요합니다.
여기서는 Retry와 Recovery를 분리해서 생각하는 것이 중요합니다.
Retry는 '다시 요청한다'는 것이지만, Recovery는 '현재 상태를 파악하고 다음에 무엇을 해야 할지 판단한다'는 것이기 때문입니다.
PI-043: External System 자체가 Idempotency 보장
여기서 다른 접근 방식도 있습니다.
Application만으로 Idempotency를 관리하는 것이 아니라, External API 자체가 Idempotency를 보장하는 방법입니다.
Application
│
│ Request + Idempotency Key
...
이 경우, External System이,
동일한 Idempotency Key
를 가진 요청을 중복 실행하지 않도록 합니다.
이것은 중요한 포인트입니다.
AI를 사용한 시스템의 안전성을 생각할 때,
AI
↓
Application
...
와 같은 시스템 전체를 봐야 합니다.
AI만 안전하게 하더라도, 연결된 API가 재실행을 안전하게 처리하지 못하면, 시스템 전체로는 안전해지지 않습니다.
PI-044: Idempotency Key와 Payload
마지막으로, 또 하나의 문제가 있습니다.
예를 들어,
Idempotency Key = abc123
에 대해 첫 번째 요청이,
abc123
candidate = A
이었다고 가정해 봅시다.
그런데 Retry 시에,
abc123
candidate = B
라는 요청이 온다면 어떨까요?
단순히,
abc123는 처리됨
이라고 판단해 버리면, 다른 요청을 동일시하게 됩니다.
따라서,
Idempotency Key
+
Request Payload
를 조합하여 관리하는 방법이 생각될 수 있습니다.
예를 들어,
abc123 + candidate A
로 등록되어 있는데,
abc123 + candidate B
가 온 경우,
Same Key
Different Payload
↓
...
와 같이 거부하는 설계입니다.
여기까지 생각해보면, Idempotency란 단순한 '이중 실행 방지'가 아니라,
동일한 논리적 작업을 유일하게 식별하기 위한 메커니즘이라는 것을 알 수 있습니다.
그렇다는 것을 알 수 있습니다.
실험 결과를 비교하기
이번 실험을 정리하면, 문제는 다음과 같이 확장되었습니다.
| 실험 | 확인한 문제 | 거기서 알 수 있는 것 |
|---|---|---|
| PI-036 | Retry로 인한 이중 실행 | Timeout이 처리 실패를 의미하지는 않는다 |
| ... | ||
| 첫 번째 질문은, |
"Retry해도 괜찮을까?"
이었습니다.
하지만 실험을 진행하면서, 단순히 Retry의 가능 여부만 판단하는 것만으로는 충분하지 않았습니다.
Retry
↓
이중 실행
...
와 같이, 처리 상태 자체를 관리할 필요가 있습니다.
AI가 정확해도 시스템은 실패한다
이번 실험을 통해 중요한 점 하나를 알 수 있습니다.
AI가,
"이 작업을 실행해 주세요"
라고 정확하게 판단했더라도,
Network Error
Timeout
Race Condition
...
에 의해 시스템은 실패할 가능성이 있습니다.
반대로, AI가 예상치 못한 타이밍에 Retry하더라도,
Idempotency
Authorization
State Management
등이 적절하게 설계되어 있다면, Application 측에서 안전하게 처리가 가능할 수도 있습니다.
즉,
AI의 판단을 정확하게 하는 것만이 안정성을 높이는 방법은 아닙니다.
AI 바깥쪽에,
AI가 같은 작업을 반복하더라도, 혹은 처리 도중에 멈추더라도, 시스템이 망가지지 않는 메커니즘
을 만드는 것도 중요합니다.
이는 지금까지의 기사에서 다루었던,
AI의 판단
↓
Application에 의한 제어
...
라는 경계를 한 단계 더 깊게 만든 것이라고 할 수 있습니다.
Transaction과 Idempotency는 역할이 다르다
지금까지의 기사를 되돌아보면, Transaction과 Idempotency는 비슷해 보이지만 해결하는 문제가 다릅니다.
Transaction / Atomicity가 주로 다루는 것은,
여러 처리를 하나의 논리적인 단위로 안전하게 완료하거나 Rollback할 수 있는지
라는 문제입니다.
반면, Idempotency가 다루는 것은,
같은 논리적 처리가 여러 번 요청되어도 안전하게 처리할 수 있는지
라는 문제입니다.
예를 들어,
복수 작업
↓
Transaction / Atomicity
...
과,
동일 작업의 재실행
↓
Idempotency
...
은 각각 다른 문제입니다.
그리고 실제 시스템에서는 둘 다 필요할 때가 있습니다.
여기는 Application 측의 책임이 된다
이번에 다룬,
- Transaction
- Atomicity
- Idempotency
- Lock
- Retry Control
- State Management
- Crash Recovery
은 기본적으로 Application 측에서 구현하는 메커니즘입니다.
AI에게,
"이중 실행하지 마세요"
라고 지시하는 것만으로는 충분하지 않습니다.
왜냐하면, AI의 출력은 Application의 실행 제어 그 자체가 아니기 때문입니다.
예를 들어,
AI
│
"알림을 전송한다"
...
라는 구조로 만든 경우,
AI는 작업을 제안하고, Application이 안전하게 실행한다
라는 역할 분담이 됩니다.
이는 이번 실험을 통해 더욱 명확해진 부분입니다.
AI에게 무엇을 맡기고, 무엇을 Application에 맡길 것인가
지금까지의 실험을 정리하면, AI와 Application의 역할이 조금씩 보이기 시작합니다.
AI
│
├─ 정보 이해
...
AI는 상황을 이해하여 판단하거나 작업을 제안하는 부분에서 강점을 발휘할 수 있습니다.
반면,
"그 작업을 실제로 실행해도 되는가"
"몇 번 실행되어도 안전한가"
"도중에 실패하면 어떻게 복구하는가"
와 같은 시스템 상태 관리는 Application 측에서 제어할 수 있습니다.
여기까지 살펴보면,
AI를 신뢰하느냐, 신뢰하지 않느냐
라는 이분법만으로는 AI를 통합한 시스템의 안정성을 충분히 설명할 수 없다는 것을 알게 됩니다.
중요한 것은,
AI에게 판단을 맡기는 부분과 Application이 제어하는 부분의 경계를 설계하는 것입니다.
이번 실험에서 알게 된 것
이번 실험에서는 Retry라는 겉보기에는 단순한 처리부터, 다음과 같은 문제로 연결된다는 것을 확인했습니다.
타임아웃
↓
결과를 알 수 없음
...
특히 중요한 것은,
'재시도할지 여부'가 아니라, '재시되더라도 안전한지'
를 생각하는 것입니다.
또한, Idempotency에 대해서도,
Key가 존재한다
것만으로는 충분하지 않습니다.
같은 작업인지
현재 어느 상태인지
외부 처리는 완료되었는지
...
와 같은 상태까지 고려할 필요가 있습니다.
그리고 이 문제는 AI 고유의 것이 아닙니다.
전통적인 Web 애플리케이션이나 분산 시스템에서 다루어져 온 문제가, AI 에이전트에 의해 'AI가 조작을 요구한다'는 새로운 진입점을 가지면서 다시 중요해지고 있다고 생각합니다.
다음 문제 — 애초에 AI의 판단은 올바른가?
지금까지의 실험에서는 Application 측에서 AI가 내린 판단이나 조작을 안전하게 처리하는 방법을 생각해 왔습니다.
여기서 또 다른 근본적인 의문이 남습니다.
애초에, AI가 처음 내린 판단 자체가 올바른 것일까요?
예를 들어 AI에게,
이 Python 코드의 답을 찾아주세요.
라고 질문했다고 가정해 봅시다.
AI가,
답은 42입니다.
라고 답변했더라도, 그것만으로는 정말로 42인지 알 수 없습니다.
그렇다면,
AI 스스로 그 답변이 올바른지 평가하게 한다면 어떻게 될까요?
더 나아가,
답변을 생성하는 AI와는 별도의 AI에게 평가하게 한다면 어떨까요?
여기서는 지금까지와 조금 다른 문제를 다룹니다.
지금까지의 실험에서는,
AI
↓
Application
...
라는 경계를 중심으로 생각해 왔습니다.
다음으로는,
AI
↓
판단・답변
...
이라는, AI 자체 판단의 평가에 초점을 맞춥니다.
다음 실험에서는,
- Self Evaluation
- Independent Evaluation
- AI-as-Judge
- Known Answer에 의한 평가
- Hallucination
- Claim Verification
등을 통해,
'AI는 자신이나 다른 AI의 답변의 정확성을 어느 정도까지 평가할 수 있는가?'
를 실험해 볼 것입니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기