Chuyển đến nội dung chính
Các chiến lược tích hợp sẵn — cheapest, quality, balanced, adaptive — chọn một mô hình theo giá và chất lượng. Routing DSL là tầng nằm dưới chúng, dành cho khi mô hình đúng đắn phụ thuộc vào việc yêu cầu thực sự là gì: một lượt coding agentic dài, một lệnh gọi phân loại rẻ, một yêu cầu thị giác, một lần thử lại sau khi test thất bại. Bạn viết các quy tắc; cổng sẽ đánh giá chúng theo từng yêu cầu và định tuyến tương ứng. Đây là chiến lược dsl của một bộ định tuyến có tên — nên ứng dụng của bạn vẫn tiếp tục gọi orcarouter/{name} còn logic định tuyến nằm trong bảng điều khiển, được phiên bản hóa và chỉnh sửa được mà không cần triển khai lại.

Khi nào nên dùng đến DSL

Dùng một chiến lược tích hợp sẵn khi “mô hình rẻ nhất đang hoạt động” hoặc “chất lượng tốt nhất” đã nắm bắt được ý định của bạn. Dùng đến DSL khi việc định tuyến phụ thuộc vào nội dung hoặc ngữ cảnh của yêu cầu:
  • Chuyên biệt hóa theo tác vụ — gửi code đến một mô hình coding, thị giác đến một mô hình thị giác, chat rẻ đến một mô hình rẻ.
  • Định tuyến nhận biết độ khó — chỉ leo thang các yêu cầu khó đến một mô hình đắt tiền; giữ các yêu cầu dễ ở mức rẻ.
  • Định tuyến nhận biết agent — định tuyến khác nhau dựa trên trạng thái phiên (agent đã dùng những công cụ nào, test vừa thất bại hay chưa, nó đã đi được bao nhiêu lượt).
  • Quy tắc theo thời gian / tenant / header — định tuyến khác nhau theo giờ, nhóm người dùng, hoặc một header của yêu cầu.

Bật nó lên

Trong bảng điều khiển dưới mục Routing, mở một router và đặt Strategy của nó thành DSL. Thao tác đó sẽ hiển thị trình biên tập DSL cho router này. Mọi thứ khác về router vẫn được áp dụng — glob Allowed models, lưới an toàn Default model, và lệnh gọi orcarouter/{name}.

Trình biên tập

Trình biên tập được xây dựng để đưa bạn từ ý định đến một bộ quy tắc hoạt động được một cách nhanh chóng:
  • Templates được seed sẵn với các mô hình thực của workspace của bạn (qua một hộp thoại tier-mapping một lần), nên bạn không bao giờ phải bắt đầu từ một file trắng hay gặp bức tường “unknown model”.
  • Insert — chèn vào một Model, một Router (orcarouter/<name>), hoặc một Pool từ autocomplete thay vì gõ tay các định danh.
  • Generate — mô tả việc định tuyến bạn muốn bằng ngôn ngữ tự nhiên và nhận lại DSL đã biên dịch, sạch lint, dựa trên các mô hình thực của bạn.
  • Explain — một bản diễn giải bằng tiếng Anh thuần về những gì bộ quy tắc hiện tại đang làm.
  • Inline lint — mỗi lỗi báo cáo {line, column, message} và mỗi mã lint có một bộ giải thích ?. Thứ tự ưu tiên (first-match-wins) và các mẫu CEL phổ biến được hiển thị ngay tại chỗ.

Cấu trúc file

Một bộ quy tắc là YAML với ba khóa cấp cao nhất:
version: 1              # required — currently must be 1
rules: [...]            # required — 1 to 30 rules, evaluated in order
default: {...}          # required — the effect when no rule matches
Một quy tắc là một điều kiện when: và một hiệu ứng use::
rules:
  - id: hard_code              # required: ^[a-z][a-z0-9_]{0,39}$, unique
    when: |                    # optional CEL boolean; absent ⇒ always matches
      task_class == "code" && difficulty > 0.6
    use:
      model: "anthropic/claude-sonnet-4-6"
default:
  delegate: balanced           # fall back to a built-in strategy
Các quy tắc được đánh giá từ trên xuống dưới; quy tắc đầu tiên có when: đúng sẽ thắng. Nếu không có quy tắc nào khớp, default: được áp dụng. Hãy sắp xếp các quy tắc cụ thể nhất trước — một quy tắc rộng đặt sớm sẽ che khuất mọi thứ bên dưới nó.

when: — điều kiện

Các điều kiện được viết bằng CEL (Common Expression Language): an toàn theo thiết kế — không vòng lặp, không I/O, đánh giá ở mức micro giây, chỉ regex RE2. Sáu mẫu này bao phủ đại đa số các quy tắc thực tế:
MẫuVí dụ
Truy cập trườngtask_class == "agent"
So sánh sốdifficulty > 0.6 && request.input_tokens < 50000
Logic booleanagent_state.has_edited && !agent_state.has_run_tests
Thành viên danh sách"Edit" in agent_state.tools_used
Macro regexsystem_prompt_matches("(?i)planning agent")
Macro công cụtool_calls_present_any(["Edit","Write","apply_patch"])

Biến

Hình dạng yêu cầu
BiếnKiểu
modelstring
request.input_tokensint
request.output_max_tokensint
request.streambool
request.visionbool
request.message_countint
request.has_system_promptbool
request.has_toolsbool
Phân loại (do cổng tính toán theo từng yêu cầu)
BiếnKiểuÝ nghĩa
task_classstringchat / code / agent / vision / audio / rag / creative
difficultydouble0.01.0
code_keyword_densitydouble0.01.0
reasoning_cue_countintsố tín hiệu suy luận phát hiện được trong prompt
tool_countintsố định nghĩa công cụ riêng biệt trên yêu cầu
Phiên agent (agent_state.*, được lưu giữ xuyên suốt một cuộc trò chuyện)
BiếnKiểu
agent_state.turnint
agent_state.tools_usedlist<string>
agent_state.files_readlist<string>
agent_state.has_editedbool
agent_state.has_run_testsbool
agent_state.last_test_failedbool
agent_state.consecutive_errorsint
agent_state.elapsed_secondsint
agent_state.models_triedlist<string>
Ngữ cảnh
BiếnKiểu
headers["x-foo"]string
user.id / user.groupint / string
token.id / token.nameint / string
time.hour / time.weekdayint (UTC)
workspace.idint

Macro

Các hàm CEL đã đăng ký cho những kiểm tra “nhìn vào bên trong yêu cầu” phổ biến:
MacroTrả về
system_prompt_matches(regex)RE2 trên các system message đã ghép
user_message_matches(regex)RE2 trên user message cuối cùng
tool_definitions_include(name)một công cụ được khai báo trên yêu cầu
tool_calls_present_any(list)yêu cầu mang theo bất kỳ tool call nào trong số này
tool_results_from_any(list)yêu cầu có các message vai trò tool từ bất kỳ nguồn nào
header_matches(name, regex)RE2 trên giá trị một header

use: — hiệu ứng

Một khối use: đặt tên cho một đích đến (đúng một) và bất kỳ số lượng núm điều chỉnh tùy chọn theo từng lệnh gọi.

Đích đến

use:
  model:    "anthropic/claude-sonnet-4-6"   # one upstream model
  models:   ["openai/gpt-4o-mini", "..."]   # load-balance across a list
  pool:     "@pool:<name>"                   # an admin-curated pool
  delegate: balanced                         # hand off to a built-in
                                             #   strategy: cheapest |
                                             #   quality | balanced |
                                             #   linucb | gated_adaptive
delegate: dsl bị từ chối (nó sẽ đệ quy). Việc ghim vào các kênh cụ thể (channels: / @channel:) hiện chưa khả dụng và sẽ bị lint là không được hỗ trợ — hãy định tuyến theo model, models, hoặc pool thay thế.

Núm điều chỉnh theo từng lệnh gọi

Kết hợp với bất kỳ đích đến nào để định hình lệnh gọi upstream:
use:
  reasoning_effort:       low | medium | high     # OpenAI o-series, Gemini
  thinking_budget_tokens: 1024..64000             # Claude / Gemini thinking
  samples:                1..16                    # the n parameter
  temperature:            0.0..2.0
  param_override:         { ... }                  # merged into upstream params
  header_override:        { ... }                  # merged into upstream headers
  reason_tag:             "<[a-z0-9_]+>"           # shows up in logs/telemetry
  affinity_ttl:           "5m"                      # channel stickiness window
  model_rewrite:          "<upstream-model>"       # send under a different name
param_overrideheader_override thực thi một danh sách cấm — bạn không thể ghi đè model, messages, stream, tools, các header xác thực, v.v. (những thứ đó sẽ phá hoại việc tính phí, kiểm toán, hoặc trạng thái agent).

Confidence cascade & ensemble (nâng cao)

Hai hiệu ứng nâng cao cho phép một quy tắc phản ứng với một câu trả lời đầu tiên yếu hoặc tỏa rộng ra trên nhiều mô hình. Chúng được soạn theo cùng cách như bất kỳ quy tắc nào. Cascade — thử lại khi có tín hiệu độ tin cậy thấp với một hiệu ứng mạnh hơn:
rules:
  - id: code_with_repair
    when: task_class == "code"
    use:
      model: "openai/gpt-4o-mini"
    on_low_confidence:
      signals: [patch_invalid, self_doubt, next_turn_test_failed]
      use:
        model: "anthropic/claude-sonnet-4-6"   # repair attempt
Ensemble — phát đi nhiều nhánh song song và để một trọng tài chọn:
use:
  parallel:
    - { model: "anthropic/claude-sonnet-4-6" }
    - { model: "openai/gpt-4o-mini", samples: 2 }
  arbiter:
    strategy: best_of_n        # or majority | first | tests_pass
    model:    "anthropic/claude-sonnet-4-6"   # judge (best_of_n only)
  max_latency_ms: 120000
Cơ chế runtime của ensemble / cascade bị gated và mặc định tắt. Vì mỗi nhánh song song và mỗi lần sửa chữa cascade đều tính phí như một lệnh gọi riêng, nên runtime tỏa rộng nằm sau một cờ máy chủ trong khi việc tính phí theo từng nhánh đang được kiểm chứng. Khi nó tắt, một quy tắc parallel: chỉ phục vụ nhánh đầu tiên và một cascade ghi lại tín hiệu của nó nhưng không gửi lại — bộ quy tắc vẫn lint, lưu và định tuyến hiệu ứng chính của nó như bình thường. Liên hệ với chúng tôi để bật runtime ensemble cho workspace của bạn.

Triển khai một cách an toàn

Một bộ quy tắc mới không tiếp quản lưu lượng của bạn ngay khoảnh khắc bạn lưu nó:
  • Shadow mode — trong một khoảng thời gian sau lần lưu đầu tiên, DSL được đánh giá nhưng không được dùng: chiến lược trước đó của bạn vẫn phục vụ lưu lượng trong khi cổng ghi lại những gì DSL lẽ ra đã làm. Bảng điều khiển hiển thị một báo cáo diff — phần trăm các tuyến định tuyến khác biệt, độ chênh chi phí dự kiến, số lần kích hoạt theo từng quy tắc, và mức độ thường xuyên nó rơi xuống default:. Hãy đọc nó trước khi bạn tin tưởng các quy tắc.
  • Canary — tăng dần DSL lên một phần trăm lưu lượng thực (5 → 25 → 50 → 100), theo dõi các chỉ số theo từng lát, và roll back ngay lập tức bằng cách trượt phần trăm về 0.
Bạn cũng có thể dry-run một bộ quy tắc với một yêu cầu tổng hợp (task class, difficulty, agent state, hình dạng yêu cầu) ngay trong trình biên tập và xem trace cùng quy tắc đã khớp — không có lưu lượng, không có gì được lưu giữ.

Giới hạn & xác thực

Mỗi lần lưu chạy một lint nghiêm ngặt; các bộ quy tắc không hợp lệ bị từ chối với {line, column, message, rule}:
  • Schema — các khóa bắt buộc, kiểu/enum đúng, không có trường lạ.
  • Size — ≤ 30 quy tắc, ≤ 16 KiB YAML, ≤ 200 ký tự mỗi when:.
  • CEL — phân tích cú pháp, kiểm tra kiểu theo môi trường biến, không có định danh lạ, và when: phải đánh giá thành một bool.
  • Effect — đúng một đích đến mỗi khối use:; mọi tham chiếu model / models / @pool: đều phải giải được trong workspace của bạn.
  • Khoảng giá trị númthinking_budget_tokens ∈ [1024, 64000], temperature ∈ [0, 2], samples ∈ [1, 16].
  • Reserved — các id quy tắc bắt đầu bằng _ được dành riêng; default làm id quy tắc bị từ chối (hãy dùng khối default: cấp cao nhất).
Mỗi lần lưu và roll back đều ghi một hàng kiểm toán; các chỉnh sửa đồng thời được phát hiện và lần lưu thứ hai được yêu cầu thử lại với trạng thái mới.

Một ví dụ hoàn chỉnh

version: 1
rules:
  - id: vision
    when: request.vision
    use: { model: "openai/gpt-4o" }

  - id: cheap_chat
    when: task_class == "chat" && difficulty < 0.3
    use: { delegate: cheapest }

  - id: hard_code
    when: task_class == "code" && difficulty > 0.6
    use:
      model: "anthropic/claude-sonnet-4-6"
      thinking_budget_tokens: 8000
      reason_tag: hard_code

  - id: agent_after_failed_test
    when: agent_state.last_test_failed && agent_state.consecutive_errors >= 2
    use:
      model: "anthropic/claude-sonnet-4-6"
      reason_tag: repair

default:
  delegate: balanced
Để xác nhận một yêu cầu đã giải ra mô hình nào, hãy đọc các header phản hồi X-Orca-RouterX-Orca-Resolved-Model.

Tham chiếu API

DSL được quản lý theo từng router; việc ghi đòi hỏi Developer+.
Method & pathRoleMục đích
GET /api/user/routers/:id/dslMemberNguồn + phiên bản + trạng thái shadow/canary.
PUT /api/user/routers/:id/dslDeveloper+Lint + lưu (phiên bản mới, được kiểm toán).
POST /api/user/routers/:id/dsl/lintMemberLint một bản nháp → {errors:[…]}.
POST /api/user/routers/dsl/lintMemberLint không trạng thái (không có router id).
POST /api/user/routers/:id/dsl/dryrunMemberĐánh giá một yêu cầu tổng hợp → trace + quy tắc đã khớp.
GET /api/user/routers/:id/dsl/historyMemberLịch sử phiên bản, mới nhất trước.
POST /api/user/routers/:id/dsl/rollback/:versionDeveloper+Lint lại và khôi phục một phiên bản cũ hơn.

FAQ

chính là một chiến lược — tùy chọn dsl bên cạnh cheapest / quality / balanced / adaptive. Các cái khác chọn theo giá và chất lượng; DSL chọn theo các quy tắc bạn viết trên hình dạng, phân loại và trạng thái agent của yêu cầu. Bạn vẫn có thể delegate: sang một chiến lược tích hợp sẵn làm hiệu ứng của một quy tắc hoặc làm mặc định.
Hiệu ứng default: cấp cao nhất được áp dụng. Nó là bắt buộc, nên luôn có một kết quả được xác định — thường là delegate: balanced hoặc một mô hình lưới an toàn cụ thể.
Có. CEL chạy trong một sandbox chỉ với các hàm thư viện chuẩn, một hạn chót đánh giá vài mili giây, regex RE2 (thời gian tuyến tính, không ReDoS), và không có quyền truy cập cơ sở dữ liệu, mạng, hay hệ thống tệp. Môi trường biến là một tập cố định các scalar và list.
Ba cách: dry-run nó với một yêu cầu tổng hợp trong trình biên tập, để nó ở shadow mode và đọc báo cáo diff, rồi canary nó lên một phần trăm nhỏ lưu lượng thực trước khi tăng lên 100%.