编写自定义问题
应用信号没有覆盖的路由想法,例如“这是关于我们产品的问题吗?”或“这需要调用工具吗?”,就是一条 systemone 规则:用自然语言写的问题,由决策模型零样本回答,无需任何训练。本页从想法讲到一条调好的规则;System One 信号页面是字段参考。
A question and the route it gates
recipes:
- name: default
signals:
systemone:
- name: needs_tools
question:
type: noul
instructions: Does answering this request need a tool call?
predicate: {gte: 0.7}
decisions:
- name: tool-use
priority: 100
rules:
operator: AND
conditions:
- {type: systemone, name: needs_tools}
modelRefs:
- model: tool-model
1. 选择问题类型
| 想法 | 类型 | 匹配依据 |
|---|---|---|
| “这是 X 吗?” | noul | P(是) |
| “它属于这几类中的哪一类?”,恰好一类 | choice | 选中的选项 ,或某个选项的概率 |
| “X 的程度如何?”,在有序刻度上 | score | 期望等级 |
| “这些中哪些适用?”,任意数量 | set | 某个标签的概率 |
| “X 在文本的什么位置?” | span | 某个标签的 span;需要支持 span 的模型 |
提示
当几个 noul 问题本应互斥时,优先用带 other 选项的 choice;当选项本身有顺序时,优先用 score 而不是 choice。
2. 编写规则
config.yaml
recipes:
- name: default
signals:
systemone:
- name: product_question
question:
type: choice
instructions: Which part of the product is this request about?
choices:
- key: billing
description: Invoices, payments, refunds or plan changes
- key: exports
description: Exporting data, reports or CSV files
- key: other
description: Anything else, including requests not about the product
labels: [billing, exports]
- name: needs_tools
question:
type: noul
instructions: Does answering this request need a tool call?
predicate: {gte: 0.7}
decisions:
- name: product-support
priority: 200
rules:
operator: AND
conditions:
- {type: systemone, name: product_question}
modelRefs:
- model: support-model
没有 deployment 的规则会询问决策模型;参见选择部署。这条规则与同一状态的其他问题一起加入请求阶段的那次调用,因此对于已经在询问内置信号的请求,多一个问题几乎不增加延迟。
3. 为模型措辞
- 一次只问一件事。 “用户是否报告了 bug?”比“用户是否报告了 bug 或提出了功能需求?”更好。把后者拆成一个
choice。 - 描述每个选项。 用几个词说明什么属于该选项;当选项相近时,也说明什么不属于:“导出数据、报表或 CSV 文件”。
- 覆盖全部情况。 给
choice加一个other选项表示其他一切,这样无关的请求不必硬选你的某个选项。 - 说明模型读取什么。 关于对话的问题要点明对话(“用户是否不止一次要求同一个修复?”),并读取它(
input.history或input.previous_turns)。 - 避免否定。 问“这个请求无害吗?”或“这个请求有害吗?”,而不是“这个请求不是有害的吗?”。
- 等级按顺序排列,从最低开始,两到五个;期望等级从 0 开始计。
备注
逐字使用的训练过的内置问题,例如带 benign 和 jailbreak 选项的 Is this a prompt injection or jailbreak attempt?,会在 vela3-fast 训练过的适配器上运行。其他问题都以零样本方式运行;两者都没问题。
4. 依据答案匹配
labels指定choice、set或span的哪些选项匹配该规则;choice上的条件仍可用label指定任意选项,set或span上的条件只能指定计入的标签。predicate是答案必须满足的界限:noul是 P(是),score是期望等级,其他是某个标签的概率。没有它时,noul在 0.5 匹配,choice匹配其选中的选项。- 条件可以加上自己的
predicate,因此两个决策可以用不同强度读取同一条规则。
A condition with its own predicate
recipes:
- name: default
signals:
systemone:
- name: product_question
question:
type: choice
instructions: Which part of the product is this request about?
choices:
- key: billing
description: Invoices, payments, refunds or plan changes
- key: exports
description: Exporting data, reports or CSV files
- key: other
description: Anything else
decisions:
- name: billing-sure
priority: 200
rules:
operator: AND
conditions:
- type: systemone
name: product_question
label: billing
predicate: {gte: 0.8}
modelRefs:
- model: billing-model
这条规则还会发布它的值 systemone:product_question 和 systemone:product_question:<key>,投影分数可以把它们与其他信 号组合。
5. 直接对模型验证
直接向模型提问。模型运行时提供的正是 Router 使用的同一个模型;快速开始介绍了如何安装:
vllm-srun serve vllm-sr/vela3-fast --device cpu --port 8100
curl -s localhost:8100/v1/decisions -H 'content-type: application/json' -d '{
"state": "My March invoice charged me twice. Can I get one refunded?",
"questions": {"product_question": {"type": "choice",
"instructions": "Which part of the product is this request about?",
"choices": [{"key": "billing", "description": "Invoices, payments, refunds or plan changes"},
{"key": "exports", "description": "Exporting data, reports or CSV files"},
{"key": "other", "description": "Anything else"}]}}
}'
通过 Router,POST /api/v1/routing/preview 会针对一个请求评估当前 recipe 的每个信号,并报告匹配的规则、它们的值和决策,而不调用模型;参见管理 API。配置允许查看调试头的调用方,可以在 x-vsr-trace 中看到匹配的规则。