비동기 태스크(SEP-1686) — 오래 걸리는 작업을 지금 호출하고 나중에 가져오기

실제 에이전트(agent) 작업은 몇 분에서 몇 시간이 걸립니다. 지속적 통합(CI; Continuous Integration) 실행, 심층 리서치 종합(deep-research synthesis), 배치 내보내기(batch export)가 그렇습니다. 동기 도구 호출(synchronous tool call)은 연결이 끊기거나, 타임아웃되거나, UI를 막습니다. 2025-11-25에 병합된 SEP-1686은 태스크(Tasks) 프리미티브(primitive)를 추가합니다. 어떤 요청이든 태스크가 되도록 보강할 수 있고, 결과는 나중에 가져오거나 상태 알림(state notification)으로 스트리밍할 수 있습니다. 드리프트(drift) 위험 메모: Tasks는 2026년 상반기까지 실험적이며, SDK 표면(surface)은 아직 스펙(spec)을 중심으로 설계되는 중입니다.

유형: Build
언어: Python (표준 라이브러리, 비동기 태스크 상태 머신)
선수 학습: Phase 13 · 07 (MCP 서버), Phase 13 · 09 (전송 방식)
소요 시간: 약 75분

학습 목표

  • 도구(tool)를 동기 실행에서 태스크 보강(task-augmented) 방식으로 승격(promote)해야 하는 시점을 식별합니다. 기준은 서버 측 작업이 30초를 넘는 경우입니다.
  • 태스크 생명주기(lifecycle)를 따라갑니다. workinginput_requiredcompleted / failed / cancelled입니다.
  • 크래시(crash)가 진행 중인 작업을 잃어버리지 않도록 태스크 상태를 영속화(persist)합니다.
  • tasks/status를 폴링(polling)하고 tasks/result를 올바르게 가져옵니다.

문제

generate_report 도구가 몇 분짜리 추출 파이프라인(pipeline)을 실행합니다. 동기 모델에서의 선택지는 다음과 같습니다.

  1. 연결(connection)을 3분 동안 열어 둡니다. 원격 전송 방식(remote transport)은 연결을 끊고, 클라이언트는 타임아웃(timeout)되며, UI는 멈춥니다.
  2. 즉시 플레이스홀더(placeholder)를 반환하고 클라이언트가 사용자 정의 엔드포인트(endpoint)를 폴링하게 합니다. MCP의 일관성(uniformity)을 깨뜨립니다.
  3. 실행만 하고 잊어버립니다(fire-and-forget). 결과가 없습니다.

어느 것도 좋지 않습니다. SEP-1686은 네 번째 선택지를 추가합니다. 태스크 보강(task augmentation)입니다. 어떤 요청, 보통 tools/call이 태스크로 태그(tag)될 수 있습니다. 서버는 즉시 태스크 ID(task id)를 반환합니다. 클라이언트는 tasks/status를 폴링하고, 끝나면 tasks/result를 가져옵니다. 서버 측 상태는 재시작 후에도 살아남습니다.

사전 테스트

2문제 · 이 강의를 시작하기 전에 얼마나 알고 있는지 확인해보세요

1.MCP 비동기 작업가 해결하는 핵심 과제는?

2.MCP 비동기 작업 이전의 주요 한계는?

0/2 답변 완료

개념

태스크 보강(task augmentation)

요청은 params._meta.task.required: true를 설정하면 태스크가 됩니다. 또는 optional: true를 설정하고 서버가 결정하게 할 수 있습니다. 서버는 즉시 다음을 응답합니다.

{
  "jsonrpc": "2.0", "id": 1,
  "result": {
    "_meta": {
      "task": {
        "id": "tsk_9f7b...",
        "state": "working",
        "ttl": 900000
      }
    }
  }
}

ttl은 서버가 상태를 보관하겠다고 약속하는 시간입니다. ttl 이후 태스크 결과는 폐기됩니다.

도구별 옵트인(per-tool opt-in)

도구 어노테이션(tool annotations)은 태스크 지원을 선언할 수 있습니다.

  • taskSupport: "forbidden" — 이 도구는 항상 동기적으로 실행됩니다. 빠른 도구에 안전합니다.
  • taskSupport: "optional" — 클라이언트가 태스크 보강을 요청할 수 있습니다.
  • taskSupport: "required" — 클라이언트는 반드시 태스크 보강을 사용해야 합니다.

generate_report 도구는 required일 것입니다. notes_search 도구는 forbidden일 것입니다.

상태(states)

working  -> input_required -> working  (elicitation을 통한 루프)
working  -> completed
working  -> failed
working  -> cancelled

상태 머신(state machine)은 추가만 가능합니다(append-only). 한 번 completed, failed, cancelled가 되면 태스크는 종료 상태(terminal state)입니다.

메서드(methods)

  • tasks/status {taskId} — 현재 상태와 진행 힌트(progress hint)를 반환합니다.
  • tasks/result {taskId} — 완료되지 않았다면 막히거나 404를 반환합니다.
  • tasks/cancel {taskId} — 멱등적(idempotent)입니다. 종료 상태는 무시합니다.
  • tasks/list — 선택 사항입니다. 활성 태스크와 최근 완료 태스크를 열거합니다.

상태 변경 스트리밍(streaming state changes)

서버가 지원한다면 클라이언트는 상태 알림을 구독(subscribe)할 수 있습니다.

server -> notifications/tasks/updated {taskId, state, progress?}

폴링 대신 스트리밍하는 클라이언트는 더 나은 사용자 경험(UX; User Experience)을 제공합니다. 폴링은 최소 인터페이스(minimal surface)로 항상 지원됩니다.

영속 상태(durable state)

스펙은 태스크 지원을 선언한 서버가 상태를 영속화하도록 요구합니다. 크래시가 ttl 안의 완료 결과를 잃어버리면 안 됩니다. 저장소(store)는 SQLite, Redis, 파일시스템(filesystem) 등 다양할 수 있습니다. Lesson 13 하네스(harness)는 파일시스템을 사용합니다.

취소 의미론(cancellation semantics)

tasks/cancel은 멱등적입니다. 태스크가 실행 중이면 서버는 중지를 시도합니다. 실행기(executor)가 협력적 취소(executor-cooperative cancellation)를 확인해야 합니다. 이미 종료 상태라면 요청은 아무 일도 하지 않습니다(no-op).

크래시 복구(crash recovery)

서버 프로세스(process)가 재시작되면 다음을 수행합니다.

  1. 영속화된 모든 태스크 상태를 로드(load)합니다.
  2. 프로세스가 죽어 있던 working 태스크를 CRASH_RECOVERY 오류와 함께 failed로 표시합니다.
  3. completed / failed / cancelled 상태는 ttl 동안 보존합니다.

비동기 태스크와 샘플링(sampling)

태스크 자체가 sampling/createMessage를 호출(call)할 수 있습니다. 오래 걸리는 리서치(research) 태스크는 이런 방식으로 동작합니다. 서버의 태스크 스레드(thread)는 필요할 때 클라이언트의 모델에 샘플링을 요청하고, 클라이언트 UI는 주기적인 진행 업데이트(progress update)와 함께 태스크를 working으로 표시합니다.

이것이 실험적(experimental)인 이유

SEP-1686은 2025-11-25에 배포(ship)되었지만, 더 넓은 로드맵(roadmap)은 세 가지 열린 이슈를 짚습니다. 영속 구독 프리미티브(durable subscription primitives), 서브태스크(subtasks; parent-child task relationships), 결과 TTL 표준화(result-TTL standardization)입니다. 2026년 동안 스펙이 진화할 것으로 예상해야 합니다. 프로덕션(production) 코드는 일반 사례에 대해서만 Tasks를 안정적이라고 보고, 서브태스크에 대한 향후 SDK 변경에 대비해야 합니다.

사용해 보기

code/main.py는 영속 태스크 저장소(filesystem-backed)와 백그라운드 스레드(background thread)에서 실행되는 generate_report 도구를 구현합니다. 클라이언트는 도구를 호출하고 즉시 태스크 ID를 받습니다. 워커(worker)가 진행률(progress)을 업데이트하는 동안 tasks/status를 폴링하고, 완료되면 tasks/result를 가져옵니다. 취소가 동작하며, 워커 스레드를 죽이고(kill) 상태를 다시 로드하는 방식으로 크래시 복구를 시뮬레이션합니다.

살펴볼 지점은 다음과 같습니다.

  • 태스크 상태 JSON은 /tmp/lesson-13-tasks/<id>.json에 영속화됩니다.
  • 워커 스레드는 progress 필드를 업데이트합니다. 폴링하면 값이 증가하는 것을 볼 수 있습니다.
  • 클라이언트 측 취소는 이벤트(event)를 설정합니다. 워커는 이를 확인하고 일찍 종료합니다.
  • "크래시" 이후 상태를 다시 로드하면 진행 중이던 태스크가 CRASH_RECOVERY와 함께 failed로 표시됩니다.

산출물 만들기

이 lesson은 outputs/skill-task-store-designer.md를 만듭니다. 리서치(research), 빌드(build), 내보내기(export)처럼 오래 걸리는 도구가 주어지면, 이 스킬(skill)은 태스크 저장소의 상태 형태(state shape), ttl, 영속성(durability), 적절한 taskSupport 플래그(flag)를 설계하고 진행 알림(progress notification)을 스케치(sketch)합니다.

연습문제

  1. code/main.py를 실행합니다. generate_report 태스크를 시작하고, 상태를 폴링한 뒤, 결과를 가져옵니다.

  2. 실행 중간에 tasks/cancel 호출을 추가합니다. 워커가 이를 존중하고 상태가 cancelled가 되는지 확인합니다.

  3. 크래시 복구를 시뮬레이션합니다. 워커 스레드를 죽이고 로더(loader)를 재시작한 뒤, CRASH_RECOVERY 실패 모드를 관찰합니다.

  4. 저장소를 SQLite로 확장합니다. 영속성의 장점은 동일하지만, 쿼리 옵션(query option)이 열립니다. 예를 들어 세션 X의 모든 태스크를 나열할 수 있습니다.

  5. 2026년 MCP 로드맵 글을 읽습니다. 다음 해 SDK API 설계에 가장 큰 영향을 줄 가능성이 있는 Tasks 관련 열린 이슈 하나를 찾습니다.

핵심 용어

용어흔한 설명실제 의미
태스크(Task)"오래 걸리는 도구 호출"비동기 실행을 위해 _meta.task로 보강된 요청
SEP-1686"Tasks 스펙"2025-11-25에 Tasks를 추가한 Spec Evolution Proposal
_meta.task"태스크 봉투"ID, 상태, ttl을 담은 요청별 메타데이터
taskSupport"도구 플래그"도구별 forbidden / optional / required
tasks/status"폴링 메서드"현재 상태와 선택적 진행 힌트를 가져옴
tasks/result"결과 가져오기"완료된 payload를 반환하거나 아직 완료 전이면 404
tasks/cancel"멈추기"멱등적 취소 요청
ttl"보관 예산"서버가 태스크 상태를 보관하겠다고 약속하는 밀리초
notifications/tasks/updated"상태 푸시"서버가 시작하는 상태 변경 이벤트
영속 저장소(Durable store)"크래시 안전 상태"파일시스템 / SQLite / Redis 영속 계층

더 읽을거리

실습 코드

이 강의의 실습 코드 1개

main
Code

산출물

이 강의에서 생성된 프롬프트, 스킬, 코드 산출물 1개

task-store-designer

Design the task store for a long-running MCP tool: state shape, ttl, durability, cancellation, crash recovery.

Skill

확인 문제

3문제 · 모두 맞추면 완료 표시가 가능합니다

1.프로덕션에서 MCP 비동기 작업의 가장 중요한 설계 원칙은?

2.MCP 비동기 작업가 올바른 선택이 아닌 경우는?

3.MCP 비동기 작업는 AI 생태계에 어떻게 들어맞나요?

0/3 답변 완료

추가 문제 풀기

AI가 강의 내용을 바탕으로 새로운 문제를 생성합니다