投影(Projections)
概览
routing.projections 位于原始信号检测与最终决策匹配之间的协调层。
信号回答「匹配了什么?」决策回答「哪条路由应胜出?」投影填补中间:如何把若干信号结果协调成可复用的路由事实?
在需要以下行为时使用:
- 在竞争性的领域或嵌入通道中解析出唯一胜者
- 将多个弱信号合成为一条连续路由分数
- 将阈值策略集中定义一次,并在多条决策中复用命名结果
主要优势
- 将信号协调与决策逻辑分离,两层都可读。
- 一条加权或阈值策略可被多条决策复用。
- 提供命名路由档位(如
balance_simple、verification_required),避免散落数值比较。 - 在竞争的领域或嵌入通道间显式选出胜者。
解决什么问题?
信号刻意保持狭窄:关键词、嵌入、领域分类或上下文检测各自给出局部事实。决策刻意是布尔性的:把这些事实组合成路由规则。
中间存在实际缺口:
- 多个领域或嵌入信号可能同时匹配,但路由只需要一个胜者
- 多个弱信号合起来可能表示「请求很难」或「回答需核验」
- 同一套阈值故事要在多条决策中复用,而不能到处复制数值逻辑
没有投影时,这种协调逻辑会被塞进决策、在路由间重复,或混回检测层。routing.projections 把协调作为独立一层。
与信号、决策的关系
把流水线想成三层:
routing.signals从请求中提取可复用事实。routing.projections协调或聚合这些事实。routing.decisions用布尔策略匹配并选 择路由。
更具体地:
partitions协调已有的domain或embedding匹配,保留一个胜者scores将匹配信号聚合成一个数值mappings将该数值变成命名的投影输出- 决策仍用原生类型引用原始信号,如
domain、embedding、keyword - 决策仅通过
type: projection引用投影输出
当前实现的两条重要边界:
- 决策不直接引用分区名
- 决策不直接引用分数名
只有 mapping.outputs[*].name 会成为决策可见的 projection(...) 目标。
运行时流程
当前运行时中,投影在信号提取之后、决策评估之前:
- 基础信号在
routing.signals下运行 routing.projections.partitions归约竞争的domain或embedding匹配routing.projections.scores根据匹配信号与置信度计算数值routing.projections.mappings产生如balance_reasoning、verification_required等命名输出- 决策组合原始信号与上述命名输出
因此分区更「靠近信号」,映射更「靠近决策」。
当前约定
仓库在编写与运行时使用统一的投影命名:
- DSL 使用
PROJECTION partition、PROJECTION score、PROJECTION mapping - 规范运行时配置将同一约定存于
routing.projections.partitions、scores、mappings
当前实现支持:
exclusive或softmax_exclusive的分区method: weighted_sum的分数method: threshold_bands的映射- 可选的
method: sigmoid_distance映射校准
工作流
- 在
routing.signals下定义可复用检测器。 - 当一个领域或嵌入族在决策读取前应归一为胜者时,使用 Partitions。
- 将匹配信号合成为加权分数时,使用 Scores。
- 将分数转为命名路由档位时,使用 Mappings。
- 在
routing.decisions[*].rules.conditions[*]中用type: projection引用这些档位。
Balance 配方示例
维护中的 deploy/recipes/balance.yaml 展示了预期模式:
balance_domain_partition在维护的路由域中解析唯一领域胜者balance_intent_partition在嵌入意图通道中解析唯一胜者difficulty_score混合上下文、结构、关键词、嵌入与复杂度等证据difficulty_band将分数映射为balance_simple、balance_medium、balance_complex、balance_reasoningverification_pressure与verification_band产生如verification_required等可复用核验输出premium_legal、reasoning_deep等决策将原始domain匹配与投影输出组合
该配方重要之处在于:投影在多条路由间复用,而非单一玩具示例。
规范形态
routing:
signals:
embeddings:
- name: technical_support
threshold: 0.75
candidates: ["installation guide", "troubleshooting"]
- name: account_management
threshold: 0.72
candidates: ["billing issue", "subscription change"]
context:
- name: long_context
min_tokens: "4000"
max_tokens: "200000"
projections:
partitions:
- name: support_intents
semantics: exclusive
members: [technical_support, account_management]
default: technical_support
scores:
- name: request_difficulty
method: weighted_sum
inputs:
- type: embedding
name: technical_support
weight: 0.18
value_source: confidence
- type: context
name: long_context
weight: 0.18
mappings:
- name: request_band
source: request_difficulty
method: threshold_bands
outputs:
- name: support_fast
lt: 0.25
- name: support_escalated
gte: 0.25
PROJECTION partition support_intents {
semantics: "exclusive"
members: ["technical_support", "account_management"]
default: "technical_support"
}
PROJECTION score request_difficulty {
method: "weighted_sum"
inputs: [
{ type: "embedding", name: "technical_support", weight: 0.18, value_source: "confidence" },
{ type: "context", name: "long_context", weight: 0.18 }
]
}
PROJECTION mapping request_band {
source: "request_difficulty"
method: "threshold_bands"
outputs: [
{ name: "support_fast", lt: 0.25 },
{ name: "support_escalated", gte: 0.25 }
]
}