Skip to content

共享热词召回与请求隔离 ​

同一个姓名在普通识别中正确、在目标识别中变成同音词,不一定是词库无效。两种模式可能使用不同 Finalizer:普通路径带请求热词及词库召回,目标路径只带固定目标提示词。热词要进入最终使用的解码提示词,网关收到热词字段并不等于模型使用了它。

共享热词解析器与独立解码路径

在 Finalizer 边界共享解析能力 ​

将热词能力提取为解析接口,网关构造一份实例,并显式注入普通、角色子段和目标 Finalizer。解析结果属于请求,不存回共享对象;普通和目标模型仍各自解码。

go
// 简化的接口示例,省略具体错误与计时结构。
type HotwordRequest struct {
    PCM       []int16
    PoolID    string
    Explicit  []string
}

type HotwordResolver interface {
    Resolve(ctx context.Context, request HotwordRequest) ([]string, error)
}

父请求的显式词和 pool ID 传给角色子段,子段以自己的 PCM 做召回。若直接复用父句所有召回词,会给无关角色施加错误先验。目标识别只编码待识别混合音频做词库召回,不把登记参考里的词带入当前内容。

解析顺序与可选依赖预算 ​

text
清洗显式请求词
  -> 读取词库快照
  -> 空池:跳过音频编码
  -> 非空池:编码当前 PCM,按 pool ID 召回
  -> 合并去重、同音词处理与数量限制
  -> 普通提示词 / 目标约束 + 热词提示词

显式词优先,召回词补充上下文。合并后控制数量和长度,避免词库规模直接膨胀为提示词规模。词库支持大量词条与单次 API 接受多少条是两种限制,应分批导入,而不是把超限拒绝当作词库容量不足。

召回是可选依赖,使用请求剩余时间中的部分预算。音频编码或检索失败时退回清洗后的显式词;文本合并服务失败时至少做精确去重。身份门控和目标约束是必需条件,不能套用相同回退方式。

空池快照只对当前请求有效。下一次请求重新观察更新,不能缓存“永远为空”而跳过后续新增词条。模型重试保留原任务的热词与目标约束,不能第一次带热词、恢复识别时丢掉。

实时检索与词库管理隔离 ​

实时 worker 处理语音召回,管理 worker 处理大词库的文本编码、增删和重载。两者分开可以避免一次词库更新堵住所有语音请求,普通与目标场景无需各建一套实时 worker。

词库更新采用快照切换:先在临时状态解析、校验和构建新索引,成功后原子替换;失败保留旧快照。坏编码文件不能先清空旧池再报错。缓存文本向量时,键包含规范化词条和编码模型身份,模型变化使旧向量失效。

并发隔离 ​

共享对象保存模型客户端、词库和只读配置;每个请求单独保存 PCM、pool ID、显式词、召回结果和提示词。两组并发请求使用不同姓名及不同池,检查模型实际提示词,能发现仅看最终文字不易察觉的串词。

回归场景断言
仅显式词三种模式的实际提示词都包含对应词
仅词库当前音频触发召回,不借用登记参考内容
空池后新增当前跳过编码,后续请求看到新快照
召回超时保留显式词与解码剩余预算
坏文件重载旧池继续可用
多池并发请求局部变量和模型提示词无交叉污染
目标重试登记参考、目标约束与热词均保留

热词的作用边界 ​

热词改变解码先验,不等于确定性拼写替换。过量或错误召回可能诱导无音频依据的文字;后处理字符串替换也无法恢复漏掉的语音。保留原始模型文本与规范化结果,对照同音词、无关词和空词库反例。热词质量、目标过滤与角色归属各自验证。

别急,先让缓存热一下。