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ọiorcarouter/{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:when: và một hiệu ứng use::
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ẫu | Ví dụ |
|---|---|
| Truy cập trường | task_class == "agent" |
| So sánh số | difficulty > 0.6 && request.input_tokens < 50000 |
| Logic boolean | agent_state.has_edited && !agent_state.has_run_tests |
| Thành viên danh sách | "Edit" in agent_state.tools_used |
| Macro regex | system_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ến | Kiểu |
|---|---|
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 |
| Biến | Kiểu | Ý nghĩa |
|---|---|---|
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 | số tín hiệu suy luận phát hiện được trong prompt |
tool_count | int | số định nghĩa công cụ riêng biệt trên yêu cầu |
agent_state.*, được lưu giữ xuyên suốt một cuộc trò chuyện)
| Biến | Kiểu |
|---|---|
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> |
| Biến | Kiểu |
|---|---|
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 |
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:| Macro | Trả 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
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:param_override và header_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: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.
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ếumodel/models/@pool:đều phải giải được trong workspace của bạn. - Khoảng giá trị núm —
thinking_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;defaultlàm id quy tắc bị từ chối (hãy dùng khốidefault:cấp cao nhất).
Một ví dụ hoàn chỉnh
X-Orca-Router và X-Orca-Resolved-Model.
Tham chiếu API
DSL được quản lý theo từng router; việc ghi đòi hỏi Developer+.| Method & path | Role | Mục đích |
|---|---|---|
GET /api/user/routers/:id/dsl | Member | Nguồn + phiên bản + trạng thái shadow/canary. |
PUT /api/user/routers/:id/dsl | Developer+ | Lint + lưu (phiên bản mới, được kiểm toán). |
POST /api/user/routers/:id/dsl/lint | Member | Lint một bản nháp → {errors:[…]}. |
POST /api/user/routers/dsl/lint | Member | Lint không trạng thái (không có router id). |
POST /api/user/routers/:id/dsl/dryrun | Member | Đánh giá một yêu cầu tổng hợp → trace + quy tắc đã khớp. |
GET /api/user/routers/:id/dsl/history | Member | Lịch sử phiên bản, mới nhất trước. |
POST /api/user/routers/:id/dsl/rollback/:version | Developer+ | Lint lại và khôi phục một phiên bản cũ hơn. |
FAQ
Cái này khác gì so với chiến lược của một bộ định tuyến có tên?
Cái này khác gì so với chiến lược của một bộ định tuyến có tên?
Nó 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.Điều gì xảy ra nếu không có quy tắc nào khớp?
Điều gì xảy ra nếu không có quy tắc nào khớp?
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ể.Chạy CEL không tin cậy trên hot path có an toàn không?
Chạy CEL không tin cậy trên hot path có an toàn không?
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.
Tôi có thể kiểm thử một bộ quy tắc trước khi nó chạm vào lưu lượng thực không?
Tôi có thể kiểm thử một bộ quy tắc trước khi nó chạm vào lưu lượng thực không?
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%.
