에이전트 워크플로의 멱등성, 가장 먼저 설계해야 하는 이유

에이전트가 사람의 손을 거치지 않고 작업을 끝낸다고 가정해 보자. 네트워크가 한 번 끊기고, 외부 API가 잠시 5xx를 돌려주고, 같은 작업이 두세 번 큐에 쌓인다. 이 흔한 순간 시스템을 안전하게 만드는 것은 정교한 모델도, 더 똑똑한 도구 선택도 아니다. 멱등성이다. 같은 요청을 몇 번 보내더라도 결과가 한 번 보낸 것과 동일하다는 단순한 약속, 자율 워크플로에서는 그것이 거의 모든 안정성을 떠받친다.

재시도는 더 이상 예외 처리가 아니다

사람이 운영하던 시절의 코드는 실패를 알림으로 처리했다. 누군가 로그를 보고, 상황을 판단하고, 직접 다시 누른다. 에이전트가 직접 작업을 돌리는 환경에서는 이 가정이 무너진다. 재시도는 코드 곳곳에 깔리고, 큐 컨슈머는 같은 메시지를 여러 번 가져오며, 모델은 도구 호출이 실패했다고 판단하면 거의 항상 한 번 더 시도한다. 즉 한 번만 실행되리라는 보장은 더 이상 없다. 그 위에서 결제, 발행, 메시지 전송 같은 부수효과가 그대로 실행되면, 한 번의 오류가 두세 개의 중복 게시물과 두세 통의 알림으로 번진다.

멱등 키와 부수효과의 경계

현실적인 해법은 새롭지 않다. 작업마다 멱등 키를 부여하고, 그 키로 결과를 기록하는 곳을 한 군데로 모은다. 같은 키가 들어오면 새로 실행하지 않고 이전 결과를 반환한다. 결제 API들이 오래전부터 채택한 패턴이고, 메시지 큐와 외부 발행 시스템에서도 동일하게 통한다. 중요한 것은 멱등 키를 만드는 위치다. 모델이 매번 다른 문자열을 만들어 내면 키의 의미가 사라진다. 키는 작업의 의도—어떤 사용자, 어떤 토픽, 어떤 시간 윈도우—에서 결정되어야 하고, 모델은 그 의도를 채울 뿐이다.

그 다음에는 부수효과의 경계를 명확히 그어야 한다. 외부에 무언가를 만들어 내는 동작—HTTP POST, 파일 쓰기, 메일 발송—은 한 군데 함수로 모으고, 그 함수만 멱등 키를 본다. 모델이 직접 다루는 코드 경로 곳곳에서 부수효과가 흩어져 일어나면, 한쪽에서 막아도 다른 쪽에서 새어 나간다. 도구 호출 인터페이스가 “실행했는가”와 “이미 실행되어 있는가”를 같은 응답 형태로 돌려주도록 설계하면, 모델이 굳이 상태를 추측할 필요도 사라진다.

설계 원칙: 작게, 명시적으로, 추적 가능하게

실무에서 통하는 규칙은 셋이다. 첫째, 단위를 작게 쪼갠다. 한 작업이 여러 부수효과를 묶고 있으면 부분 실패에서 회복이 어렵다. 둘째, 키와 결과를 명시적으로 저장한다. 메모리에만 두면 프로세스가 죽는 순간 멱등성도 함께 사라진다. 셋째, 모든 실행을 추적 가능하게 만든다. 같은 키가 몇 번 들어왔고, 어느 시점에 어떤 결과가 확정되었는지가 보여야, 에이전트가 자신이 한 일과 하지 않은 일을 구분할 수 있다.

멱등성은 화려한 주제가 아니다. 그러나 자율 시스템에서 멱등성을 나중으로 미루면, 신뢰성을 회복하기 위해 결국 전체 워크플로를 다시 쓰게 된다. 처음부터 작업의 단위, 키의 출처, 부수효과의 경계를 정해 두는 편이 늘 싸게 먹힌다.

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다