它要替换的不是「回答」,是「判断」
agent 里大量调用其实不是在写文字,而是在做判断:这句用户话属于哪个意图、这条工单该进哪个队列、这个工具该不该调、这段内容要不要拦。用生成式模型做这类事,你为它生成的那段文本付了钱,还得解析它、还得担心它编。Laya 的做法是把这一层单独拆出来:给一个状态(文本、邮件、工单或 JSON 文档)和一组带类型的问句,单次前向返回带概率的答案——模型不生成任何文本,所以没有东西要解析,也没有东西可以幻觉。
三种问句类型
- choice:从你给定的选项里选一个,返回每个选项的概率;
- score:给一个分档打分,例如「不紧急 / 尽快 / 已阻塞」;
- noul:是或否,用来做放行、拦截、升级这类二元判断。
它自带三个检查点,由内置 Router 按请求挑:laya(ModernBERT-large 底座,421M 参数,512 上下文,英语)、laya-multilingual(mmBERT-base,322M 参数,1024 上下文,100 多种语言,官方说比英语版更快)、laya-typed-decisions(421M、1024 上下文,面向类型化决策工作流)。
第一步:装起来
pip install laya权重在首次调用时从 Hugging Face 拉取。想在容器里试又不占本机环境,仓库文档给了 CPU 容器路线,模型文件会在多次运行之间保留。
第二步:用 Router 跑通一次判断
from laya import Router
# preload=True 时先把检查点加载进内存,之后单次路由在 35ms 级别
router = Router(preload=True)
state = {
"from": "user@acme.com",
"subject": "Duplicate charge on invoice #4411",
"body": "Hi, we were billed twice for March. Please refund the duplicate today."
}
questions = {
"department": {
"type": "choice",
"instructions": "Which department should handle this request?",
"criteria": {"billing": "invoices, payments, refunds",
"technical": "bugs, outages, system errors",
"sales": "pricing, new contracts",
"other": "everything else"}
},
"urgency": {"type": "score", "instructions": "How urgent is this request?",
"criteria": ["not urgent", "soon", "critical deadline or blocking issue"]},
"churn_risk": {"type": "noul", "instructions": "Does the user threaten to cancel?"},
"refund_requested": {"type": "noul", "instructions": "Does the user request a refund?"}
}
res = router.predict(state, questions)
print(res["answers"]["department"]["choice"]) # -> billing
print(res["routing"]["model"]) # -> english结果里除了 answers,还有一份 routing 元信息,写明这份状态被路由到了哪个检查点以及原因(例如「非拉丁文字,英语检查点读不了」)。这份元信息很实用:排查「这条中文工单为什么走了多语言模型」时不用猜。
想在不跑前向的情况下确认路由结果,可以用 router.route(state, questions).reason 单独看判断理由;如果你的流量以非英语为主,构造 Router 时把默认检查点改成多语言版,短文本就不会被默认丢给英语版。
第三步:阈值怎么定
它的概率是可以直接拿来卡阈值的,原因在训练方式:用强化学习对着严格 proper scoring rule 优化,在这套规则下「如实报概率」是唯一能最大化奖励的做法。但阈值不该照抄别人的:先把自己的历史样本跑一遍,按业务能接受的误放行率选一档,再对低置信度结果设一条人工兜底路径。
第四步:批量与自托管
- 批量:Router.predict_batch 会把请求按检查点与问句集合分组,同一组共用一次前向,避免在检查点之间来回切换;
- 可审计:预测钩子(prediction hooks)跑在每次决策前后,用来做记录、脱敏、缓存或结果拦截,不设钩子时结果与原来一致;
- 自托管:仓库带一个 HTTP 服务,API key 校验采用定时安全比对,默认把容器绑定在回环地址,并带健康检查。
什么时候不该用它
- 需要生成文本的场景(写回复、做摘要)继续用大模型,它不产出文字;
- 需要理由的场景:它给答案与概率,不给解释,合规审计要求可解释性的环节别只靠它;
- 跨长文档推理:上下文是 512 或 1024,超出就得自己做切分,切分带来的信息损失要单独评估。
判断类调用的正确归宿是分类器,不是聊天模型——把这层拆出去,账单和延迟会同时变好。