跳到主要内容

决策

决策服务针对文本或结构化状态回答带类型的问题,一次性给出概率,不生成说明文字。它适合封闭式的判断:某个陈述是否成立、几个选项中哪个最合适、某件事在量表上处于什么位置。使用方通过 ctx.decisions 访问所选服务。

const answer = await ctx.decisions.decide(
{message: '我被重复扣款了,邮件也没人回复。'},
{
angry: {type: 'noul', instructions: '客户很生气。'},
topic: {
type: 'choice',
instructions: '这条消息讲的是什么?',
criteria: {
billing: '被扣款、退款和付款。',
shipping: '包裹的投递和它现在在哪里。',
},
},
} as const,
{priority: 'foreground', signal},
)

answer.answers.angry.probability // 0 到 1
answer.answers.topic.choice // 'billing' | 'shipping'

同一次调用中的所有问题共用一个状态。每个答案的类型由对应的问题决定:把问题写成 as const,choice 就会收窄为你给出的选项键。

问题类型​

类型你提供你得到
noulinstructions:一个陈述或一个是非问题probability:该陈述成立的可能性,0 到 1
choiceinstructions 和 criteria:每个选项的键及其适用情形的描述choice,即概率最高的选项;每个选项的 probabilities;confidence
scoreinstructions 和 criteria:每个等级的含义,从低到高,共 2 到 10 级score,位置可以落在两个等级之间;按给定顺序排列的各等级 probabilities;confidence

状态可以是文本,也可以是提供方原样读取的 JSON。结果还包含做出决策的 model,以及提供方给出时统计的输入 tokens。

如何写问题​

决策模型只在你给出的选项之内回答,所以选项承载了问题本身。请按适用情形来描述每个选项,而不只是给它起个名字;状态只保留决策所需的内容:多余的背景会让较小的模型偏离重点。措辞会改变答案,不同模型对措辞的理解也不同。依赖答案之前,请先用自己的样例在所选模型上试一试,并在更换模型或措辞时把这些样例当作回归测试保留下来。

根据概率行动​

决策服务返回概率,调用方因此可以采纳把握大的答案,把没把握的交给更慢的服务。

const {answers} = await ctx.decisions.decide(state, questions)
if (answers.topic.confidence < 0.8) return askALanguageModel(state)
return answers.topic.choice

并非每种问题类型和每个模型的概率都同样可信:有些模型即使答错也会报告很高的置信度。请根据自己的样例选择阈值,而不要照搬其他提供方的数值,并预期它会随模型而变。

运行时会检查什么​

运行时会在请求到达提供方之前拒绝无法回答的请求,错误为 AiError,代码是 invalid-input:状态为空、没有问题、问题没有说明、选项少于两个或有选项没有描述的 choice,以及等级少于 2 或多于 10 的 score。模型自身的限制(选项数量、状态长度)由其提供方负责执行。

答案在交出之前也会被检查。有问题未被回答、答案类型不对、选项从未提供过,或概率不在 0 到 1 之间,都说明提供方行为异常,调用会以 unavailable 失败,而不是把结果继续传下去。

优先级、取消与并发​

调用支持共用的 priority 和 signal 选项。一次决策调用在并发闸门中是独立的能力,因此可以把决策和语言模型分配到不同的限制中,让决策不必排在语言模型任务之后,反之亦然。

提供方​

TypeSafe 通过其托管的 Jev 模型提供决策。LocalAI 通过安装在其中的决策模型提供决策。两者都通过库 @dsh-ai-providers/systemone 使用 System One API;复制了这套 API 的其他服务器,例如加载了决策模型的 llama.cpp llama-server,也可以通过自定义基础 URL 使用。