AI 에이전트의 데모는 대개 한 번에 끝납니다. 사용자가 요청을 입력하면 모델이 계획을 만들고, 몇 개의 도구를 호출한 다음 결과를 보여줍니다. 그러나 실제 업무는 그렇게 단순하지 않습니다. 견적서를 만들려면 고객 정보와 재고를 확인해야 하고, 할인 승인을 기다려야 하며, ERP에 주문을 등록하고, 결제 승인과 알림까지 이어져야 합니다. 담당자가 다음 날 승인할 수도 있고 외부 API가 잠시 멈출 수도 있습니다.
이때 서버가 재시작되면 어디서부터 다시 시작해야 할까요? 결제 요청까지 성공했는데 응답을 받기 전에 연결이 끊겼다면 같은 결제를 다시 실행해도 될까요? 사용자가 중간에 취소하면 이미 예약한 재고와 발행한 문서는 어떻게 되돌려야 할까요?
이 문제를 해결하는 핵심이 Durable Execution, 즉 내구성 있는 실행입니다. 실행 과정을 기억하고, 장애가 나도 마지막으로 안전하게 완료한 지점부터 이어가며, 외부 시스템에 같은 효과를 두 번 만들지 않는 구조입니다. 2026년의 AI 에이전트가 단순한 챗봇을 넘어 실제 업무를 맡기 시작하면서 이 구조는 선택 기능이 아니라 운영 기반이 되고 있습니다.
긴 모델 호출과 긴 업무 프로세스는 다르다
먼저 자주 혼동하는 두 가지를 분리해야 합니다. 모델의 백그라운드 실행은 오래 걸리는 하나의 추론 요청을 비동기로 처리하고 상태를 조회하는 기능입니다. 반면 업무의 내구성 있는 실행은 모델 호출, 데이터 조회, 사람 승인, 외부 API, 대기 타이머, 보상 작업을 포함한 전체 프로세스의 생명주기를 관리합니다.
예를 들어 모델이 8분 동안 계약서를 분석하는 일은 백그라운드 모델 요청으로 처리할 수 있습니다. 그러나 분석이 끝난 뒤 법무 검토를 요청하고, 이틀 후 승인 결과에 따라 전자서명을 보내며, 거절되면 초안을 폐기하는 과정은 별도의 워크플로 엔진과 상태 저장이 필요합니다. 모델 제공자의 응답 ID만 저장한다고 해서 회사의 업무가 복구되는 것은 아닙니다.
핵심 원칙: 모델은 각 단계에서 판단하거나 내용을 만들 수 있지만, 어떤 단계가 완료됐고 다음에 무엇을 실행할지는 애플리케이션이 소유해야 합니다.
메모리와 실행 이력도 다르다
에이전트 메모리는 대화 요약, 사용자 선호, 검색된 문서처럼 다음 판단에 도움이 되는 맥락입니다. 실행 이력은 업무의 사실 기록입니다. 주문 생성 성공, 승인 대기 시작, 결제 승인 번호, 재시도 횟수처럼 복구와 감사에 필요한 데이터를 담습니다.
메모리는 품질을 위해 압축하거나 교체할 수 있지만 실행 이력은 임의로 요약하면 안 됩니다. “결제가 된 것 같다”는 에이전트의 기억은 결제 완료 증거가 아닙니다. 결제 사업자가 반환한 거래 ID와 확정 상태, 호출에 사용한 멱등성 키가 증거입니다. 이 경계를 흐리면 모델의 자연어 요약이 회계 상태를 대신하는 위험한 시스템이 됩니다.
체크포인트에는 무엇을 남겨야 하나
내구성 있는 워크플로는 단순히 현재 단계 번호만 저장하지 않습니다. 운영에서 복구 가능한 최소 단위는 다음 다섯 종류의 기록으로 구성하는 것이 좋습니다.
| 기록 | 필수 내용 | 필요한 이유 |
|---|---|---|
| 워크플로 인스턴스 | 업무 ID, 정의 버전, 시작 주체, 현재 상태 | 어떤 규칙으로 실행 중인지 식별 |
| 단계 실행 | 단계명, 시도 번호, 시작·종료 시각, 결과 | 재시작 시 완료 단계 건너뛰기 |
| 산출물 | 모델 출력, 문서 주소, 검증 결과, 해시 | 같은 계산의 불필요한 반복 방지 |
| 외부 효과 | 대상 시스템, 요청 ID, 멱등성 키, 확정 상태 | 중복 주문·결제·알림 방지 |
| 사람의 결정 | 승인자, 결정 시각, 근거, 권한 스냅샷 | 감사와 책임 추적 |
워크플로 상태는 적어도 RUNNING, WAITING, RETRYING, COMPENSATING, COMPLETED, FAILED, CANCELLED처럼 구분해야 합니다. 단순한 성공·실패 두 값으로는 “사람 승인을 기다리는 정상 상태”와 “시스템이 멈춘 상태”를 구별할 수 없습니다.
오케스트레이터는 결정적이어야 한다
Durable Execution 구현체는 저장된 이벤트 이력을 재생해 현재 상태를 복원하는 경우가 많습니다. 따라서 워크플로의 제어 흐름은 같은 이력을 읽으면 같은 결론을 내야 합니다. 현재 시각을 직접 읽거나, 임의 난수를 만들거나, 워크플로 코드 안에서 외부 API를 바로 호출하면 재생 결과가 달라질 수 있습니다.
LLM은 본질적으로 비결정적입니다. 같은 입력에도 다른 계획이나 문장을 만들 수 있습니다. 그래서 모델 호출은 오케스트레이터 내부의 조건문이 아니라 별도의 Activity로 취급해야 합니다. Activity 결과를 저장한 뒤 재생에서는 모델을 다시 부르지 않고 저장된 결과를 사용합니다.
- 오케스트레이터: 순서, 분기, 타임아웃, 승인 대기, 보상 순서를 관리합니다.
- Activity: LLM 호출, ERP 조회, 문서 생성처럼 외부 세계와 상호작용합니다.
- 검증기: 모델 결과가 스키마와 업무 규칙에 맞는지 결정적으로 판정합니다.
- 정책 계층: 어느 작업에 사람 승인이 필요한지, 실행 한도는 얼마인지 결정합니다.
에이전트에게 전체 제어권을 주고 “실패하면 알아서 다시 해”라고 지시하는 방식은 복구 설계가 아닙니다. 모델은 이전 호출이 실제로 외부 시스템에 반영됐는지 알지 못할 수 있고, 자연어 추론만으로 정확히 한 번 실행을 보장할 수도 없습니다.
재시도는 오류 종류에 따라 달라야 한다
모든 실패를 같은 정책으로 재시도하면 장애를 더 크게 만듭니다. 네트워크 타임아웃이나 일시적인 503 응답은 지수 백오프와 지터를 적용해 제한된 횟수만 다시 시도할 수 있습니다. 반면 입력 스키마 오류, 권한 부족, 존재하지 않는 고객 ID는 기다린다고 해결되지 않습니다. 즉시 실패시키거나 수정 단계와 사람 검토로 보내야 합니다.
| 실패 유형 | 예시 | 권장 처리 |
|---|---|---|
| 일시적 | 타임아웃, 429, 503 | 백오프·지터·횟수 제한 재시도 |
| 영구적 | 잘못된 입력, 권한 없음, 리소스 없음 | 즉시 종료 또는 수정 요청 |
| 모호함 | 요청 전송 후 응답 유실 | 멱등성 키로 상태 조회 후 결정 |
| 업무적 충돌 | 재고 변경, 승인 만료, 가격 변동 | 최신 상태 재검증·재승인 |
| 모델 품질 | 근거 부족, 규칙 위반, 낮은 확신 | 재프롬프트보다 검증·대체 경로·사람 검토 |
재시도 예산도 단계별로 분리해야 합니다. 검색 API는 세 번 재시도해도 괜찮지만 문자 발송이나 결제 승인 요청은 결과 조회가 먼저입니다. “최대 세 번”이라는 숫자보다 중요한 것은 반복해도 안전한가입니다.
멱등성 키는 중복 실행을 막는 안전벨트다
분산 시스템에서는 네트워크 오류 때문에 요청이 처리됐는지 알 수 없는 순간이 반드시 생깁니다. 이때 워커가 재시작되고 같은 단계를 다시 호출하면 주문이 두 개 생기거나 고객에게 알림이 여러 번 갈 수 있습니다.
외부 효과를 만드는 요청에는 업무 의미를 가진 안정적인 멱등성 키를 사용해야 합니다. 예를 들어 workflow_id + step_name + logical_attempt 조합을 키로 만들고, 같은 키의 요청이 다시 오면 기존 결과를 반환하도록 합니다. 단순 UUID를 호출할 때마다 새로 생성하면 중복 방지 효과가 없습니다.
상대 시스템이 멱등성을 지원하지 않는다면 어댑터 계층에 요청 원장과 유일성 제약을 둬야 합니다. 다만 로컬 DB에 “호출 예정”을 적는 것만으로 외부 시스템의 실제 반영과 완벽히 원자화되지는 않습니다. 요청 상태 조회 API, 공급자 거래 ID, 웹훅, 정산 데이터 등으로 사실을 대조하는 절차가 함께 필요합니다.
되돌리기는 삭제가 아니라 새로운 업무다
여러 시스템을 거친 업무는 데이터베이스 트랜잭션처럼 한 번에 롤백할 수 없습니다. 이미 이메일을 보냈다면 수신자의 받은편지함에서 없앨 수 없고, 세금계산서를 발행했다면 단순 삭제가 아니라 취소 문서를 발행해야 할 수 있습니다. 이때 사용하는 것이 Saga의 보상 트랜잭션입니다.
보상은 과거를 지우는 작업이 아니라 현재 상태를 허용된 상태로 이동시키는 별도의 업무입니다. 재고 예약에는 예약 해제, 결제 승인에는 승인 취소, 배송 접수에는 배송 취소 요청이 대응됩니다. 각 정방향 단계에는 가능한 보상 작업과 보상이 불가능한 시점을 미리 정의해야 합니다.
보상에도 실패가 발생할 수 있습니다. 따라서 COMPENSATION_FAILED 상태, 별도의 재시도 정책, 운영자에게 전달할 복구 자료가 필요합니다. 금전·법률·안전과 관련된 단계는 자동 보상이 가능한 범위를 명확히 하고, 범위를 벗어나면 사람에게 에스컬레이션해야 합니다.
사람 승인은 긴 대기 상태이지 서버 스레드가 아니다
현실의 승인은 몇 시간이나 며칠이 걸립니다. 그동안 프로세스나 HTTP 연결을 붙잡아 두면 안 됩니다. 워크플로는 승인 요청을 생성한 뒤 상태를 WAITING으로 저장하고 완전히 내려갈 수 있어야 합니다. 승인 이벤트나 기한 만료 타이머가 들어오면 새 워커가 실행을 이어받습니다.
승인 요청에는 승인자가 무엇을 보고 결정했는지 남겨야 합니다. 모델이 만든 요약만 보여주는 대신 원문 근거, 변경 전후 값, 예상 비용, 되돌릴 수 있는지 여부를 함께 제시해야 합니다. 승인 후 시간이 오래 지났다면 가격·재고·권한 같은 변동 상태를 다시 검사해야 합니다. 어제 승인한 조건이 오늘도 유효하다는 보장은 없기 때문입니다.
취소와 타임아웃도 정상 경로로 설계한다
사용자의 취소는 예외가 아니라 업무 요구사항입니다. 취소 신호를 받으면 현재 Activity를 무조건 강제 종료하기보다 안전한 중단 지점까지 진행한 뒤 보상해야 할 수 있습니다. 외부 서비스가 이미 요청을 처리 중이라면 먼저 결과를 확인해야 합니다.
타임아웃도 세 층으로 나누면 관리가 쉬워집니다.
- 호출 타임아웃: 한 번의 API나 모델 호출이 기다릴 수 있는 시간
- 단계 기한: 재시도를 포함해 한 단계가 끝나야 하는 시간
- 업무 기한: 승인 대기를 포함한 전체 프로세스의 SLA
업무 기한을 넘겼을 때 단순히 실패로 표시할지, 담당자에게 넘길지, 이미 만든 효과를 보상할지는 프로세스별로 달라집니다. 이 정책은 프롬프트가 아니라 워크플로 정의에 명시해야 합니다.
배포할 때 실행 중인 업무는 어떻게 할까
장시간 워크플로는 코드 배포보다 오래 살아 있습니다. 오늘 시작한 프로세스가 다음 주에 재개될 때 워크플로 코드가 달라졌다면 저장된 이력과 새 코드가 충돌할 수 있습니다. 그래서 워크플로 정의 버전을 인스턴스에 고정하고, 변경된 분기에는 명시적 버전 마커를 둬야 합니다.
실무적으로는 기존 인스턴스는 구버전으로 마무리하고 신규 요청만 새 버전으로 시작하는 방식이 가장 단순합니다. 보안 취약점처럼 즉시 전환이 필요하면 상태 마이그레이션 규칙과 롤백 계획을 별도로 준비해야 합니다. 프롬프트와 모델 버전도 실행 기록에 남겨야 같은 결과를 재현하거나 차이를 설명할 수 있습니다.
관측성은 로그가 아니라 업무 타임라인이어야 한다
에이전트 운영 화면에서 토큰 수와 모델 지연만 보면 전체 업무 장애를 설명할 수 없습니다. 운영자는 하나의 업무 ID를 기준으로 모델 판단, 도구 호출, 승인, 재시도, 외부 효과, 보상 결과를 시간순으로 볼 수 있어야 합니다.
최소한 다음 지표를 대시보드에 두는 것이 좋습니다.
- 상태별 워크플로 수와 가장 오래 대기 중인 인스턴스
- 단계별 성공률, 재시도율, 평균·상위 지연시간
- 중복 요청이 멱등성 계층에서 차단된 횟수
- 자동 보상 성공률과 수동 복구 건수
- 승인 대기시간, 기한 초과율, 승인 후 상태 충돌률
- 모델·프롬프트·워크플로 버전별 품질과 비용
직접 만들 것인가, 워크플로 엔진을 쓸 것인가
단계가 두세 개이고 수 분 안에 끝나며 외부 효과가 없다면 DB 상태 컬럼과 작업 큐만으로도 충분할 수 있습니다. 반대로 실행이 오래 지속되고, 사람 승인과 타이머가 있으며, 여러 시스템에 쓰기 작업을 하고, 장애 후 정확한 재개가 중요하다면 검증된 워크플로 엔진이 유리합니다.
Temporal, Azure Durable Task·Durable Functions, AWS Step Functions 같은 도구는 상태 저장, 체크포인트, 재시도, 타이머, 복구를 서로 다른 방식으로 제공합니다. 특정 제품 이름보다 먼저 확인할 것은 실행 보장 방식, 이력 보존 기간, 데이터 위치, 암호화, 버전 관리, 최대 실행 시간, 비용 모델, 온프레미스 가능 여부입니다.
특히 오케스트레이터 저장소에는 모델 입력과 출력, 업무 데이터가 포함될 수 있습니다. 민감정보를 통째로 이력에 남기지 말고 필요한 식별자와 암호화된 참조만 저장하는 방식을 검토해야 합니다. 삭제 요청과 보존 정책도 일반 로그와 별도로 설계해야 합니다.
도입 순서: 가장 위험한 한 개의 흐름부터
- 실제 업무 하나를 골라 시작·완료·취소 조건을 문장으로 정의합니다.
- 각 단계를 읽기, 계산, 외부 효과, 사람 결정으로 분류합니다.
- 외부 효과마다 멱등성 키와 결과 확인 방법을 정합니다.
- 정방향 단계에 대응하는 보상 작업과 보상 불가 시점을 작성합니다.
- LLM 호출을 Activity로 격리하고 입력·출력·모델 버전을 저장합니다.
- 일시적·영구적·모호한 실패에 서로 다른 정책을 적용합니다.
- 승인 대기와 타이머를 영속 이벤트로 모델링합니다.
- 워크플로 버전과 배포 중인 인스턴스의 전환 정책을 정합니다.
- 운영자가 업무 타임라인을 검색하고 수동 조치할 화면을 만듭니다.
- 장애를 실제로 주입해 복구 결과와 외부 시스템 상태를 대조합니다.
테스트에서는 정상 경로보다 실패 지점을 촘촘히 바꿔야 합니다. 모델 응답 직후 프로세스를 종료하고, ERP가 처리한 뒤 응답만 유실시키고, 승인 직전에 배포하고, 보상 API도 한 번 실패시키는 식입니다. “다시 실행됐다”가 아니라 최종 주문·재고·결제·문서 상태가 업무 규칙과 일치하는지 검증해야 합니다.
좋은 에이전트는 실패하지 않는 시스템이 아니다
외부 API와 사람, 네트워크, 배포가 섞인 시스템에서 실패를 없앨 수는 없습니다. 운영 가능한 AI 에이전트의 기준은 실패 확률이 0인 것이 아니라, 실패 위치를 알고 안전하게 이어가며 결과를 설명할 수 있는가입니다.
모델이 계획을 잘 세우는 능력은 중요합니다. 하지만 실제 회사 업무를 맡기려면 그 계획을 담는 견고한 실행 골격이 먼저 필요합니다. 체크포인트는 기억을, 멱등성은 중복 방지를, 보상 트랜잭션은 불완전한 결과의 수습을, 업무 타임라인은 책임과 개선의 근거를 제공합니다.
AI 자동화의 다음 단계는 더 긴 프롬프트가 아닙니다. 서버가 바뀌고 외부 시스템이 흔들리고 사람이 늦게 응답해도 끝까지 상태를 관리하는 지속 가능한 업무 실행 구조입니다. 이 기반이 있어야 에이전트의 자율성도 안전하게 넓힐 수 있습니다.