6.2 option budget


6.2 option budget

本节摘要:高基数场景的第一个事实是算力事实:选项数直接进入前向的计算量与输入长度,选项越多、越慢、越贵——option budget(官方口径提供的能力)就是给这件事画预算:一次决策最多认真评多少个选项,超预算的候选怎么办。本节讲三层:预算机制本身——budget 参数怎么截断候选集合;超预算的三种裁法——按外部信号截(业务规则定的优先级)、按召回分截(粗排模型给的分数)、按分层配额截(重要类别保底名额);预算与延迟的关系——近似线性、可自测标定(示意值口径)。最后强调定位:budget 是止损机制,不是提分机制——它让高基数场景「跑得动、慢得可控」,精度问题的答案在 6.3 节的两段式。接口写法以官方仓库 README 为准。

学习目标

  • 说出 option budget 的机制:预算线拦截候选集合,超出部分不进决策头。
  • 按场景选择超预算裁法:外部信号截断、召回分截断、分层配额。
  • 用自测标定「预算对延迟」曲线,为业务定预算线(示意值口径)。
  • 分清 budget 与 shortlist 的分工:止损与提精不是一回事。

一、为什么需要预算

先看算力事实。第 1.2 节说过 choice 的答案空间是选项表——选项文本本身是模型输入的一部分。选项数增长会从两头吃算力:输入侧,N 个选项的文本都要拼进题面,序列长度随之增长;输出侧,决策头要在 N 个选项上分配概率。两头叠加的结果是延迟随选项数上升(近似关系,具体以自测为准),而官方对精度的口径更直白:约 20 个以上选项的场景 Jev 更强(官方口径)。

把两个事实放在一起,预算的存在理由就清楚了:既然选项多到一定程度后 laya 又慢又未必准,那就该在「多到一定程度」之前拦一道——option budget 就是这道闸门。它回答的问题是止损性质的:让高基数请求不要以失控的延迟与算力硬闯决策头。

无预算 vs 有预算 无预算:硬闯 有预算:先过闸门 ┌───────────────────────┐ ┌───────────────────────┐ │ 120 个选项直接进题面 │ │ 120 个候选 │ │ 序列暴涨·延迟不可控 │ │ │ budget = 16(示意)│ │ 精度还不占优(官方口径)│ │ ▼ 裁剪 │ │ │ │ │ 16 个选项进题面 │ │ ▼ │ │ 延迟可控·题面干净 │ │ 慢而不准 │ └───────────────────────┘ └───────────────────────┘ ​

二、预算怎么用

接口层面的用法很直接(参数名以官方文档为准):调用决策接口时带上 budget,候选超出预算的部分按机制裁掉。写法示意:

# budget_call.py —— 带预算的决策调用(写法示意,接口以官方仓库 README 为准) from laya import Router router = Router() result = router.predict( context="工单:企业版采购咨询,需要报价单与实施周期。", questions=[{ "id": "route", "type": "choice", "question": "这条工单应路由给哪个处理组?", "options": all_teams, # 全量候选:120 个组(示意规模) }], budget=16, # 预算线:最多认真评 16 个(示意值) ) # 超出预算的候选不进决策头;返回的 probabilities 只覆盖进入预算的选项 # (字段形态以官方文档为准) ​

使用上的第一条纪律是「兜底项必须在预算内」:选项表里的「其他」或兜底路由目标,无论预算怎么裁都必须保留——否则被裁掉的选项失去了代表,落在它们身上的流量会被迫挤进错误选项,这是预算机制最隐蔽的坑。

第二条纪律是预算要出现在监控里:每次调用实际裁掉了多少候选、裁掉的候选里事后有多少「本来该选中」,这两个数字是预算线定得合不合理的唯一直接证据(采集方式示意:把被裁候选与最终人工结果对账,第 7.3 节的弃权复核管道可以复用)。

三、超预算怎么裁:三种裁法

预算机制本身不决定裁谁,裁法是工程决策,三种常见做法:

裁法 依据 强项 弱项 适用
外部信号截断 业务规则给的优先级(VIP 客户对应组优先) 可解释、可审计 规则陈旧则失效 有成熟业务规则的存量场景
召回分截断 粗排信号(关键词命中、历史路由频率、向量召回) 自适应流量 粗排质量决定上限 无明确规则、候选动态的场景
分层配额 按类别保底名额(每大类至少 2 个,示意) 长尾不饿死 名额设计要维护 候选有天然分组结构

裁法选择的一个实用判断:召回分截断是默认解,因为它不需要人工维护规则;分层配额是召回截断的补丁,当监控显示某类候选总是被裁光时加上它。三种裁法可以叠加——先分层保底、层内按召回分排序截断,这是高基数场景里很常见的组合(示意设计)。

值得强调的是裁法与第 5.3 节 browser-agent 案例的呼应:那里「候选动作即选项表」的动态选项,在高基数页面上同样会撞预算线——按元素可见性与历史点击率先截一轮,再交给决策头,是同一思想在两个场景的复用。

四、预算与延迟:自己标定曲线

延迟与选项数的关系最稳妥的说法是「近似单调上升,斜率与硬件和文本长度有关」——所以曲线要自己标。方法与第 3.2 节批量基准同款:

# bench_budget.py —— 预算对延迟的标定(方法示意,数字以自测为准) import time def bench_options(router, n_options, repeat=3): options = [f"候选组{i}" for i in range(n_options)] question = [{"id": "route", "type": "choice", "question": "应路由给哪个组?", "options": options}] times = [] for _ in range(repeat): t0 = time.perf_counter() router.predict(context="工单:示例内容。", questions=question) times.append(time.perf_counter() - t0) return sorted(times)[repeat // 2] # 中位数 # for n in (4, 8, 16, 32, 64): # print(n, round(bench_options(router, n) * 1000, 1), "ms") ​

标定产出一张「选项数对延迟」的小表(示意形态:4 个选项数毫秒级、几十个开始爬升、逼近上限明显变慢——具体拐点以你的硬件为准),预算线从这张表上读:先定延迟上限(业务能接受的单次决策耗时),再反查曲线找到对应的选项数,那就是这台机器上这个题面的预算。延迟上限变了(业务加码)、硬件变了(换机器)、题面变了(选项文本变长),三件事任一发生都要重标——预算线是环境相关的运行参数,不是写死在代码里的常量。

五、定位:止损不提精

把 budget 的定位说死:它解决「跑得动、慢得可控」,不解决「评得准」。预算裁剪本质是放弃了部分候选的精细评估,被裁掉的候选如果恰是正确答案,预算机制对此无能为力——这正是 6.3 节两段式存在的理由:shortlist 用更聪明的粗筛把「该进决赛的候选」选进来,tournament 把决赛圈的排序做扎实。一句话分工:budget 是闸门,shortlist 加 tournament 是赛制;闸门管流量,赛制管名次。两者叠加才是高基数场景在 laya 侧的完整答案——而如果连这套组合都追不上精度要求,第 9 章的三向选型会告诉你什么时候该换 Jev。

本节要点回顾

  • 预算的存在理由是双事实:延迟随选项数上升(自测标定),约 20 个以上选项精度不占优(官方口径)。
  • 用法两纪律:兜底项必须在预算内;被裁候选的事后命中率要进监控。
  • 三种裁法:外部信号、召回分(默认解)、分层配额(长尾补丁),可叠加。
  • 预算线从自标的延迟曲线上反查:定延迟上限、查选项数上限;环境变则重标。
  • 定位:budget 止损不提精;精度归 6.3 节的赛制,追不上就到第 9 章换方案。

预算线画好了,下一节把闸门升级成赛制:shortlist 负责把上百候选筛成决赛圈,tournament 负责在决赛圈里两两对比排出可信的名次。


作者与出处
原作者: 灏天文库
整理: 灏天文库整理
本站整理收录,版权归原作者/开源协议所有;欢迎通过原文链接访问源仓库。
发布者: 作者: 灏天文库 转发
评论区 (0)
U