把 Microsoft-Decision-1 放进流程分岔点之前,先固定两样东西:这个节点在调用前必须采集到哪些字段,以及字段缺失或输出不可用时走哪条路。凡是输出会直接触发不可逆动作(放款、永久封禁、额度变更)的节点,通常不适合由模型直接拍板,模型结果只作为建议值进入人工队列。先写输入和回退条件,再写调用代码,后续才谈得上复现和审计。
判断方向:把 Microsoft-Decision-1 放在“输出是可枚举标签或分值、且下游有人工兜底”的分岔节点。操作动作:为每个分岔点登记必需输入字段、缺失值处理方式和回退触发条件,并生成 input_hash。验证方式:用历史工单回放,检查字段覆盖率与回退是否按预期触发。风险边界:模型输出只作为建议值时,不要让该输出直接执行不可逆动作;阈值和枚举由业务方设定,不要写死在代码里。
在流程图上标出适合交给 Microsoft-Decision-1 的分岔
做法是把现有流程图摊开,逐个节点问三件事:这个节点的输出是不是一组可枚举的标签或分值;拿不到模型结果时业务能不能停下来等人工;判断错一次会不会造成不可逆后果。第三问只要答“会”,该节点就不该由模型直接执行。
| 节点名称 | 决策类型 | 模型输出形式 | 人工兜底动作 | 不自动执行的理由 |
|---|---|---|---|---|
| 工单分类路由 | 多分类 | 队列标签 | 组长在后台改派 | 错分只影响响应时长,可回退 |
| 退款初审 | 二分类加依据 | 建议通过 / 建议复核 | 一律进入人工复核队列 | 涉及资金,输出只能当建议 |
| 风险等级标记 | 有序标签 | 低 / 中 / 高 | 高风险由风控人工确认 | 标签会联动后续策略 |
| 客户升级等级判断 | 多分类 | 等级候选 | 客服主管确认后生效 | 等级对外可见,需人工签字 |
| 账号永久封禁 | 不接入 | 无 | 全部人工处理 | 不可逆,影响用户资产 |
表里“不自动执行”的节点,在流程图上通常画成菱形后接一个人工任务节点。人工节点要写清楚进入条件、处理人角色和超时后的升级对象,否则回退会变成没人认领的悬空任务。
写出决策前必须采集的输入字段
输入字段的目标是让同一个请求在任意时间重放都能得到同一份模型输入。字段名、是否必填、缺失时行为建议放在同一份配置里,让校验逻辑和调用代码读同一处,避免两边规则漂移。
| 字段名 | 类型 | 示例值 | 缺失值处理 |
|---|---|---|---|
| ticket_text | string | “收到货后外包装破损” | 必填,为空直接触发回退 |
| order_amount | decimal | 299.00 | 必填,缺失按回退处理,不要填 0 |
| channel | enum | web / app / phone | 必填,取值不在枚举内按回退处理 |
| created_at | timestamp | 2024-05-06T09:12:00+08:00 | 必填,参与时区和先后顺序判断 |
| customer_tier | enum | gold | 可选,缺失写 UNKNOWN 并带标记位 |
| refund_history_count | integer | 2 | 可选,缺失写 -1,模型侧按未知处理 |
可选字段用显式的哨兵值(如 UNKNOWN、-1),不要用空字符串冒充缺失,否则回放时分不清“真的没有”和“上游漏传”。同时对每次请求计算 input_hash,覆盖参与决策的全部字段值。
required_fields = ["ticket_text", "order_amount", "channel", "created_at"]
optional_defaults = {"customer_tier": "UNKNOWN", "refund_history_count": -1}
def build_input(raw):
missing = [f for f in required_fields if raw.get(f) in (None, "")]
if missing:
return None, {"fallback": "missing_required", "fields": missing}
payload = {**optional_defaults, **raw}
return payload, None
为每个分岔点定义回退触发条件
回退条件写成“触发条件 + 回退动作 + 日志字段”三件套,按分岔点分别登记。触发条件建议至少覆盖:必填字段缺失、字段取值超出枚举、调用超时、输出结构校验失败、输出标签不在白名单、置信度低于业务方设定的阈值。
decision_points:
refund_review:
model: microsoft-decision-1
rules:
- when: missing_required_fields
action: route_to_queue
queue: refund_manual_review
- when: enum_value_invalid
action: route_to_queue
queue: refund_manual_review
- when: model_timeout
action: route_to_queue
queue: refund_manual_review
- when: output_schema_invalid
action: reject_and_log
- when: label_not_in_allowlist
action: reject_and_log
- when: low_confidence
action: route_to_queue
log_fields: [request_id, decision_point, model_version, input_hash,
trigger_reason, fallback_action, operator_id, timestamp]
阈值不要写死在调用代码里,放在配置中便于按节点调整。低置信度时建议直接转人工,而不是取一个默认标签放行,默认标签会让回放结果失真。日志里的 trigger_reason 用固定枚举值,便于后续统计哪类回退最常见。
用历史工单回放输入和回退条件
回放的目的不是评估模型效果,而是检查当前字段和回退规则能不能覆盖常见情况。样本选择上建议覆盖:每个已登记的分岔点至少一批;曾经触发过人工介入的工单;字段缺失或取值异常的工单;时间跨度跨过业务规则变更点的工单。
- 从只读快照导出历史工单,保留调用时可见的字段,不要带入工单结束后的补充信息。
- 按分岔点分组,逐条走 build_input 校验,统计必填缺失率和不合格枚举值。
- 对通过校验的工单调用模型,记录输出标签、input_hash 和回退是否触发。
- 把模型标签与历史人工处理结果拉平对比,输出不一致清单。
- 逐条看不一致:属于字段缺失造成的,补上游采集;属于回退过严的,调整枚举或阈值。
需要调整的字段或条件通常集中在两类:某个必填字段在历史数据里缺失率偏高,说明上游系统根本没采集,此时要么补采集,要么把它降为可选并明确缺失语义;某条回退规则触发过于频繁,说明条件本身写得过宽,需要按节点拆分。
把人工复核结果写回流程记录
人工处理完成后,把复核结果写回同一条流程记录,并复用请求的 request_id 与 input_hash,这样后续审计能顺着 request_id 还原当时看到的是哪份输入、模型给了什么、人工改成了什么。
{
"request_id": "req-8f21c7",
"decision_point": "refund_review",
"model_version": "microsoft-decision-1",
"input_hash": "...",
"label_before": "suggest_review",
"label_after": "manual_pass",
"reviewer": "zhang.wei",
"reviewed_at": "2024-05-06T14:02:11+08:00",
"note": "客户已提供补发凭证,按现行规则放行",
"fallback_action": "route_to_queue"
}
复核人、复核时间、修改前后标签、备注这四项建议设为必填,label_before 记录模型原始输出而不是回退后的最终标签。备注字段即使允许自由文本,也建议要求写明依据类型(凭证、规则条款、主管授权),方便后续按依据类型抽样复查。