决策原语
为智能体路由、打分排序与是否概率选择 Choice / Score / Noul,并用同一工单示例对照。
根据代码需要的答案选择原语:**Choice(选择)**从命名选项中选一个,**Score(评分)**按有序档位评价,Noul 估计答案为「是」的概率。针对同一张客服工单,可以询问哪个团队应该审核、回复草稿回答得是否完整,以及消息是否反映重复扣款。这是三种不同的判断,不是可以互换的置信度指标。
下方示例使用 @system-one-ai/core@0.8.0。参阅 TypeScript SDK 安装与配置指南和明确指定模型的托管快速开始,也可在决策 Playground 中体验相同概念。类型化抽取见 Clairic 抽取。
常见问题
Q: System One 的决策原语是什么?
A: System One 提供三个决策原语:Choice(选一个选项)、Score(有序打分)、Noul/是否判断(陈述为真的概率)。用于路由、排序与二元门禁。
Q: Noul 是什么?
A: Noul 是是否判断原语:返回条件成立的概率,用于完成检查与二元门禁。
根据应用需要的决策选择原语
先确定应用需要消费什么结果,而不是先决定使用哪一种数字格式。
| 应用任务 | 选择 | 为什么适合 | 不适用的情况 |
|---|---|---|---|
| 工单路由、意图分类或建议一个允许的下一步 | Choice | 代码需要从明确集合中选出一个命名选项,例如 billing、support 或 review。 | 不适合返回所有适用标签、生成开放式计划,也不会执行所选动作。 |
| 评价回复质量,或按明确标准对候选项排序 | Score | 代码需要一个有序评分标准上的位置,例如未回答 → 部分回答 → 完整回答。 | 不适合无序类别、通用的正确率百分比,也不能直接比较不同评分标准下的分数。 |
| 估计某个具体条件是否成立 | Noul | 代码需要二元命题的 P(true),例如「这条消息反映了重复扣款」。 | 不适合表示模型的整体置信度、在多个团队之间选择,也不能证明某件事确实发生。 |
关键区别是:Choice 回答「选哪一个」,Score 回答「按这套标准达到什么程度」,Noul 回答「这个明确命题有多大概率为真」。用是/否两个选项的 Choice 可以选出标签;如果后续策略需要条件成立的概率,应使用 Noul。Noul 值低,表示模型估计该条件不太可能成立,而不是模型缺乏信心。
如果多个标签可以同时成立,应为每个条件分别定义 Noul 问题,而不是强行使用一个 Choice。这些概率对应不同命题,并非互斥类别的概率分布,不要求相加等于一。如果权威应用数据已经明确给出某个事实,应直接使用该数据,不必再让模型推断。
同一张客服工单,三种有用判断
下方的问题构建器和组合请求使用同一份上下文:
客户消息:「同一笔订单被扣款两次。」
回复草稿:「请提供订单编号,以便我们核查两次扣款。」
| 命名问题 | 判断内容 | 应用如何使用答案 |
|---|---|---|
team — Choice | 应由付款团队、技术支持还是人工审核处理这条消息? | 建议目标队列,再检查访问权限和分配规则后路由。 |
quality — Score | 按下方三个档位,评价已有草稿对客户消息回答得有多完整。 | 标记需要补充的回复,或比较使用同一评分标准评价的草稿。 |
duplicate — Noul | 消息是否反映了重复扣款? | 标记可能的付款问题以便调查,而不是批准退款。 |
表格描述的是任务,不是真实模型结果。quality 评价的是 state 中已有的草稿,不会撰写回复,也不是给同一次调用中另一个问题生成的答案评分。duplicate 关注的是客户反映了什么。是否确有两笔已入账扣款,需要核对支付记录;是否符合退款条件,需要依据相关政策。这些答案都不能单独确立上述事实,也不能授权执行动作。
并非每张工单都需要三种原语,只询问工作流真正需要的问题。如果任务从回复质量变为工单紧急程度,应另行定义有序的紧急程度评分标准;直接复用质量分数,会让相同数字承载不同含义。
共享状态与独立问题
state 是一次请求中所有命名问题的上下文。字符串、JSON 对象或数组都表示一份共享状态,不是一批独立评估。独立状态应分别调用。只包含判断所需且允许分享的信息。
每个问题独立评估这份上下文,同一调用的某个答案不会成为另一个问题的判断依据。如果后续判断依赖前一个答案,请先审核该答案,再作为下一次调用的上下文。「独立」描述的是问题接口,不保证模型错误在统计上相互独立。
Core、原生 HTTP 与官方客户端类型
| 契约 | System One core 0.8.0 | 原生 HTTP/官方 TypeSafe SDK 0.6.0 |
|---|---|---|
| 上下文 | 必填、非 null 的 State:字符串、对象或数组 | state 必填,原生类型也允许 null |
| 问题说明 | 字段或参数必填,Description 允许 null | 原生类型允许省略或 null |
| 是非问题 | type: 'boolean',criteria 可省略或为对象 | type: 'noul',原生类型中 criteria 可省略、为对象或 null |
| 是非答案 | BooleanAnswer:probability | NoulResponse:noul |
| Choice/Score 统计 | 在规范化的 ChoiceAnswer/ScoreAnswer 中可选 | 原生 Choice 必须包含 probabilities、confidence;原生 Score 还需 legend |
类型接受 null,不代表每个服务或模型都接受。所选模型可能要求非空 instructions、限制问题名、拒绝 null 描述、要求多个 Choice 选项,或不支持扩展。发送内容应以当前模型目录和 API 契约为准,不要仅依赖最宽泛的 SDK 类型。示例使用明确文本与非 null 描述。
Choice:选择命名选项
import { choice } from '@system-one-ai/core';
const team = choice('选择负责审核这条消息的团队。', {
billing: '付款与发票',
support: '技术支持',
review: '需要人工审核或更多信息',
});工厂函数将 'billing' | 'support' | 'review' 保留为答案的选项类型。保持各选项含义清晰;强制归类会误导时,加入审核选项。
下方是原生 HTTP 答案对象示意,不是真实记录,也不是完整响应封装:
{
"type": "choice",
"choice": "review",
"probabilities": { "billing": 0.1, "support": 0.2, "review": 0.7 },
"confidence": 0.5
}choice 是已声明的选项名。原生概率分布以这些选项名为键。confidence 是独立报告的统计值,不一定等于选中选项的概率,两者都不是通用动作阈值。托管 API 最多允许 255 个 Choice 选项;还需检查所选模型的最小数量与其他限制。
Score:使用有序评分标准
import { score } from '@system-one-ai/core';
const quality = score('评估这份答案在多大程度上完整回答了问题。', [
'未回答问题',
'部分回答问题',
'完整回答问题',
]);档位下标从 0 到 档位数量 - 1。托管 API 要求 2–10 个有序档位。原生 Score 答案包含 type、score、probabilities、confidence 与 legend;概率与 legend 的键为档位下标。
分数是按档位概率加权的结果,不一定是概率最高的整数档位:
score = sum(levelIndex * probabilityAtThatLevel)
= (0 * 0.1) + (1 * 0.3) + (2 * 0.6)
= 1.5这份算术示例对应以下原生 HTTP 答案示意:
{
"type": "score",
"score": 1.5,
"probabilities": { "0": 0.1, "1": 0.3, "2": 0.6 },
"confidence": 0.3,
"legend": {
"0": "未回答问题",
"1": "部分回答问题",
"2": "完整回答问题"
}
}这里的 1.5 分不直接表示 75% 正确,也不是满分 10 分中的 1.5 分。请将评分标准与答案一起保存。修改描述或顺序会改变分数含义,也会改变用于幂等判断的请求。
使用一致的评分标准排序
Score 返回的是评分,不是排好序的列表。如果要按回答完整度对候选回复排序,应将每份草稿作为独立状态分别评估,并保持客户消息、问题、档位顺序和所选模型一致。然后由应用代码按返回分数排序,明确处理并列、结果缺失和请求失败。状态数组仍然是一份共享上下文,不能用它代替多个候选项的独立评估。
只在已定义的标准内比较结果。完整度评分不会同时衡量事实准确性、语气或退款资格;需要时,应为这些判断分别设置问题。分数相差很小,也不保证排序一定正确。在依赖排序结果之前,应使用有代表性的案例进行评估。分别评估候选项意味着分别发起调用,请将这些调用计入托管请求的积分估算。
Boolean/Noul:估计 P(true)
import { booleanQuestion } from '@system-one-ai/core';
const duplicate = booleanQuestion('这条消息是否反映了重复扣款?', {
true: '同一订单被扣款多次',
false: '没有反映重复扣款',
});使用 HTTP adapter 时,SDK 会将 boolean 问题转换为原生 noul。HTTP 答案示意如下:
{ "type": "noul", "noul": 0.8 }等价的 core 规范化答案为:
import type { BooleanAnswer } from '@system-one-ai/core';
const answer: BooleanAnswer = { type: 'boolean', probability: 0.8 };两者都表示 P(true),范围为 0 到 1。0.8 表示估计答案为「是」的概率为 80%,不是已确认事实、自动布尔结果,也不是对任一结果的置信度。Noul 没有单独的 confidence 字段。阈值、暂不执行和人工审核由应用决定。
不同检查应分开:识别出退款请求,不代表符合退款条件。资格判断需要政策和订单事实,而不仅是客户措辞。
组合命名问题与类型化答案
下面是续接示例,team、quality 和 duplicate 来自上方的问题工厂;client 是 SDK 指南中已配置的 SystemOne 客户端。运行会使用该客户端选择的服务和模型发起真实评估:
import { defineQuestions } from '@system-one-ai/core';
import type { Answers } from '@system-one-ai/core';
const questions = defineQuestions({ team, quality, duplicate });
const result = await client.evaluate({
state: {
message: '同一笔订单被扣款两次。',
answer: '请提供订单编号,以便我们核查两次扣款。',
},
questions,
});
const answers: Answers<typeof questions> = result.answers;
console.log({
team: answers.team.choice,
quality: answers.quality.score,
duplicateProbability: answers.duplicate.probability,
});原生 HTTP 将每个答案放在匹配的 answers 键下。Core 的 Answers<Q> 同样将问题映射到答案类型,但结果经过规范化,不等于原始 HTTP JSON。可选分布、confidence 或 token 计数缺失时保持未知。托管扣费和请求标识应从响应头读取,而不是使用正文中名称相近的字段。
限制与应用策略
托管请求最多允许 32 个问题、255 个 Choice 选项和 2–10 个 Score 档位。完整 UTF-8 请求大小因模型而异:Jev 与 HTTP 模式保留 64KB(65,536 字节);已迁移 Clef/Clef Flash 条目最高 13MB(13,631,488 字节),包含图片。所选模型可能更严格。图片使用独立的顶层 images 数组,与共享状态一起输入,详见图片输入。这些是托管 API 的边界,不是对所有 SDK 直连服务的承诺。
自动化前应尝试常见、模糊、信息不足及后果重大的案例。根据代表性案例和误判成本评估阈值,不要仅凭一次看似可信的响应。将缺失答案或请求失败视为未解决,而不是默认批准或最低分。
概率是预测,不是退款、修改权限或发送消息的许可。授权、动作白名单和必要确认由应用负责。工作流设计参阅接入智能体决策步骤并管理权限与恢复。
选择接入方式时,可以比较开源 TypeScript 决策 SDK 与托管决策 API 及当前模型目录。SDK 可以连接使用各自凭据和计费的服务;托管 API 使用平台密钥和预付积分。如需搭配使用,请按托管 SDK 快速开始配置凭据、选择模型并发送首次请求。