Claude Haiku 5.5 跑粗筛、强模型跑终审,分工与移交条件先写清

文章导读
跑两级流水线,先把三件事定死:粗筛输出哪些字段、什么条件下移交强模型、冲突时听谁的。这三条不落到配置和日志里,量上来之后就会出现「粗筛说通过、终审又重写」的对账问题,也说不清到底是省了还是亏了。
📋 目录
  1. 一 定义粗筛阶段的输入输出契约
  2. 二 写一个路由判定函数决定是否升级
  3. 三 规定终审结果如何覆盖粗筛结果
  4. 四 在日志里记录每次升级的原因
  5. 五 用小流量对照验证分工是否划算
A A

跑两级流水线,先把三件事定死:粗筛输出哪些字段、什么条件下移交强模型、冲突时听谁的。这三条不落到配置和日志里,量上来之后就会出现「粗筛说通过、终审又重写」的对账问题,也说不清到底是省了还是亏了。

两级分派适合「大部分任务答案形状固定、少数任务需要判断力」的场景。做法是让轻量模型只输出结构化结论与置信标记,路由按格式、关键词、长度、标记缺失决定是否升级;终审结果统一覆盖粗筛并带版本字段,下游只认一份结果。升级原因必须落日志,否则阈值无法调整,也分不清是路由问题还是模型问题。

定义粗筛阶段的输入输出契约

契约的目的只有一个:两级之间只交换结构化结果,下游不去解析自由文本。粗筛可以自由推理,但返回里必须带下列字段;缺字段一律按「未通过」处理,由路由函数决定是否升级,而不是让程序替模型猜一个默认值。

环节主要职责不做什么边界样例
粗筛(轻量模型)分类打标、格式规范化、给出结论与置信标记、引用原始片段不做需要权衡的最终判断,不输出长解释模板化问答、工单分类、字段抽取;输入较短、答案形状固定
终审(强模型)处理升级任务,给出最终结论与理由,必要时改写粗筛结论不负责修复格式;格式不合的输入先打回或标记回退多义条件、需要跨段推理、涉及金额或合规措辞的任务
路由函数只判断是否升级并给出原因不修改粗筛结果,不调用终审,不做重试每一份粗筛返回都过一遍

粗筛输出建议固定为这几个字段:task_id、conclusion(枚举内结论)、confidence_flag(高/中/低)、evidence_span(结论对应的原始片段引用,可以是偏移量加片段,也可以是片段本身)、schema_version、coarse_model。写法上建议接入层做一次校验:

{
  "task_id": "t-1001",
  "conclusion": "pass",
  "confidence_flag": "low",
  "evidence_span": {"start": 120, "end": 168, "text": "..."},
  "schema_version": "v1",
  "coarse_model": "haiku-class"
}

缺字段的处理要写死在接入层,不要分散到各业务分支:conclusion 缺失或不在枚举内,判为格式不合;confidence_flag 缺失,视为低置信;evidence_span 缺失,可以升级,但终审必须回看原文,不能只信粗筛的摘要。这样粗筛换版本或改提示词时,行为变化能被校验拦住,而不是悄悄流到下游。

Claude Haiku 5.5 跑粗筛、强模型跑终审,分工与移交条件先写清

写一个路由判定函数决定是否升级

路由函数放在粗筛返回之后、终审调用之前,输入是粗筛结果对象和原始任务,输出是「是否升级」加一组原因。路由只做判断,不重试也不改写,重试和降级策略放在外层。升级触发条件建议先收拢成这一份清单:

  • 格式不合:schema_version 不匹配,或缺少必填字段。
  • 结论越界:conclusion 不在允许的枚举内。
  • 命中关键词:按业务维护一份词表(如退款、合同、医疗、合规、投诉等),命中即升级。
  • 长度超限:输入长度超过阈值,或 evidence_span 长度异常(过短说明没找到依据)。
  • 标记缺失或自报不确定:confidence_flag 为低或为空。
  • 业务强制:任务自带「必须人工」或高风险标记。
def should_escalate(coarse, task, cfg):
    reasons = []
    if not schema_ok(coarse, cfg.schema_version):
        reasons.append("schema_mismatch")
    if coarse.conclusion not in cfg.allowed_labels:
        reasons.append("label_out_of_enum")
    if not coarse.confidence_flag:
        reasons.append("missing_confidence")
    if coarse.confidence_flag == "low":
        reasons.append("low_confidence")
    if hits_keywords(task.text, cfg.keywords):
        reasons.append("keyword_hit")
    if len(task.text) > cfg.max_len or span_too_short(coarse.evidence_span, cfg):
        reasons.append("length_exceeded")
    if task.must_human:
        reasons.append("human_required")
    return len(reasons) > 0, reasons

回退规则要单独写清楚:终审调用失败或超时,不要把粗筛的「通过」结论直接放行,建议落一个 pending_review 状态,交给异步重试或人工。如果业务上确实允许低风险类别直接出结果,那就在配置里按类别白名单放行,并在日志里留痕,别做成「超时就默认通过」的隐式行为。

规定终审结果如何覆盖粗筛结果

下游只能拿到一份最终结果,这条要在数据层保证,不能靠调用方自觉。建议粗筛记录和终审记录都写入同一张结果表,用 decided_by 和 result_version 区分,读取时取 result_version 最大的那条;粗筛的 evidence_span 作为附件保留,方便回溯。

Claude Haiku 5.5 跑粗筛、强模型跑终审,分工与移交条件先写清
{
  "task_id": "t-1001",
  "result_version": 2,
  "decided_by": "final",
  "supersedes": "coarse:t-1001:v1",
  "conclusion": "reject",
  "rewritten": true
}

覆盖规则建议按下面四条落地:终审成功返回时,终审结论即最终结论,decided_by 记为 final 并指向被覆盖的粗筛记录;终审失败或超时时不覆盖,落 pending_review,高风险场景禁止把粗筛结论当最终结论输出;终审结论与粗筛一致时也写一条终审记录,标记 rewritten=false,用于统计改写率;字段级冲突以终审为准,但分类标签这类字段如果粗筛词表稳定,可以按配置以粗筛为准,前提是把这条写进配置,而不是两边都「看起来对」。

在日志里记录每次升级的原因

没有升级日志,阈值只能凭感觉调。建议每次升级落一行 JSON,字段固定,便于后面按原因聚合:task_id、trace_id、hit_rules(直接取路由函数返回的原因数组)、coarse_output_digest(结论、置信标记、片段长度这类摘要,不必存全文)、escalated、final_rewritten(终审是否改写了结论)、final_status、coarse_latency_ms、final_latency_ms。

Claude Haiku 5.5 跑粗筛、强模型跑终审,分工与移交条件先写清
{"task_id":"t-1001","trace_id":"r-77",
 "hit_rules":["low_confidence","keyword_hit"],
 "coarse":{"conclusion":"pass","confidence":"low","span_chars":48},
 "escalated":true,"final_rewritten":true,"final_status":"ok",
 "coarse_latency_ms":null,"final_latency_ms":null}

耗时字段留空或由采集程序填,模板里不要写死数值。验证方式:按 hit_rules 分组,看哪条规则触发最多、其中 final_rewritten=false 的占比是否偏高。若某条规则大量升级但终审基本没改写,说明这条规则可能过严,可以收窄;若人工介入次数没有随升级下降,说明该升级的漏了,先查触发条件而不是先换模型。

用小流量对照验证分工是否划算

两级分派划不划算,取决于粗筛能不能挡掉真正需要终审的那部分任务。做法是取一小批真实任务,用同一套提示词和同一个终审模型跑两组:A 组全走强模型,B 组先粗筛再按路由升级。两组用同一批输入,避免任务难度不同带来的偏差;可以在现有流程旁并行记录,不影响线上结果。

指标A 全强模型B 两级分派备注
端到端耗时看分位数,不只盯平均值
终审调用次数A 组等于任务总数
升级率—命中任意触发条件的比例
改写率—终审与粗筛结论不一致的比例,反映粗筛结论质量
人工介入次数含 pending_review 与人工复核
单任务成本估算按各自计费口径填写

表里的数字要自己跑出来再填,别拿别处的结论代替。看结果时抓两点:升级率如果很高,两级分派只是多了一层开销,不如直接全走强模型;人工介入次数在 B 组没有下降,通常是路由漏掉了该升级的任务。小流量对照只用于判断分派结构是否合理,不构成对整体效果的结论;正式切换前建议保留一段并行运行,让两级结果与现有流程同时记录,确认覆盖规则和日志都能对上再收掉旧路径。