dsl 전략입니다 — 따라서
애플리케이션은 계속 orcarouter/{name}을 호출하고 라우팅 로직은
대시보드에 위치하며, 버전 관리되고 재배포 없이 편집할 수 있습니다.
DSL을 사용해야 할 때
“가장 저렴한 라이브 모델” 또는 “최고 품질”이 의도를 담아낼 때는 내장 전략을 사용하세요. 라우팅이 요청의 내용이나 컨텍스트에 따라 달라질 때 DSL을 사용하세요:- 작업 특화 — 코드는 코딩 모델로, 비전은 비전 모델로, 저렴한 채팅은 저렴한 모델로 보냅니다.
- 난이도 인식 라우팅 — 어려운 요청만 비싼 모델로 에스컬레이션하고, 쉬운 요청은 저렴하게 유지합니다.
- 에이전트 인식 라우팅 — 세션 상태(에이전트가 어떤 도구를 사용했는지, 방금 테스트가 실패했는지, 몇 번째 턴인지)에 따라 다르게 라우팅합니다.
- 시간 / 테넌트 / 헤더 규칙 — 시간, 사용자 그룹, 또는 요청 헤더별로 다르게 라우팅합니다.
활성화
대시보드의 Routing에서 라우터를 열고 Strategy를 DSL로 설정하세요. 그러면 이 라우터에 대한 DSL 편집기가 나타납니다. 라우터의 나머지 모든 것은 여전히 적용됩니다 — Allowed models glob, Default model 안전망, 그리고orcarouter/{name}
호출 방식입니다.
편집기
편집기는 의도에서 작동하는 규칙셋까지 빠르게 도달하도록 만들어졌습니다:- Templates는 당신의 워크스페이스의 실제 모델로 시드됩니다(일회성 티어 매핑 대화상자를 통해). 따라서 빈 파일에서 시작하거나 “알 수 없는 모델” 벽에 부딪히지 않습니다.
- Insert — 식별자를 손으로 입력하는 대신 자동완성에서 Model,
Router(
orcarouter/<name>), 또는 Pool을 끼워 넣습니다. - Generate — 원하는 라우팅을 일반 언어로 설명하면 실제 모델에 근거하여 컴파일되고 린트가 깨끗한 DSL을 받습니다.
- Explain — 현재 규칙셋이 무엇을 하는지를 평이한 영어로 풀어 설명합니다.
- Inline lint — 모든 오류는
{line, column, message}를 보고하며 모든 린트 코드에는?설명기가 있습니다. 우선순위(첫 매칭 우선)와 일반적인 CEL 패턴이 현재 위치에 표시됩니다.
파일 구조
규칙셋은 세 개의 최상위 키를 가진 YAML입니다:when: 조건과 use: 효과로 구성됩니다:
when:이 참인 첫 번째 규칙이
이깁니다. 일치하는 것이 없으면 default:가 적용됩니다. 가장 구체적인
규칙을 먼저 배치하세요 — 광범위한 초기 규칙은 그 아래 모든 것을 가립니다.
when: — 조건
조건은 CEL(Common Expression
Language)로 작성됩니다: 설계상 안전합니다 — 루프 없음, I/O 없음,
마이크로초 단위 평가, RE2 정규식만 사용. 다음 여섯 가지 패턴이 실제
규칙의 대부분을 포괄합니다:
| Pattern | Example |
|---|---|
| 필드 접근 | task_class == "agent" |
| 숫자 비교 | difficulty > 0.6 && request.input_tokens < 50000 |
| 불리언 로직 | agent_state.has_edited && !agent_state.has_run_tests |
| 리스트 멤버십 | "Edit" in agent_state.tools_used |
| 정규식 매크로 | system_prompt_matches("(?i)planning agent") |
| 도구 매크로 | tool_calls_present_any(["Edit","Write","apply_patch"]) |
변수
요청 형태| Variable | Type |
|---|---|
model | string |
request.input_tokens | int |
request.output_max_tokens | int |
request.stream | bool |
request.vision | bool |
request.message_count | int |
request.has_system_prompt | bool |
request.has_tools | bool |
| Variable | Type | Meaning |
|---|---|---|
task_class | string | chat / code / agent / vision / audio / rag / creative |
difficulty | double | 0.0–1.0 |
code_keyword_density | double | 0.0–1.0 |
reasoning_cue_count | int | 프롬프트에서 감지된 추론 신호 |
tool_count | int | 요청상의 고유한 도구 정의 수 |
agent_state.*, 대화 전반에 걸쳐 영속화됨)
| Variable | Type |
|---|---|
agent_state.turn | int |
agent_state.tools_used | list<string> |
agent_state.files_read | list<string> |
agent_state.has_edited | bool |
agent_state.has_run_tests | bool |
agent_state.last_test_failed | bool |
agent_state.consecutive_errors | int |
agent_state.elapsed_seconds | int |
agent_state.models_tried | list<string> |
| Variable | Type |
|---|---|
headers["x-foo"] | string |
user.id / user.group | int / string |
token.id / token.name | int / string |
time.hour / time.weekday | int (UTC) |
workspace.id | int |
매크로
“요청 내부를 들여다보는” 일반적인 검사를 위해 등록된 CEL 함수입니다:| Macro | Returns |
|---|---|
system_prompt_matches(regex) | 결합된 시스템 메시지에 대한 RE2 |
user_message_matches(regex) | 마지막 사용자 메시지에 대한 RE2 |
tool_definitions_include(name) | 요청에 도구가 선언되어 있음 |
tool_calls_present_any(list) | 요청이 이들 중 어떤 도구 호출을 담고 있음 |
tool_results_from_any(list) | 요청에 이들 중 어떤 것에서 온 도구 역할 메시지가 있음 |
header_matches(name, regex) | 헤더 값에 대한 RE2 |
use: — 효과
use: 블록은 목적지(정확히 하나)와 임의 개수의 선택적
호출별 노브를 지정합니다.
목적지
delegate: dsl은 거부됩니다(재귀가 발생할 것이기 때문). 특정
채널에 고정하는 것(channels: / @channel:)은 현재 사용할 수 없으며
지원되지 않음으로 린트됩니다 — 대신 model, models, 또는 pool로
라우팅하세요.호출별 노브
업스트림 호출을 형성하기 위해 어떤 목적지와도 조합합니다:param_override와 header_override는 거부 목록을 강제합니다 — model,
messages, stream, tools, 인증 헤더 등은 재정의할 수 없습니다
(이는 결제, 감사, 또는 에이전트 상태를 무력화할 수 있기 때문).
신뢰도 캐스케이드 및 앙상블 (고급)
두 가지 고급 효과를 통해 규칙이 약한 첫 응답에 반응하거나 여러 모델에 걸쳐 팬아웃할 수 있습니다. 이들은 다른 규칙과 동일한 방식으로 작성합니다. Cascade — 낮은 신뢰도 신호가 있을 때 더 강력한 효과로 재시도:앙상블 / 캐스케이드 런타임은 게이트되어 있으며 기본적으로 꺼져
있습니다. 각 병렬 레그와 각 캐스케이드 복구가 자체 호출로 청구되기
때문에, 팬아웃 런타임은 레그별 청구가 검증되는 동안 서버 플래그 뒤에
있습니다. 꺼져 있으면
parallel: 규칙은 첫 번째 레그만 제공하고
캐스케이드는 신호를 기록하지만 재디스패치하지 않습니다 — 규칙셋은 여전히
린트되고, 저장되고, 기본 효과를 정상적으로 라우팅합니다. 워크스페이스에
앙상블 런타임을 활성화하려면 문의하세요.안전하게 배포하기
새 규칙셋은 저장하는 순간 트래픽을 넘겨받지 않습니다:- Shadow mode — 첫 저장 이후 일정 기간 동안 DSL은 평가되지만
사용되지 않습니다: 이전 전략이 여전히 트래픽을 제공하는 동안
게이트웨이는 DSL이 무엇을 했을지를 기록합니다. 대시보드는
diff 리포트를 보여줍니다 — 차이 나는 라우트의 비율, 예상 비용
델타, 규칙별 발화 횟수, 그리고 얼마나 자주
default:로 떨어졌는지. 규칙을 신뢰하기 전에 이를 읽어보세요. - Canary — DSL을 라이브 트래픽의 일정 비율(5 → 25 → 50 → 100)에 점진적으로 적용하면서 슬라이스별 메트릭을 관찰하고, 비율을 0으로 밀어 즉시 롤백합니다.
제한 및 검증
모든 저장은 엄격한 린트를 실행합니다; 유효하지 않은 규칙셋은{line, column, message, rule}과 함께 거부됩니다:
- Schema — 필수 키, 올바른 타입/열거값, 알 수 없는 필드 없음.
- Size — ≤ 30개 규칙, ≤ 16 KiB YAML,
when:당 ≤ 200자. - CEL — 파싱되고, 변수 환경에 대해 타입 검사되며, 알 수 없는
식별자 없음,
when:은 반드시 bool로 평가되어야 함. - Effect —
use:블록당 정확히 하나의 목적지; 모든model/models/@pool:참조는 워크스페이스 내에서 해결되어야 함. - Knob ranges —
thinking_budget_tokens ∈ [1024, 64000],temperature ∈ [0, 2],samples ∈ [1, 16]. - Reserved —
_로 시작하는 규칙 id는 예약됨; 규칙 id로서의default는 거부됨(최상위default:블록을 사용하세요).
완전한 예시
X-Orca-Router와
X-Orca-Resolved-Model 응답 헤더를
읽으세요.
API 레퍼런스
DSL은 라우터별로 관리됩니다; 쓰기에는 **Developer+**가 필요합니다.| Method & path | Role | Purpose |
|---|---|---|
GET /api/user/routers/:id/dsl | Member | 소스 + 버전 + 섀도/카나리아 상태. |
PUT /api/user/routers/:id/dsl | Developer+ | 린트 + 저장(새 버전, 감사됨). |
POST /api/user/routers/:id/dsl/lint | Member | 초안 린트 → {errors:[…]}. |
POST /api/user/routers/dsl/lint | Member | 무상태 린트(라우터 id 없음). |
POST /api/user/routers/:id/dsl/dryrun | Member | 합성 요청 평가 → 트레이스 + 매칭된 규칙. |
GET /api/user/routers/:id/dsl/history | Member | 버전 이력, 최신순. |
POST /api/user/routers/:id/dsl/rollback/:version | Developer+ | 재린트 후 이전 버전 복원. |
FAQ
이름 지정 라우터의 전략과는 어떻게 다른가요?
이름 지정 라우터의 전략과는 어떻게 다른가요?
이것은 하나의 전략입니다 — cheapest / quality / balanced /
adaptive와 나란히 있는
dsl 옵션입니다. 나머지는 가격과 품질로
선택하고, DSL은 요청의 형태, 분류, 에이전트 상태에 대해 작성한
규칙으로 선택합니다. 규칙의 효과로서 또는 기본값으로서 여전히
내장 전략에 delegate:할 수 있습니다.일치하는 규칙이 없으면 어떻게 되나요?
일치하는 규칙이 없으면 어떻게 되나요?
최상위
default: 효과가 적용됩니다. 이는 필수이므로 항상 정의된
결과가 있습니다 — 일반적으로 delegate: balanced 또는 특정
안전망 모델입니다.핫 패스에서 신뢰할 수 없는 CEL을 실행하는 것이 안전한가요?
핫 패스에서 신뢰할 수 없는 CEL을 실행하는 것이 안전한가요?
네. CEL은 표준 라이브러리 함수만 있는 샌드박스에서 실행되며,
몇 밀리초의 평가 데드라인, RE2 정규식(선형 시간, ReDoS 없음),
그리고 데이터베이스, 네트워크, 또는 파일시스템에 대한 접근이
없습니다. 변수 환경은 고정된 스칼라와 리스트 집합입니다.
실제 트래픽에 닿기 전에 규칙셋을 테스트할 수 있나요?
실제 트래픽에 닿기 전에 규칙셋을 테스트할 수 있나요?
세 가지 방법이 있습니다: 편집기에서 합성 요청에 대해 dry-run하기,
shadow mode로 두고 diff 리포트 읽기, 그런 다음 100%로 올리기
전에 라이브 트래픽의 작은 비율에 canary 적용하기.
