MCP Tasks와 「도구 호출을 걸어놓고 기다리기」는 도대체 무엇이 다른가
걸어놓고 기다리기는 블로킹 대기이며 커넥션 생명주기에 의존한다. MCP Tasks는 영속화된 작업 핸들이며 작업 상태가 커넥션 존속과 독립적이다.
장시간 작업의 신뢰성은 반드시 전송 계층에서 응용 계층으로 끌어올려야 한다.
핵심
| 걸어놓고 기다리기 | MCP Tasks |
|---|
| 대기 방식 | 블로킹 대기 | 영속화된 작업 핸들 |
| 상태 귀속 | 커넥션 생명주기에 의존 | 커넥션 존속과 독립 |
| 라벨 | 전통 모드: 클라이언트가 「블로킹 대기」 | 현대 아키텍처: 클라이언트가 「자유롭게 단절」 |
1층: 커넥션 생명주기의 차이
도구 호출 하나를 10분 걸어둔다는 것은, 그 10분 동안 다음이 동시에 만족되어야 한다는 뜻이다:
- HTTP 커넥션이 끊기면 안 됨
- WebSocket 하트비트가 타임아웃되면 안 됨
- 서버가 재시작되면 안 됨
- 중간 프록시가 타임아웃되면 안 됨
결론: 이것은 신뢰성을 전송 계층에 전부 베팅하는 것이며, 전송 계층은 전체 공학 스택에서 가장 취약한 계층이다.
2층: 작업 핸들의 영속화 능력
1. Agent가 작업을 발기
2. 서버가 taskId 반환 (예: task_9527)
3. 커넥션은 바로 끊어도 됨
4. Agent는 언제든 taskId로 돌아와 상태를 조회
상태: 대기 중 / 실행 중 / 완료됨 / 실패함
5. 작업은 서버에서 독립적으로 실행되며 커넥션 상태와 완전히 디커플링
3층: 상태 머신과 관측성
| 롱커넥션 방안 | MCP Tasks |
|---|
| 진행 상황 | 블랙박스 — 커넥션이 아직 살아있다는 것만 앎 | 상태 머신을 외부에서 조회 가능 |
| 미지의 항목 | 「몇 퍼센트까지 갔나?」 「이상이 있었나?」 | Pending / Running / Completed / Failed |
| 문제 발견 방식 | 커넥션 단절로 수동적으로 발견 | 모니터링 시스템이 능동 폴링(Active Polling) |
4층: 실패 복구와 체크포인트 재개
상태가 서버 측에 영속화되어 있으므로, 커넥션 복구 후 중단 지점부터 조회하지 처음부터 다시 시작하지 않는다.
일괄 문서 분석이 187번째 파일까지 진행 → 서비스 재시작
→ 작업 상태가 Failed로 표기됨
→ 그러나 앞의 186개 결과는 이미 영속화됨
→ 재시도 시 중단 지점부터 계속, 전체를 다시 돌릴 필요 없음
이 능력을 설계상 **재개 가능성(可續跑性)**이라 부른다. 「롱커넥션 방안: 단절 후 처음부터 재실행 필요, 연산력과 시간 낭비」와 나란히 놓고 「공학 차원의 차원 압도」라는 라벨이 붙는다 — 즉 두 방안의 공학적 격차가 가장 큰 지점이다.
핵심 통찰
- 「둘 다 비동기 대기다」는 대기 방식과 상태 귀속을 뒤섞은 것이다 — 둘 다 확실히 「즉시 반환하지 않지만」, 하나는 상태를 커넥션에 두고 다른 하나는 서버에 둔다. 「표면 행동이 같은 것」과 「신뢰성 모델이 같은 것」을 구분할 수 있는지가 시험대다.
- 신뢰성에는 「계층」이 있으며, 장시간 작업은 그것을 전송 계층에서 응용 계층으로 끌어올려야 한다 — 걸어놓고 기다리기는 성패를 HTTP/WebSocket/프록시/프로세스 생존이라는 가장 취약한 연쇄에 건다. taskId는 성패를 오직 서버 측의 저장과 상태 머신에만 의존하게 만든다.
- 커넥션이 끊겼을 때의 진짜 손실은 「이번 호출」이 아니라 「중간 상태」다 — 10분 동안 생산된 모든 중간 산출물이 커넥션과 함께 증발한다. 장시간 작업 방안을 평가할 때 계산해야 할 것은 이미 투입한 연산력의 손실이지 요청 한 번의 재시도 비용이 아니다.
- 핸들(handle)은 「시간」을 호출에서 디커플링하는 범용 기법이다 — 결과 대신 ID를 반환하면 호출자는 「언제든 돌아올」 자유를 얻는다. 기기를 꺼도 되고, 기기를 바꿔도 되고, 프로세스를 바꿔도 된다. 이 사고는 파일 디스크립터, 작업 시스템의 job id, 비동기 작업 큐와 동형이다.
- 관측성은 로그를 더하는 것이 아니라 상태를 「외부에서 조회 가능」하게 만드는 것이다 — 롱커넥션 방안에 진행 상황이 없는 것이 아니라, 진행 상황에 외부 조회 입구가 없어서 커넥션이 끊기기를 수동적으로 기다릴 수밖에 없는 것이다. 상태 머신을 명시적 조회 인터페이스로 만들어야 모니터링이 능동 폴링을 할 수 있고 사후 알람에 그치지 않는다.
- taskId는 태생적으로 다자 협업의 회합점이다 — 같은 ID를 여러 Agent가 동시에 조회할 수 있어서 「누가 발기하고, 누가 대기하고, 누가 소비하는가」가 서로 다른 주체일 수 있다. 다중 Agent 시스템에서 핸들 공유는 커넥션 공유보다 훨씬 현실적이다.
- 재개 가능성(체크포인트 재개)이 장시간 작업 방안의 첫 번째 평가 지표다 — 실패는 무섭지 않다. 실패 후 187번째부터 이어가야지 1번부터 다시 하면 안 된다. 장시간 작업을 지원한다고 주장하면서 재개가 안 되는 방안은 본질적으로 여전히 「한 번에 다 돌아가기를 거는 도박」이다.
- 멱등 + TTL + 영속 저장이 「Tasks 모드」의 숨은 비용 청구서다 — Tasks를 고른다는 것은 곧 서버가 유상태임을 약속하는 것이다. 반복 조회가 중복 실행되지 않도록 보장해야 하고, 결과를 얼마나 보관하고 언제 정리할지 정의해야 한다. 이 셋을 답하지 못하면 써보기만 했지 설계해보지 않았다는 뜻이다.
엔지니어링 실전 Tips
- 30초가 분수령이다: 짧은 조작은 동기 호출, 30초를 넘으면 Tasks를 쓸 것. 선택은 먼저 소요를 보고 나서 아키텍처를 논한다.
- Wi-Fi가 당신의 신뢰성 설계에 참여하게 두지 말 것: 사용자가 「노트북을 덮으면 전부 헛수고」가 되는 방안이라면 상용에서는 쓸 수 없는 것이다.
- 진행 상황은 「퍼센트」가 아니라 「건수」로 기록할 것: 「186개 완료」라고 기록해야 재개가 가능하고, 「62%」는 표시밖에 못 한다.
- 실패 표기와 결과 보존을 분리할 것: 작업이 Failed로 표기되었다고 이미 산출된 부분 결과까지 함께 버려야 하는 것은 아니다. 예시에서 앞의 186개 결과는 여전히 유효하다.
- 멱등은 조회 측과 생성 측 양쪽에 걸 것: 조회 멱등성은 읽기 전용으로 확보하고, 생성 멱등성은 업무 키로 확보한다. 그렇지 않으면 사용자가 손을 한 번 잘못 놀리면 30분짜리 작업이 두 번 돌아간다.
- taskId를 협업 계약으로 발행할 것: 여러 Agent가 같은 ID를 공유해 조회하는 편이 서로 중간 결과를 전달하는 것보다 손이 덜 가고 분기도 덜 생긴다.
- 답변은 「경계 → 예시 → 선택 → 가점」 4단으로 갈 것: 특성을 하나씩 나열하는 것보다 공학적 판단력을 잘 보여준다.