dsl nazwanego routera — więc
Twoja aplikacja nadal wywołuje orcarouter/{name}, a logika routingu
żyje w panelu, wersjonowana i edytowalna bez redeployu.
Kiedy sięgnąć po DSL
Użyj wbudowanej strategii, gdy “najtańszy żywy model” lub “najlepsza jakość” oddaje Twoją intencję. Sięgnij po DSL, gdy routing zależy od treści lub kontekstu żądania:- Specjalizacja zadań — wysyłaj kod do modelu do kodowania, wizję do modelu wizyjnego, tani chat do taniego modelu.
- Routing świadomy trudności — eskaluj tylko trudne żądania do drogiego modelu; łatwe trzymaj tanio.
- Routing świadomy agenta — routuj różnie na podstawie stanu sesji (których narzędzi agent użył, czy testy właśnie zawiodły, która to tura).
- Reguły czasu / najemcy / nagłówka — różny routing według godziny, grupy użytkowników lub nagłówka żądania.
Włączanie
W panelu pod Routing otwórz router i ustaw jego Strategia na DSL. To odsłoni edytor DSL dla tego routera. Wszystko inne dotyczące routera nadal obowiązuje — glob Allowed models, siatka bezpieczeństwa Default model oraz wywołanieorcarouter/{name}.
Edytor
Edytor jest zbudowany tak, by szybko przeprowadzić Cię od intencji do działającego zestawu reguł:- Templates zasiane Twoimi prawdziwymi modelami z workspace (przez jednorazowy dialog mapowania tierów), więc nigdy nie zaczynasz od pustego pliku ani nie wpadasz na ścianę “unknown model”.
- Insert — wstaw Model, Router (
orcarouter/<name>) lub Pool z autouzupełniania, zamiast wpisywać identyfikatory ręcznie. - Generate — opisz routing, jakiego chcesz, zwykłym językiem i otrzymaj skompilowany, czysty wg lintingu DSL osadzony w Twoich prawdziwych modelach.
- Explain — parafraza zwykłym językiem tego, co robi bieżący zestaw reguł.
- Inline lint — każdy błąd raportuje
{line, column, message}, a każdy kod lintingu ma objaśnienie pod?. Pierwszeństwo (first-match-wins) i typowe wzorce CEL są pokazane w miejscu.
Struktura pliku
Zestaw reguł to YAML z trzema kluczami najwyższego poziomu:when: i efekt use::
when: jest prawdą. Jeśli żadna nie pasuje, stosuje się default:.
Uporządkuj reguły od najbardziej szczegółowej — szeroka, wczesna reguła
przesłoni wszystko poniżej.
when: — warunek
Warunki pisze się w CEL
(Common Expression Language): bezpiecznym z założenia — bez pętli, bez
I/O, ewaluacja w mikrosekundach, wyłącznie regex RE2. Te sześć wzorców
pokrywa zdecydowaną większość rzeczywistych reguł:
| Wzorzec | Przykład |
|---|---|
| Dostęp do pola | task_class == "agent" |
| Porównanie liczbowe | difficulty > 0.6 && request.input_tokens < 50000 |
| Logika boolowska | agent_state.has_edited && !agent_state.has_run_tests |
| Przynależność do listy | "Edit" in agent_state.tools_used |
| Makro regex | system_prompt_matches("(?i)planning agent") |
| Makro narzędzia | tool_calls_present_any(["Edit","Write","apply_patch"]) |
Zmienne
Kształt żądania| Zmienna | Typ |
|---|---|
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 |
| Zmienna | Typ | Znaczenie |
|---|---|---|
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 | sygnały rozumowania wykryte w promptcie |
tool_count | int | odrębne definicje narzędzi w żądaniu |
agent_state.*, utrwalana w obrębie konwersacji)
| Zmienna | Typ |
|---|---|
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> |
| Zmienna | Typ |
|---|---|
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 |
Makra
Zarejestrowane funkcje CEL do typowych sprawdzeń “zajrzyj do wnętrza żądania”:| Makro | Zwraca |
|---|---|
system_prompt_matches(regex) | RE2 po połączonych wiadomościach systemowych |
user_message_matches(regex) | RE2 po ostatniej wiadomości użytkownika |
tool_definitions_include(name) | narzędzie jest zadeklarowane w żądaniu |
tool_calls_present_any(list) | żądanie niesie którekolwiek z tych wywołań narzędzi |
tool_results_from_any(list) | żądanie ma wiadomości roli tool od któregokolwiek |
header_matches(name, regex) | RE2 po wartości nagłówka |
use: — efekt
Blok use: nazywa cel (dokładnie jeden) oraz dowolną liczbę
opcjonalnych pokręteł per wywołanie.
Cel
delegate: dsl jest odrzucane (powodowałoby rekurencję). Przypinanie do
konkretnych kanałów (channels: / @channel:) nie jest obecnie dostępne
i jest lintowane jako nieobsługiwane — routuj przez model, models lub
pool.Pokrętła per wywołanie
Połącz z dowolnym celem, aby ukształtować wywołanie upstream:param_override i header_override egzekwują listę zablokowanych — nie
możesz nadpisać model, messages, stream, tools, nagłówków
uwierzytelniania itp. (te podważyłyby rozliczanie, audyt lub stan agenta).
Kaskady pewności i ensemble (zaawansowane)
Dwa zaawansowane efekty pozwalają regule zareagować na słabą pierwszą odpowiedź lub rozwidlić się na kilka modeli. Tworzy się je tak samo jak każdą regułę. Cascade — ponów próbę przy sygnale niskiej pewności z silniejszym efektem:Środowisko runtime dla ensemble / cascade jest objęte bramką i
domyślnie wyłączone. Ponieważ każda odnoga równoległa i każda naprawa
kaskadowa rozlicza się jako osobne wywołanie, runtime rozwidlenia jest za
flagą serwera, dopóki rozliczanie per odnoga jest walidowane. Przy
wyłączonym, reguła
parallel: obsługuje tylko pierwszą odnogę, a kaskada
zapisuje swój sygnał, ale nie redyspozycjonuje ponownie — zestaw reguł
nadal lintuje się, zapisuje i routuje swój podstawowy efekt normalnie.
Skontaktuj się z nami, aby włączyć runtime ensemble dla Twojego workspace.Bezpieczne wdrażanie
Nowy zestaw reguł nie przejmuje Twojego ruchu w chwili, gdy go zapisujesz:- Tryb shadow — przez okno po pierwszym zapisie DSL jest
ewaluowane, ale nie używane: Twoja poprzednia strategia nadal obsługuje
ruch, podczas gdy bramka zapisuje, co DSL zrobiłoby. Panel pokazuje
raport różnic — odsetek różniących się tras, prognozowaną deltę kosztu,
liczbę odpaleń per reguła oraz jak często wpadało w
default:. Przeczytaj go, zanim zaufasz regułom. - Canary — wprowadzaj DSL na procent żywego ruchu (5 → 25 → 50 → 100), obserwując metryki per wycinek, i wycofaj natychmiast, przesuwając procent do 0.
Limity i walidacja
Każdy zapis uruchamia ścisły linting; nieprawidłowe zestawy reguł są odrzucane z{line, column, message, rule}:
- Schema — wymagane klucze, poprawne typy/enumy, brak nieznanych pól.
- Size — ≤ 30 reguł, ≤ 16 KiB YAML, ≤ 200 znaków na
when:. - CEL — parsuje się, przechodzi kontrolę typów względem środowiska
zmiennych, brak nieznanych identyfikatorów, a
when:musi ewaluować się do bool. - Effect — dokładnie jeden cel na blok
use:; wszystkie odwołaniamodel/models/@pool:muszą rozwiązać się w Twoim workspace. - Knob ranges —
thinking_budget_tokens ∈ [1024, 64000],temperature ∈ [0, 2],samples ∈ [1, 16]. - Reserved — id reguł zaczynające się od
_są zarezerwowane;defaultjako id reguły jest odrzucane (użyj blokudefault:najwyższego poziomu).
Kompletny przykład
X-Orca-Router i X-Orca-Resolved-Model
Nagłówki odpowiedzi.
Dokumentacja API
DSL jest zarządzane per router; zapisy wymagają Developer+.| Metoda i ścieżka | Rola | Cel |
|---|---|---|
GET /api/user/routers/:id/dsl | Member | Źródło + wersja + stan shadow/canary. |
PUT /api/user/routers/:id/dsl | Developer+ | Linting + zapis (nowa wersja, audytowana). |
POST /api/user/routers/:id/dsl/lint | Member | Linting szkicu → {errors:[…]}. |
POST /api/user/routers/dsl/lint | Member | Bezstanowy linting (bez id routera). |
POST /api/user/routers/:id/dsl/dryrun | Member | Ewaluacja syntetycznego żądania → ślad + dopasowana reguła. |
GET /api/user/routers/:id/dsl/history | Member | Historia wersji, najnowsze pierwsze. |
POST /api/user/routers/:id/dsl/rollback/:version | Developer+ | Ponowny linting i przywrócenie starszej wersji. |
FAQ
Czym to się różni od strategii nazwanego routera?
Czym to się różni od strategii nazwanego routera?
To jest strategia — opcja
dsl obok cheapest / quality /
balanced / adaptive. Pozostałe wybierają według ceny i jakości; DSL
wybiera według reguł, które piszesz nad kształtem żądania, jego
klasyfikacją i stanem agenta. Nadal możesz delegate: do wbudowanej
strategii jako efekt reguły lub jako default.Co się dzieje, gdy żadna reguła nie pasuje?
Co się dzieje, gdy żadna reguła nie pasuje?
Stosuje się efekt
default: najwyższego poziomu. Jest wymagany, więc
zawsze istnieje zdefiniowany wynik — zwykle delegate: balanced lub
konkretny model siatki bezpieczeństwa.Czy uruchamianie niezaufanego CEL na gorącej ścieżce jest bezpieczne?
Czy uruchamianie niezaufanego CEL na gorącej ścieżce jest bezpieczne?
Tak. CEL działa w piaskownicy wyłącznie z funkcjami biblioteki
standardowej, kilkumilisekundowym limitem czasu ewaluacji, regexem RE2
(czas liniowy, brak ReDoS) i bez dostępu do bazy danych, sieci czy
systemu plików. Środowisko zmiennych to ustalony zbiór skalarów i list.
Czy mogę przetestować zestaw reguł, zanim dotknie prawdziwego ruchu?
Czy mogę przetestować zestaw reguł, zanim dotknie prawdziwego ruchu?
Trzy sposoby: wykonaj na nim dry-run względem syntetycznego żądania
w edytorze, zostaw go w trybie shadow i przeczytaj raport różnic, a
następnie wprowadź go w canary na mały procent żywego ruchu, zanim
rozkręcisz do 100%.
