> ## Documentation Index
> Fetch the complete documentation index at: https://dripart-docs-comfy-router-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Comfy Router 제한 사항

> 현재 Comfy Router가 지원하지 않는 기능, 대안이 존재하는 경우 대신 사용할 도구, 그리고 변경될 것으로 예상되는 제한 사항을 설명합니다.

<Note>
  **Comfy Router는 아직 일반에 공개되지 않았습니다.** 아래에서 언급하는 라우트(`POST /v1/models/{provider}/{model}` 및 카탈로그·스키마 관련 라우트)는 아직 요청을 처리하지 않습니다. 현재 인증된 호출은 `404`를 반환합니다. 이 페이지는 해당 라우트들이 제공할 계약을 설명하며, 통합이 알려진 형태를 기준으로 작성될 수 있도록 해당 롤아웃 이전에 게시되었습니다. 아래의 모든 내용은 해당 계약에 대한 설명이지, 지금 당장 실행할 수 있는 동작에 대한 설명이 아닙니다.
</Note>

Comfy Router는 하나의 동기식 호출입니다. 파트너 모델의 네이티브 입력을 하나의 자격 증명으로 하나의 호스트에 전송하면 연결이 유지되고, `200` 응답이 해당 모델의 네이티브 출력을 전달합니다. 이러한 형태 덕분에 첫 번째 통합이 짧아지며, 이 페이지의 모든 제한 사항도 바로 여기서 비롯됩니다. Router를 중심으로 설계하기 전에, 설계 이후가 아니라 이 페이지를 읽으십시오. 아래 내용의 대부분은 간단한 대안이 있으며, 그렇지 않은 항목은 Router에 대해 성립하지 않는 가정을 기반으로 구축하기 전에 알아둘 가치가 있습니다.

## 한눈에 보기

각 행은 해당 제한을 설명하는 섹션으로 연결됩니다. **의도적**은 해당 제한이 Router 작동 방식의 일부이며 어떤 것도 기다리지 않는다는 뜻이고, **아직**은 Router가 해당 기능을 갖출 것으로 예상되지만 이 페이지는 시기에 대한 약정을 하지 않는다는 뜻입니다.

| 제한 사항                                                      | 대신 사용할 방법                                                          | 상태  |
| ---------------------------------------------------------- | ------------------------------------------------------------------ | --- |
| [대기 중 제출 없음: 호출은 동기식](#대기-중-제출-없음)                         | 연결을 계속 열어 두거나, 제출과 폴링을 수행하는 파트너 프록시 라우트를 사용하세요.                    | 아직  |
| [응답에 비용 또는 크레딧 수치 없음](#응답에-비용-또는-크레딧-수치가-없음)               | Comfy 플랫폼에서 잔액과 사용량을 확인하고, 호출 이전에 모델 카탈로그 항목의 `billing`을 확인하세요.    | 아직  |
| [손실된 호출을 재개할 방법 없음](#손실된-호출을-재개할-방법-없음)                    | `Idempotency-Key`를 보내면 재시도가 최대 한 번만 청구됩니다. 단, 손실된 결과를 복구하지는 않습니다.  | 아직  |
| [호출이 서버 마감 시간에 중단됨](#호출이-서버-마감-시간에-중단됨)                    | 클라이언트에 마감 시간보다 긴 타임아웃을 설정하고, 마감 시간 안에 완료할 수 없는 작업은 분할하세요.          | 의도적 |
| [호출 실행 중 진행 상황 없음](#호출이-실행되는-동안에는-진행률이-없음)                 | 현재 Router에는 해당 기능이 없습니다. 파트너 프록시 라우트가 자체 진행 상황을 노출할 수 있습니다.        | 아직  |
| [세 가지 예측 버킷은 어휘에 포함되지 않음](#세-가지-예고된-버킷은-어휘에-포함되어-있지-않습니다)  | Router가 게시하는 열다섯 가지 버킷을 처리하고, 인식할 수 없는 값은 `internal_error`로 처리하세요. | 아직  |
| [Router가 모든 파트너 작업을 다루지는 않음](#router는-모든-파트너-작업을-다루지-않습니다) | 동일 호스트의 `/proxy/…` 하위 파트너 프록시 라우트를 사용하세요.                          | 의도적 |

## 대기 중 제출 없음

모델을 실행하는 방법은 하나뿐입니다. `POST /v1/models/{provider}/{model}`은 생성이 끝날 때까지 연결을 유지한 뒤 응답으로 결과를 반환합니다. 작업(job)을 받아 식별자를 돌려주고 나중에 결과를 가져갈 수 있게 해주는 엔드포인트는 없으며, 완료를 알리는 콜백이나 웹훅도 없습니다. 대기 중 제출에 해당하는 엔드포인트가 계획되어 있고 API 레퍼런스에는 `/v1/queue/models/{provider}/{model}`로 언급되어 있지만, 현재는 API 계약의 일부가 아니며 해당 경로로의 호출은 처리되지 않습니다.

**대신 할 수 있는 방법.** 대부분의 모델에서는 이는 문제가 되지 않습니다. 연결을 유지한 채 결과를 읽으면 됩니다. 빠른 이미지 모델은 몇 초 안에 결과를 반환하고, 긴 비디오 생성은 수 분 동안 실행될 수 있지만 Router가 그동안 연결을 유지합니다. 클라이언트 읽기 타임아웃을 넉넉하게, [Router 자체의 데드라인](#호출이-서버-마감-시간에-중단됨) 이상으로 설정하고, 이 호출을 빠른 요청이 아닌 장기 실행으로 취급하세요. 아키텍처상 정말로 연결을 유지할 수 없는 경우, 즉 실행 시간 상한이 짧은 서버리스 함수나 사용자가 닫을 것으로 예상되는 브라우저 탭이라면, 연결을 유지할 수 있는 여러분이 제어하는 워커에서 호출을 실행하거나, 자체 제출(submit) 및 폴링(poll) 쌍을 제공하는 공급자의 파트너 프록시 경로를 사용하세요. [마지막 섹션](#router는-모든-파트너-작업을-다루지-않습니다)을 참조하세요.

**상태: 아직 없음.** 대기 중 경로는 제공될 예정이지만, 이 페이지에서는 언제 제공될지 약속하지 않습니다.

## 응답에 비용 또는 크레딧 수치가 없음

Router 응답은 모델이 무엇을 생성했는지 알려주며, 그 계약에는 비용이 얼마인지에 대한 정보가 전혀 없습니다. 응답 본문에는 청구 금액, 크레딧 잔액, 사용량 수치가 없으며, 해당 라우트는 비용 헤더를 선언하지 않습니다. 놀라지 않도록 한 가지 주의할 점을 말씀드립니다. Router는 파트너 프록시 라우트와 청구 경로를 공유하며, 해당 경로는 허용 목록에 포함된 공급자의 청구된 응답에 `X-Comfy-Credits-Used`를 기록합니다. 따라서 그중 하나를 대상으로 한 Router 호출에는 이 헤더가 나타날 수 있습니다. 이는 Router 계약의 일부가 아닙니다. 허용 목록에 없는 모든 공급자에게는 이 헤더가 없으며, 멱등 재시도(idempotent retry) 시 의도적으로 *재생되지 않습니다*. 이는 정확히, 이 헤더를 합산하는 클라이언트가 한 번만 결제된 호출을 이중으로 계산할 수 없게 하기 위해서입니다. 이 헤더를 기반으로 정산을 구축하지 마십시오. 모델 카탈로그도 마찬가지입니다. 카탈로그에는 호출자가 호출 이전에 필요한 청구 관련 *사실*만 담겨 있으며 가격은 결코 포함되지 않습니다. 따라서 Router 응답만으로 지출을 정산할 수 없으며, X를 다른 곳에서 가져오지 않고는 사용자에게 "이 호출 비용은 X입니다"라고 보여줄 수 없습니다.

**대신 이렇게 하세요.** 잔액, 사용량, 청구서는 [platform.comfy.org](https://platform.comfy.org)의 Comfy 플랫폼에 있습니다. 이곳이 지출한 금액과 남은 금액에 대한 소스(source of truth)이며, 이 페이지의 어떤 내용에도 영향을 받지 않습니다. Router가 호출 시점에 알려주는 두 가지는 활용할 가치가 있습니다. 크레딧 부족으로 거부된 호출은 `insufficient_credits`로 반환되므로, 잔액을 사전 확인하는 대신 크레딧 소진을 유형화된 오류로 처리할 수 있습니다. 그리고 각 모델의 카탈로그 항목에는 `billing.charges_on_policy_rejection`이 포함되어 있는데, 이는 해당 특정 모델이 콘텐츠 정책상 이유로 거부하는 생성에 대해 비용을 청구하는지 여부를 알려줍니다. 이 필드는 논리값이 아니라 **세 가지 값을 가진 문자열**입니다. `yes`, `no`, `unknown`입니다. `unknown`은 "청구될 수 있음"으로 해석하십시오. 즉, 아직 아무도 해당 모델의 동작을 확정하지 못했다는 뜻이며, 이 값은 확인되지 않은 모델이 `no`로 게시되지 않도록 하기 위해 정확히 존재합니다. `no`는 주장이기 때문입니다. 이 필드는 의도적으로 `enum`이 아니므로, 인식하지 못하는 값도 `unknown`으로 취급하고, 이 값에 대해 truthiness 검사를 작성하지 마십시오. 문자열 `"no"`는 대부분의 언어에서 truthy이며, 그런 검사는 이 필드가 잡아내기 위해 존재하는 바로 그 경우를 반대로 만들어 버립니다. 공급자마다 이 부분이 다르며, 그 차이는 호출 시점에는 보이지 않습니다. 호출 이전에 이 값을 읽는 것이 나중에 설명할 수 없는 청구를 피하는 방법입니다.

**상태: 아직 아님.** 호출별 수치는 아직 지원되지 않습니다. 참고로 *카탈로그*에는 의도적으로 가격이 포함되지 않습니다. 가격은 가격이 유지 관리되는 곳에 속하며, 그 가격과 점점 어긋나게 될(drift) 모델 목록에 중복으로 복사되지 않아야 합니다.

## 손실된 호출을 재개할 방법 없음

Router는 진행 중인 호출의 재개 가능한 기록을 보관하지 않습니다. 상태 라우트도, 작업 식별자도, 다시 연결할 대상도 없습니다. 호출 도중 연결이 끊기면(클라이언트 충돌, 네트워크 분할, 프로세스를 재시작하는 배포) 응답은 사라지며, 이후에 그 호출에 대해 문의할 수도 없습니다. *생성*이 완료되어 청구되었는지는 응답을 받았는지와는 별개의 문제이며, 연결이 끊어졌다는 사실만으로는 어느 쪽도 확실히 알 수 없습니다.

**대신 이렇게 하세요.** 모든 호출에 `Idempotency-Key` 헤더를 보내세요. 잃어버린 호출을 재개할 수 있게 해주지는 않지만, 재시도를 안전하게 만듭니다. Router는 호출이 진행되는 동안 키를 예약하며, 호출이 실제로 답변을 전달한 경우 해당 응답을 키에 연결해 24시간 동안 기록합니다. **같은** 키로 재시도하면 기록된 응답이 재생되고, 공급자에게 두 번째로 디스패치(및 재청구)되지 않습니다. `Idempotent-Replayed: true`가 표시되므로 재생과 새 실행을 구분할 수 있습니다. 논리적 호출마다 새 키를 생성하세요. 시도마다가 아니라요. *다른* 요청 본문으로 같은 키를 제시하면 조용한 덮어쓰기가 아니라 `409`가 반환됩니다.

이것이 무엇을 보장하는지 정확히 이해하세요. 이는 **청구** 속성이지 전달 속성이 아닙니다. **키는 최대 한 번만 청구됩니다.** 키가 공급자에게 최대 한 번만 디스패치된다는 약속이 아닙니다. Router는 실제로 답변을 받은 경우에만 키를 보유합니다. 청구되지 않은 결과는 키를 해제하여 호출을 다시 할 수 있게 합니다. `5xx`, `408`/`425`/`429`, 그리고 (여기서 중요한 경우) 아무것도 도달하지 않은 호출. 이 모든 경우가 키를 해제하며, 해당 키로 재시도하면 실제로 다시 실행되어 공급자에게 다시 디스패치됩니다.

**즉, 연결 끊김은 멱등성이 *구해주지 못하는* 경우입니다.** 호출 도중 연결이 끊어지면 대개 어떤 응답도 커밋되지 않았다는 뜻이며, 이는 정확히 위의 해제 경로입니다. 같은 키로 재시도하면 놓친 결과를 건네주는 대신 새 실행이 시작됩니다. 원래 생성이 이미 디스패치되었다면 공급자가 두 번째로 실행할 수도 있습니다. 이것이 올바른 기본값입니다. 받지 못한 미청구 호출은 다시 실행할 수 있어야 합니다. 다만 "재시도는 새 실행을 만든다"고 계획하세요. "재시도가 잃어버린 실행을 회수한다"가 아니라요.

Router가 키에 대해 무언가를 *보유*하고 있는 경우, 재시도는 재실행이 아니라 응답으로 처리됩니다. 원래 응답이 재생되거나, 그럴 수 없는 이유를 설명하는 `409`가 반환됩니다. 원래 호출이 아직 진행 중일 때 보낸 재시도는 `Retry-After`가 포함된 `409`가 되므로, 기다렸다가 같은 키를 다시 보내세요. 완료되었지만 Router가 충실한 사본을 보관하지 못한 호출에 대한 재시도도 `409`입니다. 이는 응답이 너무 큰 경우만 해당하지 않습니다. 재생 한도를 넘은 응답, 응답 후 실패하거나 패닉한 핸들러, 전송이 실패하거나 부족했던 쓰기. 이 모든 경우 키가 "소비되었지만 재생 불가"로 기록되고 같은 `409`가 반환됩니다. 크기 문제를 찾으러 가지 마세요. 이러한 모든 경우의 지침은 동일합니다. **새** 키를 사용하세요. 원래 호출은 완료되어 청구되었으며, Router는 그 응답을 지어내지도 않고 이전 키로 다시 실행하지도 않습니다.

<Note>
  **생성된 계약에는 아직 없습니다.** 여기서 설명하는 `Idempotency-Key` 요청 헤더, `409` 응답, `Idempotent-Replayed` 및 `Retry-After` 응답 헤더는 레퍼런스가 생성되는 기반인 OpenAPI 계약의 `POST /v1/models/{provider}/{model}`에 선언되어 있지 않습니다. 따라서 생성된 API 레퍼런스에는 나타나지 않으며 SDK도 이를 모델링하지 않습니다. 지원될 때까지 직접 보내고 읽으세요.
</Note>

**상태: 아직 아님.** 영구적이고 재개 가능한 실행은 대기 중 경로와 함께 제공될 예정이며, 그곳이 요청 기록이 보관될 곳입니다. 멱등 재시도는 오늘의 답이며 임시방편이 아닙니다. 어쨌든 통합할 가치가 있습니다.

## 호출이 서버 마감 시간에 중단됨

Router 호출 하나는 연결을 **10분** 동안 유지할 수 있습니다. 이것이 기본값이며, 고정 상수가 아닌 서버 측 구성 값이므로 계약에 새겨진 보장이 아니라 설계 기준으로 삼을 숫자로 취급하세요. 이를 넘으면 Router는 대기를 멈추고 공급자에 대한 진행 중 요청을 취소한 다음 `X-Comfy-Error-Type: deadline_exceeded`와 함께 `504`로 응답합니다. **`deadline_exceeded` 호출은 청구되지 않습니다.** 그 한계는 우리 쪽의 것이므로 그 비용도 우리가 부담합니다.

취소가 하지 않는 두 가지를 재시도 전에 알아두세요. 첫째, 공급자가 이미 수락한 생성을 취소하지 않습니다. Router가 작업을 제출하고 폴링하는 방식으로 구동하는 파트너의 경우, 마감 시간이 만료되면 Router 자신의 대기만 끝나고 공급자의 작업은 끝나지 않으므로 해당 작업은 완료까지 실행될 수 있으며, 재시도는 **두 번째 생성**을 만들어낼 수 있습니다(타임아웃된 호출에 대해 여전히 청구되지는 않습니다). 둘째, 이미 보낸 답변을 취소할 수 없습니다. 핸들러가 경쟁에서 이겨 한계가 만료되는 바로 그 순간 응답을 커밋하면 `504` 대신 그 응답을 받게 됩니다.

다른 `504`와 혼동하지 마세요. `provider_timeout`은 파트너가 제때 응답하지 못한 것이며, 이 경우 **는** 청구됩니다. `deadline_exceeded`는 Router 자신의 한계가 만료된 것입니다. 원인이 두 가지, 청구 결과도 두 가지이기 때문에 정확히 같은 상태 코드에 두 개의 버킷이 존재합니다. `X-Comfy-Error-Type`으로 분기하고 상태 코드만으로 판단하지 마세요.

**대신 이렇게 하세요.** 클라이언트의 읽기 타임아웃을 마감 시간보다 *위로* 넉넉하게 설정하세요. 아래로 설정하지 마세요. 먼저 포기하는 클라이언트는 요청 식별자가 있는 유형화된 `504`를 불투명한 로컬 중단으로 바꿔버리고, 지원팀이 추적할 수 있는 유일한 증거를 잃게 됩니다. 단일 생성이 마감 시간 안에 정말로 끝날 수 없다면 Router는 오늘날 그 용도에 적합하지 않습니다. 제출과 폴링을 수행하는 파트너 프록시 라우트로 실행하거나, 각각이 한계 안에 끝나는 호출로 작업을 나누세요.

**상태: 의도적.** 한계는 존재해야 합니다. 한계가 없으면 멈춘 업스트림이 연결과 동시성 슬롯을 무기한 점유합니다. 구체적인 숫자는 조정될 수 있지만 마감 시간의 존재는 사라지지 않습니다.

## 호출이 실행되는 동안에는 진행률이 없음

`POST /v1/models/{provider}/{model}`는 종료 시점에 정확히 한 번만 응답을 반환합니다. 스트리밍 응답, 서버 전송 이벤트, 백분율, 부분 또는 미리보기 프레임이 없습니다. 이는 파트너의 자체 API가 제출 후 폴링 방식인 경우에도 마찬가지입니다. Router는 해당 폴링을 내부적으로, 즉 여러분의 단일 호출 안에서 처리하며, 그 과정에서 확인되는 중간 상태는 여러분에게 전달되지 않습니다. 외부에서 보면 3초짜리 이미지와 6분짜리 비디오는 같은 형태입니다. 요청 하나, 응답 하나, 그 사이에 아무것도 없습니다.

**대신 해야 할 일.** 현재 Router에서는 할 수 있는 일이 없습니다. 출처를 알 수 없는 백분율 대신 불확정 진행 상태를 표시하세요. 특정 공급자에게 진행률이 필수 요구 사항이라면, 해당 공급자의 파트너 프록시 라우트가 자체 폴링이나 스트리밍을 제공하는지 확인하고 그 라우트를 직접 사용하세요. 일부는 해당 기능을 제공하며, 그 라우트는 변경되지 않았고 완전히 지원됩니다.

**상태: 아직 미지원**이며 대기 중 경로와 연결되어 있습니다. 진행률은 보고할 *곳*이 필요합니다. 대기 중 제출은 그 대상을 제공하지만 단일 동기 호출은 제공하지 않습니다.

## 세 가지 예고된 버킷은 어휘에 포함되어 있지 않습니다

Router의 `error_type` 어휘는 **15개로 이루어진 닫힌 집합**이며, [API 레퍼런스](/ko/api-reference/comfy-router/reference)에 나열되고 quickstart가 가리키는 바로 그 15개입니다. 해당 레퍼런스의 본문에는 예상 추가 항목으로 세 가지가 더 언급됩니다: `file_download_error`, `cancelled`, `queue_timeout`. 이름만 언급되었을 뿐이며, 그게 전부입니다. 이들은 오늘날 **집합의 멤버가 아닙니다**: 어떤 Router 응답도 이들을 담지 않으며, 계약(contract)으로부터 생성된 클라이언트는 이들을 알지 못하고, Router가 내부적으로 이들을 넘겨받더라도 전송하는 대신 `internal_error`로 대체합니다. 따라서 오늘 이들을 위해 작성하는 분기는 결코 실행되지 않는 분기이며, 레퍼런스에 이들이 등장한다고 해서 Router가 호출을 취소하거나 큐에 넣는다는 증거가 되지는 않습니다. Router는 그중 어느 것도 하지 않습니다.

이들이 아예 빠지지 않고 문서로 예고된 이유는 `error_type`이 의도적으로 단순한 문자열이지 `enum`이 아니기 때문이며, 인식할 수 없는 버킷을 무조건 거부하는 클라이언트는 이미 무언가 잘못된 바로 그 순간에 가장 크게 실패하기 때문입니다. 추가 항목을 미리 이름으로 언급하는 것은, 이 집합이 의도적으로 개방형이라는 것을 독자가 알 수 있게 하는 방법입니다.

**대신 해야 할 일.** Router가 실제로 게시하는 15개 버킷을 처리하세요. 전체 목록은 [API 레퍼런스](/ko/api-reference/comfy-router/reference)에 있습니다. 그리고 인식할 수 없는 모든 값을 `internal_error`로 취급하는 폴백 분기를 하나 작성하세요. 그 폴백이 바로 전체 메커니즘입니다. 이 폴백 덕분에 이 세 가지와, 클라이언트가 작성된 이후에 추가되는 어떤 버킷이든 여러분을 깨뜨리지 않고 도착할 수 있습니다. 제어 흐름을 위해서는 대략적인 버킷을 기준으로 분기하고, 구체적인 이유가 필요할 때는 `422` 본문 안의 필드별 `type`을 읽으세요.

**상태: 아직 아님.** 세 가지 각각은 Router가 아직 갖추지 못한 동작에 해당하며, 각각은 그것을 내보내기 시작하는 바로 그 변경과 함께 어휘에 합류합니다. 절대 그 이전에는 합류하지 않습니다.

## Router는 모든 파트너 작업을 다루지 않습니다

Router는 파트너 *모델*을 실행합니다. 파트너가 노출하는 모든 작업을 중계하지는 않습니다. 파일 업로드, 계정 및 에셋 읽기, 공급자별 관리 호출, 스트리밍 채팅 엔드포인트, 일부 파트너가 게시하는 제출-폴링(submit-and-poll) 쌍이 여기에 해당합니다. 또한 Router는 이러한 작업을 변형하지도 않습니다. 모델의 네이티브 입력을 전달하고 네이티브 출력을 변경 없이 반환하므로, 지원되지 않는 작업을 이식할 수 있는 통합 봉투가 없습니다.

**대신 수행할 작업.** `/proxy/…` 아래의 파트너 프록시 라우트는 동일한 호스트에서 동일한 자격 증명으로 완전히 지원되며, Router가 다루지 않는 모든 작업에 대한 해답입니다. 이들은 지원 중단되지 않았고, 서비스 종료(sunset) 경로에 있지도 않습니다. 동일한 통합에서 Router와 함께 사용하는 것은 우회 방법이 아니라 예상된 사용 방식입니다. 여러 모델에 걸쳐 하나의 라우트 형태와 하나의 자격 증명을 원한다면 Router를 사용하고, 특정 파트너 작업, 공급자 자체의 스트리밍 응답, 또는 Router가 의도적으로 숨기는 제출-폴링 제어가 필요하다면 `/proxy/…`를 사용하세요.

**상태: 의도된 설계입니다.** Router는 의도적으로 표면을 좁힙니다. 하나의 라우트 형태가 바로 기능입니다. 프록시 표면은 기존 그대로 유지됩니다.

## 다음

* [Comfy Router 빠른 시작](/ko/api-reference/comfy-router/quickstart): Python 또는 TypeScript로 첫 번째로 동작하는 호출을 만들어 봅니다.
* [Comfy Router API 참조](/ko/api-reference/comfy-router/reference): 모든 엔드포인트, 모든 매개변수, 그리고 Router가 전송하는 모든 오류 버킷을 다룹니다.
