Files
Agent-System-Backend/eval/switch.go
T
weichenandCursor 268f4a9abf Route conversations through a squad entry when selected
Why: Squad steps previously ran without tools, and the product had no way to make the squad the conversation entry without losing streaming, cards, or the deliverable guard.
Evidence: go test ./... -count=1 passed, including streaming, cardflow, false-deliverable rejection, tool allowlist, model routing, usage, cancel, and turn and tool budgets.
Impact: runtime.entry defaults to direct. squad uses one kernel step for simple work and the leader for the rest. squad_orchestrate is hidden in that mode. The default is not switched.
Refs: deliverable-quality-system B3-B5
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 09:34:53 +00:00

46 lines
1.6 KiB
Go

package eval
import (
"fmt"
"time"
)
// EntryScore 是一种入口在同一评测集上的结果。
type EntryScore struct {
Name string
Score int
FirstTokenP50 time.Duration
}
// SwitchDecision 判断能不能把默认入口改成 squad。
// 两条都要满足:squad 分数不低于 direct,直通路径多出来的首字延迟 P50 不超过 3 秒。
type SwitchDecision struct {
Met bool
Reason string
}
func DecideSwitch(direct, squad *EntryScore) SwitchDecision {
if direct == nil || squad == nil {
return SwitchDecision{Met: false, Reason: "还没有两种入口在同一评测集上的实测分数,默认保持 direct"}
}
extra := squad.FirstTokenP50 - direct.FirstTokenP50
if extra < 0 {
extra = 0
}
if squad.Score < direct.Score {
return SwitchDecision{Met: false, Reason: fmt.Sprintf("squad 分数 %d 低于 direct %d", squad.Score, direct.Score)}
}
if extra > 3*time.Second {
return SwitchDecision{Met: false, Reason: fmt.Sprintf("直通路径额外首字延迟 %s,超过 3 秒", extra)}
}
return SwitchDecision{Met: true, Reason: fmt.Sprintf("squad %d 不低于 direct %d,额外首字延迟 %s", squad.Score, direct.Score, extra)}
}
// Report 写成可以附在切换 PR 上的短报告。未达标时明确保持 direct。
func Report(dec SwitchDecision) string {
if dec.Met {
return "切换条件已满足:" + dec.Reason + "。可以把 runtime.entry 的默认值改为 squad,并保留 direct 作为回退。合入前需要产品确认。"
}
return "切换条件未满足:" + dec.Reason + "。runtime.entry 默认值保持 direct。"
}