DSL routingu: skomponuj panel modeli, który myśli jak Fable 5

DSL routingu: skomponuj panel modeli, który myśli jak Fable 5

Data publikacji

Powrót do wszystkich wpisów

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: balanced


when: 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: balanced


Zmienne, 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_tools


Klasyfikacja

task_class (chat/code/agent/vision/audio/rag/creative), difficulty (0.0–1.0), code_keyword_density, reasoning_cue_count, log_prompt_tokens, tool_count


Sesja 

agent_state.turn, agent_state.tools_used, agent_state.has_edited, agent_state.last_test_failed, agent_state.consecutive_errors, agent_state.models_tried


Kontekst

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_nLLM 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: balanced


Ten 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.


© 2026 OrcaRouter