Orchestrators
캐스케이드·병렬+합성 오케스트레이션을 직접 설계해 model:"orch/<slug>" 하나의 가상 모델로 호출합니다.
오케스트레이터는 여러 모델을 하나의 가상 모델로 묶는 라우팅 규칙입니다. 기존 4가지 정책 타입(fallback·weighted·latency·auto)에 캐스케이드와 병렬+합성 아키타입이 추가되었고, 모든 정책을 "model": "orch/<slug>"로 호출할 수 있습니다(기존 policy/<slug>도 그대로 동작). 대시보드의 오케스트레이터 페이지에서 폼으로 만들거나, 고급 탭에서 JSON DSL로 직접 설계하세요.
routing.orchestrators_enabled가 꺼져 있으면 이 두 타입의 호출이 400 에러로 거절됩니다(저장·CRUD는 게이트와 무관하게 항상 가능). 기존 4종은 routing.policies_enabled를 그대로 따릅니다.아키타입#
fallback·weighted·latency·auto — 기존 라우팅 정책과 동일한 동작입니다. 자세한 규칙은 라우팅 정책 문서를 참고하세요.
cascade — 엔트리를 저가→고가 티어 순서로 등록하면 요청 난이도에 맞는 티어에서 시작하고, 실패하면 한 단계 위 모델로 에스컬레이션합니다. 쉬운 요청은 저가 모델로 끝나고 어려운 요청만 강한 모델까지 올라가 평균 비용이 낮아집니다.
parallel — 엔트리(워커)들을 동시에 호출하고, 성공한 답변들을 합성 모델이 비판적으로 검증해 하나의 최종 답변으로 병합합니다.
캐스케이드 — 난이도별 티어 에스컬레이션#
시작 티어 판정은 두 단계로 조합됩니다. ① hard_categories — 요청 의도를 정규식으로 분류해(외부 전송 없음·비용 0) 지정한 카테고리면 최상위 티어에서 바로 시작합니다. ② judge_model — 설정 시 저가 모델 1콜로 시작 티어를 판정합니다(자식 호출로 정상 과금). judge 호출이 실패하거나 숫자를 답하지 못하면 ① 휴리스틱으로 폴백합니다.
에스컬레이션은 두 신호에서 일어납니다. 티어 호출이 실패하면 다음 티어로, 그리고 response_check를 켜면 성공했지만 빈 응답인 경우(공백 텍스트·콘텐츠 필터링)에도 다음 티어로 올라갑니다. 버려진 호출도 정산은 됐으므로 최종 응답의 usage·비용에 합산되어 보고됩니다(정직한 사용량 보고).
스트리밍에서는 첫 토큰이 나가기 전에 티어 판정(휴리스틱·judge)을 마치고 선택된 티어부터 순차 스트리밍합니다. 응답 기반 재판정(response_check)은 비스트리밍 호출에만 적용됩니다.
병렬+합성 — 여러 워커의 답을 하나로#
워커가 2개 이상 성공하면 synthesis.model이 후보 답변들을 검증·병합합니다( 합성 지시문 synthesis.prompt로 톤·기준을 직접 지정 가능, 미지정 시 기본 지시문 사용). 합성 모델을 지정하지 않거나 합성이 실패하면 첫 성공 워커의 답변이 반환됩니다. 워커가 1개만 성공한 경우에도 합성 없이 그대로 반환됩니다.
deep_categories를 지정하면 그 의도에만 병렬로 돌고 나머지 요청은 첫 번째 워커 1콜로 처리합니다(fast-path). 미지정 시 모든 요청을 병렬로 실행합니다.
병렬+합성은 합성이 끝나야 최종 답변이 확정되므로 스트리밍을 지원하지 않습니다 — stream=true로 호출하면 SSE 시작 전에 400 에러가 반환됩니다.
호출·과금#
일반 채팅 호출에서 "model": "orch/<slug>"를 지정하면 됩니다. OpenAI SDK와 plm_ 키 그대로 동작합니다. 조직에 공유된 오케스트레이터는 같은 조직 멤버 누구나 자기 키로 호출할 수 있습니다.
curl https://apirouter.pleum.ai/v1/chat/completions \
-H "Authorization: Bearer plm_..." \
-H "Content-Type: application/json" \
-d '{
"model": "orch/prod-cascade",
"messages": [
{"role": "user", "content": "Summarize this document."}
]
}'과금은 실제 실행된 자식 호출 각각에 정가로 청구되고, 응답의 usage·비용은 전체 자식 호출의 합계로 보고됩니다 — judge·버려진 티어·합성 호출까지 포함입니다. 오케스트레이션 자체에 별도 수수료는 없습니다.
폭주 방지를 위해 두 상한을 설정할 수 있습니다. limits.max_total_attempts(1~10, 전역 상한 6의 추가 축소)와 limits.max_cost_krw — 자식 호출의 누적 실제 비용이 이 값을 넘으면 더 위 티어로 올라가지 않습니다.
routing_prefs로 자식 호출의 제공자 선호(sort·ignore·max_price 등)를 오케스트레이터에 고정할 수 있습니다. 요청 본문에 provider 객체를 직접 보내면 그것이 우선합니다.
조직 공유#
오케스트레이터를 조직에 공유하면 같은 조직 멤버가 호출할 수 있고, 수정·삭제는 작성자와 조직 owner/admin이 가능합니다(admin은 멤버의 개인용 오케스트레이터도 관리할 수 있습니다). 비공유 상태로 두면 작성자만 접근할 수 있습니다.
JSON DSL#
대시보드의 고급 탭이나 /v1/routing-policies API로 동일한 JSON 구성을 그대로 만들 수 있습니다 — 폼과 DSL이 같은 스키마를 공유하므로 JSON을 복사·붙여넣기로 팀에 전달할 수 있습니다. 엔트리는 1~10개, 단가가 있는 실제 활성 모델만 가능하고 다른 오케스트레이터(orch/…·policy/…)나 가상 라우팅 부모는 참조할 수 없습니다.
curl -X POST https://apirouter.pleum.ai/v1/routing-policies \
-H "Authorization: Bearer <JWT>" \
-H "Content-Type: application/json" \
-d '{
"slug": "prod-cascade",
"display_name": "Production cascade",
"policy_type": "cascade",
"entries": [
{"model": "gpt-5.4-mini"},
{"model": "claude-fable-5"}
],
"config": {
"cascade": {
"hard_categories": ["code"],
"judge_model": "gpt-5.4-mini",
"response_check": true
},
"routing_prefs": {"sort": "latency", "ignore": ["slow-provider"]},
"limits": {"max_total_attempts": 4, "max_cost_krw": 3000}
}
}'{
"slug": "review-panel",
"policy_type": "parallel",
"entries": [{"model": "claude-fable-5"}, {"model": "gpt-5.5"}, {"model": "gemini-3.1-pro-preview"}],
"config": {
"parallel": {
"deep_categories": ["code", "reasoning"],
"synthesis": {
"model": "claude-fable-5",
"prompt": "Verify the answers like a senior reviewer and merge the strongest parts."
}
}
}
}