dsl d’un routeur nommé — donc
votre application continue d’appeler orcarouter/{name} et la logique de routage
réside dans le tableau de bord, versionnée et modifiable sans redéploiement.
Quand recourir au DSL
Utilisez une stratégie intégrée quand « modèle vivant le moins cher » ou « meilleure qualité » capture votre intention. Recourez au DSL quand le routage dépend du contenu ou contexte de la requête :- Spécialisation par tâche — envoyez le code à un modèle de codage, la vision à un modèle de vision, le chat bon marché à un modèle bon marché.
- Routage sensible à la difficulté — n’escaladez que les requêtes difficiles vers un modèle coûteux ; gardez les faciles bon marché.
- Routage sensible à l’agent — routez différemment selon l’état de session (quels outils l’agent a utilisés, si les tests viennent d’échouer, à combien de tours il en est).
- Règles d’heure / locataire / en-tête — routage différent selon l’heure, le groupe d’utilisateurs ou un en-tête de requête.
L’activer
Dans le tableau de bord sous Routing, ouvrez un routeur et réglez sa Stratégie sur DSL. Cela révèle l’éditeur DSL pour ce routeur. Tout le reste du routeur s’applique toujours — le glob Modèles autorisés, le filet de sécurité Modèle par défaut, et l’invocationorcarouter/{name}.
L’éditeur
L’éditeur est conçu pour vous faire passer de l’intention à un jeu de règles fonctionnel rapidement :- Templates ensemencés avec les modèles réels de votre espace de travail (via une boîte de dialogue de mappage de niveaux à usage unique), de sorte que vous ne partez jamais d’un fichier vide ni ne vous heurtez à un mur « modèle inconnu ».
- Insert — déposez un Model, un Router (
orcarouter/<name>), ou un Pool depuis l’autocomplétion au lieu de saisir les identifiants à la main. - Generate — décrivez le routage que vous voulez en langage clair et obtenez en retour un DSL compilé, propre au lint, ancré dans vos modèles réels.
- Explain — une paraphrase en français simple de ce que fait le jeu de règles actuel.
- Lint en ligne — chaque erreur rapporte
{line, column, message}et chaque code de lint a un explicateur?. La priorité (premier-match-gagne) et les motifs CEL courants sont mis en évidence sur place.
Structure du fichier
Un jeu de règles est du YAML avec trois clés de premier niveau :when: et un effet use: :
when: est vrai
gagne. Si aucune ne correspond, default: s’applique. Ordonnez vos règles de la plus
spécifique d’abord — une règle large en début masque tout ce qui se trouve en dessous.
when: — la condition
Les conditions sont écrites en CEL
(Common Expression Language) : sûr par conception — pas de boucles, pas d’E/S,
évaluation en microsecondes, regex RE2 uniquement. Ces six motifs couvrent la grande
majorité des règles réelles :
| Motif | Exemple |
|---|---|
| Accès à un champ | task_class == "agent" |
| Comparaison numérique | difficulty > 0.6 && request.input_tokens < 50000 |
| Logique booléenne | agent_state.has_edited && !agent_state.has_run_tests |
| Appartenance à une liste | "Edit" in agent_state.tools_used |
| Macro regex | system_prompt_matches("(?i)planning agent") |
| Macro d’outil | tool_calls_present_any(["Edit","Write","apply_patch"]) |
Variables
Forme de la requête| 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 | Signification |
|---|---|---|
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 | indices de raisonnement détectés dans le prompt |
tool_count | int | définitions d’outils distinctes sur la requête |
agent_state.*, persistée à travers une conversation)
| 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 |
Macros
Fonctions CEL enregistrées pour les vérifications courantes « regarder à l’intérieur de la requête » :| Macro | Retourne |
|---|---|
system_prompt_matches(regex) | RE2 sur les messages système joints |
user_message_matches(regex) | RE2 sur le dernier message utilisateur |
tool_definitions_include(name) | un outil est déclaré sur la requête |
tool_calls_present_any(list) | la requête porte l’un de ces appels d’outil |
tool_results_from_any(list) | la requête a des messages de rôle outil provenant de l’un d’eux |
header_matches(name, regex) | RE2 sur la valeur d’un en-tête |
use: — l’effet
Un bloc use: nomme une destination (exactement une) et un nombre quelconque de
boutons de réglage optionnels par appel.
Destination
delegate: dsl est rejeté (cela créerait une récursion). L’épinglage à des
canaux spécifiques (channels: / @channel:) n’est pas disponible actuellement et est signalé
au lint comme non pris en charge — routez plutôt par model, models ou pool.Boutons par appel
À combiner avec n’importe quelle destination pour façonner l’appel amont :param_override et header_override appliquent une liste de blocage — vous ne pouvez pas
remplacer model, messages, stream, tools, les en-têtes d’authentification, etc.
(cela subvertirait la facturation, l’audit ou l’état de l’agent).
Cascades de confiance et ensembles (avancé)
Deux effets avancés permettent à une règle de réagir à une première réponse faible ou de se déployer sur plusieurs modèles. Ils se rédigent de la même façon que n’importe quelle règle. Cascade — nouvelle tentative sur un signal de faible confiance avec un effet plus fort :Le runtime d’ensemble / cascade est restreint et désactivé par défaut. Comme
chaque branche parallèle et chaque réparation en cascade est facturée comme son propre appel, le
runtime de déploiement est derrière un drapeau serveur pendant que la facturation par branche est
validée. Lorsqu’il est désactivé, une règle
parallel: ne sert que la première branche et
une cascade enregistre son signal mais ne redéclenche pas — le jeu de règles passe quand même
le lint, s’enregistre et route son effet principal normalement. Contactez-nous pour
activer le runtime d’ensemble pour votre espace de travail.Déployer en toute sécurité
Un nouveau jeu de règles ne prend pas en charge votre trafic dès l’instant où vous l’enregistrez :- Mode shadow — pendant une fenêtre après le premier enregistrement, le DSL est
évalué mais pas utilisé : votre stratégie précédente sert toujours le trafic
pendant que la passerelle enregistre ce que le DSL aurait fait. Le tableau de bord
affiche un rapport de diff — pourcentage de routes divergentes, delta de coût projeté,
nombre de déclenchements par règle, et à quelle fréquence il est retombé sur
default:. Lisez-le avant de faire confiance aux règles. - Canary — montez progressivement le DSL sur un pourcentage du trafic en direct (5 → 25 → 50 → 100), en surveillant les métriques par tranche, et revenez en arrière instantanément en faisant glisser le pourcentage à 0.
Limites et validation
Chaque enregistrement exécute un lint strict ; les jeux de règles invalides sont rejetés avec{line, column, message, rule} :
- Schéma — clés requises, types/enums corrects, aucun champ inconnu.
- Taille — ≤ 30 règles, ≤ 16 Kio de YAML, ≤ 200 caractères par
when:. - CEL — analyse, vérification de type contre l’environnement de variables, aucun
identifiant inconnu, et
when:doit s’évaluer en un bool. - Effet — exactement une destination par bloc
use:; toutes les référencesmodel/models/@pool:doivent se résoudre dans votre espace de travail. - Plages des boutons —
thinking_budget_tokens ∈ [1024, 64000],temperature ∈ [0, 2],samples ∈ [1, 16]. - Réservé — les ids de règle commençant par
_sont réservés ;defaultcomme id de règle est rejeté (utilisez le blocdefault:de premier niveau).
Un exemple complet
X-Orca-Router et
X-Orca-Resolved-Model.
Référence API
Le DSL est géré par routeur ; les écritures requièrent Developer+.| Méthode et chemin | Rôle | But |
|---|---|---|
GET /api/user/routers/:id/dsl | Member | Source + version + état shadow/canary. |
PUT /api/user/routers/:id/dsl | Developer+ | Lint + enregistrement (nouvelle version, audité). |
POST /api/user/routers/:id/dsl/lint | Member | Lint d’un brouillon → {errors:[…]}. |
POST /api/user/routers/dsl/lint | Member | Lint sans état (sans id de routeur). |
POST /api/user/routers/:id/dsl/dryrun | Member | Évalue une requête synthétique → trace + règle correspondante. |
GET /api/user/routers/:id/dsl/history | Member | Historique des versions, la plus récente d’abord. |
POST /api/user/routers/:id/dsl/rollback/:version | Developer+ | Re-lint et restaure une version antérieure. |
FAQ
En quoi est-ce différent de la stratégie d'un routeur nommé ?
En quoi est-ce différent de la stratégie d'un routeur nommé ?
C’est une stratégie — l’option
dsl aux côtés de cheapest / quality /
balanced / adaptive. Les autres choisissent selon le prix et la qualité ; le DSL
choisit selon des règles que vous écrivez sur la forme, la classification et
l’état d’agent de la requête. Vous pouvez toujours delegate: vers une stratégie intégrée comme
effet d’une règle ou comme valeur par défaut.Que se passe-t-il si aucune règle ne correspond ?
Que se passe-t-il si aucune règle ne correspond ?
L’effet
default: de premier niveau s’applique. Il est requis, donc il y a
toujours un résultat défini — couramment delegate: balanced ou un modèle
filet de sécurité spécifique.Est-il sûr d'exécuter du CEL non fiable sur le chemin critique ?
Est-il sûr d'exécuter du CEL non fiable sur le chemin critique ?
Oui. CEL s’exécute dans un bac à sable avec seulement les fonctions de la bibliothèque standard, une
échéance d’évaluation de quelques millisecondes, des regex RE2 (temps linéaire, pas de
ReDoS), et aucun accès à la base de données, au réseau ou au système de fichiers. L’
environnement de variables est un ensemble fixe de scalaires et de listes.
Puis-je tester un jeu de règles avant qu'il ne touche le trafic réel ?
Puis-je tester un jeu de règles avant qu'il ne touche le trafic réel ?
Trois façons : faites-en un dry-run contre une requête synthétique dans l’éditeur,
laissez-le en mode shadow et lisez le rapport de diff, puis faites-en un canary
sur un petit pourcentage de trafic en direct avant de monter à 100 %.
