← 블로그 목록
2026-08-30visionlinqdocument-aiarchitectureko

두 번 배달되는 세계에서 정확히 한 번 일하기 — VisionLinq 설계 노트 ③

2편에서 문서 변환을 격리된 컨테이너에 가둔 이야기를 했습니다. 3편은 그 컨테이너들을 조율하는 층 — 의 이야기입니다.

"최소 한 번"이라는 계약

VisionLinq의 파이프라인 단계들(변환, OCR, 분류, 추출)은 큐로 이어져 있습니다. 그리고 분산 큐가 실제로 약속할 수 있는 것은 "정확히 한 번"이 아니라 "최소 한 번(at-least-once)" 배달입니다. 네트워크가 흔들리면 같은 메시지가 두 번 배달되고, 워커가 죽으면 처리 중이던 작업이 다시 배달됩니다.

여기서 갈림길이 있습니다. 중복 배달을 버그로 취급하면 — "웬만하면 한 번만 오니까" — 시스템은 평소에 잘 돌다가 가장 바쁜 날, 가장 흔들리는 날에 같은 문서를 두 번 과금하고 결과를 두 번 씁니다. 중복 배달을 계약으로 받아들이면 모든 단계를 "두 번 실행돼도 한 번 실행된 것과 같게" 만들어야 합니다. VisionLinq는 후자를 택했습니다. 이 성질의 이름이 **멱등성 (idempotency)**입니다.

같은 일에는 같은 이름을

멱등성의 첫 재료는 결정적 이름입니다. 같은 작업의 같은 단계는 언제 계산해도 같은 ID가 나오도록 — 난수나 타임스탬프가 아니라 작업의 내용에서 유도되도록 — 만듭니다.

이름이 결정적이면 "이 메시지, 처음 보는 일인가?"라는 어려운 질문이 "이 이름으로 끝난 기록이 있는가?"라는 쉬운 질문으로 바뀝니다. 두 번째 배달은 자기 이름을 조회해 보고 조용히 물러납니다.

승자는 한 명

이름이 같아도, 두 워커가 동시에 같은 메시지를 집으면 조회 시점엔 둘 다 "기록 없음"을 봅니다. 그래서 조회가 아니라 원자적 선점으로 승자를 정합니다 — "이 단계의 리스(lease)가 비어 있으면 나를 적는다"를 데이터베이스의 compare-and-set 한 번으로. 성공한 쪽만 일하고, 실패한 쪽은 이미 임자가 있다는 뜻이므로 물러납니다.

검사하고-나서-행동하는(check-then-act) 코드는 검사와 행동 사이의 틈으로 경쟁이 스며듭니다. 선점 자체가 원자적이면 틈이 없습니다.

결과는 덮어쓰지 않는다

작업의 결과는 불변이고 버전이 있습니다. 재시도가 이미 있는 결과를 덮어쓰는 일은 구조적으로 없습니다 — 같은 버전은 다시 쓰이지 않고, 새 실행은 새 버전이 됩니다. "마지막에 쓴 놈이 이긴다"는 규칙은 재시도가 있는 세계에서 "우연히 늦게 도착한 옛 실행이 이긴다"가 되기 때문입니다.

과금도 같은 원리로 지킵니다. 사용량은 예약 → 확정 또는 해제의 두 단계로 기록됩니다. 작업이 시작될 때 예약하고, 성공하면 확정, 실패하면 해제 — 중복 배달이 몇 번 오든 확정은 한 번입니다. 고객 입장에서 멱등성이 가장 직접적으로 돈이 되는 지점입니다.

계속 실패하는 것은 옆으로

재시도로 해결되는 실패(일시적 네트워크, 워커 재시작)와 재시도로 해결되지 않는 실패(파이프라인이 처리 못 하는 문서)는 다른 문제입니다. 후자를 계속 재시도하면 큐가 그 메시지에 붙잡힙니다. 그래서 반복 실패하는 메시지는 DLQ(dead-letter queue)로 격리하고 파이프라인은 계속 흐릅니다. 격리된 것은 사라지는 게 아니라 사람이 볼 수 있는 곳에 남습니다.

재시도를 두려워하지 않는 시스템이 단순하다

이 장치들 — 결정적 이름, 원자적 리스, 불변 결과, 2단계 과금, DLQ — 을 갖추고 나면 이상한 일이 일어납니다. 실패 처리가 단순해집니다. 어디서 무엇이 죽었는지 정밀하게 복구하는 코드 대신, 대부분의 실패에 대한 답이 "그냥 다시 돌려"가 됩니다. 다시 돌려도 한 일은 다시 하지 않고, 과금은 두 번 되지 않고, 결과는 덮이지 않으니까요.

2편의 격리가 "뚫려도 아무 일도 일어나지 않게"였다면, 3편의 멱등성은 "두 번 돌아도 아무 일도 일어나지 않게"입니다. 같은 철학의 두 얼굴입니다 — 나쁜 경우를 막으려 애쓰는 대신, 나쁜 경우가 일어나도 무해하게.


다음 편에서는 파이프라인의 출구 — 추출된 값마다 원문 근거와 신뢰도를 함께 돌려주는 evidence-bearing 결과의 데이터 모델을 다룹니다.