DSL routingu: skomponuj panel modeli, który myśli jak Fable 5
Przez dwa lata podręcznik "więcej inteligencji" brzmiał: "poczekaj na następny model". Uważamy, że to błędna jednostka postępu. Granica nie jest pojedynczym punktem kontrolnym – to panel. Daj trzy dobre modele ten sam trudny problem, pozwól im się nie zgodzić, a następnie rozstrzygnij między odpowiedziami, a panel pokonuje każdego ze swoich członków. Często pokonuje następny model wyżej w cenniku.
Ten Routing DSL to sposób, w jaki buduje się ten panel. Jest to programowalna strategia routingu — YAML + CEL — która przekształca Twój endpoint OrcaRouter w graf inferencyjny: kieruj według trudności, kieruj według zadania, rozdzielaj do kilku modeli jednocześnie, oceniaj lub głosuj na ich wyniki, cofaj się, gdy pewność jest niska, i dostrajaj całość pod kątem kosztów, opóźnienia lub jakości. Piszesz reguły; brama kompiluje i uruchamia je przy każdym żądaniu w ~5 ms.
Ten post to przewodnik inżynieryjny: gramatyka, zmienne, na których można rozgałęziać, cztery arbitry, kaskada oraz kompletny zestaw reguł produkcyjnych na końcu.
Najpierw wynik
Dwa ilustracyjne benchmarki. (Liczby są ilustracyjne — mają pokazać kształt efektu, a nie być cytowane jako oficjalne wyniki.)
Porównanie Frontier — punkt końcowy DSL z routowaniem trudnościowym vs. samotna granica:

Panele Fusion a modele solo — oceniono na 93 z 100 zadań (z OpenRouter):

Trzy rzeczy, na które warto popatrzeć:
Każdy panel fuzyjny pokonuje każdego ze swoich członków. Opus 4.8 + GPT-5.5 (~67.5%) pokonuje zarówno Opus solo (~58.5%), jak i GPT-5.5 solo (~60%) o 7–9 punktów. Niezgodność to sygnał; arbitraż go wykorzystuje.
Fusion osiąga kolejny poziom. Trzy różne panele krzyżują się Fable 5 solo (~65.5%) używając tylko modeli poniżej niego.
Nie potrzebujesz drogich subskrypcji. Opus + Opus self-fusion (~65,5%) dorównuje Fable 5 z jednym modelem i samplerem. Panel tanich modeli — Gemini 3 Flash + Kimi K2.6 + DeepSeek V4 Pro (~64,5%) — plasuje się tuż poniżej Fable 5 za ułamek kosztu na token. To cała teza: kupuj inteligencję za pomocą topologii, a nie za pomocą kolejnego przedziału cenowego.
Routing DSL to powierzchnia sterująca, która pozwala inwestować tę topologię tylko tam, gdzie się opłaca — tanie modele na łatwe 80%, panel fuzyjny na trudny ogon.
Gramatyka w 30 sekund
Zestaw reguł to wersja, lista reguł i wymagana domyślna. Reguły są oceniane od góry do dołu; pierwsze when: które jest prawdziwe wygrywa. Brak when: oznacza „zawsze pasuje”.
wersja: 1
rules:
- id: only_rule
use: { model: "claude-sonnet-4-6" }
default:
delegate: balancedwhen: jest CEL wyrażenie boolowskie — piaskownicowe, wyrażenie regularne tylko RE2, brak pętli, brak we/wy, ocena w mikrosekundach, z pojedynczym limitem 5 ms wspólnym dla całego zestawu reguł. use: to efekt: gdzie idzie żądanie i jak jest dostrajane. Limity są celowo małe (≤30 reguł, ≤16 KiB źródła, ≤200 znaków na when:), aby zestaw reguł pozostał audytowalny.
Primitive 1 — trasa według trudności i zadania
Dystrybutor klasyfikuje każde żądanie przed routowaniem i udostępnia funkcje do CEL. Rozgałęzisz się na nich bezpośrednio:
wersja: 1
rules:
- id: hard_reasoning
when: difficulty > 0.8
use:
model: "claude-opus-4-8"
reasoning_effort: "high"
thinking_budget_tokens: 32000
- id: code_path
when: task_class == "code" && code_keyword_density > 0.5
use: { model: "gpt-5.5" }
- id: cheap_chat
when: difficulty < 0.3
use: { model: "gemini-3-flash" }
default:
delegate: balancedZmienne, które możesz odczytać w when: (skrócone — zobacz pełną dokumentację w dokumentach):
Przykłady grup
Kształt żądania
request.input_tokens, request.output_max_tokens, request.stream, request.vision, request.message_count, request.has_toolsKlasyfikacja
task_class (chat/code/agent/vision/audio/rag/creative), difficulty (0.0–1.0), code_keyword_density, reasoning_cue_count, log_prompt_tokens, tool_countSesja
agent_state.turn, agent_state.tools_used, agent_state.has_edited, agent_state.last_test_failed, agent_state.consecutive_errors, agent_state.models_triedKontekst
headers["x-…"], user.group, token.name, time.hour, workspace.id
…plus six macros for the things regex-over-payload is good at: system_prompt_matches(re), user_message_matches(re), tool_definitions_include(name), tool_calls_present_any([…]), tool_results_from_any([…]), header_matches(name, re).Każde miejsce docelowe może przenosić pokrętła na połączenie, przekształcone na natywne parametry każdego dostawcy przez adapter przekazujący: reasoning_effort (niski/średni/wysoki), thinking_budget_tokens (1024–64000), samples (1–16), temperature (0.0–2.0), plus param_override / header_override zabezpieczone listą blokad. To już wystarczy, aby zbudować punkt końcowy z routingiem według trudności z Tabeli A: tani model na łatwym ogonie, Opus z budżetem myślowym na trudnym.
Prymityw 2 — rozgałęzienie do panelu (fuzja)
To jest źródło wzrostu benchmarku. Równolegle: efekt wysyła zapytanie do 2–5 odnóg jednocześnie, a następnie arbiter decyduje o tym, co faktycznie widzi klient:
- id: hard_tail_panel
when: difficulty > 0.7 && task_class == "agent"
use:
parallel:
- { model: "anthropic/claude-opus-4-8", reasoning_effort: "high" }
- { model: "openai/gpt-5.5", thinking_budget_tokens: 16000 }
- { model: "google/gemini-3.1-pro", temperature: 0.3 }
arbiter:
strategy: best_of_n
model: "anthropic/claude-sonnet-4-6" # the judge
template: judge_code
max_latency_ms: 120000
on_disagreement: # majority-only escape hatch
model: "anthropic/claude-opus-4-8"
reasoning_effort: "high"Cztery strategie arbitra, każda z inną odpowiedzią na pytanie 'czyje wyjście wygrywa?':
pierwszy — uruchom konkurencyjne zadania, obsłuż pierwszy sukces, anuluj przegrane. Optymalizuje opóźnienie (otrzymujesz najszybsze z N).
większość — ustrukturyzowane głosowanie na podstawie wyjść odnogów, bez dodatkowego wywołania modelu. Gdy odnogi dzielą się bez ścisłej większości, opcjonalna gałąź on_disagreement: ponownie wysyła świeżą, silniejszą próbę zamiast przeprowadzać dogrywkę. Optymalizuje solidność w zadaniach z kanoniczną odpowiedzią.
best_of_n — LLM judge czyta wszystkie kandydatury i je rankuje. To jest konfiguracja Opus + GPT-5.5 → judge z Tabeli B. Optymalizuje jakość nad otwartymi zadaniami; wraca do pierwszej udanej, jeśli sędzia popełni błąd.
tests_pass — execution-grounded: wybiera kandydata, którego łatka faktycznie powoduje przejście zestawu testów. Bez zgadywania sędziego — decyduje uprząż. To najsilniejszy arbiter dla pracy kodu/agenta. Weryfikator znajduje się poza bramką (podłączony przez VerifierProvider); jeśli żaden nie jest podłączony, degradowany jest do first-successful.
max_latency_ms (1000–600000, domyślnie 120000) ogranicza rozgałęzienie (fan-out), tak aby jedna wolna gałąź nie mogła zablokować odpowiedzi – opóźnione są odrzucane. Zagnieżdżanie konstrukcji `parallel` wewnątrz `parallel` jest odrzucane podczas lintowania; panel celowo ma tylko jeden poziom głębokości.
Uwaga dotycząca dostępności: środowisko uruchomieniowe N-kierunkowego fan-out jest blokowane przez flagę serwera ROUTING_DSL_ENSEMBLE_RUNTIME , a rozliczenia za poszczególne nogi są testowane (hardened) na środowisku staging – dlatego fusion jest w wersji preview, a nie GA. Gdy flaga jest wyłączona, reguła parallel: czysto obsługuje swoją pierwszą nogę, więc możesz już teraz tworzyć i shadowować swoje panele, a włączyć je, gdy fusion pojawi się w Twoim regionie.
Prymityw 3 — mechanizmy awaryjne i kaskady ufności
Fan-out wydaje N× z góry. Kaskada wydaje dodatkowo tylko wtedy, gdy pierwsza odpowiedź wygląda na błędną. Po odpowiedzi, on_low_confidence: ocenia sygnały i, jeśli któryś z nich zostanie uruchomiony, ponownie przekazuje do silniejszego miejsca docelowego:
- id: agent_with_safety_net
when: task_class == "agent"
use:
pool: "@pool:fast"
on_low_confidence:
signals: [patch_invalid, self_doubt, next_turn_test_failed]
threshold: { low_logprob: -1.5 }
use:
model: "claude-opus-4-8"
reasoning_effort: "high"Sygnały: patch_invalid (diff nie przechodzi git apply --check), self_doubt (zestaw wyrażeń regularnych dla fraz zabezpieczających), low_logprob (średnie logprawdopodobieństwo tokenów poniżej progu, jeśli dostawca je udostępnia), i next_turn_test_failed (zatrzask międzyobrotowy — podpowiedź tej tury przenosi kształt nieudanych testów poprzedniej tury). Kaskady są z założenia głębokości 1. Połącz je z agent_state.models_tried, aby uzyskać różnorodność przy ponownym wysłaniu — nigdy nie wysyłaj naprawy do modelu, który właśnie zawiódł.
Dostrajanie pokrętła: koszt, opóźnienie, jakość
Ten sam DSL wyraża wszystkie trzy cele; wybierasz na regułę:
Koszt — deleguj: najtańszy, zostaw tani model na łatwym ogonie i zarezerwuj rozgałęzianie dla trudności > 0.7. Tani panel z Tabeli B (~64,5% ≈ Fable 5 solo) jest dowodem na istnienie: fuzja małych modeli może zastąpić model graniczny za ułamek kosztu na token. Bądź jednak świadomy — fuzja używa "bill every leg" modelu: panel best_of_n z 3 nogami obciąża trzy kandydatury plus sędziego. Ekonomika działa, ponieważ (a) rozgałęziasz się tylko na trudnej mniejszości zapytań oraz (b) łączysz tańszych członków niż model graniczny, który zastępujesz.
Latencja — arbiter: { strategy: first } plus ścisłe max_latency_ms daje najszybszy z N z twardym ograniczeniem.
Jakość — best_of_n dla pracy otwartej, tests_pass, gdy istnieje zestaw testów, na którym można się oprzeć. próbki i thinking_budget_tokens kupują więcej w ramach jednej nogi.
Obsługiwanie go bez psucia produkcji
Zmiany routingu są przerażające, więc DSL jest wyposażony w zabezpieczenia, jakich oczekuje SRE:
Lint przy każdym zapisie — schemat, kontrola typów CEL (każdy when: musi być obliczany do wartości bool), rozwiązywanie referencji, zakresy pokręteł, listy zablokowanych nagłówków/parametrów. Błędy są zwracane jako {line, column, message, rule} i wyświetlane jako znaczniki w rynience w edytorze.
Suchy przebieg — POST syntetyczne żądanie (task_class, difficulty, agent_state, …) i uzyskaj dopasowaną regułę, rozstrzygnięty efekt oraz czas ewaluacji, zanim cokolwiek zostanie wysłane.
Tryb cienia — przez 24 godziny po pierwszym zapisie DSL jest oceniany, ale nieużywany; dziennik cienia rejestruje potencjalne wybory, a konsola pokazuje różnicę (procent zmienionych tras, prognozowana dzienna delta kosztów, liczby uruchomień reguł).
Canary — suwak ruchu od 0 do 100. Zwiększaj stopniowo: 5 → 25 → 50 → 100, obserwując metryki dla każdego wycinka; cofnij, przesuwając do 0.
Audyt + rollback — każdy zapis/wycofanie zapisuje wiersz audytu w tej samej transakcji; równoczesne edycje otrzymują 409 z bieżącą wersją, więc ponawiasz próbę na świeżym stanie.
Przypadki testowe, powtórzenia śladów oraz widok AI "wyjaśnij ten zestaw reguł" uzupełniają całość. Znajdziesz to w dashboardzie pod routing → strategy → DSL.
Kompletny zestaw reguł
Tanio na łatwym, średnio na średnim, oceniany panel fuzyjny na twardym agentycznym ogonie, z kaskadą pewności pod spodem:
wersja: 1
rules:
- id: trivial
when: difficulty < 0.3 && !has_tools
use: { model: "gemini-3-flash" }
- id: standard
when: difficulty < 0.7
use:
model: "gpt-5.5"
on_low_confidence:
signals: [self_doubt, low_logprob]
use: { model: "claude-opus-4-8", reasoning_effort: "high" }
- id: hard_agent_panel
when: difficulty >= 0.7 && task_class == "agent"
use:
parallel:
- { model: "anthropic/claude-opus-4-8", reasoning_effort: "high" }
- { model: "openai/gpt-5.5", thinking_budget_tokens: 16000 }
- { model: "google/gemini-3.1-pro" }
arbiter:
strategy: tests_pass # execution-grounded; judged fallback if no harness
max_latency_ms: 180000
on_disagreement:
model: "claude-opus-4-8"
reasoning_effort: "high"
default:
delegate: balancedTen punkt końcowy znajduje się na szczycie Tabeli A — nie dlatego, że znalazł lepszy model, ale dlatego, że wydaje właściwy model na właściwe żądanie i scala panel dokładnie tam, gdzie panel wygrywa.
Rozpocznij pisanie
Następny skok w możliwościach nie musi czekać na kolejny punkt kontrolny. To graf, który możesz napisać dziś po południu: kieruj według trudności, rozgałęziaj na twardym ogonie, oceniaj lub testuj wyniki, kaskaduj, gdy spada pewność.
Dokumentacja: https://docs.orcarouter.ai/routing/routing-dsl
Interfejs użytkownika: routing → Utwórz router -> Strategia routingu → DSL (ekspert)
Granica to panel. Zbuduj swój.
